diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 579ef283..89691a02 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -6,9 +6,6 @@ name: Lint ############################# on: push: - branches-ignore: [main] - pull_request: - branches: [main] ############### # Set the Job # diff --git a/.gitignore b/.gitignore index dbe5e160..afc76a51 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,6 @@ yarn-error.* # typescript *.tsbuildinfo + +.vscode/ +eas.json diff --git a/.vscode/extensions.json b/.vscode/extensions.json deleted file mode 100644 index c162df42..00000000 --- a/.vscode/extensions.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "recommendations": [ - "dbaeumer.vscode-eslint", - "esbenp.prettier-vscode", - "eamodio.gitlens" - ], - "unwantedRecommendations": [] -} diff --git a/.vscode/settings.json b/.vscode/settings.json index a93e2d6f..46d5ce93 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,7 +1,7 @@ { "editor.defaultFormatter": "esbenp.prettier-vscode", "editor.codeActionsOnSave": { - "source.formatDocument": true, - "source.fixAll.eslint": true + "source.formatDocument": "explicit", + "source.fixAll.eslint": "explicit" } } diff --git a/assets/icon.png b/assets/icon.png index a0b1526f..4edbdfe6 100644 Binary files a/assets/icon.png and b/assets/icon.png differ diff --git a/assets/save_story.png b/assets/save_story.png new file mode 100644 index 00000000..65b2ea6e Binary files /dev/null and b/assets/save_story.png differ diff --git a/assets/saved_story.png b/assets/saved_story.png new file mode 100644 index 00000000..46c3e7b0 Binary files /dev/null and b/assets/saved_story.png differ diff --git a/package-lock.json b/package-lock.json index ccd4c392..4bd8250b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,8 +19,8 @@ "@mui/material": "^5.14.13", "@mui/styled-engine-sc": "^6.0.0-alpha.1", "@mui/system": "^5.14.13", - "@react-native-async-storage/async-storage": "1.18.2", - "@react-native-community/datetimepicker": "7.2.0", + "@react-native-async-storage/async-storage": "^1.18.2", + "@react-native-community/datetimepicker": "^7.2.0", "@react-navigation/bottom-tabs": "^6.5.9", "@react-navigation/material-bottom-tabs": "^6.2.17", "@react-navigation/native": "^6.1.8", @@ -29,35 +29,46 @@ "@rneui/themed": "^4.0.0-rc.8", "@supabase/supabase-js": "^2.36.0", "@types/validator": "^13.11.5", + "@xenova/transformers": "^2.16.1", "axios": "^1.5.0", + "cheerio": "^1.0.0-rc.12", "deprecated-react-native-prop-types": "^4.2.1", "dom-parser": "^0.1.6", "expo": "~49.0.11", "expo-constants": "~14.4.2", "expo-font": "~11.4.0", + "expo-image": "~1.3.5", "expo-linking": "~5.0.2", "expo-router": "^2.0.0", "expo-status-bar": "~1.6.0", "html-entities": "^2.4.0", "react": "18.2.0", + "react-apple-emojis": "^2.2.1", "react-native": "0.72.10", "react-native-dom-parser": "^1.5.3", "react-native-element-dropdown": "^2.10.0", "react-native-elements": "^3.4.3", + "react-native-emoji": "^1.8.0", + "react-native-emojicon": "^1.0.0", "react-native-gesture-handler": "~2.12.0", "react-native-htmlview": "^0.16.0", "react-native-ionicons": "^4.6.5", + "react-native-modal-datetime-picker": "^17.1.0", + "react-native-neat-date-picker": "^1.4.12", "react-native-otp-textinput": "^1.1.3", "react-native-paper": "^5.10.6", + "react-native-paper-dates": "^0.22.3", "react-native-render-html": "^6.3.4", "react-native-root-siblings": "^4.1.1", - "react-native-root-toast": "^3.5.1", "react-native-safe-area-context": "4.6.3", "react-native-screens": "~3.22.0", "react-native-svg": "13.9.0", + "react-native-toast-message": "^2.2.0", + "react-native-ui-datepicker": "^2.0.2", "react-native-url-polyfill": "^2.0.0", "react-native-vector-icons": "^10.0.2", "react-scroll-to-top": "^3.0.0", + "use-debounce": "^10.0.0", "validator": "^13.11.0" }, "devDependencies": { @@ -70,8 +81,7 @@ "eslint-config-universe": "^12.0.0", "husky": "^8.0.3", "prettier": "^3.0.3", - "supabase": "^1.110.1", - "typescript": "^5.1.3" + "supabase": "^1.110.1" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -96,12 +106,12 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.22.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", - "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", + "version": "7.24.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz", + "integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==", "dependencies": { - "@babel/highlight": "^7.22.13", - "chalk": "^2.4.2" + "@babel/highlight": "^7.24.2", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" @@ -145,13 +155,13 @@ } }, "node_modules/@babel/generator": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.15.tgz", - "integrity": "sha512-Zu9oWARBqeVOW0dZOjXc3JObrzuqothQ3y/n1kUtrjCoCPLkXUwMvOo/F/TCfoHMbWIFlWwpZtkZVb9ga4U2pA==", + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.4.tgz", + "integrity": "sha512-Xd6+v6SnjWVx/nus+y0l1sxMOTOMBkyL4+BIdbALyatQnAe/SRVjANeDPSCYaX+i1iJmuGSKf3Z+E+V/va1Hvw==", "dependencies": { - "@babel/types": "^7.22.15", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", + "@babel/types": "^7.24.0", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^2.5.1" }, "engines": { @@ -454,22 +464,23 @@ } }, "node_modules/@babel/highlight": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", - "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", + "version": "7.24.2", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.2.tgz", + "integrity": "sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==", "dependencies": { "@babel/helper-validator-identifier": "^7.22.20", "chalk": "^2.4.2", - "js-tokens": "^4.0.0" + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.22.16", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.16.tgz", - "integrity": "sha512-+gPfKv8UWeKKeJTUxe59+OobVcrYHETCsORl61EmSkmgymguYk/X5bp7GuUIXaFsc6y++v8ZxPsLSSuujqDphA==", + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.4.tgz", + "integrity": "sha512-zTvEBcghmeBma9QIGunWevvBAp4/Qu9Bdq+2k0Ot4fVMD6v3dsC9WOcRSKk7tRRyBM/53yKMJko9xOatGQAwSg==", "bin": { "parser": "bin/babel-parser.js" }, @@ -1995,19 +2006,19 @@ } }, "node_modules/@babel/traverse": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.20.tgz", - "integrity": "sha512-eU260mPZbU7mZ0N+X10pxXhQFMGTeLb9eFS0mxehS8HZp9o1uSnFeWQuG1UPrlxgA7QoUzFhOnilHDp0AXCyHw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.1.tgz", + "integrity": "sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ==", "dependencies": { - "@babel/code-frame": "^7.22.13", - "@babel/generator": "^7.22.15", + "@babel/code-frame": "^7.24.1", + "@babel/generator": "^7.24.1", "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.22.5", + "@babel/helper-function-name": "^7.23.0", "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.22.16", - "@babel/types": "^7.22.19", - "debug": "^4.1.0", + "@babel/parser": "^7.24.1", + "@babel/types": "^7.24.0", + "debug": "^4.3.1", "globals": "^11.1.0" }, "engines": { @@ -2015,9 +2026,9 @@ } }, "node_modules/@babel/types": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.9.tgz", - "integrity": "sha512-dQjSq/7HaSjRM43FFGnv5keM2HsxpmyV1PfaSVm0nzzjwwTmjOe6J4bC8e3+pTEIgHaHj+1ZlLThRJ2auc/w1Q==", + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz", + "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==", "dependencies": { "@babel/helper-string-parser": "^7.23.4", "@babel/helper-validator-identifier": "^7.22.20", @@ -2385,9 +2396,9 @@ } }, "node_modules/@expo/cli": { - "version": "0.10.12", - "resolved": "https://registry.npmjs.org/@expo/cli/-/cli-0.10.12.tgz", - "integrity": "sha512-sc4IkRBbm6HO1Z/0JeJMY/sJiyCAfHyt2EOHhAY8jYfbXr/aqCIGsPrwEGQAfGpsE2OPvyzRa+byZG03HRPTkQ==", + "version": "0.10.17", + "resolved": "https://registry.npmjs.org/@expo/cli/-/cli-0.10.17.tgz", + "integrity": "sha512-HkHDvHPzq4M244hIerwnsw2IdjOo7RSsMYWGhc7ZY7DQWIMUC88b7f5+0RtD4JQfXQrgKS5Tvqm/5E6kAH0rIA==", "dependencies": { "@babel/runtime": "^7.20.0", "@expo/code-signing-certificates": "0.0.5", @@ -2521,9 +2532,9 @@ } }, "node_modules/@expo/cli/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", "dependencies": { "lru-cache": "^6.0.0" }, @@ -2758,6 +2769,18 @@ "temp-dir": "^2.0.0" } }, + "node_modules/@expo/dev-server/node_modules/@expo/osascript": { + "version": "2.0.33", + "resolved": "https://registry.npmjs.org/@expo/osascript/-/osascript-2.0.33.tgz", + "integrity": "sha512-FQinlwHrTlJbntp8a7NAlCKedVXe06Va/0DSLXRO8lZVtgbEMrYYSUZWQNcOlNtc58c2elNph6z9dMOYwSo3JQ==", + "dependencies": { + "@expo/spawn-async": "^1.5.0", + "exec-async": "^2.2.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/@expo/dev-server/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -2837,9 +2860,9 @@ } }, "node_modules/@expo/dev-server/node_modules/jsonfile/node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "engines": { "node": ">= 10.0.0" } @@ -2948,14 +2971,6 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, - "node_modules/@expo/env/node_modules/dotenv": { - "version": "16.0.3", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", - "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==", - "engines": { - "node": ">=12" - } - }, "node_modules/@expo/env/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -3259,9 +3274,9 @@ } }, "node_modules/@expo/metro-runtime": { - "version": "2.2.10", - "resolved": "https://registry.npmjs.org/@expo/metro-runtime/-/metro-runtime-2.2.10.tgz", - "integrity": "sha512-4lEHpOpm7FFwnNsD985eZFtcf32WakD8wSGZmfqc/bkBks076PUb5qIfTgJviGEHF9OAuic+htQi/IcbEdBr9w==", + "version": "2.2.16", + "resolved": "https://registry.npmjs.org/@expo/metro-runtime/-/metro-runtime-2.2.16.tgz", + "integrity": "sha512-WOUe7ByZsQpFRifyh9WgsjMYrCGHirWA8VvtR5fs+vi0za3yFIaC89wYMvEZILyvn+RIe7Ysln8nzF4xgtnKFg==", "dependencies": { "@bacons/react-views": "^1.1.3", "qs": "^6.10.3" @@ -3271,9 +3286,9 @@ } }, "node_modules/@expo/osascript": { - "version": "2.0.33", - "resolved": "https://registry.npmjs.org/@expo/osascript/-/osascript-2.0.33.tgz", - "integrity": "sha512-FQinlwHrTlJbntp8a7NAlCKedVXe06Va/0DSLXRO8lZVtgbEMrYYSUZWQNcOlNtc58c2elNph6z9dMOYwSo3JQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@expo/osascript/-/osascript-2.1.0.tgz", + "integrity": "sha512-bOhuFnlRaS7CU33+rFFIWdcET/Vkyn1vsN8BYFwCDEF5P1fVVvYN7bFOsQLTMD3nvi35C1AGmtqUr/Wfv8Xaow==", "dependencies": { "@expo/spawn-async": "^1.5.0", "exec-async": "^2.2.0" @@ -3283,9 +3298,9 @@ } }, "node_modules/@expo/package-manager": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@expo/package-manager/-/package-manager-1.1.1.tgz", - "integrity": "sha512-NxtfIA25iEiNwMT+s8PEmdKzjyfWd2qkCLJkf6jKZGaH9c06YXyOAi2jvCyM8XuSzJz4pcEH8kz1HkJAInjB7Q==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@expo/package-manager/-/package-manager-1.1.2.tgz", + "integrity": "sha512-JI9XzrxB0QVXysyuJ996FPCJGDCYRkbUvgG4QmMTTMFA1T+mv8YzazC3T9C1pHQUAAveVCre1+Pqv0nZXN24Xg==", "dependencies": { "@expo/json-file": "^8.2.37", "@expo/spawn-async": "^1.5.0", @@ -3509,9 +3524,9 @@ "integrity": "sha512-TI+l71+5aSKnShYclFa14Kum+hQMZ86b95SH6tQUG3qZEmLTarvWpKwqtTwQKqvlJSJrpFiSFu3eCuZokY6zWA==" }, "node_modules/@expo/xcpretty": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@expo/xcpretty/-/xcpretty-4.2.2.tgz", - "integrity": "sha512-Lke/geldJqUV0Dfxg5/QIOugOzdqZ/rQ9yHKSgGbjZtG1uiSqWyFwWvXmrdd3/sIdX33eykGvIcf+OrvvcXVUw==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@expo/xcpretty/-/xcpretty-4.3.1.tgz", + "integrity": "sha512-sqXgo1SCv+j4VtYEwl/bukuOIBrVgx6euIoCat3Iyx5oeoXwEA2USCoeL0IPubflMxncA2INkqJ/Wr3NGrSgzw==", "dependencies": { "@babel/code-frame": "7.10.4", "chalk": "^4.1.0", @@ -3717,6 +3732,14 @@ "@hapi/hoek": "^9.0.0" } }, + "node_modules/@huggingface/jinja": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@huggingface/jinja/-/jinja-0.2.2.tgz", + "integrity": "sha512-/KPde26khDUIPkTGU82jdtTW9UAuvUTumCAbFs/7giR0SxsvZC4hru51PBvpijH6BVkHcROcvZM/lpy5h1jRRA==", + "engines": { + "node": ">=18" + } + }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.11", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz", @@ -4146,13 +4169,13 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "dependencies": { - "@jridgewell/set-array": "^1.0.1", + "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { "node": ">=6.0.0" @@ -4167,9 +4190,9 @@ } }, "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "engines": { "node": ">=6.0.0" } @@ -4189,9 +4212,9 @@ "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.19", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz", - "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==", + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -4631,9 +4654,9 @@ } }, "node_modules/@npmcli/fs/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", "dependencies": { "lru-cache": "^6.0.0" }, @@ -4805,6 +4828,60 @@ "url": "https://opencollective.com/popperjs" } }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" + }, "node_modules/@radix-ui/react-compose-refs": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.0.tgz", @@ -7277,6 +7354,11 @@ "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "dev": true }, + "node_modules/@types/long": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==" + }, "node_modules/@types/node": { "version": "20.6.3", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.6.3.tgz", @@ -7311,12 +7393,11 @@ } }, "node_modules/@types/react": { - "version": "18.2.22", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.22.tgz", - "integrity": "sha512-60fLTOLqzarLED2O3UQImc/lsNRgG0jE/a1mPW9KjMemY0LMITWEsbS4VvZ4p6rorEHd5YKxxmMKSDK505GHpA==", + "version": "18.2.78", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.78.tgz", + "integrity": "sha512-qOwdPnnitQY4xKlKayt42q5W5UQrSHjgoXNVEtxeqdITJ99k4VXJOP3vt8Rkm9HmgJpH50UNU+rlqfkfWOqp0A==", "dependencies": { "@types/prop-types": "*", - "@types/scheduler": "*", "csstype": "^3.0.2" } }, @@ -7364,11 +7445,6 @@ "@types/react": "*" } }, - "node_modules/@types/scheduler": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz", - "integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==" - }, "node_modules/@types/semver": { "version": "7.5.3", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.3.tgz", @@ -7729,6 +7805,19 @@ "graphql": "^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" } }, + "node_modules/@xenova/transformers": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/@xenova/transformers/-/transformers-2.16.1.tgz", + "integrity": "sha512-p2ii7v7oC3Se0PC012dn4vt196GCroaN5ngOYJYkfg0/ce8A5frsrnnnktOBJuejG3bW5Hreb7JZ/KxtUaKd8w==", + "dependencies": { + "@huggingface/jinja": "^0.2.2", + "onnxruntime-web": "1.14.0", + "sharp": "^0.32.0" + }, + "optionalDependencies": { + "onnxruntime-node": "1.14.0" + } + }, "node_modules/@xmldom/xmldom": { "version": "0.7.13", "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.7.13.tgz", @@ -8141,11 +8230,11 @@ } }, "node_modules/axios": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.5.0.tgz", - "integrity": "sha512-D4DdjDo5CY50Qms0qGQTTw6Q44jl7zRwY7bthds06pUGfChBCTcQs+N743eFWGEd6pRTMd6A+I87aWyFV5wiZQ==", + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.8.tgz", + "integrity": "sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==", "dependencies": { - "follow-redirects": "^1.15.0", + "follow-redirects": "^1.15.6", "form-data": "^4.0.0", "proxy-from-env": "^1.1.0" } @@ -8163,6 +8252,11 @@ "node": ">= 6" } }, + "node_modules/b4a": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.6.tgz", + "integrity": "sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg==" + }, "node_modules/babel-core": { "version": "7.0.0-bridge.0", "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-7.0.0-bridge.0.tgz", @@ -8411,6 +8505,38 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, + "node_modules/bare-events": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.2.2.tgz", + "integrity": "sha512-h7z00dWdG0PYOQEvChhOSWvOfkIKsdZGkWr083FgN/HyoQuebSew/cgirYqh9SCuy/hRvxc5Vy6Fw8xAmYHLkQ==", + "optional": true + }, + "node_modules/bare-fs": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-2.2.3.tgz", + "integrity": "sha512-amG72llr9pstfXOBOHve1WjiuKKAMnebcmMbPWDZ7BCevAoJLpugjuAPRsDINEyjT0a6tbaVx3DctkXIRbLuJw==", + "optional": true, + "dependencies": { + "bare-events": "^2.0.0", + "bare-path": "^2.0.0", + "streamx": "^2.13.0" + } + }, + "node_modules/bare-os": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-2.2.1.tgz", + "integrity": "sha512-OwPyHgBBMkhC29Hl3O4/YfxW9n7mdTr2+SsO29XBWKKJsbgj3mnorDB80r5TiCQgQstgE5ga1qNYrpes6NvX2w==", + "optional": true + }, + "node_modules/bare-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-2.1.1.tgz", + "integrity": "sha512-OHM+iwRDRMDBsSW7kl3dO62JyHdBKO3B25FB9vNQBPcGHMo4+eA8Yj41Lfbk3pS/seDY+siNge0LdRTulAau/A==", + "optional": true, + "dependencies": { + "bare-os": "^2.1.0" + } + }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -8911,95 +9037,273 @@ "node": "*" } }, - "node_modules/chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "node_modules/cheerio": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", + "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", + "dependencies": { + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "htmlparser2": "^8.0.1", + "parse5": "^7.0.0", + "parse5-htmlparser2-tree-adapter": "^7.0.0" + }, "engines": { - "node": ">=10" + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" } }, - "node_modules/ci-info": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", - "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==", + "node_modules/cheerio-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", + "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", + "dependencies": { + "boolbase": "^1.0.0", + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cheerio-select/node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/cheerio-select/node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", "funding": [ { "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" + "url": "https://github.com/sponsors/fb55" } - ], - "engines": { - "node": ">=8" - } + ] }, - "node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "node_modules/cheerio-select/node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dependencies": { + "domelementtype": "^2.3.0" + }, "engines": { - "node": ">=6" + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" } }, - "node_modules/cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==", + "node_modules/cheerio-select/node_modules/domutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", "dependencies": { - "restore-cursor": "^2.0.0" + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" }, - "engines": { - "node": ">=4" + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" } }, - "node_modules/cli-spinners": { - "version": "2.9.1", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.1.tgz", - "integrity": "sha512-jHgecW0pxkonBJdrKsqxgRX9AcG+u/5k0Q7WPDfi8AogLAdwxEkyYYNWwZ5GvVFoFx2uiY1eNcSK00fh+1+FyQ==", + "node_modules/cheerio-select/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", "engines": { - "node": ">=6" + "node": ">=0.12" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/fb55/entities?sponsor=1" } }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "node_modules/cheerio/node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" }, - "engines": { - "node": ">=12" + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" } }, - "node_modules/cliui/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "node_modules/cheerio/node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/cheerio/node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", "dependencies": { - "ansi-regex": "^5.0.1" + "domelementtype": "^2.3.0" }, "engines": { - "node": ">=8" - } - }, - "node_modules/clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", - "engines": { - "node": ">=0.8" + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" } }, - "node_modules/clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "dependencies": { + "node_modules/cheerio/node_modules/domutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/cheerio/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/cheerio/node_modules/htmlparser2": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", + "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "entities": "^4.4.0" + } + }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "engines": { + "node": ">=10" + } + }, + "node_modules/ci-info": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", + "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==", + "dependencies": { + "restore-cursor": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.1.tgz", + "integrity": "sha512-jHgecW0pxkonBJdrKsqxgRX9AcG+u/5k0Q7WPDfi8AogLAdwxEkyYYNWwZ5GvVFoFx2uiY1eNcSK00fh+1+FyQ==", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dependencies": { "is-plain-object": "^2.0.4", "kind-of": "^6.0.2", "shallow-clone": "^3.0.0" @@ -9096,9 +9400,12 @@ "integrity": "sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA==" }, "node_modules/component-type": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/component-type/-/component-type-1.2.1.tgz", - "integrity": "sha512-Kgy+2+Uwr75vAi6ChWXgHuLvd+QLD7ssgpaRq2zCvt80ptvAfMc/hijcJxXkBa2wMlEZcJvC2H8Ubo+A9ATHIg==" + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/component-type/-/component-type-1.2.2.tgz", + "integrity": "sha512-99VUHREHiN5cLeHm3YLq312p6v+HUEcwtLCAtelvUDI6+SH5g5Cr85oNR2S1o6ywzL0ykMbuwLzM2ANocjEOIA==", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/compressible": { "version": "2.0.18", @@ -9463,6 +9770,20 @@ "node": ">=0.10" } }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/deep-extend": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", @@ -9955,6 +10276,14 @@ "domelementtype": "1" } }, + "node_modules/dotenv": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", + "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==", + "engines": { + "node": ">=12" + } + }, "node_modules/dotenv-expand": { "version": "10.0.0", "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-10.0.0.tgz", @@ -10167,13 +10496,14 @@ } }, "node_modules/es5-ext": { - "version": "0.10.62", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz", - "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", + "version": "0.10.64", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.64.tgz", + "integrity": "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==", "hasInstallScript": true, "dependencies": { "es6-iterator": "^2.0.3", "es6-symbol": "^3.1.3", + "esniff": "^2.0.1", "next-tick": "^1.1.0" }, "engines": { @@ -10810,6 +11140,25 @@ "node": ">= 8" } }, + "node_modules/esniff": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/esniff/-/esniff-2.0.1.tgz", + "integrity": "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==", + "dependencies": { + "d": "^1.0.1", + "es5-ext": "^0.10.62", + "event-emitter": "^0.3.5", + "type": "^2.7.2" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esniff/node_modules/type": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", + "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==" + }, "node_modules/espree": { "version": "9.6.1", "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", @@ -10888,6 +11237,15 @@ "node": ">= 0.6" } }, + "node_modules/event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", + "dependencies": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, "node_modules/event-target-shim": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", @@ -10923,13 +11281,21 @@ "node": ">=6" } }, + "node_modules/expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "engines": { + "node": ">=6" + } + }, "node_modules/expo": { - "version": "49.0.11", - "resolved": "https://registry.npmjs.org/expo/-/expo-49.0.11.tgz", - "integrity": "sha512-4UtSnaVn4bAEsdp2Z2I8okCJEmAm2cj1Rl3ifm79fI4zMz3EqBaXMKs6OdMSTa6DWq3dZp8C/5dEKy/ynah0CA==", + "version": "49.0.23", + "resolved": "https://registry.npmjs.org/expo/-/expo-49.0.23.tgz", + "integrity": "sha512-mFdBpWisPXBuocRGywC14nDai5vSUmvEyQpwvKH/xUo+m5/TUvfqV6YIewFpW22zn5WFGFiuJPhzNrqhBBinIw==", "dependencies": { "@babel/runtime": "^7.20.0", - "@expo/cli": "0.10.12", + "@expo/cli": "0.10.17", "@expo/config": "8.1.2", "@expo/config-plugins": "7.2.5", "@expo/vector-icons": "^13.0.0", @@ -10937,11 +11303,11 @@ "expo-application": "~5.3.0", "expo-asset": "~8.10.1", "expo-constants": "~14.4.2", - "expo-file-system": "~15.4.4", + "expo-file-system": "~15.4.5", "expo-font": "~11.4.0", "expo-keep-awake": "~12.3.0", "expo-modules-autolinking": "1.5.1", - "expo-modules-core": "1.5.11", + "expo-modules-core": "1.5.13", "fbemitter": "^3.0.0", "invariant": "^2.2.4", "md5-file": "^3.2.3", @@ -10988,9 +11354,9 @@ } }, "node_modules/expo-file-system": { - "version": "15.4.4", - "resolved": "https://registry.npmjs.org/expo-file-system/-/expo-file-system-15.4.4.tgz", - "integrity": "sha512-F0xS88D85F7qVQ61r0qBnzh6VW/s6iIl+VaQEEi2nAIOQHw1JIEj4yCXPLTtbyn5VmArbe2dSL3KYz1V+BLkKA==", + "version": "15.4.5", + "resolved": "https://registry.npmjs.org/expo-file-system/-/expo-file-system-15.4.5.tgz", + "integrity": "sha512-xy61KaTaDgXhT/dllwYDHm3ch026EyO8j4eC6wSVr/yE12MMMxAC09yGwy4f7kkOs6ztGVQF5j7ldRzNLN4l0Q==", "dependencies": { "uuid": "^3.4.0" }, @@ -11010,9 +11376,9 @@ } }, "node_modules/expo-head": { - "version": "0.0.14", - "resolved": "https://registry.npmjs.org/expo-head/-/expo-head-0.0.14.tgz", - "integrity": "sha512-NvG6dwzi06F2hlYuz1rW/O8B/Us/2lDHTHZv0DJJmSWjAuT3Ja04WtS0QI9Yn5n0bSKKPrEGl4515q1zJ9MI0A==", + "version": "0.0.20", + "resolved": "https://registry.npmjs.org/expo-head/-/expo-head-0.0.20.tgz", + "integrity": "sha512-K0ETFOp/I+Td1T40D8k+Nlk8zCtvUFKTVYiwUhLoCCPf4dGC0zXv/noJLgyZ8jZ+5FJLlrSTpk2Gm9bxJfqkLw==", "dependencies": { "react-helmet-async": "^1.3.0" }, @@ -11022,6 +11388,14 @@ "react-native": "*" } }, + "node_modules/expo-image": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/expo-image/-/expo-image-1.3.5.tgz", + "integrity": "sha512-yrIR2mnfIKbKcguoqWK3U5m3zvLPnonvSCabB2ErVGhws8zQs7ILYf+7T08j8U6eFcohjw0CoAFJ6RWNsX2EhA==", + "peerDependencies": { + "expo": "*" + } + }, "node_modules/expo-keep-awake": { "version": "12.3.0", "resolved": "https://registry.npmjs.org/expo-keep-awake/-/expo-keep-awake-12.3.0.tgz", @@ -11156,26 +11530,26 @@ } }, "node_modules/expo-modules-core": { - "version": "1.5.11", - "resolved": "https://registry.npmjs.org/expo-modules-core/-/expo-modules-core-1.5.11.tgz", - "integrity": "sha512-1Dj2t74nVjxq6xEQf2b9WFfAMhPzVnR0thY0PfRFgob4STyj3sq1U4PIHVWvKQBtDKIa227DrNRb+Hu+LqKWQg==", + "version": "1.5.13", + "resolved": "https://registry.npmjs.org/expo-modules-core/-/expo-modules-core-1.5.13.tgz", + "integrity": "sha512-cKRsiHKwpDPRkBgMW3XdUWmEUDzihEPWXAyeo629BXpJ6uX6a66Zbz63SEXhlgsbLq8FB77gvYku3ceBqb+hHg==", "dependencies": { "compare-versions": "^3.4.0", "invariant": "^2.2.4" } }, "node_modules/expo-router": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/expo-router/-/expo-router-2.0.8.tgz", - "integrity": "sha512-hKm15AzEmqASgts1qf1UQzjB4ON6iXrV+KsHVicK7L3lb2rLpI6Cj5ayWjjUAQ7GmTw5O2FR/gdlPYil4hALIQ==", + "version": "2.0.15", + "resolved": "https://registry.npmjs.org/expo-router/-/expo-router-2.0.15.tgz", + "integrity": "sha512-6TZKWG6nVne5kGjTPOInAEsSmWy2K4DxXp96OoNUXKoRbJYIZyB++0VQRhXcUCGQSXZRfUa0z2ud8CusF+axNA==", "dependencies": { "@bacons/react-views": "^1.1.3", - "@expo/metro-runtime": "2.2.10", + "@expo/metro-runtime": "2.2.16", "@radix-ui/react-slot": "1.0.1", "@react-navigation/bottom-tabs": "~6.5.7", "@react-navigation/native": "~6.1.6", "@react-navigation/native-stack": "~6.9.12", - "expo-head": "0.0.14", + "expo-head": "0.0.20", "expo-splash-screen": "~0.20.2", "query-string": "7.1.3", "react-helmet-async": "^1.3.0", @@ -11185,10 +11559,6 @@ "peerDependencies": { "@react-navigation/drawer": "^6.5.8", "expo": "^49.0.0", - "expo-constants": "*", - "expo-linking": "*", - "expo-status-bar": "*", - "metro": "~0.76.7", "react-native-gesture-handler": "*", "react-native-reanimated": "*", "react-native-safe-area-context": "*", @@ -11246,6 +11616,11 @@ "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", "dev": true }, + "node_modules/fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==" + }, "node_modules/fast-glob": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", @@ -11519,6 +11894,11 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/flatbuffers": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/flatbuffers/-/flatbuffers-1.12.0.tgz", + "integrity": "sha512-c7CZADjRcl6j0PlvFy0ZqXQ67qSEZfrVPynmnL+2zPc+NtMvrF8Y0QceMo7QqnSPc7+uWjUIAbvCQ5WIKlMVdQ==" + }, "node_modules/flatted": { "version": "3.2.9", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", @@ -11539,9 +11919,9 @@ } }, "node_modules/follow-redirects": { - "version": "1.15.3", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", - "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==", + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", "funding": [ { "type": "individual", @@ -11612,6 +11992,11 @@ "node": ">= 0.6" } }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" + }, "node_modules/fs-extra": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", @@ -11759,6 +12144,11 @@ "node": ">=6" } }, + "node_modules/github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==" + }, "node_modules/glob": { "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", @@ -11876,6 +12266,11 @@ "graphql": "^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" } }, + "node_modules/guid-typescript": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/guid-typescript/-/guid-typescript-1.0.9.tgz", + "integrity": "sha512-Y8T4vYhEfwJOTbouREvG+3XDsjr8E3kIr7uf+JZ0BYloFsttiHU0WfvANVsR7TxNUJa/WpCnw/Ino/p+DeBhBQ==" + }, "node_modules/has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -13834,6 +14229,25 @@ "lightningcss-win32-x64-msvc": "1.19.0" } }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.19.0.tgz", + "integrity": "sha512-wIJmFtYX0rXHsXHSr4+sC5clwblEMji7HHQ4Ub1/CznVRxtCFha6JIt5JZaNf8vQrfdZnBxLLC6R8pC818jXqg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, "node_modules/lightningcss-darwin-x64": { "version": "1.19.0", "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.19.0.tgz", @@ -13853,51 +14267,212 @@ "url": "https://opencollective.com/parcel" } }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dependencies": { - "p-locate": "^5.0.0" - }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.19.0.tgz", + "integrity": "sha512-P15VXY5682mTXaiDtbnLYQflc8BYb774j2R84FgDLJTN6Qp0ZjWEFyN1SPqyfTj2B2TFjRHRUvQSSZ7qN4Weig==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=10" + "node": ">= 12.0.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.19.0.tgz", + "integrity": "sha512-zwXRjWqpev8wqO0sv0M1aM1PpjHz6RVIsBcxKszIG83Befuh4yNysjgHVplF9RTU7eozGe3Ts7r6we1+Qkqsww==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } }, - "node_modules/lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.19.0.tgz", + "integrity": "sha512-vSCKO7SDnZaFN9zEloKSZM5/kC5gbzUjoJQ43BvUpyTFUX7ACs/mDfl2Eq6fdz2+uWhUh7vf92c4EaaP4udEtA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } }, - "node_modules/lodash.isequal": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.19.0.tgz", + "integrity": "sha512-0AFQKvVzXf9byrXUq9z0anMGLdZJS+XSDqidyijI5njIwj6MdbvX2UZK/c4FfNmeRa2N/8ngTffoIuOUit5eIQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.19.0.tgz", + "integrity": "sha512-SJoM8CLPt6ECCgSuWe+g0qo8dqQYVcPiW2s19dxkmSI5+Uu1GIRzyKA0b7QqmEXolA+oSJhQqCmJpzjY4CuZAg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.19.0.tgz", + "integrity": "sha512-C+VuUTeSUOAaBZZOPT7Etn/agx/MatzJzGRkeV+zEABmPuntv1zihncsi+AyGmjkkzq3wVedEy7h0/4S84mUtg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha512-xYHt68QRoYGjeeM/XOE1uJtvXQAgvszfBhjV4yvsQH0u2i9I6cI6c6/eG4Hh3UAOVn0y/xAXwmTzEay49Q//HA==" + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" + }, + "node_modules/lodash.frompairs": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.frompairs/-/lodash.frompairs-4.0.1.tgz", + "integrity": "sha512-dvqe2I+cO5MzXCMhUnfYFa9MD+/760yx2aTAN1lqEcEkf896TxgrX373igVdqSJj6tQd0jnSLE1UMuKufqqxFw==" + }, + "node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==" }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" + }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "node_modules/lodash.omit": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.omit/-/lodash.omit-4.5.0.tgz", + "integrity": "sha512-XeqSp49hNGmlkj2EJlfrQFIzQ6lXdNro9sddtQzcJY8QaoC2GO0DT7xaIokHeyM+mIT0mPMlPvkYzg2xCuHdZg==" + }, + "node_modules/lodash.pick": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", + "integrity": "sha512-hXt6Ul/5yWjfklSGvLQl8vM//l3FtyHZeuelpzK6mm99pNvN9yTDruNZPEJZD1oWrqo+izBmB7oUfWgcCX7s4Q==" + }, + "node_modules/lodash.template": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", + "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", + "dependencies": { + "lodash._reinterpolate": "^3.0.0", + "lodash.templatesettings": "^4.0.0" + } + }, + "node_modules/lodash.templatesettings": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", + "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", + "dependencies": { + "lodash._reinterpolate": "^3.0.0" + } + }, "node_modules/lodash.throttle": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", "integrity": "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==" }, + "node_modules/lodash.toarray": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.toarray/-/lodash.toarray-4.4.0.tgz", + "integrity": "sha512-QyffEA3i5dma5q2490+SgCvDN0pXLmRGSyAANuVi0HQ01Pkfr9fuoKQW8wm1wGBnJITs/mS7wQvS6VshUEBFCw==" + }, "node_modules/log-symbols": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", @@ -14080,6 +14655,11 @@ "node": ">=6" } }, + "node_modules/long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -14927,6 +15507,17 @@ "node": ">=4" } }, + "node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -15023,6 +15614,11 @@ "mkdirp": "bin/cmd.js" } }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -15097,6 +15693,11 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/napi-build-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", + "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==" + }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -15148,11 +15749,57 @@ "node": ">=12.0.0" } }, + "node_modules/node-abi": { + "version": "3.57.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.57.0.tgz", + "integrity": "sha512-Dp+A9JWxRaKuHP35H77I4kCKesDy5HUDEmScia2FyncMTOXASMyg251F5PhFoDA5uqBrDDffiLpbqnrZmNXW+g==", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-abi/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-abi/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-abi/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, "node_modules/node-abort-controller": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz", "integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==" }, + "node_modules/node-addon-api": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz", + "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==" + }, "node_modules/node-dir": { "version": "0.1.17", "resolved": "https://registry.npmjs.org/node-dir/-/node-dir-0.1.17.tgz", @@ -15183,6 +15830,14 @@ "node": ">=10.5.0" } }, + "node_modules/node-emoji": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.10.0.tgz", + "integrity": "sha512-Yt3384If5H6BYGVHiHwTL+99OzJKHhgp82S8/dktEK73T26BazdgZ4JZh92xSVtGNJvz9UbXdNAc5hcrXV42vw==", + "dependencies": { + "lodash.toarray": "^4.4.0" + } + }, "node_modules/node-fetch": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", @@ -15467,6 +16122,46 @@ "node": ">=4" } }, + "node_modules/onnx-proto": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/onnx-proto/-/onnx-proto-4.0.4.tgz", + "integrity": "sha512-aldMOB3HRoo6q/phyB6QRQxSt895HNNw82BNyZ2CMh4bjeKv7g/c+VpAFtJuEMVfYLMbRx61hbuqnKceLeDcDA==", + "dependencies": { + "protobufjs": "^6.8.8" + } + }, + "node_modules/onnxruntime-common": { + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/onnxruntime-common/-/onnxruntime-common-1.14.0.tgz", + "integrity": "sha512-3LJpegM2iMNRX2wUmtYfeX/ytfOzNwAWKSq1HbRrKc9+uqG/FsEA0bbKZl1btQeZaXhC26l44NWpNUeXPII7Ew==" + }, + "node_modules/onnxruntime-node": { + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/onnxruntime-node/-/onnxruntime-node-1.14.0.tgz", + "integrity": "sha512-5ba7TWomIV/9b6NH/1x/8QEeowsb+jBEvFzU6z0T4mNsFwdPqXeFUM7uxC6QeSRkEbWu3qEB0VMjrvzN/0S9+w==", + "optional": true, + "os": [ + "win32", + "darwin", + "linux" + ], + "dependencies": { + "onnxruntime-common": "~1.14.0" + } + }, + "node_modules/onnxruntime-web": { + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/onnxruntime-web/-/onnxruntime-web-1.14.0.tgz", + "integrity": "sha512-Kcqf43UMfW8mCydVGcX9OMXI2VN17c0p6XvR7IPSZzBf/6lteBzXHvcEVWDPmCKuGombl997HgLqj91F11DzXw==", + "dependencies": { + "flatbuffers": "^1.12.0", + "guid-typescript": "^1.0.9", + "long": "^4.0.0", + "onnx-proto": "^4.0.4", + "onnxruntime-common": "~1.14.0", + "platform": "^1.3.6" + } + }, "node_modules/open": { "version": "8.4.2", "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", @@ -15649,6 +16344,65 @@ "node": ">=10" } }, + "node_modules/parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "dependencies": { + "entities": "^4.4.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz", + "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==", + "dependencies": { + "domhandler": "^5.0.2", + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter/node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/parse5-htmlparser2-tree-adapter/node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/parse5/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -15928,6 +16682,11 @@ "node": ">=4" } }, + "node_modules/platform": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.6.tgz", + "integrity": "sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==" + }, "node_modules/plist": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/plist/-/plist-3.1.0.tgz", @@ -15997,6 +16756,83 @@ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" }, + "node_modules/prebuild-install": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.2.tgz", + "integrity": "sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ==", + "dependencies": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^1.0.1", + "node-abi": "^3.3.0", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + }, + "bin": { + "prebuild-install": "bin.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/prebuild-install/node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + }, + "node_modules/prebuild-install/node_modules/detect-libc": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/prebuild-install/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/prebuild-install/node_modules/tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/prebuild-install/node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -16141,6 +16977,31 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, + "node_modules/protobufjs": { + "version": "6.11.4", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.4.tgz", + "integrity": "sha512-5kQWPaJHi1WoCpjTGszzQ32PG2F4+wRY6BmAT4Vfw56Q2FZ4YZzK20xUYQH4YkfehY1e6QSICrJquM6xXZNcrw==", + "hasInstallScript": true, + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.1", + "@types/node": ">=13.7.0", + "long": "^4.0.0" + }, + "bin": { + "pbjs": "bin/pbjs", + "pbts": "bin/pbts" + } + }, "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", @@ -16234,6 +17095,11 @@ } ] }, + "node_modules/queue-tick": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", + "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==" + }, "node_modules/ramda": { "version": "0.27.2", "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.27.2.tgz", @@ -16286,11 +17152,21 @@ "node": ">=0.10.0" } }, - "node_modules/react-devtools-core": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/react-devtools-core/-/react-devtools-core-4.28.0.tgz", - "integrity": "sha512-E3C3X1skWBdBzwpOUbmXG8SgH6BtsluSMe+s6rRcujNKG1DGi8uIfhdhszkgDpAsMoE55hwqRUzeXCmETDBpTg==", - "dependencies": { + "node_modules/react-apple-emojis": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/react-apple-emojis/-/react-apple-emojis-2.2.1.tgz", + "integrity": "sha512-tgq/+GUR6WsBkkkl0EYgVbaU803IF8GoELcG83cfircrEiyiiIbHqpBXIHyD8YIOecAGgN2ucEG6U/REDR7jvQ==", + "peerDependencies": { + "prop-types": "*", + "react": ">=16.x", + "react-dom": ">=16.x" + } + }, + "node_modules/react-devtools-core": { + "version": "4.28.5", + "resolved": "https://registry.npmjs.org/react-devtools-core/-/react-devtools-core-4.28.5.tgz", + "integrity": "sha512-cq/o30z9W2Wb4rzBefjv5fBalHU0rJGZCHAkf/RHSBWSSYwh8PlQTqqOJmgIIbBtpj27T6FIPXeomIjZtCNVqA==", + "dependencies": { "shell-quote": "^1.6.1", "ws": "^7" } @@ -16427,6 +17303,14 @@ "react": "18.2.0" } }, + "node_modules/react-native-animatable": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/react-native-animatable/-/react-native-animatable-1.3.3.tgz", + "integrity": "sha512-2ckIxZQAsvWn25Ho+DK3d1mXIgj7tITkrS4pYDvx96WyOttSvzzFeQnM2od0+FUMzILbdHDsDEqZvnz1DYNQ1w==", + "dependencies": { + "prop-types": "^15.7.2" + } + }, "node_modules/react-native-dom-parser": { "version": "1.5.3", "resolved": "https://registry.npmjs.org/react-native-dom-parser/-/react-native-dom-parser-1.5.3.tgz", @@ -16467,6 +17351,19 @@ "react-native-vector-icons": ">7.0.0" } }, + "node_modules/react-native-emoji": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/react-native-emoji/-/react-native-emoji-1.8.0.tgz", + "integrity": "sha512-VunKOtYes6eymyWwE7QS3mhmNXksTt2AN92PcGRtmDKLDPjuKrwd5tcJckFUekAK3H+6AMpwYy30CsiCJrDdFQ==", + "dependencies": { + "node-emoji": "1.10.0" + } + }, + "node_modules/react-native-emojicon": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/react-native-emojicon/-/react-native-emojicon-1.0.0.tgz", + "integrity": "sha512-rK6/7EIf/yNgkB24ujpV8zmmZylbQV+oq4F7YopZ9aSfNKmVKKFmqGOPahPo6OW8b1Dg5dm8caybgfpM2GP4Nw==" + }, "node_modules/react-native-gesture-handler": { "version": "2.12.1", "resolved": "https://registry.npmjs.org/react-native-gesture-handler/-/react-native-gesture-handler-2.12.1.tgz", @@ -16501,6 +17398,105 @@ "react-native": "*" } }, + "node_modules/react-native-modal": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/react-native-modal/-/react-native-modal-13.0.1.tgz", + "integrity": "sha512-UB+mjmUtf+miaG/sDhOikRfBOv0gJdBU2ZE1HtFWp6UixW9jCk/bhGdHUgmZljbPpp0RaO/6YiMmQSSK3kkMaw==", + "dependencies": { + "prop-types": "^15.6.2", + "react-native-animatable": "1.3.3" + }, + "peerDependencies": { + "react": "*", + "react-native": ">=0.65.0" + } + }, + "node_modules/react-native-modal-datetime-picker": { + "version": "17.1.0", + "resolved": "https://registry.npmjs.org/react-native-modal-datetime-picker/-/react-native-modal-datetime-picker-17.1.0.tgz", + "integrity": "sha512-jfTwfaCLtBffYbQ+pOGFLM+J5HmUh3vb9rT0JrrQPjxzecdc8pNYreB1c96+mVuq8bDCvaCdIeuEsslTqLJL0Q==", + "dependencies": { + "prop-types": "^15.7.2" + }, + "peerDependencies": { + "@react-native-community/datetimepicker": ">=6.7.0", + "react-native": ">=0.65.0" + } + }, + "node_modules/react-native-neat-date-picker": { + "version": "1.4.12", + "resolved": "https://registry.npmjs.org/react-native-neat-date-picker/-/react-native-neat-date-picker-1.4.12.tgz", + "integrity": "sha512-gnVmLrpnlNqO6F0wMdJOfFFSLdi5Dq62ugnxLAqWu43PGShlpOCW6CNpjJa84QB/Cd0xmRPlHh7+fEOuMtzjYA==", + "dependencies": { + "react-native-modal": "13.0.1", + "react-native-vector-icons": "^8.1.0" + } + }, + "node_modules/react-native-neat-date-picker/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/react-native-neat-date-picker/node_modules/react-native-vector-icons": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/react-native-vector-icons/-/react-native-vector-icons-8.1.0.tgz", + "integrity": "sha512-sHIdBB6Y0dHaot2fMXgy5J/hhCn5YuyN7SKDNFgPzL8KA1oF2/v7mgYMavnK7LIIs2dJoGnDANKf61dsU+TZlg==", + "dependencies": { + "lodash.frompairs": "^4.0.1", + "lodash.isequal": "^4.5.0", + "lodash.isstring": "^4.0.1", + "lodash.omit": "^4.5.0", + "lodash.pick": "^4.4.0", + "lodash.template": "^4.5.0", + "prop-types": "^15.7.2", + "yargs": "^16.1.1" + }, + "bin": { + "fa5-upgrade": "bin/fa5-upgrade.sh", + "generate-icon": "bin/generate-icon.js" + } + }, + "node_modules/react-native-neat-date-picker/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/react-native-neat-date-picker/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/react-native-neat-date-picker/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "engines": { + "node": ">=10" + } + }, "node_modules/react-native-otp-textinput": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/react-native-otp-textinput/-/react-native-otp-textinput-1.1.3.tgz", @@ -16528,6 +17524,48 @@ "react-native-vector-icons": "*" } }, + "node_modules/react-native-paper-dates": { + "version": "0.22.3", + "resolved": "https://registry.npmjs.org/react-native-paper-dates/-/react-native-paper-dates-0.22.3.tgz", + "integrity": "sha512-3zmhN09Z06SnYzHKEui7NRzwpxA/CkzlEo57pKiLZIg5TbfqtGu6WPTQZ17CpymfIhhyWZgPWcRTPasBr0XyJA==", + "dependencies": { + "color": "^4.2.3" + }, + "peerDependencies": { + "react": "*", + "react-native": "*", + "react-native-paper": "*", + "react-native-vector-icons": "*" + } + }, + "node_modules/react-native-paper-dates/node_modules/color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "dependencies": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.0" + } + }, + "node_modules/react-native-paper-dates/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/react-native-paper-dates/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, "node_modules/react-native-ratings": { "version": "8.0.4", "resolved": "https://registry.npmjs.org/react-native-ratings/-/react-native-ratings-8.0.4.tgz", @@ -16565,29 +17603,6 @@ "resolved": "https://registry.npmjs.org/react-native-root-siblings/-/react-native-root-siblings-4.1.1.tgz", "integrity": "sha512-sdmLElNs5PDWqmZmj4/aNH4anyxreaPm61c4ZkRiR8SO/GzLg6KjAbb0e17RmMdnBdD0AIQbS38h/l55YKN4ZA==" }, - "node_modules/react-native-root-toast": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/react-native-root-toast/-/react-native-root-toast-3.5.1.tgz", - "integrity": "sha512-zqsuec7Ugx2/9hR9BHqcmb3WWC/WBouqn2RYIpeTG+OpVvVfvr2UhWK4kLPJLk5/icZWl3xJrqiktPpbRpEA2A==", - "dependencies": { - "deprecated-react-native-prop-types": "^2.3.0", - "prop-types": "^15.5.10", - "react-native-root-siblings": "^4.0.0" - }, - "peerDependencies": { - "react-native": ">=0.47.0" - } - }, - "node_modules/react-native-root-toast/node_modules/deprecated-react-native-prop-types": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/deprecated-react-native-prop-types/-/deprecated-react-native-prop-types-2.3.0.tgz", - "integrity": "sha512-pWD0voFtNYxrVqvBMYf5gq3NA2GCpfodS1yNynTPc93AYA/KEMGeWDqqeUB6R2Z9ZofVhks2aeJXiuQqKNpesA==", - "dependencies": { - "@react-native/normalize-color": "*", - "invariant": "*", - "prop-types": "*" - } - }, "node_modules/react-native-safe-area-context": { "version": "4.6.3", "resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-4.6.3.tgz", @@ -16631,6 +17646,32 @@ "react-native": "*" } }, + "node_modules/react-native-toast-message": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/react-native-toast-message/-/react-native-toast-message-2.2.0.tgz", + "integrity": "sha512-AFti8VzUk6JvyGAlLm9/BknTNDXrrhqnUk7ak/pM7uCTxDPveAu2ekszU0on6vnUPFnG04H/QfYE2IlETqeaWw==", + "peerDependencies": { + "react": "*", + "react-native": "*" + } + }, + "node_modules/react-native-ui-datepicker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/react-native-ui-datepicker/-/react-native-ui-datepicker-2.0.2.tgz", + "integrity": "sha512-mCV7nj87YXKiPXGC0blYH+kUphUIZfbvJtgDUD8u2FPsvQhJ1G8jVahqNQYURTbiyuZd+okeUTAKUVCH5N2IqQ==", + "dependencies": { + "dayjs": "^1.11.10", + "lodash": "^4.17.21", + "uninstall": "^0.0.0" + }, + "engines": { + "node": ">= 16.0.0" + }, + "peerDependencies": { + "react": "*", + "react-native": "*" + } + }, "node_modules/react-native-url-polyfill": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/react-native-url-polyfill/-/react-native-url-polyfill-2.0.0.tgz", @@ -17490,6 +18531,94 @@ "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" }, + "node_modules/sharp": { + "version": "0.32.6", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.32.6.tgz", + "integrity": "sha512-KyLTWwgcR9Oe4d9HwCwNM2l7+J0dUQwn/yf7S0EnTtb0eVS4RxO0eUSvxPtzT4F3SY+C4K6fqdv/DO27sJ/v/w==", + "hasInstallScript": true, + "dependencies": { + "color": "^4.2.3", + "detect-libc": "^2.0.2", + "node-addon-api": "^6.1.0", + "prebuild-install": "^7.1.1", + "semver": "^7.5.4", + "simple-get": "^4.0.1", + "tar-fs": "^3.0.4", + "tunnel-agent": "^0.6.0" + }, + "engines": { + "node": ">=14.15.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/sharp/node_modules/color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "dependencies": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.0" + } + }, + "node_modules/sharp/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/sharp/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/sharp/node_modules/detect-libc": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/sharp/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/sharp/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/sharp/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, "node_modules/shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", @@ -17535,6 +18664,49 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, "node_modules/simple-plist": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/simple-plist/-/simple-plist-1.3.1.tgz", @@ -17730,6 +18902,18 @@ "node": ">= 0.10.0" } }, + "node_modules/streamx": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.16.1.tgz", + "integrity": "sha512-m9QYj6WygWyWa3H1YY69amr4nVgy61xfjys7xO7kviL5rfIEc2naf+ewFiOA+aEJD7y0JO3h2GoiUv4TDwEGzQ==", + "dependencies": { + "fast-fifo": "^1.1.0", + "queue-tick": "^1.0.1" + }, + "optionalDependencies": { + "bare-events": "^2.2.0" + } + }, "node_modules/strict-uri-encode": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz", @@ -17993,16 +19177,16 @@ "integrity": "sha512-rlBo3HU/1zAJUrkY6jNxDOC9eVYliG6nS4JA8u8KAshITd07tafMc/Br7xQwCSseXwJ2iCcHCE8SNWX3q8Z+kw==" }, "node_modules/supabase": { - "version": "1.110.1", - "resolved": "https://registry.npmjs.org/supabase/-/supabase-1.110.1.tgz", - "integrity": "sha512-pQVfbs/n8ZBDuSDv6YJKIH1Uh/QBRxjp6pLW52YkKgjgfwndlKwKuJoPiuWDxBkRG1QXxmCHi3Hk+JeNx9/FRg==", + "version": "1.157.2", + "resolved": "https://registry.npmjs.org/supabase/-/supabase-1.157.2.tgz", + "integrity": "sha512-vmmNNJX7f/gNpCXagdcaPgiKINl2/0IeZSyXd2Jgqal2UlQpeZ5vo6fTzBjZHPZwhKkJecsGoyCxbEKdHPE/yQ==", "dev": true, "hasInstallScript": true, "dependencies": { - "bin-links": "^4.0.1", + "bin-links": "^4.0.3", "https-proxy-agent": "^7.0.2", - "node-fetch": "^3.2.10", - "tar": "6.2.0" + "node-fetch": "^3.3.2", + "tar": "6.2.1" }, "bin": { "supabase": "bin/supabase" @@ -18124,9 +19308,9 @@ } }, "node_modules/tar": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.0.tgz", - "integrity": "sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", "dependencies": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", @@ -18139,6 +19323,29 @@ "node": ">=10" } }, + "node_modules/tar-fs": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.5.tgz", + "integrity": "sha512-JOgGAmZyMgbqpLwct7ZV8VzkEB6pxXFBVErLtb+XCOqzc6w1xiWKI9GVd6bwk68EX7eJ4DWmfXVmq8K2ziZTGg==", + "dependencies": { + "pump": "^3.0.0", + "tar-stream": "^3.1.5" + }, + "optionalDependencies": { + "bare-fs": "^2.1.1", + "bare-path": "^2.1.0" + } + }, + "node_modules/tar-stream": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", + "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", + "dependencies": { + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" + } + }, "node_modules/tar/node_modules/minipass": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", @@ -18374,9 +19581,12 @@ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, "node_modules/traverse": { - "version": "0.6.7", - "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.7.tgz", - "integrity": "sha512-/y956gpUo9ZNCb99YjxG7OaslxZWHfCHAUUfshwqOXmxUIvqLjVO581BT+gM59+QV9tFe6/CGG53tsA1Y7RSdg==", + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.8.tgz", + "integrity": "sha512-aXJDbk6SnumuaZSANd21XAo15ucCDE38H4fkqiGsc3MhCK+wOlZvLP9cB/TvpHT0mOyWgC4Z8EwRlzqYSUzdsA==", + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -18432,6 +19642,17 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, "node_modules/type": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", @@ -18558,6 +19779,7 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", "dev": true, + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -18668,6 +19890,11 @@ "node": ">=4" } }, + "node_modules/uninstall": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/uninstall/-/uninstall-0.0.0.tgz", + "integrity": "sha512-pjP/0+A4gsbDVa8XH/S2GZdT9NPJW8NFMy3GI7HnsWG+NAmFSSj3QidNosXBI9cPtxxNExEDdhKFO6sli8K3mA==" + }, "node_modules/unique-filename": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", @@ -18804,6 +20031,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/use-debounce": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/use-debounce/-/use-debounce-10.0.0.tgz", + "integrity": "sha512-XRjvlvCB46bah9IBXVnq/ACP2lxqXyZj0D9hj4K5OzNroMDpTEBg8Anuh1/UfRTRs7pLhQ+RiNxxwZu9+MVl1A==", + "engines": { + "node": ">= 16.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0" + } + }, "node_modules/use-latest-callback": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/use-latest-callback/-/use-latest-callback-0.1.6.tgz", @@ -19163,9 +20401,9 @@ } }, "node_modules/ws": { - "version": "8.14.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz", - "integrity": "sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", + "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", "engines": { "node": ">=10.0.0" }, diff --git a/package.json b/package.json index ca31a24f..d058a0c8 100644 --- a/package.json +++ b/package.json @@ -23,8 +23,8 @@ "@mui/material": "^5.14.13", "@mui/styled-engine-sc": "^6.0.0-alpha.1", "@mui/system": "^5.14.13", - "@react-native-async-storage/async-storage": "1.18.2", - "@react-native-community/datetimepicker": "7.2.0", + "@react-native-async-storage/async-storage": "^1.18.2", + "@react-native-community/datetimepicker": "^7.2.0", "@react-navigation/bottom-tabs": "^6.5.9", "@react-navigation/material-bottom-tabs": "^6.2.17", "@react-navigation/native": "^6.1.8", @@ -33,7 +33,9 @@ "@rneui/themed": "^4.0.0-rc.8", "@supabase/supabase-js": "^2.36.0", "@types/validator": "^13.11.5", + "@xenova/transformers": "^2.16.1", "axios": "^1.5.0", + "cheerio": "^1.0.0-rc.12", "deprecated-react-native-prop-types": "^4.2.1", "dom-parser": "^0.1.6", "expo": "~49.0.11", @@ -44,25 +46,34 @@ "expo-status-bar": "~1.6.0", "html-entities": "^2.4.0", "react": "18.2.0", + "react-apple-emojis": "^2.2.1", "react-native": "0.72.10", "react-native-dom-parser": "^1.5.3", "react-native-element-dropdown": "^2.10.0", "react-native-elements": "^3.4.3", + "react-native-emoji": "^1.8.0", + "react-native-emojicon": "^1.0.0", "react-native-gesture-handler": "~2.12.0", "react-native-htmlview": "^0.16.0", "react-native-ionicons": "^4.6.5", + "react-native-modal-datetime-picker": "^17.1.0", + "react-native-neat-date-picker": "^1.4.12", "react-native-otp-textinput": "^1.1.3", "react-native-paper": "^5.10.6", + "react-native-paper-dates": "^0.22.3", "react-native-render-html": "^6.3.4", "react-native-root-siblings": "^4.1.1", - "react-native-root-toast": "^3.5.1", "react-native-safe-area-context": "4.6.3", "react-native-screens": "~3.22.0", "react-native-svg": "13.9.0", + "react-native-toast-message": "^2.2.0", + "react-native-ui-datepicker": "^2.0.2", "react-native-url-polyfill": "^2.0.0", "react-native-vector-icons": "^10.0.2", "react-scroll-to-top": "^3.0.0", - "validator": "^13.11.0" + "use-debounce": "^10.0.0", + "validator": "^13.11.0", + "expo-image": "~1.3.5" }, "devDependencies": { "@babel/core": "^7.20.0", @@ -74,8 +85,7 @@ "eslint-config-universe": "^12.0.0", "husky": "^8.0.3", "prettier": "^3.0.3", - "supabase": "^1.110.1", - "typescript": "^5.1.3" + "supabase": "^1.110.1" }, "private": true } diff --git a/src/app/(tabs)/_layout.tsx b/src/app/(tabs)/_layout.tsx index fe17ad64..eb7592c6 100644 --- a/src/app/(tabs)/_layout.tsx +++ b/src/app/(tabs)/_layout.tsx @@ -1,5 +1,5 @@ import { Tabs } from 'expo-router'; -import { Platform } from 'react-native'; +import { Platform, View } from 'react-native'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; import Icon from '../../../assets/icons'; @@ -34,6 +34,7 @@ function TabNav() { return ( @@ -54,7 +56,6 @@ function TabNav() { headerShown: false, tabBarLabel: 'Home', tabBarIcon: ({ color }) => HomeIcon({ color }), - // tabBarLabelStyle: { borderTopWidth: 12, paddingTop: 12 }, }} /> LibraryIcon({ color }), }} /> + { + return cheerio.load(text).text().trim(); + }; + return ( - + {isLoading ? ( ) : ( router.back()} /> @@ -68,12 +74,14 @@ function AuthorScreen() { - {authorInfo.name} + {getTextFromHtml(authorInfo.name)} {authorInfo?.pronouns && ( - {authorInfo.pronouns} + + {authorInfo.pronouns} + )} )} @@ -83,18 +91,22 @@ function AuthorScreen() { {authorInfo?.bio && ( <> - {decode(authorInfo.bio)} + + {getTextFromHtml(authorInfo.bio)} + )} {authorInfo?.artist_statement && ( <> - + Artist's Statement - - {decode(authorInfo.artist_statement)} + + {getTextFromHtml(authorInfo.artist_statement)} @@ -110,6 +122,7 @@ function AuthorScreen() { {authorStoryPreview?.map(story => ( ))} + + {/* View so there's space between the tab bar and the stories */} + )} diff --git a/src/app/(tabs)/author/styles.tsx b/src/app/(tabs)/author/styles.tsx index d85a4dd7..dee04f89 100644 --- a/src/app/(tabs)/author/styles.tsx +++ b/src/app/(tabs)/author/styles.tsx @@ -4,34 +4,17 @@ import colors from '../../../styles/colors'; const styles = StyleSheet.create({ authorCardContainer: { - marginTop: 16, marginBottom: 8, flexDirection: 'row', justifyContent: 'flex-start', alignItems: 'flex-end', }, - name: { - fontWeight: 'bold', - fontSize: 24, - fontFamily: 'Manrope-Regular', - }, image: { height: 68, width: 68, backgroundColor: colors.darkGrey, borderRadius: 4, }, - bioText: { - color: 'black', - fontFamily: 'Manrope-Regular', - fontSize: 14, - }, - authorStatement: { - fontSize: 14, - color: 'black', - fontWeight: '400', - fontFamily: 'Manrope-Regular', - }, authorTextContainer: { paddingLeft: 20, }, @@ -40,9 +23,6 @@ const styles = StyleSheet.create({ borderTopWidth: 20, }, authorStatementTitle: { - fontWeight: 'bold', - fontFamily: 'Manrope-Regular', - fontSize: 16, marginBottom: 8, }, storyCountText: { @@ -50,7 +30,7 @@ const styles = StyleSheet.create({ marginBottom: 8, }, pronouns: { - color: '#797979', + color: colors.textGrey, }, }); diff --git a/src/app/(tabs)/genre/index.tsx b/src/app/(tabs)/genre/index.tsx index a5b82774..2a8315af 100644 --- a/src/app/(tabs)/genre/index.tsx +++ b/src/app/(tabs)/genre/index.tsx @@ -1,5 +1,5 @@ import { useLocalSearchParams, router } from 'expo-router'; -import { useEffect, useState } from 'react'; +import { useEffect, useState, useMemo, ReactNode } from 'react'; import { ActivityIndicator, ScrollView, @@ -7,205 +7,166 @@ import { Text, FlatList, } from 'react-native'; -import { Dropdown } from 'react-native-element-dropdown'; +import { Dropdown, MultiSelect } from 'react-native-element-dropdown'; import { Icon } from 'react-native-elements'; import { TouchableOpacity } from 'react-native-gesture-handler'; import { SafeAreaView } from 'react-native-safe-area-context'; import styles from './styles'; import BackButton from '../../../components/BackButton/BackButton'; -import FilterModal, { - CATEGORIES as FilterCategories, -} from '../../../components/FilterModal/FilterModal'; -import GenreStoryPreviewCard from '../../../components/GenreStoryPreviewCard/GenreStoryPreviewCard'; -import { fetchGenreStoryPreviews, fetchGenres } from '../../../queries/genres'; -import { fetchStoryPreviewById } from '../../../queries/stories'; -import { StoryPreview, GenreStories, Genre } from '../../../queries/types'; + +import PreviewCard from '../../../components/PreviewCard/PreviewCard'; +import { fetchGenreStoryById } from '../../../queries/genres'; +import { fetchStoryPreviewByIds } from '../../../queries/stories'; +import { StoryPreview, GenreStories } from '../../../queries/types'; import globalStyles from '../../../styles/globalStyles'; -import { TagFilter, useFilter } from '../../../utils/FilterContext'; function GenreScreen() { - const { filters } = useFilter(); - const [genreStoryInfo, setGenreStoryInfo] = useState(); + const [genreStoryData, setGenreStoryData] = useState(); const [genreStoryIds, setGenreStoryIds] = useState([]); const [subgenres, setSubgenres] = useState([]); const [allStoryPreviews, setAllStoryPreviews] = useState([]); + const [filteredStoryPreviews, setFilteredStoryPreviews] = useState< + StoryPreview[] + >([]); const [selectedSubgenre, setSelectedSubgenre] = useState(''); const [mainGenre, setMainGenre] = useState(''); const [isLoading, setLoading] = useState(true); - const [genreTones, setgenreTones] = useState([]); - const [genreTopics, setgenreTopics] = useState([]); - const [currTone, setCurrTone] = useState(''); - const [currTopic, setCurrTopic] = useState(''); - const [toneTopicFilters, setToneTopicFilters] = useState([]); - const params = useLocalSearchParams<{ genreId: string }>(); - const params2 = useLocalSearchParams<{ genreType: string }>(); - const params3 = useLocalSearchParams<{ genreName: string }>(); - const { genreId } = params; - const { genreType } = params2; - const { genreName } = params3; - - console.log('passing in genreId params:', genreId); - console.log('testing passing in genreType', genreType); - console.log('testing genreName', genreName); - - async function getAllStoryIds( - genreStories: GenreStories[], - ): Promise { - const allStoryIds: string[] = []; - for (const subgenre of genreStories) { - if (subgenre.genre_story_previews[0] != null) { - subgenre.genre_story_previews.forEach(id => { - allStoryIds.push(id); - }); - } - } - return allStoryIds; + const [toneFilterOptions, setToneFilterOptions] = useState([]); + const [topicFilterOptions, setTopicFilterOptions] = useState([]); + const [selectedTonesForFiltering, setSelectedTonesForFiltering] = useState< + string[] + >([]); + const [selectedTopicsForFiltering, setSelectedTopicsForFiltering] = useState< + string[] + >([]); + const { genreId, genreType, genreName } = useLocalSearchParams<{ + genreId: string; + genreType: GenreType; + genreName: string; + }>(); + + useEffect(() => { + const checkTopic = (preview: StoryPreview): boolean => { + if (preview?.topic == null) return false; + if (selectedTopicsForFiltering.length == 0) return true; + else + return selectedTopicsForFiltering.every(t => preview.topic.includes(t)); + }; + const checkTone = (preview: StoryPreview): boolean => { + if (preview?.tone == null) return false; + if (selectedTonesForFiltering.length == 0) return true; + else + return selectedTonesForFiltering.every(t => preview.tone.includes(t)); + }; + + const filteredPreviews = allStoryPreviews.filter( + preview => checkTopic(preview) && checkTone(preview), + ); + setFilteredStoryPreviews(filteredPreviews); + }, [selectedTopicsForFiltering, selectedTonesForFiltering]); + + function getAllStoryIds(genreStories: GenreStories[]): string[] { + return genreStories + .map(story => story.genre_story_previews) + .flat() + .filter(story => story !== null); } - async function findStoryIdsByName( - subgenre_name: string, - genreStories: GenreStories[], - ): Promise { - const filteredStoryIds: string[] = []; - const matchingGenreStory = genreStories.find( - subgenre => subgenre.subgenre_name === subgenre_name, + function filterStoriesBySubgenreName( + subgenreName: string, + stories: GenreStories[], + ): string[] { + const matchingGenreStory = stories.find( + subgenre => subgenre.subgenre_name === subgenreName, ); - if (matchingGenreStory?.genre_story_previews[0] != null) { - matchingGenreStory.genre_story_previews.forEach(id => { - filteredStoryIds.push(id); - }); - } else { - setLoading(false); - return []; - } - console.log('testing find story IDs by Name Function:', filteredStoryIds); - return filteredStoryIds; + + return matchingGenreStory?.genre_story_previews ?? []; } - async function getSubgenres(genreStories: GenreStories[]): Promise { - const subGenres: string[] = []; - subGenres.push('All'); - for (const subgenre of genreStories) { - subGenres.push(subgenre.subgenre_name); - } - return subGenres; + function getSubgenres(stories: GenreStories[]): string[] { + const subgenres = stories.map(subgenre => subgenre.subgenre_name); + return ['All', ...subgenres]; } - async function filterBySubgenre(filter_name: string) { + function filterBySubgenre(subgenre: string) { setLoading(true); - setSelectedSubgenre(filter_name); - if (!genreStoryInfo) { + setSelectedSubgenre(subgenre); + if (!genreStoryData) { + setLoading(false); return []; } - if (filter_name === 'All') { - const storyIds = await getAllStoryIds(genreStoryInfo); - setGenreStoryIds(storyIds); + + if (subgenre === 'All') { + setGenreStoryIds(getAllStoryIds(genreStoryData)); } else { - const filteredStoryIds = await findStoryIdsByName( - filter_name, - genreStoryInfo, + const filteredStoryIds = filterStoriesBySubgenreName( + subgenre, + genreStoryData, ); + setGenreStoryIds(filteredStoryIds); + setToneFilterOptions([]); + setTopicFilterOptions([]); setLoading(false); - setgenreTones([]); - setgenreTopics([]); - } - } - - //will be triggered when users click checkboxes, will concat all of these clicked and added to a usestate? - //this concatted array will be passed into filterByToneAndTopic array which will go through, genreStoryInfo, and filter - //out each story based on the array that is passed into this fu - async function filterByToneAndTopic(filters: string[]) { - setLoading(true); - setToneTopicFilters(filters); - if (!genreStoryInfo) { - return []; } } useEffect(() => { const getGenre = async () => { - const genreStoryPreviewData: GenreStories[] = - await fetchGenreStoryPreviews(parseInt(genreId as string, 10)); - const getGenres: string[] = await getSubgenres(genreStoryPreviewData); - setSubgenres(getGenres); - setGenreStoryInfo(genreStoryPreviewData); - setMainGenre(genreStoryPreviewData[0].parent_name); - if (genreType === 'parent_genre') { - console.log( - 'running if check on genreType, populating usestate with all data', - ); - const allStoryIds = await getAllStoryIds(genreStoryPreviewData); - setGenreStoryIds(allStoryIds); + setLoading(true); + + const genreStoryData: GenreStories[] = await fetchGenreStoryById( + parseInt(genreId as string, 10), + ); + + setGenreStoryData(genreStoryData); + setMainGenre(genreStoryData[0].parent_name); + setSubgenres(getSubgenres(genreStoryData)); + + if (genreType == GenreType.PARENT) { setSelectedSubgenre('All'); //if user clicks see all, selected should be 'ALL' - } else if (genreType === 'subgenre') { - const filteredStoryIds = await findStoryIdsByName( + setGenreStoryIds(getAllStoryIds(genreStoryData)); + } else if (genreType == GenreType.SUBGENRE) { + setSelectedSubgenre(genreName || ''); //if user clicks a specific genre, selected should be genreName + + const filteredStoryIds = filterStoriesBySubgenreName( genreName || '', - genreStoryPreviewData, + genreStoryData, ); setGenreStoryIds(filteredStoryIds); - setSelectedSubgenre(genreName || ''); //if user clicks a specific genre, selected should be genreName + + setLoading(false); } }; getGenre(); }, [genreName]); - const flattenenedFilters = Array.from(filters) - .map(([id, parent]) => [...parent.children, parent as TagFilter]) - .flat(); - const activeFilterNames = flattenenedFilters.filter(({ active }) => active); - - const activeGenreNames = activeFilterNames - .filter(({ category }) => category == FilterCategories.GENRE) - .map(({ name }) => name); - const activeToneNames = activeFilterNames - .filter(({ category }) => category == FilterCategories.TONE) - .map(({ name }) => name); - const activeTopicNames = activeFilterNames - .filter(({ category }) => category == FilterCategories.TOPIC) - .map(({ name }) => name); - useEffect(() => { const showAllStoryPreviews = async () => { - if (genreStoryIds.length > 0) { - setLoading(true); - const previews: StoryPreview[] = []; - const tones: string[] = []; - const topics: string[] = []; - for (const idString of genreStoryIds) { - const id = parseInt(idString, 10); - try { - const storyPreview: StoryPreview[] = - await fetchStoryPreviewById(id); - previews.push(storyPreview[0]); - storyPreview[0].tone.forEach(item => { - tones.push(item); - }); - storyPreview[0].topic.forEach(item => { - topics.push(item); - }); - console.log('testing storyPreview outputs:', storyPreview); - } catch (error) { - console.log( - `There was an error while trying to fetch a story preview by id: ${error}`, - ); - } - } - const filteredTopics: string[] = topics.filter( - (item): item is string => item !== null, - ); - const filteredTones: string[] = tones.filter( - (item): item is string => item !== null, - ); - setAllStoryPreviews(previews.flat()); - setgenreTopics(filteredTopics); - setgenreTones(filteredTones); - console.log('testing tone usestate'); - setLoading(false); - } else { - setLoading(false); //if there are no story IDs, we cannot load anything, there are no results - } + setLoading(true); + + const previews: StoryPreview[] = await fetchStoryPreviewByIds( + genreStoryIds as any, + ); + + const tones: string[] = previews + .reduce((acc: string[], current: StoryPreview) => { + return acc.concat(current.tone); + }, [] as string[]) + .filter(tone => tone !== null); + const topics: string[] = previews + .reduce((acc: string[], current: StoryPreview) => { + return acc.concat(current.topic); + }, [] as string[]) + .filter(topic => topic !== null); + + setAllStoryPreviews(previews.flat()); + setFilteredStoryPreviews(previews.flat()); + setTopicFilterOptions([...new Set(topics)]); + setToneFilterOptions([...new Set(tones)]); + + setLoading(false); }; if (genreStoryIds.length > 0) { @@ -213,117 +174,153 @@ function GenreScreen() { } }, [genreStoryIds]); + const renderGenreScrollSelector = () => { + return ( + + {subgenres.map((subgenre, index) => ( + filterBySubgenre(subgenre)} //onPress will trigger the filterBySubgenre function + style={{ paddingHorizontal: 20, paddingTop: 5 }} + key={index} + > + + {subgenre} + + + ))} + + ); + }; + + const renderGenreHeading = () => { + return ( + + + {selectedSubgenre === 'All' ? mainGenre : selectedSubgenre} + + {/* */} + {/* {' '} */} + {/* Subheading about{' '} */} + {/* {selectedSubgenre === 'All' ? mainGenre : selectedSubgenre} */} + {/* ...Include Later? */} + {/* */} + + ); + }; + + const renderFilterDropdown = ( + placeholder: string, + value: string[], + data: string[], + setter: React.Dispatch>, + ) => { + return ( + { + return { label: topic, value: topic }; + })} + renderSelectedItem={() => } + maxHeight={400} + labelField="label" + valueField="value" + placeholder={placeholder} + renderRightIcon={() => } + onChange={item => { + if (item) { + setter(item); + } + }} + /> + ); + }; + + const renderNoStoryText = () => { + return ( + + Sorry! + + There are no stories under this Genre or Subgenre. Please continue to + search for other stories + + + ); + }; + + const renderStories = () => { + return ( + ( + { + router.push({ + pathname: '/story', + params: { storyId: item.id.toString() }, + }); + }} + /> + )} + /> + ); + }; + return ( - + - - router.push({ - pathname: '/search', - }) - } - /> - - - {selectedSubgenre === 'All' ? mainGenre : selectedSubgenre} - - - {' '} - Subheading about{' '} - {selectedSubgenre === 'All' ? mainGenre : selectedSubgenre} - ...Include Later? - - - - {subgenres.map((subgenre, index) => ( - filterBySubgenre(subgenre)} //onPress will trigger the filterBySubgenre function - style={{ marginRight: 40 }} - > - - {subgenre} - - - ))} - + router.back()} /> + + {useMemo(renderGenreHeading, [selectedSubgenre, mainGenre])} + {useMemo(renderGenreScrollSelector, [subgenres, selectedSubgenre])} - - { - return { label: tone, value: tone }; - })} - maxHeight={400} - labelField="label" - valueField="value" - placeholder="Tone" - renderRightIcon={() => ( - - )} - onChange={item => { - if (item) { - // Check if item is not null or undefined - setCurrTone(item.label); // Use the label property of the selected item - } - }} - /> - { - return { label: topic, value: topic }; - })} - maxHeight={400} - labelField="label" - valueField="value" - placeholder="Topic" - renderRightIcon={() => ( - - )} - onChange={item => { - if (item) { - // Check if item is not null or undefined - setCurrTone(item.label); // Use the label property of the selected item - } - }} - /> + + {renderFilterDropdown( + 'Tone', + selectedTonesForFiltering, + toneFilterOptions, + setSelectedTonesForFiltering, + )} + {renderFilterDropdown( + 'Topic', + selectedTopicsForFiltering, + topicFilterOptions, + setSelectedTopicsForFiltering, + )} - {genreStoryIds.length === 0 ? ( // Check if there are no story IDs - - Sorry! - - There are no stories under this Genre or Subgenre. Please continue - to search for other stories - - + {genreStoryIds.length === 0 && !isLoading ? ( + renderNoStoryText() ) : ( <> @@ -332,33 +329,7 @@ function GenreScreen() { ) : ( - ( - { - router.push({ - pathname: '/story', - params: { storyId: item.id.toString() }, - }); - }} - /> - )} - /> + renderStories() )} @@ -368,4 +339,9 @@ function GenreScreen() { ); } +export enum GenreType { + PARENT = 'parent', + SUBGENRE = 'subgenre', +} + export default GenreScreen; diff --git a/src/app/(tabs)/genre/styles.tsx b/src/app/(tabs)/genre/styles.tsx index 3dbfc0d6..181292de 100644 --- a/src/app/(tabs)/genre/styles.tsx +++ b/src/app/(tabs)/genre/styles.tsx @@ -8,19 +8,16 @@ const styles = StyleSheet.create({ color: '#EB563B', textDecorationLine: 'underline', }, - container: { + paddingHorizontal: 24, width: '100%', - marginTop: 24, flex: 1, }, - flatListStyle: { paddingTop: 15, }, scrollViewContainer: { - marginTop: 30, - marginBottom: 15, + marginVertical: 15, width: '100%', }, noStoriesText: { @@ -31,6 +28,7 @@ const styles = StyleSheet.create({ fontSize: 13, }, renderStories: { + paddingBottom: 10, flex: 1, }, headerContainer: {}, diff --git a/src/app/(tabs)/home/index.tsx b/src/app/(tabs)/home/index.tsx index 7be7bd9f..6bdf1a55 100644 --- a/src/app/(tabs)/home/index.tsx +++ b/src/app/(tabs)/home/index.tsx @@ -1,20 +1,28 @@ +import AsyncStorage from '@react-native-async-storage/async-storage'; import { router } from 'expo-router'; import { useEffect, useState } from 'react'; -import { Pressable, ScrollView, Text, View } from 'react-native'; +import { + ActivityIndicator, + Pressable, + ScrollView, + Text, + View, +} from 'react-native'; import { SafeAreaView } from 'react-native-safe-area-context'; import styles from './styles'; -import Icon from '../../../../assets/icons'; import ContentCard from '../../../components/ContentCard/ContentCard'; import PreviewCard from '../../../components/PreviewCard/PreviewCard'; import ReactionPicker from '../../../components/ReactionPicker/ReactionPicker'; import RecentSearchCard from '../../../components/RecentSearchCard/RecentSearchCard'; + import { fetchUsername } from '../../../queries/profiles'; import { fetchFeaturedStoriesDescription, fetchFeaturedStoryPreviews, fetchNewStories, fetchRecommendedStories, + fetchStoryPreviewById, } from '../../../queries/stories'; import { StoryCard, StoryPreview } from '../../../queries/types'; import globalStyles from '../../../styles/globalStyles'; @@ -25,71 +33,137 @@ function HomeScreen() { const [username, setUsername] = useState(''); const [loading, setLoading] = useState(true); const [featuredStories, setFeaturedStories] = useState([]); + const [recentlyViewed, setRecentlyViewed] = useState([]); const [featuredStoriesDescription, setFeaturedStoriesDescription] = useState(''); const [recommendedStories, setRecommendedStories] = useState([]); const [newStories, setNewStories] = useState([]); + const getRecentStory = async () => { + try { + const jsonValue = await AsyncStorage.getItem('GWN_RECENT_STORIES_ARRAY'); + return jsonValue != null ? JSON.parse(jsonValue) : []; + } catch (error) { + console.log(error); + } + }; + + const setRecentStory = async (recentStories: StoryCard[]) => { + try { + const jsonValue = JSON.stringify(recentStories); + await AsyncStorage.setItem('GWN_RECENT_STORIES_ARRAY', jsonValue); + } catch (error) { + console.log(error); + } + }; + + const handleStoryPreviewPressed = (story: StoryPreview) => { + recentlyViewedStacking(story); + router.push({ + pathname: '/story', + params: { storyId: story.id.toString() }, + }); + }; + + const handleStoryCardPressed = async (story: StoryCard) => { + const newStoryArray = await fetchStoryPreviewById(story.id); + recentlyViewedStacking(newStoryArray[0]); + router.push({ + pathname: '/story', + params: { storyId: story.id.toString() }, + }); + }; + + const recentlyViewedStacking = async (story: StoryPreview) => { + const maxArrayLength = 5; + const newRecentlyViewed = [...recentlyViewed]; + + for (let i = 0; i < recentlyViewed.length; i++) { + if (story.id === recentlyViewed[i].id) { + newRecentlyViewed.splice(i, 1); + break; + } + } + + if (newRecentlyViewed.length >= maxArrayLength) { + newRecentlyViewed.splice(-1, 1); + } + + newRecentlyViewed.splice(0, 0, story); + + setRecentStory(newRecentlyViewed); + setRecentlyViewed(newRecentlyViewed); + }; + useEffect(() => { + const getRecommendedStories = async () => { + const recentStoryResponse = await getRecentStory(); + + const recommendedStoriesResponse = + await fetchRecommendedStories(recentStoryResponse); + setRecommendedStories(recommendedStoriesResponse); + }; + (async () => { const [ usernameResponse, featuredStoryResponse, featuredStoryDescriptionResponse, - recommendedStoriesResponse, newStoriesResponse, + recentStoryResponse, ] = await Promise.all([ fetchUsername(user?.id).catch(() => ''), fetchFeaturedStoryPreviews().catch(() => []), fetchFeaturedStoriesDescription().catch(() => ''), - fetchRecommendedStories().catch(() => []), fetchNewStories().catch(() => []), + getRecentStory(), ]); setUsername(usernameResponse); setFeaturedStories(featuredStoryResponse); setFeaturedStoriesDescription(featuredStoryDescriptionResponse); - setRecommendedStories(recommendedStoriesResponse); setNewStories(newStoriesResponse); + setRecentlyViewed(recentStoryResponse); + await getRecommendedStories(); })().finally(() => { setLoading(false); }); }, [user]); + if (loading) { + return ; + } return ( - {loading && ( - - Loading - - )} - + {username ? `Welcome, ${username}` : 'Welcome!'} - router.push('/settings')}> - - - - + {featuredStories.length > 0 && ( Featured Stories - - {featuredStoriesDescription} - - + {featuredStoriesDescription != null && + featuredStoriesDescription.length > 0 && ( + + {featuredStoriesDescription} + + )} + {featuredStories.map(story => ( - router.push({ - pathname: '/story', - params: { storyId: story.id.toString() }, - }) - } + pressFunction={() => handleStoryPreviewPressed(story)} /> ))} @@ -119,19 +188,17 @@ function HomeScreen() { horizontal showsHorizontalScrollIndicator={false} bounces={false} - style={styles.scrollView} + style={styles.scrollView1} > {recommendedStories.map(story => ( - router.push({ - pathname: '/story', - params: { storyId: story.id.toString() }, - }) - } + authorImage={story.author_image} + pressFunction={() => handleStoryCardPressed(story)} image={story.featured_media} /> ))} @@ -147,19 +214,17 @@ function HomeScreen() { horizontal showsHorizontalScrollIndicator={false} bounces={false} - style={styles.scrollView} + style={styles.scrollView2} > {newStories.map(story => ( - router.push({ - pathname: '/story', - params: { storyId: story.id.toString() }, - }) - } + authorImage={story.author_image} + pressFunction={() => handleStoryCardPressed(story)} image={story.featured_media} /> ))} diff --git a/src/app/(tabs)/home/styles.ts b/src/app/(tabs)/home/styles.ts index 231f5d9d..9f75b42d 100644 --- a/src/app/(tabs)/home/styles.ts +++ b/src/app/(tabs)/home/styles.ts @@ -19,9 +19,15 @@ const styles = StyleSheet.create({ marginTop: 12, marginBottom: 16, }, - scrollView: { - marginBottom: 20, + scrollView1: { + paddingBottom: 16, flexGrow: 0, + padding: 8, + }, + scrollView2: { + paddingBottom: 20, + flexGrow: 0, + padding: 8, }, headerContainer: { flexDirection: 'row', diff --git a/src/app/(tabs)/library/index.tsx b/src/app/(tabs)/library/index.tsx index 8a05bef0..2542da9e 100644 --- a/src/app/(tabs)/library/index.tsx +++ b/src/app/(tabs)/library/index.tsx @@ -1,13 +1,157 @@ -import { Text } from 'react-native'; -import { SafeAreaView } from 'react-native-safe-area-context'; +import { Text, View, Pressable, ScrollView } from 'react-native'; +import { useState, useEffect, useMemo } from 'react'; +import { useSession } from '../../../utils/AuthContext'; +import { router } from 'expo-router'; import globalStyles from '../../../styles/globalStyles'; +import styles from './styles'; +import LibraryHeader from '../../../components/LibraryHeader/LibraryHeader'; +import PreviewCard from '../../../components/PreviewCard/PreviewCard'; +import { StoryPreview } from '../../../queries/types'; +import { + fetchUserStoriesFavorites, + fetchUserStoriesReadingList, +} from '../../../queries/savedStories'; +import { FlatList } from 'react-native-gesture-handler'; +import { usePubSub } from '../../../utils/PubSubContext'; function LibraryScreen() { + const { user } = useSession(); + const [favoritesSelected, setFavoritesSelected] = useState(true); + const [readingSelected, setReadingSelected] = useState(false); + const [favoriteStories, setFavoriteStories] = useState([]); + const [readingListStories, setReadingListStories] = useState( + [], + ); + const { channels } = usePubSub(); + let updateReadingListTimeout: NodeJS.Timeout | null = null; + + const favoritesPressed = () => { + setFavoritesSelected(true); + setReadingSelected(false); + }; + + const readingPressed = () => { + setFavoritesSelected(false); + setReadingSelected(true); + }; + + const renderItem = ({ item }: { item: StoryPreview }) => { + return ( + + + router.push({ + pathname: '/story', + params: { storyId: item.id.toString() }, + }) + } + /> + + ); + }; + + useEffect(() => { + if (updateReadingListTimeout) { + clearTimeout(updateReadingListTimeout); + } + + updateReadingListTimeout = setTimeout( + () => + fetchUserStoriesReadingList(user?.id).then(readingList => { + setReadingListStories(readingList); + }), + 5000, + ); + }, [channels]); + + useEffect(() => { + (async () => { + await Promise.all([ + fetchUserStoriesFavorites(user?.id).then(favorites => + setFavoriteStories(favorites), + ), + fetchUserStoriesReadingList(user?.id).then(readingList => { + setReadingListStories(readingList); + }), + ]); + })(); + }, [user]); + return ( - - Library - + + + + + + + + + Favorites + + + + + + + + + Reading List + + + + + + + + {favoritesSelected && + (favoriteStories.length > 0 ? ( + + ) : ( + + + Favorited stories + + + will appear here. + + + ))} + + {readingSelected && + (readingListStories.length > 0 ? ( + + ) : ( + + + Saved stories + + + will appear here. + + + ))} + + ); } diff --git a/src/app/(tabs)/library/styles.ts b/src/app/(tabs)/library/styles.ts index ebaf5c77..5da69e42 100644 --- a/src/app/(tabs)/library/styles.ts +++ b/src/app/(tabs)/library/styles.ts @@ -1,5 +1,43 @@ import { StyleSheet } from 'react-native'; +import colors from '../../../styles/colors'; -const styles = StyleSheet.create({}); +const styles = StyleSheet.create({ + container: { + flex: 1, + backgroundColor: 'white', + alignItems: 'flex-start', + justifyContent: 'flex-start', + }, + selector: { + display: 'flex', + width: '100%', + flexDirection: 'row', + justifyContent: 'space-around', + backgroundColor: '#fbfbfb', + marginBottom: 24, + }, + header: { + paddingHorizontal: 24, + marginBottom: 24, + marginTop: 60, + }, + selectedText: { + textAlign: 'center', + color: colors.gwnOrange, + paddingVertical: 8, + }, + unselectedText: { + textAlign: 'center', + color: colors.black, + paddingVertical: 8, + }, + selectedButton: { + borderBottomWidth: 1, + borderBottomColor: colors.gwnOrange, + }, + scrollView: { + width: '100%', + }, +}); export default styles; diff --git a/src/app/(tabs)/search/index.tsx b/src/app/(tabs)/search/index.tsx index 807d19de..6163689c 100644 --- a/src/app/(tabs)/search/index.tsx +++ b/src/app/(tabs)/search/index.tsx @@ -1,7 +1,7 @@ import AsyncStorage from '@react-native-async-storage/async-storage'; import { SearchBar } from '@rneui/themed'; import { router } from 'expo-router'; -import { useEffect, useState } from 'react'; +import { Fragment, useEffect, useState } from 'react'; import { Button, FlatList, @@ -20,16 +20,22 @@ import PreviewCard from '../../../components/PreviewCard/PreviewCard'; import RecentSearchCard from '../../../components/RecentSearchCard/RecentSearchCard'; import { fetchGenres } from '../../../queries/genres'; import { fetchAllStoryPreviews } from '../../../queries/stories'; -import { StoryPreview, RecentSearch, Genre } from '../../../queries/types'; +import { + StoryPreview, + RecentSearch, + Genre, + StoryPreviewWithPreloadedReactions, +} from '../../../queries/types'; import colors from '../../../styles/colors'; import globalStyles from '../../../styles/globalStyles'; +import { GenreType } from '../genre'; const getRecentSearch = async () => { try { const jsonValue = await AsyncStorage.getItem('GWN_RECENT_SEARCHES_ARRAY'); return jsonValue != null ? JSON.parse(jsonValue) : []; } catch (error) { - console.log(error); + console.error(error); } }; @@ -38,7 +44,7 @@ const setRecentSearch = async (searchResult: RecentSearch[]) => { const jsonValue = JSON.stringify(searchResult); await AsyncStorage.setItem('GWN_RECENT_SEARCHES_ARRAY', jsonValue); } catch (error) { - console.log(error); + console.error(error); } }; @@ -47,7 +53,7 @@ const getRecentStory = async () => { const jsonValue = await AsyncStorage.getItem('GWN_RECENT_STORIES_ARRAY'); return jsonValue != null ? JSON.parse(jsonValue) : []; } catch (error) { - console.log(error); + console.error(error); } }; @@ -56,34 +62,40 @@ const setRecentStory = async (recentStories: StoryPreview[]) => { const jsonValue = JSON.stringify(recentStories); await AsyncStorage.setItem('GWN_RECENT_STORIES_ARRAY', jsonValue); } catch (error) { - console.log(error); + console.error(error); } }; function SearchScreen() { - const [allStories, setAllStories] = useState([]); + const [allStories, setAllStories] = useState< + StoryPreviewWithPreloadedReactions[] + >([]); const [allGenres, setAllGenres] = useState([]); - const [searchResults, setSearchResults] = useState([]); + const [searchResults, setSearchResults] = useState< + StoryPreviewWithPreloadedReactions[] + >([]); const [search, setSearch] = useState(''); const [filterVisible, setFilterVisible] = useState(false); const [recentSearches, setRecentSearches] = useState([]); const [showGenreCarousals, setShowGenreCarousals] = useState(true); const [showRecents, setShowRecents] = useState(false); const [recentlyViewed, setRecentlyViewed] = useState([]); + const genreColors = [colors.citrus, colors.lime, colors.lilac]; useEffect(() => { (async () => { - const data: StoryPreview[] = await fetchAllStoryPreviews(); - setAllStories(data); - const genreData: Genre[] = await fetchGenres(); - setAllGenres(genreData); - setRecentSearches(await getRecentSearch()); - setRecentlyViewed(await getRecentStory()); + fetchAllStoryPreviews().then(stories => setAllStories(stories)); + fetchGenres().then((genres: Genre[]) => setAllGenres(genres)); + getRecentSearch().then((searches: RecentSearch[]) => + setRecentSearches(searches), + ); + getRecentStory().then((viewed: StoryPreview[]) => + setRecentlyViewed(viewed), + ); })(); }, []); const getColor = (index: number) => { - const genreColors = [colors.citrus, colors.lime, colors.lilac]; return genreColors[index % genreColors.length]; }; @@ -93,12 +105,14 @@ function SearchScreen() { setSearchResults([]); return; } - const updatedData = allStories.filter((item: StoryPreview) => { + + const updatedData = allStories.filter(item => { const title = `${item.title.toUpperCase()})`; const author = `${item.author_name.toUpperCase()})`; const text_data = text.toUpperCase(); return title.indexOf(text_data) > -1 || author.indexOf(text_data) > -1; }); + setSearch(text); setSearchResults(updatedData); setShowGenreCarousals(false); @@ -176,7 +190,7 @@ function SearchScreen() { return ( searchFunction(text)} value={search} onSubmitEditing={searchString => { @@ -223,19 +240,44 @@ function SearchScreen() { )} {showRecents && - (search ? ( + (search && searchResults.length > 0 ? ( - - {searchResults.length}{' '} - {searchResults.length === 1 ? 'Story' : 'Stories'} + + Showing results 1-{searchResults.length} - ) : ( + ) : search && searchResults.length === 0 ? ( + + + + There are no stories + + + for "{search}". + + + + Try searching by title or author, or + + + check if your spelling is correct. + + + ) : recentSearches.length > 0 || recentlyViewed.length > 0 ? ( - Recent Searches + + Recent Searches + - Clear All + + Clear All + @@ -253,15 +295,25 @@ function SearchScreen() { - Recently Viewed + + Recently Viewed + - Clear All + + Clear All + {recentlyViewed.map(item => ( + ) : ( + + + + Find stories from young creators. + + + + Search for stories, authors, or collections. + + ))} {showGenreCarousals ? ( @@ -287,7 +350,7 @@ function SearchScreen() { contentContainerStyle={{ paddingHorizontal: 8 }} > {allGenres.map((genre, index) => ( - <> + {genre.parent_name} {genre.subgenres.map(subgenre => ( ))} - + ))} ) : ( @@ -339,9 +403,11 @@ function SearchScreen() { contentContainerStyle={styles.contentCotainerStories} renderItem={({ item }) => ( any) => { + return (value: any) => { + setShowSaveEdits(true); + return onChange(value); + }; + }; + + const getProfile = async () => { + try { + setLoading(true); + if (!session?.user) throw new Error('No user on the session!'); + + const { data, error, status } = await supabase + .from('profiles') + .select( + `first_name, last_name, username, birthday, gender, race_ethnicity, pronouns`, + ) + .eq('user_id', session?.user.id) + .single(); + + if (error && status !== 406 && error instanceof Error) { + throw error; + } + + if (data) { + setFirstName(data.first_name || firstName); + setLastName(data.last_name || lastName); + setUsername(data.username || username); + + if (data.birthday) { + setBirthday( + new Date(data.birthday).toLocaleDateString('en-US', { + timeZone: 'UTC', + }), + ); + setBirthdayExists(true); + } + + setGender(data.gender || gender); + setPronouns(data.pronouns || pronouns); + setRaceEthnicity(data.race_ethnicity || raceEthnicity); + } + } catch (error) { + if (error instanceof Error) { + Alert.alert(`Get profile error: ${error.message}`); + } + } finally { + setLoading(false); + } + }; + + const resetAndPushToRouter = (path: string) => { + while (router.canGoBack()) { + router.back(); + } + router.replace(path); + }; + + useEffect(() => { + if (session) getProfile(); + }, [session]); + + useEffect(() => { + if (!session) resetAndPushToRouter('/auth/login'); + }, [session]); + + const updateProfile = async () => { + try { + setLoading(true); + if (!session?.user) throw new Error('No user on the session!'); + + // Only update values that are not blank + const updates = { + ...(gender && { gender }), + ...(pronouns && { pronouns }), + ...(raceEthnicity && { race_ethnicity: raceEthnicity }), + ...(birthday && { birthday }), + }; + + // Check if user exists + const { count } = await supabase + .from('profiles') + .select(`*`, { count: 'exact' }) + .eq('user_id', session?.user.id); + + if (count && count >= 1) { + // Update user if they exist + const { error } = await supabase + .from('profiles') + .update(updates) + .eq('user_id', session?.user.id) + .select('*'); + + if (error && error instanceof Error) { + if (process.env.NODE_ENV !== 'production') { + throw error; + } + } + } else { + // Create user if they don't exist + const { error } = await supabase.from('profiles').insert(updates); + + if (error && error instanceof Error) { + if (process.env.NODE_ENV !== 'production') { + throw error; + } + } + } + } catch (error) { + if (error instanceof Error) { + Alert.alert(error.message); + } + } finally { + setLoading(false); + setShowSaveEdits(false); + setBirthdayExists(true); + setBirthdayChanged(false); + } + }; + + const onConfirmDate = (date: Date) => { + setShowDatePicker(false); + setBirthday(date.toLocaleDateString()); + setDisplayDate(date); + setShowSaveEdits(true); + setBirthdayChanged(true); + }; + + if (!session) { + return ; + } + + return ( + + + + router.back()} /> + + setShowDatePicker(false)} + date={displayDate} + display="inline" + isDarkModeEnabled={isDark} + themeVariant={isDark ? 'dark' : 'light'} + /> + + + Settings + Account + + + + + + + { + setShowDatePicker(!showDatePicker); + }} + > + + + {birthdayChanged ? birthday : 'Select Date'} + + + + + + ) : ( + + {birthday} + + ) + } + /> + + + + + + + + {birthdayChanged && ( + + + + You can only input your birthday once. Please make sure the date + is correct before saving as you will not be able to change your + birthday in the future. + + + )} + + + + {showSaveEdits ? ( + + ) : ( + + )} + + + + ); +} + +export default SettingsScreen; diff --git a/src/app/(tabs)/settings/styles.tsx b/src/app/(tabs)/settings/styles.tsx new file mode 100644 index 00000000..f9476b36 --- /dev/null +++ b/src/app/(tabs)/settings/styles.tsx @@ -0,0 +1,60 @@ +import { StyleSheet } from 'react-native'; + +import colors from '../../../styles/colors'; + +export default StyleSheet.create({ + selectors: { + flex: 1, + gap: 16, + }, + container: { + flex: 1, + backgroundColor: 'white', + paddingHorizontal: 24, + paddingBottom: 60, + }, + button: { + marginBottom: 32, + }, + main: { + paddingLeft: 12, + width: '100%', + justifyContent: 'space-between', + flexGrow: 1, + }, + subheading: { + paddingBottom: 16, + }, + heading: { + paddingBottom: 20, + }, + staticData: { + flexDirection: 'row', + flexWrap: 'wrap', + alignItems: 'flex-start', + marginBottom: 6, + }, + icon: { + paddingLeft: 8, + }, + dateButtonText: { + flexDirection: 'row', + alignItems: 'flex-start', + }, + dateButton: { + paddingTop: 18, + }, + info: { + flexDirection: 'row', + marginLeft: 8, + marginTop: 40, + marginBottom: 20, + marginRight: 30, + maxWidth: '80%', + }, + subtext: { + color: colors.darkGrey, + marginLeft: 8, + flexWrap: 'wrap', + }, +}); diff --git a/src/app/(tabs)/story/index.tsx b/src/app/(tabs)/story/index.tsx index f358e474..286c4a48 100644 --- a/src/app/(tabs)/story/index.tsx +++ b/src/app/(tabs)/story/index.tsx @@ -5,21 +5,25 @@ import React, { useEffect, useState } from 'react'; import { ActivityIndicator, FlatList, - Image, ScrollView, Share, Text, TouchableOpacity, View, + useWindowDimensions, } from 'react-native'; +import { Image } from 'expo-image'; import { Button } from 'react-native-paper'; import { RenderHTML } from 'react-native-render-html'; import { SafeAreaView } from 'react-native-safe-area-context'; import styles from './styles'; import ReactionPicker from '../../../components/ReactionPicker/ReactionPicker'; +import BackButton from '../../../components/BackButton/BackButton'; import { fetchStory } from '../../../queries/stories'; import { Story } from '../../../queries/types'; +import colors from '../../../styles/colors'; +import globalStyles, { fonts } from '../../../styles/globalStyles'; function StoryScreen() { const [isLoading, setLoading] = useState(true); @@ -29,6 +33,8 @@ function StoryScreen() { const params = useLocalSearchParams<{ storyId: string }>(); const { storyId } = params; + const { width } = useWindowDimensions(); + const scrollUp = () => { scrollRef.current?.scrollTo({ x: 0, y: 0 }); }; @@ -63,7 +69,7 @@ function StoryScreen() { }; return ( - + {isLoading ? ( ) : ( @@ -72,9 +78,10 @@ function StoryScreen() { ref={scrollRef} showsVerticalScrollIndicator={false} > - {/* */} + router.back()} /> + + {story?.title} - {story?.title} { router.push({ @@ -88,7 +95,14 @@ function StoryScreen() { style={styles.authorImage} source={{ uri: story.author_image ? story.author_image : '' }} /> - By {story.author_name} + + By {story.author_name} + @@ -99,47 +113,88 @@ function StoryScreen() { data={story.genre_medium} renderItem={({ item }) => ( - {item} + + {item} + )} /> - + - + - Author's Process + + Author's Process + - + - - - By {story.author_name} - + { + router.push({ + pathname: '/author', + params: { author: story.author_id.toString() }, + }); + }} + > + + + + By {story.author_name} + + + diff --git a/src/app/(tabs)/story/styles.ts b/src/app/(tabs)/story/styles.ts index 67b6ce58..9dd547c2 100644 --- a/src/app/(tabs)/story/styles.ts +++ b/src/app/(tabs)/story/styles.ts @@ -1,19 +1,11 @@ import { StyleSheet } from 'react-native'; +import colors from '../../../styles/colors'; + const styles = StyleSheet.create({ container: { - flex: 1, - backgroundColor: 'white', - alignItems: 'flex-start', - justifyContent: 'flex-start', paddingLeft: 24, paddingRight: 24, - paddingTop: 48, - }, - image: { - width: '100%', - height: 153, - marginBottom: 16, }, authorImage: { backgroundColor: '#D9D9D9', @@ -22,11 +14,6 @@ const styles = StyleSheet.create({ borderRadius: 100 / 2, }, title: { - fontFamily: 'Manrope-Regular', - fontSize: 24, - fontWeight: '400', - textAlign: 'left', - color: 'black', marginBottom: 16, }, author: { @@ -35,13 +22,6 @@ const styles = StyleSheet.create({ gap: 10, marginBottom: 16, }, - authorText: { - fontFamily: 'Manrope-Regular', - fontSize: 12, - fontWeight: '400', - textAlign: 'left', - color: 'black', - }, genres: { display: 'flex', flexDirection: 'row', @@ -59,52 +39,22 @@ const styles = StyleSheet.create({ marginRight: 8, }, genresText: { - fontFamily: 'Manrope-Regular', - fontSize: 12, - fontWeight: '400', - color: 'black', backgroundColor: '#D9D9D9', }, shareButtonText: { - fontFamily: 'Manrope-Regular', - fontSize: 12, - fontWeight: '400', - textAlign: 'left', - color: 'black', - textDecorationLine: 'underline', - backgroundColor: '#D9D9D9', + color: colors.white, }, excerpt: { - fontFamily: 'Manrope-Regular', - fontSize: 16, - fontWeight: '400', textAlign: 'left', - color: 'black', - paddingTop: 16, - paddingBottom: 16, + paddingVertical: 16, }, story: { - fontFamily: 'Manrope-Regular', - fontSize: 12, - fontWeight: '400', - textAlign: 'left', - color: 'black', marginBottom: 16, }, authorProcess: { - fontFamily: 'Manrope-Regular', - fontSize: 16, - fontWeight: '600', - textAlign: 'left', - color: 'black', marginBottom: 16, }, process: { - fontFamily: 'Manrope-Regular', - fontSize: 12, - fontWeight: '400', - textAlign: 'left', - color: 'black', marginBottom: 16, }, backToTopButtonText: { diff --git a/src/app/_layout.tsx b/src/app/_layout.tsx index 92819933..b8f05279 100644 --- a/src/app/_layout.tsx +++ b/src/app/_layout.tsx @@ -2,18 +2,23 @@ import { Stack } from 'expo-router'; import { SafeAreaProvider } from 'react-native-safe-area-context'; import { AuthContextProvider } from '../utils/AuthContext'; +import { BooleanPubSubProvider } from '../utils/PubSubContext'; +import ToastComponent from '../components/Toast/Toast'; +import { Keyboard, TouchableWithoutFeedback } from 'react-native'; function StackLayout() { return ( - - - - - - + + + + + + + + ); } diff --git a/src/app/auth/_layout.tsx b/src/app/auth/_layout.tsx index 9d255f97..6bc4e7b0 100644 --- a/src/app/auth/_layout.tsx +++ b/src/app/auth/_layout.tsx @@ -1,14 +1,24 @@ import { Stack } from 'expo-router'; +import { Keyboard, TouchableWithoutFeedback } from 'react-native'; +import { SafeAreaProvider, SafeAreaView } from 'react-native-safe-area-context'; function StackLayout() { return ( - - - - - - - + + + + + + + + + + + + ); } diff --git a/src/app/auth/forgotPassword/index.tsx b/src/app/auth/forgotPassword/index.tsx index ce73303d..34eace9d 100644 --- a/src/app/auth/forgotPassword/index.tsx +++ b/src/app/auth/forgotPassword/index.tsx @@ -1,117 +1,112 @@ -import { router } from 'expo-router'; -import React, { useState } from 'react'; -import { Alert, TextInput, View } from 'react-native'; -import { Button, Input } from 'react-native-elements'; +import { router, Link } from 'expo-router'; +import { useState, useRef, useEffect } from 'react'; +import { Alert, Text, View } from 'react-native'; +import { SafeAreaView } from 'react-native-safe-area-context'; +import { useDebounce } from 'use-debounce'; +import validator from 'validator'; import styles from './styles'; +import BackButton from '../../../components/BackButton/BackButton'; +import StyledButton from '../../../components/StyledButton/StyledButton'; +import UserStringInput from '../../../components/UserStringInput/UserStringInput'; +import { queryEmailByUsername } from '../../../queries/auth'; +import { isEmailTaken } from '../../../queries/profiles'; +import colors from '../../../styles/colors'; import globalStyles from '../../../styles/globalStyles'; import { useSession } from '../../../utils/AuthContext'; function ForgotPasswordScreen() { - const { updateUser, signOut, resetPassword, verifyOtp } = useSession(); + const { resetPassword } = useSession(); const [email, setEmail] = useState(''); - const [password, setPassword] = useState(''); - const [loading, setLoading] = useState(false); - const [verificationCode, setCode] = useState(''); - const [changingPassword, setChangingPassword] = useState(false); + const [emailToReset, setEmailToReset] = useState(''); + const [emailError, setEmailError] = useState(''); + const [value] = useDebounce(email, 250); + const [validEmail, setValidEmail] = useState(false); const sendResetEmail = async () => { - const { error } = await resetPassword(email); + const { error } = await resetPassword(emailToReset); if (error) Alert.alert('Could not send a reset password email. Please try again.'); else - Alert.alert( - 'Enter the verification code from your email to change your password', - ); + router.push({ + pathname: '/auth/verify', + params: { finalRedirect: 'resetPassword', userEmail: emailToReset }, + }); }; - const verifyCode = async () => { - setLoading(true); - if (email && verificationCode) { - const { error } = await verifyOtp(email, verificationCode); + useEffect(() => { + checkEmailOrUsername(value); + }, [value]); - if (error) { - Alert.alert(error.message); - setChangingPassword(false); - } else { - setChangingPassword(true); + const checkEmailOrUsername = async (newEmail: string) => { + setValidEmail(false); + if (validator.isEmail(newEmail)) { + if (newEmail.length === 0) { + setEmailError(''); + return; + } + const emailIsTaken = await isEmailTaken(newEmail); + if (!emailIsTaken) { + setEmailError( + 'An account with that email does not exist. Please try again.', + ); + setValidEmail(false); + return; } - } else if (!verificationCode) { - Alert.alert(`Please enter a verification code`); + setEmailToReset(newEmail); } else { - Alert.alert(`Please sign up again.`); - } + const { data, error } = await queryEmailByUsername(newEmail); - setLoading(false); - }; - - const changePassword = async () => { - setLoading(true); - const { error } = await updateUser({ password }); - - if (error) { - Alert.alert('Updating password failed'); - } else { - await signOut(); - router.replace('/auth/login'); + if (data && data?.length > 0 && !error) { + setValidEmail(true); + setEmailToReset(data[0].email); + } else { + setEmailError( + 'An account with that username does not exist. Please try again.', + ); + setValidEmail(false); + return; + } } - - setLoading(false); + setValidEmail(true); + setEmailError(''); }; return ( - - - setEmail(text)} - value={email} - placeholder="email@address.com" - autoCapitalize="none" - /> - - - - )} - {showDatePicker && ( - { - setShowDatePicker(Platform.OS === 'ios'); - if (date.nativeEvent.timestamp) { - setDate(new Date(date.nativeEvent.timestamp)); - } - }} - /> - )} - - ); -} - -export default DatePicker; diff --git a/src/components/DatePicker/styles.tsx b/src/components/DatePicker/styles.tsx deleted file mode 100644 index a11509d5..00000000 --- a/src/components/DatePicker/styles.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import { StyleSheet } from 'react-native'; - -export default StyleSheet.create({ - mt16: { - marginTop: 16, - width: '100%', - }, - container: { - paddingRight: 10, - marginTop: 8, - flexDirection: 'row', - alignItems: 'center', - justifyContent: 'center', - borderWidth: 1, - borderRadius: 5, - borderColor: 'black', - fontFamily: 'Manrope-Regular', - }, - inputField: { - flex: 1, - fontSize: 14, - padding: 10, - color: '#000000', - }, - button: { - backgroundColor: 'gray', - }, - verticallySpaced: { - alignSelf: 'stretch', - }, -}); diff --git a/src/components/GenreStoryPreviewCard/GenreStoryPreviewCard.tsx b/src/components/GenreStoryPreviewCard/GenreStoryPreviewCard.tsx index 00b413da..7ea1ba20 100644 --- a/src/components/GenreStoryPreviewCard/GenreStoryPreviewCard.tsx +++ b/src/components/GenreStoryPreviewCard/GenreStoryPreviewCard.tsx @@ -1,10 +1,10 @@ import { GestureResponderEvent, Text, - Image, View, TouchableOpacity, } from 'react-native'; +import { Image } from 'expo-image'; import styles from './styles'; import globalStyles from '../../styles/globalStyles'; diff --git a/src/components/LibraryHeader/LibraryHeader.tsx b/src/components/LibraryHeader/LibraryHeader.tsx new file mode 100644 index 00000000..e9e4a191 --- /dev/null +++ b/src/components/LibraryHeader/LibraryHeader.tsx @@ -0,0 +1,35 @@ +import { View, Text, Image, Pressable } from 'react-native'; +import { router } from 'expo-router'; +import { useEffect, useState } from 'react'; +import Icon from '../../../assets/icons'; + +import styles from './styles'; +import globalStyles from '../../styles/globalStyles'; +import colors from '../../styles/colors'; +import { useSession } from '../../utils/AuthContext'; + +export default function LibraryHeader() { + const { user } = useSession(); + + return ( + + + + + {user?.user_metadata.username} + + + + + router.push('/settings')}> + + + + + + + ); +} diff --git a/src/components/LibraryHeader/styles.ts b/src/components/LibraryHeader/styles.ts new file mode 100644 index 00000000..a3aafbb5 --- /dev/null +++ b/src/components/LibraryHeader/styles.ts @@ -0,0 +1,31 @@ +import { StyleSheet } from 'react-native'; +import colors from '../../styles/colors'; + +const styles = StyleSheet.create({ + container: { + display: 'flex', + flexGrow: 1, + width: '100%', + }, + image: { + height: 51, + width: 51, + borderRadius: 51 / 2, + marginBottom: 12, + }, + textContainer: { + flexDirection: 'row', + }, + username: { + paddingLeft: 12, + }, + horizontal: { + display: 'flex', + flexDirection: 'row', + justifyContent: 'space-between', + width: '100%', + alignContent: 'center', + }, +}); + +export default styles; diff --git a/src/components/PasswordComplexityText/PasswordComplexityText.tsx b/src/components/PasswordComplexityText/PasswordComplexityText.tsx new file mode 100644 index 00000000..23268e4e --- /dev/null +++ b/src/components/PasswordComplexityText/PasswordComplexityText.tsx @@ -0,0 +1,31 @@ +import { View, Text } from 'react-native'; +import Icon from '../../../assets/icons'; + +import styles from './styles'; +import globalStyles from '../../styles/globalStyles'; +import colors from '../../styles/colors'; + +type PasswordComplexityTextProps = { + message: string; + condition: boolean; +}; + +export default function PasswordComplexityText({ + condition, + message, +}: PasswordComplexityTextProps) { + return ( + + + + {message} + + + ); +} diff --git a/src/components/PasswordComplexityText/styles.ts b/src/components/PasswordComplexityText/styles.ts new file mode 100644 index 00000000..83d83d87 --- /dev/null +++ b/src/components/PasswordComplexityText/styles.ts @@ -0,0 +1,15 @@ +import { StyleSheet } from 'react-native'; + +const styles = StyleSheet.create({ + passwordComplexity: { + display: 'flex', + flexDirection: 'row', + paddingBottom: 8, + }, + + passwordErrorText: { + marginLeft: 8, + }, +}); + +export default styles; diff --git a/src/components/PreviewCard/PreviewCard.tsx b/src/components/PreviewCard/PreviewCard.tsx index 61e42f2e..8302d48f 100644 --- a/src/components/PreviewCard/PreviewCard.tsx +++ b/src/components/PreviewCard/PreviewCard.tsx @@ -1,70 +1,125 @@ +import * as cheerio from 'cheerio'; +import { Image } from 'expo-image'; +import { useEffect, useState } from 'react'; import { GestureResponderEvent, - Image, Pressable, Text, + TouchableOpacity, View, } from 'react-native'; +import Emoji from 'react-native-emoji'; import styles from './styles'; +import { fetchAllReactionsToStory } from '../../queries/reactions'; +import { Reactions } from '../../queries/types'; import globalStyles from '../../styles/globalStyles'; +import SaveStoryButton from '../SaveStoryButton/SaveStoryButton'; +import ReactionDisplay from '../ReactionDisplay/ReactionDisplay'; + +const placeholderImage = + 'https://gwn-uploads.s3.amazonaws.com/wp-content/uploads/2021/10/10120952/Girls-Write-Now-logo-avatar.png'; type PreviewCardProps = { title: string; image: string; + storyId: number; author: string; authorImage: string; + defaultSavedStoriesState?: boolean; excerpt: { html: string }; tags: string[]; + reactions?: string[] | null; pressFunction: (event: GestureResponderEvent) => void; }; function PreviewCard({ title, image, + storyId, author, authorImage, excerpt, tags, + defaultSavedStoriesState = false, pressFunction, + reactions: preloadedReactions = null, }: PreviewCardProps) { + const [reactions, setReactions] = useState( + preloadedReactions, + ); + useEffect(() => { + if (preloadedReactions != null) { + return; + } + + (async () => { + const temp = await fetchAllReactionsToStory(storyId); + if (temp != null) { + setReactions(temp.map(r => r.reaction)); + return; + } + setReactions([]); + })(); + }, []); + return ( - - + + + {title} + + + + + + + + + - - {title} - {author} - - {excerpt.html.slice(3, -3)} + + "{cheerio.load(excerpt.html ?? '').text()}" - {/* - - {tags.map(tag => ( - - {tag} + + + + {(tags?.length ?? 0) > 0 && ( + + + {tags[0]} + + + )} + + + {' '} + + {(tags?.length ?? 1) - 1} - ))} - - - - more tags - */} + ); diff --git a/src/components/PreviewCard/savedStoriesIcon.png b/src/components/PreviewCard/savedStoriesIcon.png new file mode 100644 index 00000000..65b2ea6e Binary files /dev/null and b/src/components/PreviewCard/savedStoriesIcon.png differ diff --git a/src/components/PreviewCard/styles.ts b/src/components/PreviewCard/styles.ts index 9f361b45..e3e9b927 100644 --- a/src/components/PreviewCard/styles.ts +++ b/src/components/PreviewCard/styles.ts @@ -6,39 +6,14 @@ const styles = StyleSheet.create({ card: { flexDirection: 'column', justifyContent: 'flex-end', - backgroundColor: colors.white, + backgroundColor: '#FFF', borderRadius: 6, marginTop: 8, marginBottom: 8, shadowColor: 'black', - shadowOffset: { width: 0, height: 4 }, - shadowOpacity: 0.5, + shadowOffset: { width: 0, height: 0 }, + shadowOpacity: 0.2, elevation: 4, - paddingRight: 8, - }, - top: { - flex: 1, - flexDirection: 'row', - justifyContent: 'flex-start', - alignItems: 'flex-start', - paddingLeft: 12, - paddingRight: 12, - shadowColor: '#000', - shadowOffset: { width: 0, height: 2 }, - shadowOpacity: 0.3, - shadowRadius: 3, - }, - bottom: { - flex: 1, - flexDirection: 'column', - justifyContent: 'flex-start', - alignItems: 'flex-start', - height: 48, - backgroundColor: colors.lightGrey, - overflow: 'hidden', - borderRadius: 6, - paddingHorizontal: 12, - paddingTop: 8, }, image: { height: 96, @@ -46,7 +21,6 @@ const styles = StyleSheet.create({ backgroundColor: colors.lilac, borderRadius: 4, marginBottom: 12, - marginTop: 12, }, author: { marginLeft: 8, @@ -56,11 +30,11 @@ const styles = StyleSheet.create({ width: 22, backgroundColor: colors.gwnOrange, borderRadius: 22 / 2, + marginLeft: 8, }, cardTextContainer: { flex: 1, - marginLeft: 16, - marginTop: 12, + marginTop: 10, marginBottom: 8, }, authorContainer: { @@ -70,23 +44,86 @@ const styles = StyleSheet.create({ marginBottom: 12, }, title: { - marginBottom: 8, + flex: 1, + alignSelf: 'flex-start', + // marginBottom: 8, + }, + titleContainer: { + paddingTop: 16, + paddingLeft: 12, + paddingRight: 12, + paddingBottom: 8, + borderBottomColor: '#EBEBEB', + borderBottomWidth: StyleSheet.hairlineWidth, + flexDirection: 'row', + flex: 1, }, tag: { paddingHorizontal: 8, paddingVertical: 4, - backgroundColor: colors.darkGrey, + backgroundColor: '#EBEBEB', borderRadius: 10, width: 'auto', marginRight: 8, marginBottom: 10, }, tagsContainer: { - // backgroundColor: colors.darkGrey, + flex: 1, flexDirection: 'row', - justifyContent: 'flex-start', + justifyContent: 'space-between', alignItems: 'center', flexWrap: 'wrap', + borderRadius: 6, + paddingLeft: 12, + paddingBottom: 4, + backgroundColor: colors.white, + }, + tagsRow: { + flexDirection: 'row', + justifyContent: 'flex-end', + alignContent: 'flex-end', + alignItems: 'center', + flexWrap: 'wrap', + }, + moreTags: { + paddingVertical: 10, + paddingRight: 12, + alignItems: 'center', + justifyContent: 'flex-end', + }, + moreTagsText: { + color: colors.darkGrey, + }, + reactions: { + width: 32, + height: 32, + borderRadius: 32 / 2, + borderWidth: 1, + backgroundColor: '#89CFF0', //different per emoji reaction + borderColor: 'white', + marginTop: 10, + marginRight: -5, // -10 + overflow: 'hidden', + justifyContent: 'center', + paddingLeft: 4, + }, + reactionText: { + color: colors.grey, + }, + reactionNumber: { + marginLeft: 16, + marginTop: 16, + }, + storyDescription: { + color: colors.darkGrey, + paddingRight: 12, + paddingLeft: 10, + }, + body: { + flexDirection: 'row', + marginTop: 16, + paddingLeft: 12, + paddingBottom: 12, }, }); diff --git a/src/components/ReactionDisplay/ReactionDisplay.tsx b/src/components/ReactionDisplay/ReactionDisplay.tsx new file mode 100644 index 00000000..0bfb0970 --- /dev/null +++ b/src/components/ReactionDisplay/ReactionDisplay.tsx @@ -0,0 +1,60 @@ +import { Text, View } from 'react-native'; +import styles from './styles'; +import Emoji from 'react-native-emoji'; +import globalStyles from '../../styles/globalStyles'; + +type ReactionDisplayProps = { + reactions: string[]; +}; + +function ReactionDisplay({ reactions }: ReactionDisplayProps) { + const reactionColors: Record = { + heart: '#FFCCCB', + clap: '#FFD580', + cry: '#89CFF0', + hugging_face: '#ffc3bf', + muscle: '#eddcf7', + }; + const defaultColor = reactionColors['heart']; + const setOfReactions = [...reactions]; + setOfReactions.push('heart'); + setOfReactions.push('clap'); + setOfReactions.push('muscle'); + + const reactionDisplay = [...new Set(setOfReactions)].slice(0, 3); + + return ( + + {reactionDisplay.map(reaction => { + return ( + + + + ); + })} + + + {reactions?.length ?? 0} + + + + ); +} + +export default ReactionDisplay; diff --git a/src/components/ReactionDisplay/styles.tsx b/src/components/ReactionDisplay/styles.tsx new file mode 100644 index 00000000..e0d37ab4 --- /dev/null +++ b/src/components/ReactionDisplay/styles.tsx @@ -0,0 +1,27 @@ +import { StyleSheet } from 'react-native'; +import colors from '../../styles/colors'; + +const styles = StyleSheet.create({ + reactions: { + width: 32, + height: 32, + borderRadius: 32 / 2, + borderWidth: 1, + backgroundColor: '#89CFF0', //different per emoji reaction + borderColor: 'white', + marginTop: 10, + marginRight: -5, // -10 + overflow: 'hidden', + justifyContent: 'center', + paddingLeft: 4, + }, + reactionText: { + color: colors.grey, + }, + reactionNumber: { + marginLeft: 16, + marginTop: 16, + }, +}); + +export default styles; diff --git a/src/components/RecentSearchCard/RecentSearchCard.tsx b/src/components/RecentSearchCard/RecentSearchCard.tsx index eb77fcc6..e142baee 100644 --- a/src/components/RecentSearchCard/RecentSearchCard.tsx +++ b/src/components/RecentSearchCard/RecentSearchCard.tsx @@ -21,10 +21,14 @@ function RecentSearchCard({ - {value} + + {value} + - {numResults} Results + + {numResults} Results + diff --git a/src/components/RecentSearchCard/styles.ts b/src/components/RecentSearchCard/styles.ts index 676937de..b0cb9012 100644 --- a/src/components/RecentSearchCard/styles.ts +++ b/src/components/RecentSearchCard/styles.ts @@ -1,4 +1,5 @@ import { StyleSheet } from 'react-native'; +import colors from '../../styles/colors'; const styles = StyleSheet.create({ card: { @@ -13,10 +14,11 @@ const styles = StyleSheet.create({ paddingRight: 12, paddingBottom: 10, paddingTop: 10, + shadowColor: 'black', - shadowOffset: { width: 0, height: 4 }, - shadowOpacity: 0.5, - elevation: 4, + shadowOffset: { width: 0, height: 0 }, + shadowOpacity: 0.3, + elevation: 7, }, leftItems: { gap: 8, @@ -29,9 +31,6 @@ const styles = StyleSheet.create({ alignItems: 'center', }, searchValueText: { - color: 'black', - fontWeight: '400', - fontSize: 14, justifyContent: 'center', }, numResultsText: { diff --git a/src/components/SaveStoryButton/SaveStoryButton.tsx b/src/components/SaveStoryButton/SaveStoryButton.tsx new file mode 100644 index 00000000..be44ebb9 --- /dev/null +++ b/src/components/SaveStoryButton/SaveStoryButton.tsx @@ -0,0 +1,68 @@ +import { useEffect, useState } from 'react'; +import { + addUserStoryToReadingList, + deleteUserStoryToReadingList, + isStoryInReadingList, +} from '../../queries/savedStories'; +import { usePubSub } from '../../utils/PubSubContext'; +import { useSession } from '../../utils/AuthContext'; +import { Image } from 'expo-image'; +import { TouchableOpacity } from 'react-native-gesture-handler'; + +type SaveStoryButtonProps = { + storyId: number; + defaultState?: boolean | null; +}; + +const saveStoryImage = require('../../../assets/save_story.png'); +const savedStoryImage = require('../../../assets/saved_story.png'); + +export default function SaveStoryButton({ + storyId, + defaultState = null, +}: SaveStoryButtonProps) { + const { user } = useSession(); + const [storyIsSaved, setStoryIsSaved] = useState( + defaultState, + ); + const { channels, initializeChannel, publish } = usePubSub(); + + useEffect(() => { + if (defaultState != null) { + return; + } + + isStoryInReadingList(storyId, user?.id).then(storyInReadingList => { + setStoryIsSaved(storyInReadingList); + initializeChannel(storyId); + }); + }, [storyId]); + + useEffect(() => { + // if another card updates this story, update it here also + if (typeof channels[storyId] !== 'undefined') { + setStoryIsSaved(channels[storyId] ?? false); + } + }, [channels[storyId]]); + + const saveStory = async (saved: boolean) => { + setStoryIsSaved(saved); + publish(storyId, saved); // update other cards with this story + + if (saved) { + await addUserStoryToReadingList(user?.id, storyId); + } else { + await deleteUserStoryToReadingList(user?.id, storyId); + } + }; + + return ( + saveStory(!storyIsSaved)}> + {storyIsSaved ? ( + + ) : ( + + )} + + ); +} diff --git a/src/components/SplashScreen/SplashScreen.tsx b/src/components/SplashScreen/SplashScreen.tsx index 3d791035..d9585ce9 100644 --- a/src/components/SplashScreen/SplashScreen.tsx +++ b/src/components/SplashScreen/SplashScreen.tsx @@ -1,5 +1,6 @@ import React from 'react'; -import { View, Image } from 'react-native'; +import { View } from 'react-native'; +import { Image } from 'expo-image'; import styles from './styles'; diff --git a/src/components/StyledButton/styles.tsx b/src/components/StyledButton/styles.tsx index 4e664ced..b2c4dc94 100644 --- a/src/components/StyledButton/styles.tsx +++ b/src/components/StyledButton/styles.tsx @@ -13,7 +13,7 @@ export default StyleSheet.create({ }, titleStyle: { paddingHorizontal: 24, - paddingVertical: 10, + paddingVertical: 5, color: 'white', }, }); diff --git a/src/components/TestCard/TestCard.tsx b/src/components/TestCard/TestCard.tsx new file mode 100644 index 00000000..4bbd02c6 --- /dev/null +++ b/src/components/TestCard/TestCard.tsx @@ -0,0 +1,66 @@ +import { + GestureResponderEvent, + TextInput, + Pressable, + Text, + View, +} from 'react-native'; + +import styles from './styles'; +import globalStyles from '../../styles/globalStyles'; +import { + addUserStoryToFavorites, + addUserStoryToReadingList, + fetchUserStoriesFavorites, + fetchUserStoriesReadingList, +} from '../../queries/savedStories'; +import { useState } from 'react'; +import { useSession } from '../../utils/AuthContext'; +import { Button } from 'react-native-paper'; + +function TestCard() { + const { user } = useSession(); + const [storyId, setStoryId] = useState(''); + + return ( + + + + setStoryId(t)} value={storyId} /> + + await addUserStoryToReadingList(user?.id, parseInt(storyId)) + } + > + Add story to reading + + + await addUserStoryToFavorites(user?.id, parseInt(storyId)) + } + > + Add story to favs list + + + + + + + ); +} + +export default TestCard; diff --git a/src/components/TestCard/styles.tsx b/src/components/TestCard/styles.tsx new file mode 100644 index 00000000..1ea6f118 --- /dev/null +++ b/src/components/TestCard/styles.tsx @@ -0,0 +1,26 @@ +import { StyleSheet } from 'react-native'; + +import colors from '../../styles/colors'; + +const styles = StyleSheet.create({ + contentCard: { + marginRight: 20, + flexDirection: 'column', + justifyContent: 'space-between', + }, + image: { + height: 140, + width: 148, + backgroundColor: colors.lime, + borderRadius: 4, + marginBottom: 8, + }, + textContainer: { + width: 148, + }, + title: { + marginBottom: 4, + }, +}); + +export default styles; diff --git a/src/components/Toast/Toast.tsx b/src/components/Toast/Toast.tsx new file mode 100644 index 00000000..66f5a614 --- /dev/null +++ b/src/components/Toast/Toast.tsx @@ -0,0 +1,31 @@ +import Toast, { + BaseToast, + BaseToastProps, + ToastConfig, +} from 'react-native-toast-message'; +import colors from '../../styles/colors'; +import { Icon } from 'react-native-elements'; +import styles from './styles'; + +const toastConfig: ToastConfig = { + success: (props: BaseToastProps) => ( + ( + + )} + /> + ), +}; + +function ToastComponent() { + return ; +} + +export default ToastComponent; diff --git a/src/components/Toast/styles.tsx b/src/components/Toast/styles.tsx new file mode 100644 index 00000000..ee18783c --- /dev/null +++ b/src/components/Toast/styles.tsx @@ -0,0 +1,14 @@ +import { StyleSheet } from 'react-native'; + +import colors from '../../styles/colors'; + +export default StyleSheet.create({ + icon: { + flex: 1, + justifyContent: 'center', + marginLeft: 10, + }, + toast: { + borderLeftColor: colors.white, + }, +}); diff --git a/src/components/ToastScreen.tsx b/src/components/ToastScreen.tsx deleted file mode 100644 index 4d0f4775..00000000 --- a/src/components/ToastScreen.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import React from 'react'; -import { Button, Text, View } from 'react-native'; -import { RootSiblingParent } from 'react-native-root-siblings'; -import Toast from 'react-native-root-toast'; - -const toast = () => { - Toast.show('Testing this out?', { - duration: Toast.durations.LONG, - position: Toast.positions.BOTTOM, - shadow: true, - animation: true, - hideOnPress: true, - delay: 0, - // onShow: () => {}, - // onShown: () => {}, - // onHide: () => {}, - // onHidden: () => {} - }); -}; - -export default function ToastScreen() { - return ( - - - Toast Page -