Commit 875f4af0 authored by Malsha Jayakody's avatar Malsha Jayakody

Merge remote-tracking branch 'origin/feature/skin-manage' into final-app

parents 3909a05d 2be5b4f1
{
"java.compile.nullAnalysis.mode": "automatic"
}
\ No newline at end of file
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- optionally, if you want to record audio: --> <!-- optionally, if you want to record audio: -->
<uses-permission android:name="android.permission.RECORD_AUDIO" /> <uses-permission android:name="android.permission.RECORD_AUDIO" />
......
...@@ -51,6 +51,7 @@ ...@@ -51,6 +51,7 @@
"eslint": "^8.19.0", "eslint": "^8.19.0",
"jest": "^29.6.3", "jest": "^29.6.3",
"prettier": "2.8.8", "prettier": "2.8.8",
"react-native-image-picker": "^7.1.1",
"react-test-renderer": "18.2.0", "react-test-renderer": "18.2.0",
"typescript": "5.0.4" "typescript": "5.0.4"
}, },
...@@ -3260,6 +3261,14 @@ ...@@ -3260,6 +3261,14 @@
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
}, },
"node_modules/@react-native-community/cli-config/node_modules/deepmerge": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
"integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/@react-native-community/cli-config/node_modules/has-flag": { "node_modules/@react-native-community/cli-config/node_modules/has-flag": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
...@@ -3363,6 +3372,14 @@ ...@@ -3363,6 +3372,14 @@
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
}, },
"node_modules/@react-native-community/cli-doctor/node_modules/deepmerge": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
"integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/@react-native-community/cli-doctor/node_modules/has-flag": { "node_modules/@react-native-community/cli-doctor/node_modules/has-flag": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
...@@ -3948,6 +3965,14 @@ ...@@ -3948,6 +3965,14 @@
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
}, },
"node_modules/@react-native-community/cli/node_modules/deepmerge": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
"integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/@react-native-community/cli/node_modules/has-flag": { "node_modules/@react-native-community/cli/node_modules/has-flag": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
...@@ -4398,22 +4423,6 @@ ...@@ -4398,22 +4423,6 @@
"react": "*" "react": "*"
} }
}, },
"node_modules/@react-navigation/core/node_modules/escape-string-regexp": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/@react-navigation/core/node_modules/react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
"node_modules/@react-navigation/elements": { "node_modules/@react-navigation/elements": {
"version": "1.3.30", "version": "1.3.30",
"resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-1.3.30.tgz", "resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-1.3.30.tgz",
...@@ -4440,17 +4449,6 @@ ...@@ -4440,17 +4449,6 @@
"react-native": "*" "react-native": "*"
} }
}, },
"node_modules/@react-navigation/native/node_modules/escape-string-regexp": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/@react-navigation/routers": { "node_modules/@react-navigation/routers": {
"version": "6.1.9", "version": "6.1.9",
"resolved": "https://registry.npmjs.org/@react-navigation/routers/-/routers-6.1.9.tgz", "resolved": "https://registry.npmjs.org/@react-navigation/routers/-/routers-6.1.9.tgz",
...@@ -4844,6 +4842,14 @@ ...@@ -4844,6 +4842,14 @@
} }
} }
}, },
"node_modules/@svgr/plugin-svgo/node_modules/deepmerge": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
"integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/@svgr/plugin-svgo/node_modules/js-yaml": { "node_modules/@svgr/plugin-svgo/node_modules/js-yaml": {
"version": "4.1.0", "version": "4.1.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
...@@ -6085,6 +6091,14 @@ ...@@ -6085,6 +6091,14 @@
"node": ">=4" "node": ">=4"
} }
}, },
"node_modules/chalk/node_modules/escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
"engines": {
"node": ">=0.8.0"
}
},
"node_modules/char-regex": { "node_modules/char-regex": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz",
...@@ -6111,17 +6125,6 @@ ...@@ -6111,17 +6125,6 @@
"node": ">=12.13.0" "node": ">=12.13.0"
} }
}, },
"node_modules/chrome-launcher/node_modules/escape-string-regexp": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/chromium-edge-launcher": { "node_modules/chromium-edge-launcher": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/chromium-edge-launcher/-/chromium-edge-launcher-1.0.0.tgz", "resolved": "https://registry.npmjs.org/chromium-edge-launcher/-/chromium-edge-launcher-1.0.0.tgz",
...@@ -6135,17 +6138,6 @@ ...@@ -6135,17 +6138,6 @@
"rimraf": "^3.0.2" "rimraf": "^3.0.2"
} }
}, },
"node_modules/chromium-edge-launcher/node_modules/escape-string-regexp": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/chromium-edge-launcher/node_modules/mkdirp": { "node_modules/chromium-edge-launcher/node_modules/mkdirp": {
"version": "1.0.4", "version": "1.0.4",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
...@@ -6799,9 +6791,9 @@ ...@@ -6799,9 +6791,9 @@
"dev": true "dev": true
}, },
"node_modules/deepmerge": { "node_modules/deepmerge": {
"version": "4.3.1", "version": "2.2.1",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz",
"integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", "integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==",
"engines": { "engines": {
"node": ">=0.10.0" "node": ">=0.10.0"
} }
...@@ -7266,11 +7258,14 @@ ...@@ -7266,11 +7258,14 @@
"integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
}, },
"node_modules/escape-string-regexp": { "node_modules/escape-string-regexp": {
"version": "1.0.5", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
"integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
"engines": { "engines": {
"node": ">=0.8.0" "node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/eslint": { "node_modules/eslint": {
...@@ -7359,6 +7354,15 @@ ...@@ -7359,6 +7354,15 @@
"eslint": ">=4.19.1" "eslint": ">=4.19.1"
} }
}, },
"node_modules/eslint-plugin-eslint-comments/node_modules/escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
"dev": true,
"engines": {
"node": ">=0.8.0"
}
},
"node_modules/eslint-plugin-ft-flow": { "node_modules/eslint-plugin-ft-flow": {
"version": "2.0.3", "version": "2.0.3",
"resolved": "https://registry.npmjs.org/eslint-plugin-ft-flow/-/eslint-plugin-ft-flow-2.0.3.tgz", "resolved": "https://registry.npmjs.org/eslint-plugin-ft-flow/-/eslint-plugin-ft-flow-2.0.3.tgz",
...@@ -7598,18 +7602,6 @@ ...@@ -7598,18 +7602,6 @@
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true "dev": true
}, },
"node_modules/eslint/node_modules/escape-string-regexp": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
"dev": true,
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/eslint/node_modules/eslint-scope": { "node_modules/eslint/node_modules/eslint-scope": {
"version": "7.2.2", "version": "7.2.2",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
...@@ -8291,14 +8283,6 @@ ...@@ -8291,14 +8283,6 @@
"react": ">=16.8.0" "react": ">=16.8.0"
} }
}, },
"node_modules/formik/node_modules/deepmerge": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz",
"integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/fresh": { "node_modules/fresh": {
"version": "0.5.2", "version": "0.5.2",
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
...@@ -8662,11 +8646,6 @@ ...@@ -8662,11 +8646,6 @@
"react-is": "^16.7.0" "react-is": "^16.7.0"
} }
}, },
"node_modules/hoist-non-react-statics/node_modules/react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
"node_modules/hsluv": { "node_modules/hsluv": {
"version": "0.0.3", "version": "0.0.3",
"resolved": "https://registry.npmjs.org/hsluv/-/hsluv-0.0.3.tgz", "resolved": "https://registry.npmjs.org/hsluv/-/hsluv-0.0.3.tgz",
...@@ -9787,6 +9766,15 @@ ...@@ -9787,6 +9766,15 @@
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true "dev": true
}, },
"node_modules/jest-config/node_modules/deepmerge": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
"integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/jest-config/node_modules/has-flag": { "node_modules/jest-config/node_modules/has-flag": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
...@@ -12863,6 +12851,11 @@ ...@@ -12863,6 +12851,11 @@
"url": "https://github.com/chalk/ansi-styles?sponsor=1" "url": "https://github.com/chalk/ansi-styles?sponsor=1"
} }
}, },
"node_modules/pretty-format/node_modules/react-is": {
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
"integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="
},
"node_modules/process-nextick-args": { "node_modules/process-nextick-args": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
...@@ -12898,11 +12891,6 @@ ...@@ -12898,11 +12891,6 @@
"react-is": "^16.13.1" "react-is": "^16.13.1"
} }
}, },
"node_modules/prop-types/node_modules/react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
"node_modules/proxy-from-env": { "node_modules/proxy-from-env": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
...@@ -13032,9 +13020,9 @@ ...@@ -13032,9 +13020,9 @@
} }
}, },
"node_modules/react-is": { "node_modules/react-is": {
"version": "18.3.1", "version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
}, },
"node_modules/react-native": { "node_modules/react-native": {
"version": "0.73.6", "version": "0.73.6",
...@@ -13133,6 +13121,16 @@ ...@@ -13133,6 +13121,16 @@
"react-native": "*" "react-native": "*"
} }
}, },
"node_modules/react-native-image-picker": {
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/react-native-image-picker/-/react-native-image-picker-7.1.2.tgz",
"integrity": "sha512-b5y5nP60RIPxlAXlptn2QwlIuZWCUDWa/YPUVjgHc0Ih60mRiOg1PSzf0IjHSLeOZShCpirpvSPGnDExIpTRUg==",
"dev": true,
"peerDependencies": {
"react": "*",
"react-native": "*"
}
},
"node_modules/react-native-linear-gradient": { "node_modules/react-native-linear-gradient": {
"version": "2.8.3", "version": "2.8.3",
"resolved": "https://registry.npmjs.org/react-native-linear-gradient/-/react-native-linear-gradient-2.8.3.tgz", "resolved": "https://registry.npmjs.org/react-native-linear-gradient/-/react-native-linear-gradient-2.8.3.tgz",
...@@ -13507,6 +13505,12 @@ ...@@ -13507,6 +13505,12 @@
"react": "^18.2.0" "react": "^18.2.0"
} }
}, },
"node_modules/react-test-renderer/node_modules/react-is": {
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
"integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
"dev": true
},
"node_modules/react-test-renderer/node_modules/scheduler": { "node_modules/react-test-renderer/node_modules/scheduler": {
"version": "0.23.2", "version": "0.23.2",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
...@@ -14803,7 +14807,7 @@ ...@@ -14803,7 +14807,7 @@
"version": "5.0.4", "version": "5.0.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz",
"integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==", "integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==",
"dev": true, "devOptional": true,
"bin": { "bin": {
"tsc": "bin/tsc", "tsc": "bin/tsc",
"tsserver": "bin/tsserver" "tsserver": "bin/tsserver"
......
...@@ -9,6 +9,7 @@ export default { ...@@ -9,6 +9,7 @@ export default {
gray: '#666666', gray: '#666666',
grayLight: '#ccc', grayLight: '#ccc',
black: '#0a0a0a', black: '#0a0a0a',
blue:'#ADC4CE',
navyBlue: '#000080', navyBlue: '#000080',
purple: '#DFCCFB', purple: '#DFCCFB',
light_purple: '#D9ACF5', light_purple: '#D9ACF5',
......
...@@ -5,6 +5,16 @@ export default { ...@@ -5,6 +5,16 @@ export default {
ex_2: require('../assets/ex_2.jpg'), ex_2: require('../assets/ex_2.jpg'),
ex_3: require('../assets/ex_3.jpg'), ex_3: require('../assets/ex_3.jpg'),
ex_4: require('../assets/ex_4.jpg'), ex_4: require('../assets/ex_4.jpg'),
sk_1: require('../assets/sk_1.png'),
sk_2: require('../assets/sk_2.png'),
sk_3: require('../assets/sk_3.png'),
sk_7: require('../assets/sk_7.png'),
sk_5: require('../assets/sk_5.png'),
sk_8: require('../assets/sk_8.png'),
sk_9: require('../assets/sk_9.png'),
sk_14: require('../assets/sk_14.png'),
sk_15: require('../assets/sk_15.png'),
sk_16: require('../assets/sk_16.png'),
//games //games
......
...@@ -24,6 +24,19 @@ export default { ...@@ -24,6 +24,19 @@ export default {
EXERCISE_ACTION_VIEW: 'Exercise_ACTION_View', EXERCISE_ACTION_VIEW: 'Exercise_ACTION_View',
EXERCISE_PROGRESS: 'Exercise_PROGRESS', EXERCISE_PROGRESS: 'Exercise_PROGRESS',
//skin
SKIN_WELCOME: 'Skin_Welcome',
SKIN_UPLOAD: 'Skin_Upload',
SKIN_RISK: 'Skin_Risk',
SKIN_VIDEO: 'Skin_Video',
SKIN_VIDEO1: 'Skin_Video1',
SKIN_VIDEO2: 'Skin_Video2',
SKIN_VIDEO3: 'Skin_Video3',
SKIN_VIDEO4: 'Skin_Video4',
SKIN_VIDEO5: 'Skin_Video5',
EXERCISE_PROGRESS: 'Exercise_PROGRESS',
//GAMES //GAMES
GAME_HOME: 'Game_Home', GAME_HOME: 'Game_Home',
......
...@@ -4,7 +4,8 @@ import Home from '../screens/home/Home'; ...@@ -4,7 +4,8 @@ import Home from '../screens/home/Home';
import Settings from '../screens/home/Settings'; import Settings from '../screens/home/Settings';
import WelcomeExercise from '../screens/home/exercise/WelcomeExercise'; import WelcomeExercise from '../screens/home/exercise/WelcomeExercise';
// import { Home, Wallet, Settings, WelcomeExercise} from '../screens'; // import { Home, Wallet, Settings, WelcomeExercise} from '../screens';
import ExerciseNavigator from './ExerciseNavigator'; import ExerciseNavigator from './ExerciseNavigator'
import SkinNavigator from './SkinNavigator';
import {COLORS, ROUTES} from '../constants'; import {COLORS, ROUTES} from '../constants';
import Icon from 'react-native-vector-icons/Ionicons'; import Icon from 'react-native-vector-icons/Ionicons';
import {StyleSheet} from 'react-native'; import {StyleSheet} from 'react-native';
...@@ -35,6 +36,12 @@ function BottomTabNavigator() { ...@@ -35,6 +36,12 @@ function BottomTabNavigator() {
) : ( ) : (
<Icon name="home-outline" size={22} color={color} /> <Icon name="home-outline" size={22} color={color} />
); );
} else if (route.name === ROUTES.SKIN_WELCOME) {
return focused ? (
<Icon name="home" size={22} color={color} />
) : (
<Icon name="home-outline" size={22} color={color} />
);
} else if (route.name === ROUTES.EXERCISE_HOME) { } else if (route.name === ROUTES.EXERCISE_HOME) {
return focused ? ( return focused ? (
<Logo1 width={22} height={22} /> <Logo1 width={22} height={22} />
...@@ -47,12 +54,6 @@ function BottomTabNavigator() { ...@@ -47,12 +54,6 @@ function BottomTabNavigator() {
) : ( ) : (
<Icon name="game-controller-outline" size={22} color={color}/> <Icon name="game-controller-outline" size={22} color={color}/>
); );
} else if (route.name === ROUTES.SETTINGS) {
return focused ? (
<Icon name="notifications-sharp" size={22} color={color} />
) : (
<Icon name="notifications-outline" size={22} color={color} />
);
} else if (route.name === ROUTES.LOGIN) { } else if (route.name === ROUTES.LOGIN) {
return focused ? ( return focused ? (
<Icon name="person-circle-sharp" size={22} color={color} /> <Icon name="person-circle-sharp" size={22} color={color} />
...@@ -70,11 +71,11 @@ function BottomTabNavigator() { ...@@ -70,11 +71,11 @@ function BottomTabNavigator() {
}} }}
/> />
<Tab.Screen <Tab.Screen
name={ROUTES.SETTINGS} name={ROUTES.SKIN_WELCOME}
component={Settings} component={SkinNavigator}
options={{ options={{
tabBarButton: props => <CustomTabBarButton {...props} />, tabBarButton: props => <CustomTabBarButton {...props} />,
}} }}
/> />
<Tab.Screen <Tab.Screen
name={ROUTES.GAME_HOME} name={ROUTES.GAME_HOME}
......
import React from 'react';
import { createStackNavigator } from '@react-navigation/stack';
import WelcomeSkin from '../screens/home/skin/WelcomeSkin';
import Camera from '../screens/home/skin/SkinUploader';
import SkinRisk from '../screens/home/skin/SkinRisk';
import AdditionalSymptoms from '../screens/home/skin/AdditionalSymptoms';
import AdditionalSymptoms1 from '../screens/home/skin/AdditionalSymptoms1';
import AdditionalSymptoms2 from '../screens/home/skin/AdditionalSymptoms2';
import AdditionalSymptoms3 from '../screens/home/skin/AdditionalSymptoms3';
import AdditionalSymptoms4 from '../screens/home/skin/AdditionalSymptoms4';
import AdditionalSymptoms5 from '../screens/home/skin/AdditionalSymptoms5';
import {COLORS, ROUTES} from "../constants"
const Stack = createStackNavigator();
function SkinNavigator() {
return (
<Stack.Navigator screenOptions={{
headerBackTitleVisible: false,
headerShown: false
}}
initialRouteName={ROUTES.SKIN_WELCOME}>
<Stack.Screen name={ROUTES.SKIN_WELCOME} component={WelcomeSkin} />
<Stack.Screen name={ROUTES.SKIN_UPLOAD} component={Camera} />
<Stack.Screen name={ROUTES.SKIN_VIDEO} component={AdditionalSymptoms} />
<Stack.Screen name={ROUTES.SKIN_RISK} component={SkinRisk} />
<Stack.Screen name={ROUTES.SKIN_VIDEO1} component={AdditionalSymptoms1} />
<Stack.Screen name={ROUTES.SKIN_VIDEO2} component={AdditionalSymptoms2} />
<Stack.Screen name={ROUTES.SKIN_VIDEO3} component={AdditionalSymptoms3} />
<Stack.Screen name={ROUTES.SKIN_VIDEO4} component={AdditionalSymptoms4} />
<Stack.Screen name={ROUTES.SKIN_VIDEO5} component={AdditionalSymptoms5} />
</Stack.Navigator>
);
}
export default SkinNavigator;
\ No newline at end of file
import React, { useState, useRef, useEffect } from 'react';
import { View, StyleSheet, Text, ScrollView, TouchableOpacity, ActivityIndicator, Image } from 'react-native';
import { COLORS ,IMGS, ROUTES} from '../../../constants';
import CheckBox from '@react-native-community/checkbox'; // Make sure to install this package
import Video from 'react-native-video'; // Make sure to install this package
import Button from '../../../components/Button';
import { SafeAreaView } from 'react-native-safe-area-context';
import { Dimensions } from 'react-native';
import { Linking } from 'react-native';
const AdditionalSymptomsScreen = ({ navigation }) => {
const [selectedSymptoms, setSelectedSymptoms] = useState({
symptom1: false, symptom2: false, symptom3: false, symptom4: false,
symptom5: false, symptom6: false, symptom7: false, symptom8: false,
symptom9: false, symptom10: false, symptom11: false, symptom12: false,
symptom13: false, symptom14: false
});
const [loading, setLoading] = useState(true);
const [videoPaused, setVideoPaused] = useState(true);
const [fullscreen, setFullscreen] = useState(false);
const [controlsVisible, setControlsVisible] = useState(false);
const hideTimer = useRef(null);
const URL_link = "https://res.cloudinary.com/dl207ux6g/video/upload/v1715374532/3D/wfu4pr9phnadjqargex4.mp4";
const videoRef = useRef(null);
const screenHeight = Dimensions.get('window').height;
const imageHeight = screenHeight * 0.20;
const symptomsGroups = [
[
{ key: 'symptom1', text: 'Headache | හිසරදය' },
{ key: 'symptom2', text: 'Shoulder pain | උරහිස් වේදනාව' },
{ key: 'symptom3', text: 'Upper Abdominal pain | ඉහළ උදරයේ වේදනාව' },
{ key: 'symptom4', text: 'Lower Abdomen pain | පහළ උදරයේ වේදනාව' },
],
[
{ key: 'symptom5', text: 'Swollen Ankle pain | ඉදිමුණු වළලුකර වේදනාව' },
{ key: 'symptom6', text: 'Leg joint pain | පාදයේ සන්ධි වේදනාව' },
{ key: 'symptom7', text: 'Thigh muscle pain | කලවා මාංශ පේශි වේදනාව' },
{ key: 'symptom8', text: 'Groin pain | ඉකිලි වේදනාව' },
{ key: 'symptom9', text: 'Breast Pain |පියයුරු වේදනාව'},
{ key: 'symptom10', text: 'Side muscle pain | පැත්තේ මාංශ පේශි වේදනාව'},
],
[
{ key: 'symptom11', text: 'Upper arm pain | ඉහළ අතේ වේදනාව' },
{ key: 'symptom12', text: 'Heart burn | හදවත දැවෙනවා' },
{ key: 'symptom13', text: 'Mouth and Nose ulcer’s | මුඛයේ සහ නාසයේ වණ'},
{ key: 'symptom14', text: 'Back Pain |පිටුපස මාංශ පේශි වේදනාව'},
],
// Add more groups as needed
];
const handleLoad = () => {
setLoading(false);
};
const handleBuffer = () => {
setLoading(true);
};
const toggleCheckbox = (symptom) => {
setSelectedSymptoms(prevState => ({
...prevState,
[symptom]: !prevState[symptom],
}));
};
const handleSubmit = () => {
// Checking for specific symptoms that lead to SKIN_RISK
const skinRiskSymptoms = ['symptom12', 'symptom5', 'symptom4','symptom10', 'symptom8', 'symptom6'];
const toSkinRisk = skinRiskSymptoms.some(symptom => selectedSymptoms[symptom]);
// Navigate based on condition
if (toSkinRisk) {
navigation.navigate(ROUTES.SKIN_RISK);
} else {
navigation.navigate(ROUTES.SKIN_UPLOAD);
}
};
const toggleFullscreen = () => {
if (videoRef.current) {
if (!fullscreen) {
videoRef.current.presentFullscreenPlayer(); // This will open the video in fullscreen
} else {
videoRef.current.dismissFullscreenPlayer(); // This will exit the fullscreen mode
}
setFullscreen(!fullscreen); // Toggle the fullscreen state
}
};
const togglePlayPause = () => {
setVideoPaused(!videoPaused);
showControlsTemporarily(); // Toggle the pause state of the video
};
const showControlsTemporarily = () => {
setControlsVisible(true);
if (hideTimer.current) {
clearTimeout(hideTimer.current);
}
hideTimer.current = setTimeout(() => {
setControlsVisible(false);
}, 3000); // Hide controls after 3 seconds of inactivity
};
useEffect(() => {
return () => {
if (hideTimer.current) {
clearTimeout(hideTimer.current);
}
};
}, []);
return (
<SafeAreaView style={styles.container}>
<ScrollView style={styles.scrollContainer} contentContainerStyle={styles.contentContainer}>
<View style={styles.topContainer}>
<Text style={styles.topicText}>Discoid Additional Symptoms </Text>
<View style={styles.videoBox}>
<View style={styles.videoDescriptionBox}>
<Text style={styles.descriptionText}>
Self diagnose with the 3D Model
</Text>
</View>
<TouchableOpacity style={styles.videoContainer} onPress={showControlsTemporarily}>
<Video
// ref={videoRef}
source={{ uri: URL_link }} // Replace with the path to your video file
style={[styles.video, { height: fullscreen ? '100%' : 300 }]}
paused={videoPaused}
resizeMode="contain" // This ensures the video fits within its container
onLoad={() => setVideoPaused(false)}
onError={(error) => console.error('Video playback error:', error)}
/>
{controlsVisible && (
<TouchableOpacity style={styles.playPauseButton} onPress={togglePlayPause}>
<Image
style={styles.playPauseIcon}
source={videoPaused ? require('./skinassets/play.png') : require('./skinassets/pause.png')}
/>
</TouchableOpacity>
)}
</TouchableOpacity>
</View>
<Image source={require('./skinassets/scanme.png')}
style={{ width: '50%', height: imageHeight, alignSelf: 'center', resizeMode: 'contain', marginBottom: -29 }} />
<View style={styles.qrCodeBox}>
<Image
source={require('./skinassets/QR1.png')} // Make sure the path is correct
style={styles.qrCodeImage}
/>
<TouchableOpacity
style={styles.orButton}
onPress={() => Linking.openURL('https://mywebar.com/p/Project_0_ysb0ffrwxn')}>
<Text style={styles.orButtonText}>OR Click This</Text>
</TouchableOpacity>
</View>
<Text style={styles.checkboxLabel}>Check the related box</Text>
<View style={styles.checkboxContainer}>
{symptomsGroups.map((group, index) => (
<View key={index}>
{group.map(symptom => (
<View style={styles.individualCheckboxContainer} key={symptom.key}>
<CheckBox
value={selectedSymptoms[symptom.key]}
onValueChange={() => toggleCheckbox(symptom.key)}
/>
<Text style={styles.checkboxText}>{symptom.text}</Text>
</View>
))}
{index !== symptomsGroups.length - 1 && (
<View style={styles.separator} />
)}
</View>
))}
</View>
</View>
<Button
title="Continue for more information"
style={styles.nextButton}
onPress={handleSubmit}
/>
</ScrollView>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
scrollContainer: {
flexGrow: 1,
},
container: {
flexGrow: 1,
backgroundColor: COLORS.white,
},
topContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: COLORS.white,
// This creates the curve effect for the background
},
topicText: {
fontSize: 24,
fontWeight: 'bold',
color: COLORS.black,
textAlign: 'center',
marginVertical: 20,
},
descriptionText: {
fontSize: 18,
textAlign: 'center',
marginHorizontal: 20,
marginBottom: 20,
color:COLORS.black,
fontWeight: 'bold',
},
separator: {
height: 2,
backgroundColor: COLORS.blue,
marginVertical: 10,
width: '90%', // Reduce width to see margins from container edges
alignSelf: 'center',
marginLeft:-197,
},
checkboxContainer: {
backgroundColor: COLORS.lightBlue,
borderRadius: 25,
width: '100%', // Ensure it's taking the full width of its parent
alignSelf: 'center', // This ensures it's centered relative to the parent
paddingTop: 10,
marginLeft:197,
},
checkboxLabel: {
fontSize: 18,
fontWeight: 'bold',
marginBottom: 10,
alignSelf: 'center',
color:COLORS.black,
},
checkboxRow: {
flexDirection: 'row',
alignItems: 'center',
marginBottom: 10,
},
checkboxText: {
fontSize: 16,
marginLeft: 8,
flexShrink: 1, // Allows the text to shrink and wrap onto the next line
},
submitButton: {
backgroundColor: COLORS.primary,
borderRadius: 20,
padding: 15,
marginVertical: 20,
width: '90%',
alignSelf: 'center',
},
bottomContainer: {
flex: 2,
justifyContent: 'flex-end',
marginBottom: 2,
marginTop:-20,
alignItems: 'center',
backgroundColor: COLORS.blue,
borderTopRightRadius: 85,
borderTopLeftRadius: 85,
},
nextButton: {
width: '70%',
paddingVertical: 10,
marginBottom: 80, // Adjust the margin to move the button up further if necessary
backgroundColor: COLORS.white,
borderRadius: 20,
alignSelf: 'center',
},
videoContainer: {
width: '100%',
aspectRatio: 16 / 9, // You can adjust this aspect ratio as needed
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'black'
},
video: {
width: '110%',
height: '100%',
},
individualCheckboxContainer: {
backgroundColor: COLORS.white, // Set the background color to white
borderRadius: 10, // Set border radius for rounded corners
padding: 10, // Add some padding around the content
marginBottom: 10, // Add bottom margin for spacing between items
flexDirection: 'row', // Align checkbox and label in a row
alignItems: 'center', // Center align items vertically
borderWidth: 0.6, // Optional border width
width: '98%', // Width 100% to fill container width
marginLeft:-95,
elevation: 6,
minHeight: 50,
},
fullscreenButton: {
marginTop: 10,
backgroundColor: 'rgba(0, 0, 0, 0.8)',
padding: 10,
borderRadius: 5,
},
fullscreenButtonText: {
color: '#fff',
},
videoBox: {
backgroundColor: COLORS.white, // Set background color to white
borderWidth: 2, // Set the border width
borderColor: '#80BCBD', // Set the border color
borderRadius: 10, // Set border radius for rounded corners
padding: 20, // Add padding around the content
marginBottom: -20, // Add bottom margin for spacing
width: '100%', // Adjust the width as necessary
alignSelf: 'center', // Center the box within its container
// Add shadows for elevation effect (optional)
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 3.84,
elevation: 5,
},
playPauseButton: {
position: 'absolute',
top: '50%',
left: '50%',
bottom:'30%',
transform: [{ translateX: -25 }, { translateY: -25 }],
width: 50,
height: 50,
justifyContent: 'center',
alignItems: 'center',
},
playPauseIcon: {
width: 50,
height: 50,
},
contentContainer: {
paddingBottom: 20, // Adds padding at the bottom
},
qrCodeBox: {
width: '90%',
justifyContent: 'center',
alignItems: 'center',
padding: 20,
backgroundColor: COLORS.white,
marginBottom: 20,
shadowColor: "#000",
borderColor: '#80BCBD',
borderWidth: 2,
borderRadius: 10,
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 3.84,
elevation: 5,
},
qrCodeImage: {
width: 200, // Adjust size as needed
height: 200, // Adjust size as needed
},
orButton: {
marginTop: 30,
backgroundColor: COLORS.primary,
padding: 10,
borderRadius: 5,
alignItems: 'center',
justifyContent: 'center',
},
orButtonText: {
color: COLORS.white,
fontSize: 14,
fontWeight: 'bold',
}
// ... possibly other styles
});
export default AdditionalSymptomsScreen;
import React, { useState, useRef, useEffect } from 'react';
import { View, StyleSheet, Text, ScrollView, TouchableOpacity, ActivityIndicator, Image } from 'react-native';
import { COLORS ,IMGS, ROUTES} from '../../../constants';
import CheckBox from '@react-native-community/checkbox'; // Make sure to install this package
import Video from 'react-native-video'; // Make sure to install this package
import Button from '../../../components/Button';
import { SafeAreaView } from 'react-native-safe-area-context';
import { Dimensions } from 'react-native';
import { Linking } from 'react-native';
const AdditionalSymptomsScreen = ({ navigation }) => {
const [selectedSymptoms, setSelectedSymptoms] = useState({
symptom1: false, symptom2: false, symptom3: false, symptom4: false,
symptom5: false, symptom6: false, symptom7: false, symptom8: false,
symptom9: false,
});
const [loading, setLoading] = useState(true);
const [videoPaused, setVideoPaused] = useState(true);
const [fullscreen, setFullscreen] = useState(false);
const [controlsVisible, setControlsVisible] = useState(false);
const hideTimer = useRef(null);
const URL_link = "https://res.cloudinary.com/dl207ux6g/video/upload/v1715374537/3D/ulxecngohldnmcizzrej.mp4";
const videoRef = useRef(null);
const screenHeight = Dimensions.get('window').height;
const imageHeight = screenHeight * 0.20;
const symptomsGroups = [
[
{ key: 'symptom1', text: 'Headache | හිසරදය' },
{ key: 'symptom2', text: 'Shoulder pain |උරහිස් වේදනාව'},
{ key: 'symptom3', text: 'Swelling in the hands | අත්වල ඉදිමීම'},
],
[ { key: 'symptom4', text: 'Change in vision | ඇස් පෙනීම වෙනස් වීම'},
{ key: 'symptom5', text: 'Shortness in breath | හුස්ම හිරවීම'},
{ key: 'symptom6', text: 'Upper Abdominal pain | ඉහළ උදරයේ වේදනාව'},
],
[
{ key: 'symptom7', text: 'Swelling in joints | සන්ධි ඉදිමීම'},
{ key: 'symptom8', text: 'Back Pain | පිටුපස වේදනාව'},
{ key: 'symptom9', text: 'Side muscle pain | පැත්තේ මාංශ පේශි වේදනාව'},
],
// Add more groups as needed
];
const handleLoad = () => {
setLoading(false);
};
const handleBuffer = () => {
setLoading(true);
};
const toggleCheckbox = (symptom) => {
setSelectedSymptoms(prevState => ({
...prevState,
[symptom]: !prevState[symptom],
}));
};
const handleSubmit = () => {
// Checking for specific symptoms that lead to SKIN_RISK
const skinRiskSymptoms = ['symptom3', 'symptom4', 'symptom7','symptom9'];
const toSkinRisk = skinRiskSymptoms.some(symptom => selectedSymptoms[symptom]);
// Navigate based on condition
if (toSkinRisk) {
navigation.navigate(ROUTES.SKIN_RISK);
} else {
navigation.navigate(ROUTES.SKIN_UPLOAD);
}
};
const toggleFullscreen = () => {
if (videoRef.current) {
if (!fullscreen) {
videoRef.current.presentFullscreenPlayer(); // This will open the video in fullscreen
} else {
videoRef.current.dismissFullscreenPlayer(); // This will exit the fullscreen mode
}
setFullscreen(!fullscreen); // Toggle the fullscreen state
}
};
const togglePlayPause = () => {
setVideoPaused(!videoPaused);
showControlsTemporarily(); // Toggle the pause state of the video
};
const showControlsTemporarily = () => {
setControlsVisible(true);
if (hideTimer.current) {
clearTimeout(hideTimer.current);
}
hideTimer.current = setTimeout(() => {
setControlsVisible(false);
}, 3000); // Hide controls after 3 seconds of inactivity
};
useEffect(() => {
return () => {
if (hideTimer.current) {
clearTimeout(hideTimer.current);
}
};
}, []);
return (
<SafeAreaView style={styles.container}>
<ScrollView style={styles.scrollContainer} contentContainerStyle={styles.contentContainer}>
<View style={styles.topContainer}>
<Text style={styles.topicText}>Patechiae Additional Symptoms</Text>
<View style={styles.videoBox}>
<View style={styles.videoDescriptionBox}>
<Text style={styles.descriptionText}>
Self diagnose with the 3D Model
</Text>
</View>
<TouchableOpacity style={styles.videoContainer} onPress={showControlsTemporarily}>
<Video
// ref={videoRef}
source={{ uri: URL_link }} // Replace with the path to your video file
style={[styles.video, { height: fullscreen ? '100%' : 300 }]}
paused={videoPaused}
resizeMode="contain" // This ensures the video fits within its container
onLoad={() => setVideoPaused(false)}
onError={(error) => console.error('Video playback error:', error)}
/>
{controlsVisible && (
<TouchableOpacity style={styles.playPauseButton} onPress={togglePlayPause}>
<Image
style={styles.playPauseIcon}
source={videoPaused ? require('./skinassets/play.png') : require('./skinassets/pause.png')}
/>
</TouchableOpacity>
)}
</TouchableOpacity>
</View>
<Image source={require('./skinassets/scanme.png')}
style={{ width: '50%', height: imageHeight, alignSelf: 'center', resizeMode: 'contain', marginBottom: -29 }} />
<View style={styles.qrCodeBox}>
<Image
source={require('./skinassets/QR1.png')} // Make sure the path is correct
style={styles.qrCodeImage}
/>
<TouchableOpacity
style={styles.orButton}
onPress={() => Linking.openURL('https://mywebar.com/p/Project_0_ysb0ffrwxn')}>
<Text style={styles.orButtonText}>OR Click This</Text>
</TouchableOpacity>
</View>
<Text style={styles.checkboxLabel}>Check the related box</Text>
<View style={styles.checkboxContainer}>
{symptomsGroups.map((group, index) => (
<View key={index}>
{group.map(symptom => (
<View style={styles.individualCheckboxContainer} key={symptom.key}>
<CheckBox
value={selectedSymptoms[symptom.key]}
onValueChange={() => toggleCheckbox(symptom.key)}
/>
<Text style={styles.checkboxText}>{symptom.text}</Text>
</View>
))}
{index !== symptomsGroups.length - 1 && (
<View style={styles.separator} />
)}
</View>
))}
</View>
</View>
<Button
title="Continue for more information"
style={styles.nextButton}
onPress={handleSubmit}
/>
</ScrollView>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
scrollContainer: {
flexGrow: 1,
},
container: {
flexGrow: 1,
backgroundColor: COLORS.white,
},
topContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: COLORS.white,
// This creates the curve effect for the background
},
topicText: {
fontSize: 24,
fontWeight: 'bold',
color: COLORS.black,
textAlign: 'center',
marginVertical: 20,
},
descriptionText: {
fontSize: 18,
textAlign: 'center',
marginHorizontal: 20,
marginBottom: 20,
color:COLORS.black,
fontWeight: 'bold',
},
separator: {
height: 2,
backgroundColor: COLORS.blue,
marginVertical: 10,
width: '90%', // Reduce width to see margins from container edges
alignSelf: 'center',
marginLeft:-197,
},
checkboxContainer: {
backgroundColor: COLORS.lightBlue,
borderRadius: 25,
width: '100%', // Ensure it's taking the full width of its parent
alignSelf: 'center', // This ensures it's centered relative to the parent
paddingTop: 10,
marginLeft:197,
},
checkboxLabel: {
fontSize: 18,
fontWeight: 'bold',
marginBottom: 10,
alignSelf: 'center',
color:COLORS.black,
},
checkboxRow: {
flexDirection: 'row',
alignItems: 'center',
marginBottom: 10,
},
checkboxText: {
fontSize: 16,
marginLeft: 8,
flexShrink: 1, // Allows the text to shrink and wrap onto the next line
},
submitButton: {
backgroundColor: COLORS.primary,
borderRadius: 20,
padding: 15,
marginVertical: 20,
width: '90%',
alignSelf: 'center',
},
bottomContainer: {
flex: 2,
justifyContent: 'flex-end',
marginBottom: 2,
marginTop:-20,
alignItems: 'center',
backgroundColor: COLORS.blue,
borderTopRightRadius: 85,
borderTopLeftRadius: 85,
},
nextButton: {
width: '70%',
paddingVertical: 10,
marginBottom: 80, // Adjust the margin to move the button up further if necessary
backgroundColor: COLORS.white,
borderRadius: 20,
alignSelf: 'center',
},
videoContainer: {
width: '100%',
aspectRatio: 16 / 9, // You can adjust this aspect ratio as needed
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'black'
},
video: {
width: '110%',
height: '100%',
},
individualCheckboxContainer: {
backgroundColor: COLORS.white, // Set the background color to white
borderRadius: 10, // Set border radius for rounded corners
padding: 10, // Add some padding around the content
marginBottom: 10, // Add bottom margin for spacing between items
flexDirection: 'row', // Align checkbox and label in a row
alignItems: 'center', // Center align items vertically
borderWidth: 0.6, // Optional border width
width: '98%', // Width 100% to fill container width
marginLeft:-95,
elevation: 6,
minHeight: 50,
},
fullscreenButton: {
marginTop: 10,
backgroundColor: 'rgba(0, 0, 0, 0.8)',
padding: 10,
borderRadius: 5,
},
fullscreenButtonText: {
color: '#fff',
},
videoBox: {
backgroundColor: COLORS.white, // Set background color to white
borderWidth: 2, // Set the border width
borderColor: '#80BCBD', // Set the border color
borderRadius: 10, // Set border radius for rounded corners
padding: 20, // Add padding around the content
marginBottom: -20, // Add bottom margin for spacing
width: '100%', // Adjust the width as necessary
alignSelf: 'center', // Center the box within its container
// Add shadows for elevation effect (optional)
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 3.84,
elevation: 5,
},
playPauseButton: {
position: 'absolute',
top: '50%',
left: '50%',
bottom:'30%',
transform: [{ translateX: -25 }, { translateY: -25 }],
width: 50,
height: 50,
justifyContent: 'center',
alignItems: 'center',
},
playPauseIcon: {
width: 50,
height: 50,
},
contentContainer: {
paddingBottom: 20, // Adds padding at the bottom
},
qrCodeBox: {
width: '90%',
justifyContent: 'center',
alignItems: 'center',
padding: 20,
backgroundColor: COLORS.white,
marginBottom: 20,
shadowColor: "#000",
borderColor: '#80BCBD',
borderWidth: 2,
borderRadius: 10,
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 3.84,
elevation: 5,
},
qrCodeImage: {
width: 200, // Adjust size as needed
height: 200, // Adjust size as needed
},
orButton: {
marginTop: 30,
backgroundColor: COLORS.primary,
padding: 10,
borderRadius: 5,
alignItems: 'center',
justifyContent: 'center',
},
orButtonText: {
color: COLORS.white,
fontSize: 14,
fontWeight: 'bold',
}
// ... possibly other styles
});
export default AdditionalSymptomsScreen;
import React, { useState, useRef, useEffect } from 'react';
import { View, StyleSheet, Text, ScrollView, TouchableOpacity, ActivityIndicator, Image } from 'react-native';
import { COLORS ,IMGS, ROUTES} from '../../../constants';
import CheckBox from '@react-native-community/checkbox'; // Make sure to install this package
import Video from 'react-native-video'; // Make sure to install this package
import Button from '../../../components/Button';
import { SafeAreaView } from 'react-native-safe-area-context';
import { Dimensions } from 'react-native';
import { Linking } from 'react-native';
const AdditionalSymptomsScreen = ({ navigation }) => {
const [selectedSymptoms, setSelectedSymptoms] = useState({
symptom1: false, symptom2: false, symptom3: false, symptom4: false,
symptom5: false, symptom6: false, symptom7: false, symptom8: false,
symptom9: false, symptom10: false, symptom11: false, symptom12: false,
symptom13: false, symptom14: false
});
const [loading, setLoading] = useState(true);
const [videoPaused, setVideoPaused] = useState(true);
const [fullscreen, setFullscreen] = useState(false);
const [controlsVisible, setControlsVisible] = useState(false);
const hideTimer = useRef(null);
const URL_link = "https://res.cloudinary.com/dl207ux6g/video/upload/v1715374525/3D/tu1jhgaa6hvcyby5zybr.mp4";
const videoRef = useRef(null);
const screenHeight = Dimensions.get('window').height;
const imageHeight = screenHeight * 0.20;
const symptomsGroups = [
[
{ key: 'symptom1', text: 'Headache | හිසරදය' },
{ key: 'symptom2', text: 'Sore throat | උගුරේ අමාරුව'},
{ key: 'symptom3', text: 'Swelling in joints | සන්ධි ඉදිමීම'},
],
[
{ key: 'symptom5', text: 'Shortness in breath | හුස්ම හිරවීම'},
{ key: 'symptom6', text: 'Large mouth ulcers | මුඛයේ විශාල වණ'},
{ key: 'symptom4', text: 'Weight loss | බර අඩුවීම '},
],
// Add more groups as needed
];
const handleLoad = () => {
setLoading(false);
};
const handleBuffer = () => {
setLoading(true);
};
const toggleCheckbox = (symptom) => {
setSelectedSymptoms(prevState => ({
...prevState,
[symptom]: !prevState[symptom],
}));
};
const handleSubmit = () => {
// Checking for specific symptoms that lead to SKIN_RISK
const skinRiskSymptoms = ['symptom3', 'symptom4', 'symptom4','symptom10', 'symptom8', 'symptom6'];
const toSkinRisk = skinRiskSymptoms.some(symptom => selectedSymptoms[symptom]);
// Navigate based on condition
if (toSkinRisk) {
navigation.navigate(ROUTES.SKIN_RISK);
} else {
navigation.navigate(ROUTES.SKIN_UPLOAD);
}
};
const toggleFullscreen = () => {
if (videoRef.current) {
if (!fullscreen) {
videoRef.current.presentFullscreenPlayer(); // This will open the video in fullscreen
} else {
videoRef.current.dismissFullscreenPlayer(); // This will exit the fullscreen mode
}
setFullscreen(!fullscreen); // Toggle the fullscreen state
}
};
const togglePlayPause = () => {
setVideoPaused(!videoPaused);
showControlsTemporarily(); // Toggle the pause state of the video
};
const showControlsTemporarily = () => {
setControlsVisible(true);
if (hideTimer.current) {
clearTimeout(hideTimer.current);
}
hideTimer.current = setTimeout(() => {
setControlsVisible(false);
}, 3000); // Hide controls after 3 seconds of inactivity
};
useEffect(() => {
return () => {
if (hideTimer.current) {
clearTimeout(hideTimer.current);
}
};
}, []);
return (
<SafeAreaView style={styles.container}>
<ScrollView style={styles.scrollContainer} contentContainerStyle={styles.contentContainer}>
<View style={styles.topContainer}>
<Text style={styles.topicText}>Cytomegalovirus Additional Symptoms</Text>
<View style={styles.videoBox}>
<View style={styles.videoDescriptionBox}>
<Text style={styles.descriptionText}>
Self diagnose with the 3D Model
</Text>
</View>
<TouchableOpacity style={styles.videoContainer} onPress={showControlsTemporarily}>
<Video
// ref={videoRef}
source={{ uri: URL_link }} // Replace with the path to your video file
style={[styles.video, { height: fullscreen ? '100%' : 300 }]}
paused={videoPaused}
resizeMode="contain" // This ensures the video fits within its container
onLoad={() => setVideoPaused(false)}
onError={(error) => console.error('Video playback error:', error)}
/>
{controlsVisible && (
<TouchableOpacity style={styles.playPauseButton} onPress={togglePlayPause}>
<Image
style={styles.playPauseIcon}
source={videoPaused ? require('./skinassets/play.png') : require('./skinassets/pause.png')}
/>
</TouchableOpacity>
)}
</TouchableOpacity>
</View>
<Image source={require('./skinassets/scanme.png')}
style={{ width: '50%', height: imageHeight, alignSelf: 'center', resizeMode: 'contain', marginBottom: -29 }} />
<View style={styles.qrCodeBox}>
<Image
source={require('./skinassets/QR1.png')} // Make sure the path is correct
style={styles.qrCodeImage}
/>
<TouchableOpacity
style={styles.orButton}
onPress={() => Linking.openURL('https://mywebar.com/p/Project_0_ysb0ffrwxn')}>
<Text style={styles.orButtonText}>OR Click This</Text>
</TouchableOpacity>
</View>
<Text style={styles.checkboxLabel}>Check the related box</Text>
<View style={styles.checkboxContainer}>
{symptomsGroups.map((group, index) => (
<View key={index}>
{group.map(symptom => (
<View style={styles.individualCheckboxContainer} key={symptom.key}>
<CheckBox
value={selectedSymptoms[symptom.key]}
onValueChange={() => toggleCheckbox(symptom.key)}
/>
<Text style={styles.checkboxText}>{symptom.text}</Text>
</View>
))}
{index !== symptomsGroups.length - 1 && (
<View style={styles.separator} />
)}
</View>
))}
</View>
</View>
<Button
title="Continue for more information"
style={styles.nextButton}
onPress={handleSubmit}
/>
</ScrollView>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
scrollContainer: {
flexGrow: 1,
},
container: {
flexGrow: 1,
backgroundColor: COLORS.white,
},
topContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: COLORS.white,
// This creates the curve effect for the background
},
topicText: {
fontSize: 24,
fontWeight: 'bold',
color: COLORS.black,
textAlign: 'center',
marginVertical: 20,
},
descriptionText: {
fontSize: 18,
textAlign: 'center',
marginHorizontal: 20,
marginBottom: 20,
color:COLORS.black,
fontWeight: 'bold',
},
separator: {
height: 2,
backgroundColor: COLORS.blue,
marginVertical: 10,
width: '90%', // Reduce width to see margins from container edges
alignSelf: 'center',
marginLeft:-197,
},
checkboxContainer: {
backgroundColor: COLORS.lightBlue,
borderRadius: 25,
width: '100%', // Ensure it's taking the full width of its parent
alignSelf: 'center', // This ensures it's centered relative to the parent
paddingTop: 10,
marginLeft:197,
},
checkboxLabel: {
fontSize: 18,
fontWeight: 'bold',
marginBottom: 10,
alignSelf: 'center',
color:COLORS.black,
},
checkboxRow: {
flexDirection: 'row',
alignItems: 'center',
marginBottom: 10,
},
checkboxText: {
fontSize: 16,
marginLeft: 8,
flexShrink: 1, // Allows the text to shrink and wrap onto the next line
},
submitButton: {
backgroundColor: COLORS.primary,
borderRadius: 20,
padding: 15,
marginVertical: 20,
width: '90%',
alignSelf: 'center',
},
bottomContainer: {
flex: 2,
justifyContent: 'flex-end',
marginBottom: 2,
marginTop:-20,
alignItems: 'center',
backgroundColor: COLORS.blue,
borderTopRightRadius: 85,
borderTopLeftRadius: 85,
},
nextButton: {
width: '70%',
paddingVertical: 10,
marginBottom: 80, // Adjust the margin to move the button up further if necessary
backgroundColor: COLORS.white,
borderRadius: 20,
alignSelf: 'center',
},
videoContainer: {
width: '100%',
aspectRatio: 16 / 9, // You can adjust this aspect ratio as needed
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'black'
},
video: {
width: '110%',
height: '100%',
},
individualCheckboxContainer: {
backgroundColor: COLORS.white, // Set the background color to white
borderRadius: 10, // Set border radius for rounded corners
padding: 10, // Add some padding around the content
marginBottom: 10, // Add bottom margin for spacing between items
flexDirection: 'row', // Align checkbox and label in a row
alignItems: 'center', // Center align items vertically
borderWidth: 0.6, // Optional border width
width: '98%', // Width 100% to fill container width
marginLeft:-95,
elevation: 6,
minHeight: 50,
},
fullscreenButton: {
marginTop: 10,
backgroundColor: 'rgba(0, 0, 0, 0.8)',
padding: 10,
borderRadius: 5,
},
fullscreenButtonText: {
color: '#fff',
},
videoBox: {
backgroundColor: COLORS.white, // Set background color to white
borderWidth: 2, // Set the border width
borderColor: '#80BCBD', // Set the border color
borderRadius: 10, // Set border radius for rounded corners
padding: 20, // Add padding around the content
marginBottom: -20, // Add bottom margin for spacing
width: '100%', // Adjust the width as necessary
alignSelf: 'center', // Center the box within its container
// Add shadows for elevation effect (optional)
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 3.84,
elevation: 5,
},
playPauseButton: {
position: 'absolute',
top: '50%',
left: '50%',
bottom:'30%',
transform: [{ translateX: -25 }, { translateY: -25 }],
width: 50,
height: 50,
justifyContent: 'center',
alignItems: 'center',
},
playPauseIcon: {
width: 50,
height: 50,
},
contentContainer: {
paddingBottom: 20, // Adds padding at the bottom
},
qrCodeBox: {
width: '90%',
justifyContent: 'center',
alignItems: 'center',
padding: 20,
backgroundColor: COLORS.white,
marginBottom: 20,
shadowColor: "#000",
borderColor: '#80BCBD',
borderWidth: 2,
borderRadius: 10,
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 3.84,
elevation: 5,
},
qrCodeImage: {
width: 200, // Adjust size as needed
height: 200, // Adjust size as needed
},
orButton: {
marginTop: 30,
backgroundColor: COLORS.primary,
padding: 10,
borderRadius: 5,
alignItems: 'center',
justifyContent: 'center',
},
orButtonText: {
color: COLORS.white,
fontSize: 14,
fontWeight: 'bold',
}
// ... possibly other styles
});
export default AdditionalSymptomsScreen;
import React, { useState, useRef, useEffect } from 'react';
import { View, StyleSheet, Text, ScrollView, TouchableOpacity, ActivityIndicator, Image } from 'react-native';
import { COLORS ,IMGS, ROUTES} from '../../../constants';
import CheckBox from '@react-native-community/checkbox'; // Make sure to install this package
import Video from 'react-native-video'; // Make sure to install this package
import Button from '../../../components/Button';
import { SafeAreaView } from 'react-native-safe-area-context';
import { Dimensions } from 'react-native';
import { Linking } from 'react-native';
const AdditionalSymptomsScreen = ({ navigation }) => {
const [selectedSymptoms, setSelectedSymptoms] = useState({
symptom1: false, symptom2: false, symptom3: false, symptom4: false,
symptom5: false, symptom6: false, symptom7: false, symptom8: false,
symptom9: false, symptom10: false, symptom11: false, symptom12: false,
symptom13: false, symptom14: false
});
const [loading, setLoading] = useState(true);
const [videoPaused, setVideoPaused] = useState(true);
const [fullscreen, setFullscreen] = useState(false);
const [controlsVisible, setControlsVisible] = useState(false);
const hideTimer = useRef(null);
const URL_link = "https://res.cloudinary.com/dl207ux6g/video/upload/v1715374517/3D/q2zk6ka9aqamthwgn1vv.mp4";
const videoRef = useRef(null);
const screenHeight = Dimensions.get('window').height;
const imageHeight = screenHeight * 0.20;
const symptomsGroups = [
[
{ key: 'symptom1', text: 'Headache | හිසරදය' },
{ key: 'symptom2', text: 'Sore throat | උගුරේ අමාරුව'},
{ key: 'symptom3', text: 'Pain around genitals | ලිංගික අවයව වටා වේදනාව'},
{ key: 'symptom5', text: 'Pain in urination | මුත්රා කිරීමේදී වේදනාව'},
],
];
const handleLoad = () => {
setLoading(false);
};
const handleBuffer = () => {
setLoading(true);
};
const toggleCheckbox = (symptom) => {
setSelectedSymptoms(prevState => ({
...prevState,
[symptom]: !prevState[symptom],
}));
};
const handleSubmit = () => {
// Checking for specific symptoms that lead to SKIN_RISK
const skinRiskSymptoms = ['symptom3', 'symptom4', 'symptom4','symptom10', 'symptom8', 'symptom6'];
const toSkinRisk = skinRiskSymptoms.some(symptom => selectedSymptoms[symptom]);
// Navigate based on condition
if (toSkinRisk) {
navigation.navigate(ROUTES.SKIN_RISK);
} else {
navigation.navigate(ROUTES.SKIN_UPLOAD);
}
};
const toggleFullscreen = () => {
if (videoRef.current) {
if (!fullscreen) {
videoRef.current.presentFullscreenPlayer(); // This will open the video in fullscreen
} else {
videoRef.current.dismissFullscreenPlayer(); // This will exit the fullscreen mode
}
setFullscreen(!fullscreen); // Toggle the fullscreen state
}
};
const togglePlayPause = () => {
setVideoPaused(!videoPaused);
showControlsTemporarily(); // Toggle the pause state of the video
};
const showControlsTemporarily = () => {
setControlsVisible(true);
if (hideTimer.current) {
clearTimeout(hideTimer.current);
}
hideTimer.current = setTimeout(() => {
setControlsVisible(false);
}, 3000); // Hide controls after 3 seconds of inactivity
};
useEffect(() => {
return () => {
if (hideTimer.current) {
clearTimeout(hideTimer.current);
}
};
}, []);
return (
<SafeAreaView style={styles.container}>
<ScrollView style={styles.scrollContainer} contentContainerStyle={styles.contentContainer}>
<View style={styles.topContainer}>
<Text style={styles.topicText}>Cytomegalovirus Additional Symptoms</Text>
<View style={styles.videoBox}>
<View style={styles.videoDescriptionBox}>
<Text style={styles.descriptionText}>
Self diagnose with the 3D Model
</Text>
</View>
<TouchableOpacity style={styles.videoContainer} onPress={showControlsTemporarily}>
<Video
// ref={videoRef}
source={{ uri: URL_link }} // Replace with the path to your video file
style={[styles.video, { height: fullscreen ? '100%' : 300 }]}
paused={videoPaused}
resizeMode="contain" // This ensures the video fits within its container
onLoad={() => setVideoPaused(false)}
onError={(error) => console.error('Video playback error:', error)}
/>
{controlsVisible && (
<TouchableOpacity style={styles.playPauseButton} onPress={togglePlayPause}>
<Image
style={styles.playPauseIcon}
source={videoPaused ? require('./skinassets/play.png') : require('./skinassets/pause.png')}
/>
</TouchableOpacity>
)}
</TouchableOpacity>
</View>
<Image source={require('./skinassets/scanme.png')}
style={{ width: '50%', height: imageHeight, alignSelf: 'center', resizeMode: 'contain', marginBottom: -29 }} />
<View style={styles.qrCodeBox}>
<Image
source={require('./skinassets/QR1.png')} // Make sure the path is correct
style={styles.qrCodeImage}
/>
<TouchableOpacity
style={styles.orButton}
onPress={() => Linking.openURL('https://mywebar.com/p/Project_0_ysb0ffrwxn')}>
<Text style={styles.orButtonText}>OR Click This</Text>
</TouchableOpacity>
</View>
<Text style={styles.checkboxLabel}>Check the related box</Text>
<View style={styles.checkboxContainer}>
{symptomsGroups.map((group, index) => (
<View key={index}>
{group.map(symptom => (
<View style={styles.individualCheckboxContainer} key={symptom.key}>
<CheckBox
value={selectedSymptoms[symptom.key]}
onValueChange={() => toggleCheckbox(symptom.key)}
/>
<Text style={styles.checkboxText}>{symptom.text}</Text>
</View>
))}
{index !== symptomsGroups.length - 1 && (
<View style={styles.separator} />
)}
</View>
))}
</View>
</View>
<Button
title="Continue for more information"
style={styles.nextButton}
onPress={handleSubmit}
/>
</ScrollView>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
scrollContainer: {
flexGrow: 1,
},
container: {
flexGrow: 1,
backgroundColor: COLORS.white,
},
topContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: COLORS.white,
// This creates the curve effect for the background
},
topicText: {
fontSize: 24,
fontWeight: 'bold',
color: COLORS.black,
textAlign: 'center',
marginVertical: 20,
},
descriptionText: {
fontSize: 18,
textAlign: 'center',
marginHorizontal: 20,
marginBottom: 20,
color:COLORS.black,
fontWeight: 'bold',
},
separator: {
height: 2,
backgroundColor: COLORS.blue,
marginVertical: 10,
width: '90%', // Reduce width to see margins from container edges
alignSelf: 'center',
marginLeft:-197,
},
checkboxContainer: {
backgroundColor: COLORS.lightBlue,
borderRadius: 25,
width: '100%', // Ensure it's taking the full width of its parent
alignSelf: 'center', // This ensures it's centered relative to the parent
paddingTop: 10,
marginLeft:197,
},
checkboxLabel: {
fontSize: 18,
fontWeight: 'bold',
marginBottom: 10,
alignSelf: 'center',
color:COLORS.black,
},
checkboxRow: {
flexDirection: 'row',
alignItems: 'center',
marginBottom: 10,
},
checkboxText: {
fontSize: 16,
marginLeft: 8,
flexShrink: 1, // Allows the text to shrink and wrap onto the next line
},
submitButton: {
backgroundColor: COLORS.primary,
borderRadius: 20,
padding: 15,
marginVertical: 20,
width: '90%',
alignSelf: 'center',
},
bottomContainer: {
flex: 2,
justifyContent: 'flex-end',
marginBottom: 2,
marginTop:-20,
alignItems: 'center',
backgroundColor: COLORS.blue,
borderTopRightRadius: 85,
borderTopLeftRadius: 85,
},
nextButton: {
width: '70%',
paddingVertical: 10,
marginBottom: 80, // Adjust the margin to move the button up further if necessary
backgroundColor: COLORS.white,
borderRadius: 20,
alignSelf: 'center',
},
videoContainer: {
width: '100%',
aspectRatio: 16 / 9, // You can adjust this aspect ratio as needed
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'black'
},
video: {
width: '110%',
height: '100%',
},
individualCheckboxContainer: {
backgroundColor: COLORS.white, // Set the background color to white
borderRadius: 10, // Set border radius for rounded corners
padding: 10, // Add some padding around the content
marginBottom: 10, // Add bottom margin for spacing between items
flexDirection: 'row', // Align checkbox and label in a row
alignItems: 'center', // Center align items vertically
borderWidth: 0.6, // Optional border width
width: '98%', // Width 100% to fill container width
marginLeft:-95,
elevation: 6,
minHeight: 50,
},
fullscreenButton: {
marginTop: 10,
backgroundColor: 'rgba(0, 0, 0, 0.8)',
padding: 10,
borderRadius: 5,
},
fullscreenButtonText: {
color: '#fff',
},
videoBox: {
backgroundColor: COLORS.white, // Set background color to white
borderWidth: 2, // Set the border width
borderColor: '#80BCBD', // Set the border color
borderRadius: 10, // Set border radius for rounded corners
padding: 20, // Add padding around the content
marginBottom: -20, // Add bottom margin for spacing
width: '100%', // Adjust the width as necessary
alignSelf: 'center', // Center the box within its container
// Add shadows for elevation effect (optional)
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 3.84,
elevation: 5,
},
playPauseButton: {
position: 'absolute',
top: '50%',
left: '50%',
bottom:'30%',
transform: [{ translateX: -25 }, { translateY: -25 }],
width: 50,
height: 50,
justifyContent: 'center',
alignItems: 'center',
},
playPauseIcon: {
width: 50,
height: 50,
},
contentContainer: {
paddingBottom: 20, // Adds padding at the bottom
},
qrCodeBox: {
width: '90%',
justifyContent: 'center',
alignItems: 'center',
padding: 20,
backgroundColor: COLORS.white,
marginBottom: 20,
shadowColor: "#000",
borderColor: '#80BCBD',
borderWidth: 2,
borderRadius: 10,
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 3.84,
elevation: 5,
},
qrCodeImage: {
width: 200, // Adjust size as needed
height: 200, // Adjust size as needed
},
orButton: {
marginTop: 30,
backgroundColor: COLORS.primary,
padding: 10,
borderRadius: 5,
alignItems: 'center',
justifyContent: 'center',
},
orButtonText: {
color: COLORS.white,
fontSize: 14,
fontWeight: 'bold',
}
// ... possibly other styles
});
export default AdditionalSymptomsScreen;
import React, { useState, useRef, useEffect } from 'react';
import { View, StyleSheet, Text, ScrollView, TouchableOpacity, ActivityIndicator, Image } from 'react-native';
import { COLORS ,IMGS, ROUTES} from '../../../constants';
import CheckBox from '@react-native-community/checkbox'; // Make sure to install this package
import Video from 'react-native-video'; // Make sure to install this package
import Button from '../../../components/Button';
import { SafeAreaView } from 'react-native-safe-area-context';
const AdditionalSymptomsScreen = ({ navigation }) => {
const [selectedSymptoms, setSelectedSymptoms] = useState({ symptom1: false,
symptom2: false,
symptom3: false,});
const [loading, setLoading] = useState(true);
const [videoPaused, setVideoPaused] = useState(true);
const [fullscreen, setFullscreen] = useState(false);
const [controlsVisible, setControlsVisible] = useState(false);
const hideTimer = useRef(null);
const URL_link = "https://res.cloudinary.com/dl207ux6g/video/upload/v1715374529/3D/ri0w5kgmpchajypa7xfb.mp4";
const videoRef = useRef(null);
const handleLoad = () => {
setLoading(false);
};
const handleBuffer = () => {
setLoading(true);
};
const toggleCheckbox = (symptom) => {
setSelectedSymptoms(prevState => ({
...prevState,
[symptom]: !prevState[symptom],
}));
};
const handleSubmit = () => {
// Handle the submission of symptoms
console.log(selectedSymptoms);
// Navigate or perform next steps
};
const toggleFullscreen = () => {
if (videoRef.current) {
if (!fullscreen) {
videoRef.current.presentFullscreenPlayer(); // This will open the video in fullscreen
} else {
videoRef.current.dismissFullscreenPlayer(); // This will exit the fullscreen mode
}
setFullscreen(!fullscreen); // Toggle the fullscreen state
}
};
const togglePlayPause = () => {
setVideoPaused(!videoPaused);
showControlsTemporarily(); // Toggle the pause state of the video
};
const showControlsTemporarily = () => {
setControlsVisible(true);
if (hideTimer.current) {
clearTimeout(hideTimer.current);
}
hideTimer.current = setTimeout(() => {
setControlsVisible(false);
}, 3000); // Hide controls after 3 seconds of inactivity
};
useEffect(() => {
return () => {
if (hideTimer.current) {
clearTimeout(hideTimer.current);
}
};
}, []);
return (
<SafeAreaView style={styles.container}>
<ScrollView style={styles.scrollContainer}>
<View style={styles.topContainer}>
<Text style={styles.topicText}>Pupp Hives Additional Symptoms </Text>
<View style={styles.videoBox}>
<Text style={styles.descriptionText}>
Self diagnose with the 3D Model
</Text>
<TouchableOpacity style={styles.videoContainer} onPress={showControlsTemporarily}>
<Video
// ref={videoRef}
source={{ uri: URL_link }} // Replace with the path to your video file
style={[styles.video, { height: fullscreen ? '100%' : 300 }]}
paused={videoPaused}
resizeMode="contain" // This ensures the video fits within its container
onLoad={() => setVideoPaused(false)}
onError={(error) => console.error('Video playback error:', error)}
/>
{controlsVisible && (
<TouchableOpacity style={styles.playPauseButton} onPress={togglePlayPause}>
<Image
style={styles.playPauseIcon}
source={videoPaused ? require('./skinassets/play.png') : require('./skinassets/pause.png')}
/>
</TouchableOpacity>
)}
</TouchableOpacity>
</View>
<Text style={styles.checkboxLabel}>Check the related box</Text>
<View style={styles.checkboxContainer}>
{/* Repeat this CheckBox component for each symptom */}
<View style={styles.individualCheckboxContainer}>
<CheckBox
value={selectedSymptoms['symptom1']}
onValueChange={() => toggleCheckbox('symptom1')}
/>
<Text style={styles.checkboxText}>Scattered itchy bumps</Text>
</View>
<View style={styles.individualCheckboxContainer}>
<CheckBox
value={selectedSymptoms['symptom2']}
onValueChange={() => toggleCheckbox('symptom2')}
/>
<Text style={styles.checkboxText}>Large red inflamed area across belly</Text>
</View>
<View style={styles.individualCheckboxContainer}>
<CheckBox
value={selectedSymptoms['symptom3']}
onValueChange={() => toggleCheckbox('symptom3')}
/>
<Text style={styles.checkboxText}>Yellow discharges</Text>
</View>
</View>
</View>
<Button
title="Continue for more information"
style={styles.nextButton}
onPress={() => navigation.navigate(ROUTES.SKIN_RISK)}
/>
</ScrollView>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
scrollContainer: {
flexGrow: 1,
},
container: {
flexGrow: 1,
backgroundColor: COLORS.white,
},
topContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: COLORS.white,
// This creates the curve effect for the background
},
topicText: {
fontSize: 24,
fontWeight: 'bold',
color: COLORS.black,
textAlign: 'center',
marginVertical: 20,
},
descriptionText: {
fontSize: 16,
textAlign: 'center',
marginHorizontal: 20,
marginBottom: 20,
},
checkboxContainer: {
backgroundColor: COLORS.lightBlue, // Use a light pastel blue color
borderRadius: 25,
width:'100%',
marginLeft:197,
paddingTop:10
},
checkboxLabel: {
fontSize: 18,
fontWeight: 'bold',
marginBottom: 10,
alignSelf: 'center',
},
checkboxRow: {
flexDirection: 'row',
alignItems: 'center',
marginBottom: 10,
},
checkboxText: {
fontSize: 16,
marginLeft: 8,
},
submitButton: {
backgroundColor: COLORS.primary,
borderRadius: 20,
padding: 15,
marginVertical: 20,
width: '90%',
alignSelf: 'center',
},
bottomContainer: {
flex: 2,
justifyContent: 'flex-end',
marginBottom: 2,
marginTop:-20,
alignItems: 'center',
backgroundColor: COLORS.blue,
borderTopRightRadius: 85,
borderTopLeftRadius: 85,
},
nextButton: {
width: '70%',
paddingVertical: 10,
marginBottom: 80, // Adjust the margin to move the button up further if necessary
backgroundColor: COLORS.white,
borderRadius: 20,
alignSelf: 'center',
},
videoContainer: {
width: '100%',
aspectRatio: 16 / 9, // You can adjust this aspect ratio as needed
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'black'
},
video: {
width: '110%',
height: '100%',
},
individualCheckboxContainer: {
backgroundColor: COLORS.white, // Set the background color to white
borderRadius: 10, // Set border radius for rounded corners
padding: 10, // Add some padding around the content
marginBottom: 10, // Add bottom margin for spacing between items
flexDirection: 'row', // Align checkbox and label in a row
alignItems: 'center', // Center align items vertically
borderWidth: 0.6, // Optional border width
width: '100%', // Width 100% to fill container width
marginLeft:-100,
elevation: 6,
},
fullscreenButton: {
marginTop: 10,
backgroundColor: 'rgba(0, 0, 0, 0.8)',
padding: 10,
borderRadius: 5,
},
fullscreenButtonText: {
color: '#fff',
},
videoBox: {
backgroundColor: COLORS.white, // Set background color to white
borderWidth: 2, // Set the border width
borderColor: '#80BCBD', // Set the border color
borderRadius: 10, // Set border radius for rounded corners
padding: 20, // Add padding around the content
marginBottom: 20, // Add bottom margin for spacing
width: '100%', // Adjust the width as necessary
alignSelf: 'center', // Center the box within its container
// Add shadows for elevation effect (optional)
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 3.84,
elevation: 5,
},
playPauseButton: {
position: 'absolute',
top: '50%',
left: '50%',
bottom:'30%',
transform: [{ translateX: -25 }, { translateY: -25 }],
width: 50,
height: 50,
justifyContent: 'center',
alignItems: 'center',
},
playPauseIcon: {
width: 50,
height: 50,
},
contentContainer: {
paddingBottom: 20, // Adds padding at the bottom
},
// ... possibly other styles
});
export default AdditionalSymptomsScreen;
import React, { useState, useRef, useEffect } from 'react';
import { View, StyleSheet, Text, ScrollView, TouchableOpacity, ActivityIndicator, Image } from 'react-native';
import { COLORS ,IMGS, ROUTES} from '../../../constants';
import CheckBox from '@react-native-community/checkbox'; // Make sure to install this package
import Video from 'react-native-video'; // Make sure to install this package
import Button from '../../../components/Button';
import { SafeAreaView } from 'react-native-safe-area-context';
const AdditionalSymptomsScreen = ({ navigation }) => {
const [selectedSymptoms, setSelectedSymptoms] = useState({ symptom1: false,
symptom2: false,
symptom3: false,});
const [loading, setLoading] = useState(true);
const [videoPaused, setVideoPaused] = useState(true);
const [fullscreen, setFullscreen] = useState(false);
const [controlsVisible, setControlsVisible] = useState(false);
const hideTimer = useRef(null);
const URL_link = "https://res.cloudinary.com/dl207ux6g/video/upload/v1715374540/3D/biile6hyrj1aiqvyvedi.mp4";
const videoRef = useRef(null);
const handleLoad = () => {
setLoading(false);
};
const handleBuffer = () => {
setLoading(true);
};
const toggleCheckbox = (symptom) => {
setSelectedSymptoms(prevState => ({
...prevState,
[symptom]: !prevState[symptom],
}));
};
const handleSubmit = () => {
// Handle the submission of symptoms
console.log(selectedSymptoms);
// Navigate or perform next steps
};
const toggleFullscreen = () => {
if (videoRef.current) {
if (!fullscreen) {
videoRef.current.presentFullscreenPlayer(); // This will open the video in fullscreen
} else {
videoRef.current.dismissFullscreenPlayer(); // This will exit the fullscreen mode
}
setFullscreen(!fullscreen); // Toggle the fullscreen state
}
};
const togglePlayPause = () => {
setVideoPaused(!videoPaused);
showControlsTemporarily(); // Toggle the pause state of the video
};
const showControlsTemporarily = () => {
setControlsVisible(true);
if (hideTimer.current) {
clearTimeout(hideTimer.current);
}
hideTimer.current = setTimeout(() => {
setControlsVisible(false);
}, 3000); // Hide controls after 3 seconds of inactivity
};
useEffect(() => {
return () => {
if (hideTimer.current) {
clearTimeout(hideTimer.current);
}
};
}, []);
return (
<SafeAreaView style={styles.container}>
<ScrollView style={styles.scrollContainer}>
<View style={styles.topContainer}>
<Text style={styles.topicText}>Melanoma Additional Symptoms </Text>
<View style={styles.videoBox}>
<Text style={styles.descriptionText}>
Self diagnose with the 3D Model
</Text>
<TouchableOpacity style={styles.videoContainer} onPress={showControlsTemporarily}>
<Video
// ref={videoRef}
source={{ uri: URL_link }} // Replace with the path to your video file
style={[styles.video, { height: fullscreen ? '100%' : 300 }]}
paused={videoPaused}
resizeMode="contain" // This ensures the video fits within its container
onLoad={() => setVideoPaused(false)}
onError={(error) => console.error('Video playback error:', error)}
/>
{controlsVisible && (
<TouchableOpacity style={styles.playPauseButton} onPress={togglePlayPause}>
<Image
style={styles.playPauseIcon}
source={videoPaused ? require('./skinassets/play.png') : require('./skinassets/pause.png')}
/>
</TouchableOpacity>
)}
</TouchableOpacity>
</View>
<Text style={styles.checkboxLabel}>Check the related box</Text>
<View style={styles.checkboxContainer}>
{/* Repeat this CheckBox component for each symptom */}
<View style={styles.individualCheckboxContainer}>
<CheckBox
value={selectedSymptoms['symptom1']}
onValueChange={() => toggleCheckbox('symptom1')}
/>
<Text style={styles.checkboxText}>Scattered itchy bumps</Text>
</View>
<View style={styles.individualCheckboxContainer}>
<CheckBox
value={selectedSymptoms['symptom2']}
onValueChange={() => toggleCheckbox('symptom2')}
/>
<Text style={styles.checkboxText}>Large red inflamed area across belly</Text>
</View>
<View style={styles.individualCheckboxContainer}>
<CheckBox
value={selectedSymptoms['symptom3']}
onValueChange={() => toggleCheckbox('symptom3')}
/>
<Text style={styles.checkboxText}>Yellow discharges</Text>
</View>
</View>
</View>
<Button
title="Continue for more information"
style={styles.nextButton}
onPress={() => navigation.navigate(ROUTES.SKIN_RISK)}
/>
</ScrollView>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
scrollContainer: {
flexGrow: 1,
},
container: {
flexGrow: 1,
backgroundColor: COLORS.white,
},
topContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: COLORS.white,
// This creates the curve effect for the background
},
topicText: {
fontSize: 24,
fontWeight: 'bold',
color: COLORS.black,
textAlign: 'center',
marginVertical: 20,
},
descriptionText: {
fontSize: 16,
textAlign: 'center',
marginHorizontal: 20,
marginBottom: 20,
},
checkboxContainer: {
backgroundColor: COLORS.lightBlue, // Use a light pastel blue color
borderRadius: 25,
width:'100%',
marginLeft:197,
paddingTop:10
},
checkboxLabel: {
fontSize: 18,
fontWeight: 'bold',
marginBottom: 10,
alignSelf: 'center',
},
checkboxRow: {
flexDirection: 'row',
alignItems: 'center',
marginBottom: 10,
},
checkboxText: {
fontSize: 16,
marginLeft: 8,
},
submitButton: {
backgroundColor: COLORS.primary,
borderRadius: 20,
padding: 15,
marginVertical: 20,
width: '90%',
alignSelf: 'center',
},
bottomContainer: {
flex: 2,
justifyContent: 'flex-end',
marginBottom: 2,
marginTop:-20,
alignItems: 'center',
backgroundColor: COLORS.blue,
borderTopRightRadius: 85,
borderTopLeftRadius: 85,
},
nextButton: {
width: '70%',
paddingVertical: 10,
marginBottom: 80, // Adjust the margin to move the button up further if necessary
backgroundColor: COLORS.white,
borderRadius: 20,
alignSelf: 'center',
},
videoContainer: {
width: '100%',
aspectRatio: 16 / 9, // You can adjust this aspect ratio as needed
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'black'
},
video: {
width: '110%',
height: '100%',
},
individualCheckboxContainer: {
backgroundColor: COLORS.white, // Set the background color to white
borderRadius: 10, // Set border radius for rounded corners
padding: 10, // Add some padding around the content
marginBottom: 10, // Add bottom margin for spacing between items
flexDirection: 'row', // Align checkbox and label in a row
alignItems: 'center', // Center align items vertically
borderWidth: 0.6, // Optional border width
width: '100%', // Width 100% to fill container width
marginLeft:-100,
elevation: 6,
},
fullscreenButton: {
marginTop: 10,
backgroundColor: 'rgba(0, 0, 0, 0.8)',
padding: 10,
borderRadius: 5,
},
fullscreenButtonText: {
color: '#fff',
},
videoBox: {
backgroundColor: COLORS.white, // Set background color to white
borderWidth: 2, // Set the border width
borderColor: '#80BCBD', // Set the border color
borderRadius: 10, // Set border radius for rounded corners
padding: 20, // Add padding around the content
marginBottom: 20, // Add bottom margin for spacing
width: '100%', // Adjust the width as necessary
alignSelf: 'center', // Center the box within its container
// Add shadows for elevation effect (optional)
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 3.84,
elevation: 5,
},
playPauseButton: {
position: 'absolute',
top: '50%',
left: '50%',
bottom:'30%',
transform: [{ translateX: -25 }, { translateY: -25 }],
width: 50,
height: 50,
justifyContent: 'center',
alignItems: 'center',
},
playPauseIcon: {
width: 50,
height: 50,
},
contentContainer: {
paddingBottom: 20, // Adds padding at the bottom
},
// ... possibly other styles
});
export default AdditionalSymptomsScreen;
import React, { useState } from 'react';
import { View, StyleSheet, Text, TouchableOpacity, ScrollView, Image } from 'react-native';
// import Video from 'react-native-video'; // or any other audio player you prefer
import { launchCamera, launchImageLibrary } from 'react-native-image-picker';
import { COLORS, IMGS, ROUTES } from '../../../constants';
import Button from '../../../components/Button';
import Video from 'react-native-video';
const RiskEvaluationScreen = ({ navigation }) => {
const [audioPaused, setAudioPaused] = useState(true);
// Function to handle the continuation to the next screen
const handleContinue = () => {
// navigation.navigate('NextScreenRoute');
};
return (
<View style={styles.container}>
<View style={styles.topContainer}>
<Text style={styles.topicText}>Risk evaluation</Text>
<Text style={styles.descriptionText}>
Your Condition Risk Level: High,Low will be displayed below
</Text>
<Text style={styles.subTopicText}>Why High Risk ?</Text>
<View style={styles.audioPlayerContainer}>
<Video
source={require("./skinassets/pause.png")}
style={styles.audioPlayer}
controls={true}
audioOnly={true}
resizeMode="cover" // Cover the audio's aspect ratio
paused={audioPaused}
repeat={true}
onLoad={() => setAudioPaused(false)}
/>
</View>
<Image style={styles.babyImage} source={IMGS.sk_14} />
<View style={styles.resultBox}>
<Text style={styles.resultText}>High Risk</Text>
</View>
</View>
<View style={styles.bottomContainer}>
<Button
title="Continue for more information"
style={styles.nextButton}
onPress={handleContinue}
/>
</View>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
},
topContainer: {
flex: 3,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: COLORS.white,
// This creates the curve effect for the background
},
container: {
flex: 1,
backgroundColor: COLORS.white,
},
topicText: {
fontSize: 24,
fontWeight: 'bold',
color: COLORS.black,
textAlign: 'center',
marginVertical: 20,
},
descriptionText: {
fontSize: 16,
textAlign: 'center',
marginHorizontal: 20,
marginBottom: 20,
},
videoPlayer: {
width: '90%',
alignSelf: 'center',
height: 200, // Adjust the height as needed
marginBottom: 20,
},
checkboxContainer: {
margin: 20,
padding: 20,
backgroundColor: COLORS.lightBlue, // Use a light pastel blue color
borderRadius: 25,
},
checkboxLabel: {
fontSize: 18,
fontWeight: 'bold',
marginBottom: 10,
},
checkboxRow: {
flexDirection: 'row',
alignItems: 'center',
marginBottom: 10,
},
checkboxText: {
fontSize: 16,
marginLeft: 8,
},
bottomContainer: {
flex: 2,
justifyContent: 'flex-end',
marginBottom: 2,
marginTop:20,
alignItems: 'center',
backgroundColor: '#EF9595',
borderTopRightRadius: 75,
borderTopLeftRadius: 75,
},
nextButton: {
width: '80%',
paddingVertical: 10,
marginBottom: 80, // Adjust the margin to move the button up further if necessary
backgroundColor: COLORS.white,
borderRadius: 20,
alignSelf: 'center',
},
resultText: {
fontSize: 18,
fontWeight: 'bold',
color: '#EF9595',
textAlign: 'center',
},
resultBox: {
borderWidth: 2,
borderColor: '#EF9595',
borderRadius: 10,
paddingVertical: 25,
paddingHorizontal: 40,
backgroundColor: COLORS.white, // Set the background color to white
shadowColor: "#000", // Shadow color for iOS and also works as elevation shadow color in Android
shadowOffset: {
width: 0,
height: 2, // Shadow offset for iOS
},
shadowOpacity: 0.25, // Shadow opacity for iOS
shadowRadius: 3.84, // Shadow radius for iOS
elevation: 5, // Elevation for Android
alignSelf: 'center',
marginTop: 148, // Adjust the margin to fit your layout
marginLeft:20
},
audioPlayerContainer: {
width: '90%',
height: 50, // Set a fixed height for the audio player container
alignSelf: 'center',
justifyContent: 'center',
marginTop: 20, // Space between the text and the player
},
audioPlayer: {
width: '100%', // Fill the container width
height: '100%', // Fill the container height
// Add more styles as needed
},
babyImage: {
position: 'absolute', // Use absolute positioning
width: 200,
height: 100,
resizeMode: 'contain',
bottom: 70, // Adjust this value based on the height of your result box + desired gap
alignSelf: 'center', // Center the image horizontally
marginLeft:40,
marginRight:100,
},
});
export default RiskEvaluationScreen;
import React, { useState } from 'react';
import { View, StyleSheet, Image, TouchableOpacity, PermissionsAndroid, Text, ScrollView } from 'react-native';
import { launchCamera, launchImageLibrary } from 'react-native-image-picker';
import { COLORS, IMGS, ROUTES } from '../../../constants';
import Button from '../../../components/Button';
import axios from 'axios'; // Import Axios
const Camera = ({ navigation }) => {
const [cameraPhoto, setCameraPhoto] = useState();
const [galleryPhoto, setGalleryPhoto] = useState();
const REACT_APP_API_URL='https://us-central1-skin-condition-detection.cloudfunctions.net/predict';
const [prediction, setPrediction] = useState(null);
const [photo, setPhoto] = useState(null);
let options = {
saveToPhotos: true,
mediaType: 'photo',
};
const openCamera = async () => {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.CAMERA,
);
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
const result = await launchCamera(options);
if (result.assets) {
setPhoto(result.assets[0].uri);
submitPhoto(result.assets[0].uri);
}
}
};
const openGallery = async () => {
const result = await launchImageLibrary(options);
if (result.assets) {
setPhoto(result.assets[0].uri);
submitPhoto(result.assets[0].uri);
}
};
const submitPhoto = async (photoUri) => {
try {
const formData = new FormData();
formData.append('file', {
uri: photoUri,
type: 'image/jpeg',
name: 'photo.jpg',
});
const response = await axios.post(REACT_APP_API_URL, formData, {
headers: {
'Content-Type': 'multipart/form-data',
},
});
if (response.status === 200) {
setPrediction(response.data); // Set prediction state with the received data
} else {
console.error('Error:', response.status);
}
} catch (error) {
console.error('Error:', error);
}
};
const handleContinue = () => {
let route; // Variable to store the route name
// Check the class and assign the route accordingly
if (prediction && prediction.class) {
switch (prediction.class) {
case 'Discoid':
route = ROUTES.SKIN_VIDEO;
break;
case 'Herpes HPV':
route = ROUTES.SKIN_VIDEO5;
break;
case 'Maculopapular':
route = ROUTES.SKIN_VIDEO2;
break;
case 'Melanoma':
route = ROUTES.SKIN_VIDEO3;
break;
case 'patechiae':
route = ROUTES.SKIN_VIDEO4;
break;
case 'PUPP Hives':
route = ROUTES.SKIN_VIDEO1;
break;
default:
route = ROUTES.SKIN_VIDEO1; // Define this route in your ROUTES constant
}
navigation.navigate(route);
} else {
// Handle the scenario where prediction or prediction.class is undefined
// Maybe navigate to an error page or show an alert
console.log("No valid prediction available.");
// navigation.navigate(ROUTES.DEFAULT_ROUTE); // Example fallback
}
};
return (
<View style={styles.container}>
<View style={styles.topContainer}>
<Text style={styles.topicText}>Skin Diagnostic Photo Upload</Text>
<Image style={styles.babyImage} source={IMGS.sk_1} />
<View style={styles.buttonContainer}>
<TouchableOpacity onPress={openGallery} style={[styles.button, styles.buttonLeft]}>
<Image source={IMGS.sk_2} style={styles.buttonImage} />
</TouchableOpacity>
<TouchableOpacity onPress={openCamera} style={[styles.button, styles.buttonRight]}>
<Image source={IMGS.sk_3} style={styles.buttonImage} />
</TouchableOpacity>
</View>
{photo && (
<View style={styles.photoContainer}>
<Image source={{ uri: photo }} style={styles.photo} />
</View>
)}
</View>
<Text style={styles.descriptionText}>'Use phone camera or select a photo from the gallery that clearly shows your skin.'</Text>
<View style={styles.bottomContainer}>
{!prediction && (
<>
<Text style={styles.resultsHeading}>Results will appear below</Text>
</>
)}
{prediction && (
<View style={styles.predictionContainer}>
<Text style={styles.predictionText}>Predicted Class: {prediction.class}</Text>
<Text style={styles.predictionText}>Confidence: {prediction.confidence}</Text>
</View>
)}
<Button
title="Continue for more information"
style={styles.nextButton}
onPress={() => navigation.navigate(ROUTES.SKIN_VIDEO2)}
/>
</View>
</View>
);
};
const styles = StyleSheet.create({
container: {
flexGrow: 1,
backgroundColor: COLORS.white,
},
predictionText: {
fontSize: 16,
color: '#000', // Text color
textAlign: 'center',
marginBottom: 5, // Space between text lines
},
topContainer: {
flex: 3,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: COLORS.white,
// This creates the curve effect for the background
},
buttonContainer: {
flexDirection: 'row',
marginTop: -26,
alignSelf: 'center', // Center the button container
borderRadius: 30,
overflow: 'hidden',
maxWidth: 300, // Set the max width for the container
borderWidth: 1, // Border for the whole container
borderColor: COLORS.blue, // Color of the container border and the separator line
},
button: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
paddingVertical: 10,
backgroundColor: COLORS.white, // White background for the buttons
// Adding border only for the right button to act as the line separator
},
buttonImage: {
width: 50, // Adjust as necessary for your design
height: 50, // Adjust as necessary for your design
resizeMode: 'contain',
},
buttonLeft: {
borderTopLeftRadius: 30, // Rounded left-top edge
borderBottomLeftRadius: 30, // Rounded left-bottom edge
borderRightWidth: 1, // Separator line
borderColor: COLORS.lightGray, // Color of the separator line
},
buttonRight: {
borderTopRightRadius: 30, // Rounded right-top edge
borderBottomRightRadius: 30, // Rounded right-bottom edge
},
babyImage: {
width: 100,
height: 100,
resizeMode: 'contain',
marginVertical: 20,
},
topicText: {
fontSize: 22,
fontWeight: 'bold',
color: COLORS.black,
textAlign: 'center',
marginBottom: 20,
},
descriptionText: {
fontSize: 16,
textAlign: 'center',
marginHorizontal: 10,
marginBottom: -10,
marginTop:-40
},
bottomContainer: {
flex: 2,
justifyContent: 'flex-end',
marginBottom: 2,
marginTop:20,
alignItems: 'center',
backgroundColor: COLORS.blue,
borderTopRightRadius: 75,
borderTopLeftRadius: 75,
},
nextButton: {
width: '70%',
paddingVertical: 10,
marginBottom: 80, // Adjust the margin to move the button up further if necessary
backgroundColor: COLORS.white,
borderRadius: 20,
alignSelf: 'center',
},
photoContainer: {
elevation: 4, // Android shadow
shadowColor: '#000', // iOS shadow
shadowOffset: { width: 0, height: 2 }, // iOS shadow
shadowOpacity: 0.1, // iOS shadow
shadowRadius: 2, // iOS shadow
borderRadius: 10,
marginTop: 20,
marginBottom: 20,
},
photo: {
width: 100,
height: 100,
borderRadius: 10,
},
predictionContainer: {
width: '80%',
backgroundColor: COLORS.white, // White background for the prediction box
borderRadius: 10,
padding: 15,
marginVertical: 20, // Adjust as needed
alignSelf: 'center',
alignItems: 'center',
justifyContent: 'center',
// Add shadows if you like for better visual separation
elevation: 4, // Android shadow
shadowColor: '#000', // iOS shadow
shadowOffset: { width: 0, height: 2 }, // iOS shadow
shadowOpacity: 0.1, // iOS shadow
shadowRadius: 2, // iOS shadow
},
resultsHeading: {
fontSize: 16,
color: '#000',
fontWeight: 'bold',
padding: 10,
textAlign: 'center',
marginBottom: 100,
marginLeft:0
},
resultImage: {
width: 100, // Set your desired width
height: 100, // Set your desired height
alignSelf: 'center',
marginVertical: 20, // Adjust margin as needed
},
});
export default Camera;
// import React from 'react';
// import { SafeAreaView, StyleSheet, Text, View } from 'react-native';
// const WelcomeExercise = () => {
// return (
// <View >
// <Text>Register</Text>
// </View>
// );
// };
// export default WelcomeExercise;
import { View, Text, Pressable, Image, StyleSheet } from 'react-native'
import React from 'react'
import LinearGradient from 'react-native-linear-gradient';
import {COLORS, IMGS, ROUTES} from '../../../constants';
import Button from '../../../components/Button';
const WelcomeExercise = ({ navigation }) => {
return (
<LinearGradient
style={styles.linearGradient}
colors={['#F1F0E8', '#96B6C5']}
>
<View style={styles.container}>
{/* Floating images with white borders */}
<Image source={IMGS.sk_5} style={styles.image1} />
<Image source={IMGS.sk_7} style={styles.image2} />
<Image source={IMGS.sk_8} style={styles.image3} />
<Image source={IMGS.sk_9} style={styles.image4} />
{/* Content */}
<View style={{
paddingHorizontal: 22,
position: "absolute",
top: 370,
width: "100%"
}}>
<Text style={{
fontSize: 50,
// fontWeight: 800,
color: COLORS.white
}}>Let's Get</Text>
<Text style={{
fontSize: 46,
// fontWeight: 800,
color: COLORS.white
}}>Started</Text>
<View style={{ marginVertical: 22 }}>
<Text style={{
fontSize: 16,
color: COLORS.white,
marginVertical: 4
}}>Reveal Your Skin's Story </Text>
<Text style={{
fontSize: 16,
color: COLORS.white,
}}>Your Skin, Your Health, Your App.</Text>
</View>
<Button
title="Start Today"
style={{
marginTop: 12,
width: "100%"
}}
onPress={() => navigation.navigate(ROUTES.SKIN_UPLOAD)}
/>
{/* ... rest of your content */}
</View>
</View>
</LinearGradient>
);
};
const styles = StyleSheet.create({
linearGradient: {
flex: 1,
},
container: {
flex: 1,
},
image1: {
height: 100,
width: 100,
borderRadius: 20,
position: 'absolute',
top: -20,
transform: [
{ translateX: 20 },
{ translateY: 50 },
{ rotate: '-15deg' },
],
borderWidth: 3, // White border
borderColor: '#FFFFFF',
},
image2: {
height: 100,
width: 100,
borderRadius: 20,
position: 'absolute',
top: -20,
left: 200,
transform: [
{ translateX: 50 },
{ translateY: 50 },
{ rotate: '-5deg' },
],
borderWidth: 3, // White border
borderColor: '#FFFFFF',
},
image3: {
width: 100,
height: 100,
borderRadius: 20,
position: 'absolute',
top: 130,
left: -30,
transform: [
{ translateX: 50 },
{ translateY: 50 },
{ rotate: '15deg' },
],
borderWidth: 3, // White border
borderColor: '#FFFFFF',
},
image4: {
height: 150,
width: 150,
borderRadius: 20,
position: 'absolute',
top: 140,
left: 140,
transform: [
{ translateX: 50 },
{ translateY: 50 },
{ rotate: '-15deg' },
],
borderWidth: 3, // White border
borderColor: '#FFFFFF',
},
// ... rest of your styles
});
export default WelcomeExercise;
...@@ -3311,7 +3311,17 @@ deepmerge@^2.1.1: ...@@ -3311,7 +3311,17 @@ deepmerge@^2.1.1:
resolved "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz" resolved "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz"
integrity sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA== integrity sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==
deepmerge@^4.2.2, deepmerge@^4.3.0, deepmerge@^4.3.1: deepmerge@^4.2.2:
version "4.3.1"
resolved "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz"
integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==
deepmerge@^4.3.0:
version "4.3.1"
resolved "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz"
integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==
deepmerge@^4.3.1:
version "4.3.1" version "4.3.1"
resolved "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz" resolved "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz"
integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==
...@@ -6378,22 +6388,7 @@ react-freeze@^1.0.0: ...@@ -6378,22 +6388,7 @@ react-freeze@^1.0.0:
resolved "https://registry.npmjs.org/react-freeze/-/react-freeze-1.0.4.tgz" resolved "https://registry.npmjs.org/react-freeze/-/react-freeze-1.0.4.tgz"
integrity sha512-r4F0Sec0BLxWicc7HEyo2x3/2icUTrRmDjaaRyzzn+7aDyFZliszMDOgLVwSnQnYENOlL1o569Ze2HZefk8clA== integrity sha512-r4F0Sec0BLxWicc7HEyo2x3/2icUTrRmDjaaRyzzn+7aDyFZliszMDOgLVwSnQnYENOlL1o569Ze2HZefk8clA==
"react-is@^16.12.0 || ^17.0.0 || ^18.0.0", react-is@^18.0.0, react-is@^18.2.0: "react-is@^16.12.0 || ^17.0.0 || ^18.0.0", react-is@^16.13.0, react-is@^16.13.1, react-is@^16.7.0:
version "18.3.1"
resolved "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz"
integrity sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==
react-is@^16.13.0:
version "16.13.1"
resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
react-is@^16.13.1:
version "16.13.1"
resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
react-is@^16.7.0:
version "16.13.1" version "16.13.1"
resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz" resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
...@@ -6403,6 +6398,16 @@ react-is@^17.0.1: ...@@ -6403,6 +6398,16 @@ react-is@^17.0.1:
resolved "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz" resolved "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz"
integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==
react-is@^18.0.0:
version "18.3.1"
resolved "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz"
integrity sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==
react-is@^18.2.0:
version "18.3.1"
resolved "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz"
integrity sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==
react-native-circular-progress-indicator@^4.4.2: react-native-circular-progress-indicator@^4.4.2:
version "4.4.2" version "4.4.2"
resolved "https://registry.npmjs.org/react-native-circular-progress-indicator/-/react-native-circular-progress-indicator-4.4.2.tgz" resolved "https://registry.npmjs.org/react-native-circular-progress-indicator/-/react-native-circular-progress-indicator-4.4.2.tgz"
...@@ -6428,6 +6433,11 @@ react-native-gesture-handler@^2.16.2: ...@@ -6428,6 +6433,11 @@ react-native-gesture-handler@^2.16.2:
lodash "^4.17.21" lodash "^4.17.21"
prop-types "^15.7.2" prop-types "^15.7.2"
react-native-image-picker@^7.1.1:
version "7.1.2"
resolved "https://registry.npmjs.org/react-native-image-picker/-/react-native-image-picker-7.1.2.tgz"
integrity sha512-b5y5nP60RIPxlAXlptn2QwlIuZWCUDWa/YPUVjgHc0Ih60mRiOg1PSzf0IjHSLeOZShCpirpvSPGnDExIpTRUg==
react-native-linear-gradient@^2.8.3: react-native-linear-gradient@^2.8.3:
version "2.8.3" version "2.8.3"
resolved "https://registry.npmjs.org/react-native-linear-gradient/-/react-native-linear-gradient-2.8.3.tgz" resolved "https://registry.npmjs.org/react-native-linear-gradient/-/react-native-linear-gradient-2.8.3.tgz"
...@@ -7487,7 +7497,7 @@ typed-array-length@^1.0.6: ...@@ -7487,7 +7497,7 @@ typed-array-length@^1.0.6:
is-typed-array "^1.1.13" is-typed-array "^1.1.13"
possible-typed-array-names "^1.0.0" possible-typed-array-names "^1.0.0"
typescript@5.0.4: "typescript@>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta", typescript@>=4.9.5, typescript@5.0.4:
version "5.0.4" version "5.0.4"
resolved "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz" resolved "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz"
integrity sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw== integrity sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment