diff --git a/App.tsx b/App.tsx
index 5b7a91a..8fee37b 100644
--- a/App.tsx
+++ b/App.tsx
@@ -1,10 +1,79 @@
import React from 'react';
+import { NavigationContainer } from '@react-navigation/native';
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+
+import { Image } from 'react-native';
import { RecoilRoot } from 'recoil';
+
import SettingsView from './src/components/Settings';
+import ArtistsList from './src/components/ArtistsList';
+import NowPlayingLayout from './src/components/NowPlayingLayout';
+
+
+const SettingsIcon: React.FC<{ focused: boolean }> = ({ focused }) => (
+
+);
+
+const NowPlayingIcon: React.FC<{ focused: boolean }> = ({ focused }) => (
+
+);
+
+const ArtistsIcon: React.FC<{ focused: boolean }> = ({ focused }) => (
+
+);
+
+const Tab = createBottomTabNavigator();
const App = () => (
-
+
+
+
+
+
+
+
);
diff --git a/index.js b/index.js
index 8f869d4..99a6e59 100644
--- a/index.js
+++ b/index.js
@@ -1,3 +1,6 @@
+import 'react-native-gesture-handler';
+import 'react-native-get-random-values';
+
import { AppRegistry, LogBox } from 'react-native';
// ignore recoil's timer warning on android:
diff --git a/package-lock.json b/package-lock.json
index e68e36b..fb2f57a 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -8,11 +8,21 @@
"name": "subsonify",
"version": "0.0.1",
"dependencies": {
+ "@react-native-community/masked-view": "^0.1.11",
+ "@react-navigation/bottom-tabs": "^5.11.11",
+ "@react-navigation/native": "^5.9.4",
+ "@react-navigation/stack": "^5.14.5",
"md5": "^2.3.0",
"react": "17.0.1",
"react-native": "0.64.1",
+ "react-native-gesture-handler": "^1.10.3",
+ "react-native-get-random-values": "^1.7.0",
+ "react-native-reanimated": "^2.2.0",
+ "react-native-safe-area-context": "^3.2.0",
+ "react-native-screens": "^3.4.0",
"react-native-sqlite-storage": "^5.0.0",
"recoil": "^0.3.1",
+ "uuid": "^8.3.2",
"xmldom": "^0.5.0"
},
"devDependencies": {
@@ -24,6 +34,7 @@
"@types/react-native": "^0.64.5",
"@types/react-native-sqlite-storage": "^5.0.0",
"@types/react-test-renderer": "^16.9.2",
+ "@types/uuid": "^8.3.0",
"@types/xmldom": "^0.1.30",
"babel-jest": "^26.6.3",
"eslint": "^7.14.0",
@@ -1504,6 +1515,17 @@
"node": ">=0.1.95"
}
},
+ "node_modules/@egjs/hammerjs": {
+ "version": "2.0.17",
+ "resolved": "https://registry.npmjs.org/@egjs/hammerjs/-/hammerjs-2.0.17.tgz",
+ "integrity": "sha512-XQsZgjm2EcVUiZQf11UBJQfmZeEmOW8DpI1gsFeln6w0ae0ii4dMQEQ0kjl6DspdWX1aGY1/loyXnP0JS06e/A==",
+ "dependencies": {
+ "@types/hammerjs": "^2.0.36"
+ },
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
"node_modules/@eslint/eslintrc": {
"version": "0.4.2",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.2.tgz",
@@ -2925,6 +2947,15 @@
"integrity": "sha512-W/J0fNYVO01tioHjvYWQ9m6RgndVtbElzYozBq1ZPrHO/iCzlqoySHl4gO/fpCl9QEFjvJfjPgtPMTMlsoq5DQ==",
"dev": true
},
+ "node_modules/@react-native-community/masked-view": {
+ "version": "0.1.11",
+ "resolved": "https://registry.npmjs.org/@react-native-community/masked-view/-/masked-view-0.1.11.tgz",
+ "integrity": "sha512-rQfMIGSR/1r/SyN87+VD8xHHzDYeHaJq6elOSCAD+0iLagXkSI2pfA0LmSXP21uw5i3em7GkkRjfJ8wpqWXZNw==",
+ "peerDependencies": {
+ "react": ">=16.0",
+ "react-native": ">=0.57"
+ }
+ },
"node_modules/@react-native/assets": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@react-native/assets/-/assets-1.0.0.tgz",
@@ -2940,6 +2971,104 @@
"resolved": "https://registry.npmjs.org/@react-native/polyfills/-/polyfills-1.0.0.tgz",
"integrity": "sha512-0jbp4RxjYopTsIdLl+/Fy2TiwVYHy4mgeu07DG4b/LyM0OS/+lPP5c9sbnt/AMlnF6qz2JRZpPpGw1eMNS6A4w=="
},
+ "node_modules/@react-navigation/bottom-tabs": {
+ "version": "5.11.11",
+ "resolved": "https://registry.npmjs.org/@react-navigation/bottom-tabs/-/bottom-tabs-5.11.11.tgz",
+ "integrity": "sha512-hThj6Vfw+ITzAVj5TgLEoxkVEcBD+gYeieWOe6FryBRgokgKNCzFQzqArJ5UCmNMxklNH0rstJfcdyHflLuPtw==",
+ "dependencies": {
+ "color": "^3.1.3",
+ "react-native-iphone-x-helper": "^1.3.0"
+ },
+ "peerDependencies": {
+ "@react-navigation/native": "^5.0.5",
+ "react": "*",
+ "react-native": "*",
+ "react-native-safe-area-context": ">= 0.6.0",
+ "react-native-screens": ">= 2.0.0-alpha.0 || >= 2.0.0-beta.0 || >= 2.0.0"
+ }
+ },
+ "node_modules/@react-navigation/core": {
+ "version": "5.15.3",
+ "resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-5.15.3.tgz",
+ "integrity": "sha512-3ZdyDInh8qg1kygCNkmh9lFgpDf29lTvPsaMe2mm/qvmxLKSgttWBz07P2fc181aV9jTdgQpzYfWZ5KWT036zw==",
+ "dependencies": {
+ "@react-navigation/routers": "^5.7.2",
+ "escape-string-regexp": "^4.0.0",
+ "nanoid": "^3.1.15",
+ "query-string": "^6.13.6",
+ "react-is": "^16.13.0"
+ },
+ "peerDependencies": {
+ "react": "*"
+ }
+ },
+ "node_modules/@react-navigation/core/node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@react-navigation/core/node_modules/react-is": {
+ "version": "16.13.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
+ },
+ "node_modules/@react-navigation/native": {
+ "version": "5.9.4",
+ "resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-5.9.4.tgz",
+ "integrity": "sha512-BUCrOXfZDdKWBqM8OhOKQhCX5we4HUo5XG6tCQtVqQAep+7UcApZmMUuemUXDxVe8NPESUpoUlB0RaEpyIdfTQ==",
+ "dependencies": {
+ "@react-navigation/core": "^5.15.3",
+ "escape-string-regexp": "^4.0.0",
+ "nanoid": "^3.1.15"
+ },
+ "peerDependencies": {
+ "react": "*",
+ "react-native": "*"
+ }
+ },
+ "node_modules/@react-navigation/native/node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@react-navigation/routers": {
+ "version": "5.7.2",
+ "resolved": "https://registry.npmjs.org/@react-navigation/routers/-/routers-5.7.2.tgz",
+ "integrity": "sha512-BxNSMLHpU+oS37Xok0ql6rc9U7IC8aUD4+U5ZPbjDJ0pwzZxGGh0YOEBzfV4k/Ig3cbPdvVWbc1C9HHbCVr2oQ==",
+ "dependencies": {
+ "nanoid": "^3.1.15"
+ }
+ },
+ "node_modules/@react-navigation/stack": {
+ "version": "5.14.5",
+ "resolved": "https://registry.npmjs.org/@react-navigation/stack/-/stack-5.14.5.tgz",
+ "integrity": "sha512-hpdn1SS0tc3/3atkV2Q2y++n5B4e0rUcCj4W43PODMu72yX2m0LkKAAcpkPDCWAvwnLLIoLAEl5BEifZigl/6A==",
+ "dependencies": {
+ "color": "^3.1.3",
+ "react-native-iphone-x-helper": "^1.3.0"
+ },
+ "peerDependencies": {
+ "@react-native-community/masked-view": ">= 0.1.0",
+ "@react-navigation/native": "^5.0.5",
+ "react": "*",
+ "react-native": "*",
+ "react-native-gesture-handler": ">= 1.0.0",
+ "react-native-safe-area-context": ">= 0.6.0",
+ "react-native-screens": ">= 2.0.0-alpha.0 || >= 2.0.0-beta.0 || >= 2.0.0"
+ }
+ },
"node_modules/@sideway/address": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.2.tgz",
@@ -3040,6 +3169,11 @@
"@types/node": "*"
}
},
+ "node_modules/@types/hammerjs": {
+ "version": "2.0.39",
+ "resolved": "https://registry.npmjs.org/@types/hammerjs/-/hammerjs-2.0.39.tgz",
+ "integrity": "sha512-lYR2Y/tV2ujpk/WyUc7S0VLI0a9hrtVIN9EwnrNo5oSEJI2cK2/XrgwOQmXLL3eTulOESvh9qP6si9+DWM9cOA=="
+ },
"node_modules/@types/istanbul-lib-coverage": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz",
@@ -3167,6 +3301,12 @@
"integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==",
"dev": true
},
+ "node_modules/@types/uuid": {
+ "version": "8.3.0",
+ "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.0.tgz",
+ "integrity": "sha512-eQ9qFW/fhfGJF8WKHGEHZEyVWfZxrT+6CLIJGBcZPfxUh/+BnEj+UCGYMlr9qZuX/2AltsvwrGqp0LhEW8D0zQ==",
+ "dev": true
+ },
"node_modules/@types/xmldom": {
"version": "0.1.30",
"resolved": "https://registry.npmjs.org/@types/xmldom/-/xmldom-0.1.30.tgz",
@@ -4439,6 +4579,15 @@
"node": ">=0.10.0"
}
},
+ "node_modules/color": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/color/-/color-3.1.3.tgz",
+ "integrity": "sha512-xgXAcTHa2HeFCGLE9Xs/R82hujGtu9Jd9x4NW3T34+OMs7VoPsjwzRczKHvTAHeJwWFwX5j15+MgAppE8ztObQ==",
+ "dependencies": {
+ "color-convert": "^1.9.1",
+ "color-string": "^1.5.4"
+ }
+ },
"node_modules/color-convert": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
@@ -4452,6 +4601,15 @@
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
},
+ "node_modules/color-string": {
+ "version": "1.5.5",
+ "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.5.tgz",
+ "integrity": "sha512-jgIoum0OfQfq9Whcfc2z/VhCNcmQjWbey6qBX0vqt7YICflUmBCh9E9CiQD5GSJ+Uehixm3NUwHVhqUAWRivZg==",
+ "dependencies": {
+ "color-name": "^1.0.0",
+ "simple-swizzle": "^0.2.2"
+ }
+ },
"node_modules/colorette": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz",
@@ -4646,6 +4804,14 @@
"node": ">=4"
}
},
+ "node_modules/cross-fetch": {
+ "version": "3.1.4",
+ "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.4.tgz",
+ "integrity": "sha512-1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ==",
+ "dependencies": {
+ "node-fetch": "2.6.1"
+ }
+ },
"node_modules/cross-spawn": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
@@ -5909,6 +6075,11 @@
"node": ">=0.10.0"
}
},
+ "node_modules/fast-base64-decode": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fast-base64-decode/-/fast-base64-decode-1.0.0.tgz",
+ "integrity": "sha512-qwaScUgUGBYeDNRnbc/KyllVU88Jk1pRHPStuF/lO7B0/RTRLj7U0lkdTAutlBblY08rwZDff6tNU9cjv6j//Q=="
+ },
"node_modules/fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
@@ -5941,6 +6112,33 @@
"bser": "2.1.1"
}
},
+ "node_modules/fbjs": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-3.0.0.tgz",
+ "integrity": "sha512-dJd4PiDOFuhe7vk4F80Mba83Vr2QuK86FoxtgPmzBqEJahncp+13YCmfoa53KHCo6OnlXLG7eeMWPfB5CrpVKg==",
+ "dependencies": {
+ "cross-fetch": "^3.0.4",
+ "fbjs-css-vars": "^1.0.0",
+ "loose-envify": "^1.0.0",
+ "object-assign": "^4.1.0",
+ "promise": "^7.1.1",
+ "setimmediate": "^1.0.5",
+ "ua-parser-js": "^0.7.18"
+ }
+ },
+ "node_modules/fbjs-css-vars": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz",
+ "integrity": "sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ=="
+ },
+ "node_modules/fbjs/node_modules/promise": {
+ "version": "7.3.1",
+ "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
+ "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
+ "dependencies": {
+ "asap": "~2.0.3"
+ }
+ },
"node_modules/file-entry-cache": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
@@ -5964,6 +6162,14 @@
"node": ">=8"
}
},
+ "node_modules/filter-obj": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz",
+ "integrity": "sha1-mzERErxsYSehbgFsbF1/GeCAXFs=",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/finalhandler": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
@@ -6449,6 +6655,19 @@
"node": ">= 8"
}
},
+ "node_modules/hoist-non-react-statics": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
+ "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
+ "dependencies": {
+ "react-is": "^16.7.0"
+ }
+ },
+ "node_modules/hoist-non-react-statics/node_modules/react-is": {
+ "version": "16.13.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
+ },
"node_modules/hosted-git-info": {
"version": "2.8.9",
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
@@ -9699,11 +9918,27 @@
"mkdirp": "bin/cmd.js"
}
},
+ "node_modules/mockdate": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/mockdate/-/mockdate-3.0.5.tgz",
+ "integrity": "sha512-iniQP4rj1FhBdBYS/+eQv7j1tadJ9lJtdzgOpvsOHng/GbcDh2Fhdeq+ZRldrPYdXvCyfFUmFeEwEGXZB5I/AQ=="
+ },
"node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
+ "node_modules/nanoid": {
+ "version": "3.1.23",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.23.tgz",
+ "integrity": "sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw==",
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
"node_modules/nanomatch": {
"version": "1.2.13",
"resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
@@ -10556,6 +10791,23 @@
"node": ">=6"
}
},
+ "node_modules/query-string": {
+ "version": "6.14.1",
+ "resolved": "https://registry.npmjs.org/query-string/-/query-string-6.14.1.tgz",
+ "integrity": "sha512-XDxAeVmpfu1/6IjyT/gXHOl+S0vQ9owggJ30hhWKdHAsNPOcasn5o9BW0eejZqL2e4vMjhAxoW3jVHcD6mbcYw==",
+ "dependencies": {
+ "decode-uri-component": "^0.2.0",
+ "filter-obj": "^1.1.0",
+ "split-on-first": "^1.0.0",
+ "strict-uri-encode": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/range-parser": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
@@ -10648,6 +10900,74 @@
"nullthrows": "^1.1.1"
}
},
+ "node_modules/react-native-gesture-handler": {
+ "version": "1.10.3",
+ "resolved": "https://registry.npmjs.org/react-native-gesture-handler/-/react-native-gesture-handler-1.10.3.tgz",
+ "integrity": "sha512-cBGMi1IEsIVMgoox4RvMx7V2r6bNKw0uR1Mu1o7NbuHS6BRSVLq0dP34l2ecnPlC+jpWd3le6Yg1nrdCjby2Mw==",
+ "dependencies": {
+ "@egjs/hammerjs": "^2.0.17",
+ "fbjs": "^3.0.0",
+ "hoist-non-react-statics": "^3.3.0",
+ "invariant": "^2.2.4",
+ "prop-types": "^15.7.2"
+ }
+ },
+ "node_modules/react-native-get-random-values": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/react-native-get-random-values/-/react-native-get-random-values-1.7.0.tgz",
+ "integrity": "sha512-zDhmpWUekGRFb9I+MQkxllHcqXN9HBSsgPwBQfrZ1KZYpzDspWLZ6/yLMMZrtq4pVqNR7C7N96L3SuLpXv1nhQ==",
+ "dependencies": {
+ "fast-base64-decode": "^1.0.0"
+ },
+ "peerDependencies": {
+ "react-native": ">=0.56"
+ }
+ },
+ "node_modules/react-native-iphone-x-helper": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/react-native-iphone-x-helper/-/react-native-iphone-x-helper-1.3.1.tgz",
+ "integrity": "sha512-HOf0jzRnq2/aFUcdCJ9w9JGzN3gdEg0zFE4FyYlp4jtidqU03D5X7ZegGKfT1EWteR0gPBGp9ye5T5FvSWi9Yg==",
+ "peerDependencies": {
+ "react-native": ">=0.42.0"
+ }
+ },
+ "node_modules/react-native-reanimated": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-2.2.0.tgz",
+ "integrity": "sha512-lOJDd+5w1gY6DHGXG2jD1dsjzQmXQ2699HUc3IztvI2WP4zUT+UAA+zSG+5JiBS5DUnTL8YhhkmUQmr1KNGO5w==",
+ "dependencies": {
+ "@babel/plugin-transform-object-assign": "^7.10.4",
+ "fbjs": "^3.0.0",
+ "mockdate": "^3.0.2",
+ "string-hash-64": "^1.0.3"
+ },
+ "peerDependencies": {
+ "react": "*",
+ "react-native": "*",
+ "react-native-gesture-handler": "*"
+ }
+ },
+ "node_modules/react-native-safe-area-context": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-3.2.0.tgz",
+ "integrity": "sha512-k2Nty4PwSnrg9HwrYeeE+EYqViYJoOFwEy9LxL5RIRfoqxAq/uQXNGwpUg2/u4gnKpBbEPa9eRh15KKMe/VHkA==",
+ "peerDependencies": {
+ "react": "*",
+ "react-native": "*"
+ }
+ },
+ "node_modules/react-native-screens": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-3.4.0.tgz",
+ "integrity": "sha512-cg+q9MRnVdeOcJyvJtqffoXLur/C2wHA/7IO2+FAipzTlgHbbM1mTuSM7qG+SeiQjoIs4mHOEf7A0ziPKW04sA==",
+ "dependencies": {
+ "warn-once": "^0.1.0"
+ },
+ "peerDependencies": {
+ "react": "*",
+ "react-native": "*"
+ }
+ },
"node_modules/react-native-sqlite-storage": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/react-native-sqlite-storage/-/react-native-sqlite-storage-5.0.0.tgz",
@@ -11523,6 +11843,11 @@
"node": ">=0.10.0"
}
},
+ "node_modules/setimmediate": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
+ "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU="
+ },
"node_modules/setprototypeof": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
@@ -11623,6 +11948,19 @@
"plist": "^3.0.1"
}
},
+ "node_modules/simple-swizzle": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
+ "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=",
+ "dependencies": {
+ "is-arrayish": "^0.3.1"
+ }
+ },
+ "node_modules/simple-swizzle/node_modules/is-arrayish": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
+ "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="
+ },
"node_modules/sisteransi": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
@@ -11895,6 +12233,14 @@
"integrity": "sha512-Ki212dKK4ogX+xDo4CtOZBVIwhsKBEfsEEcwmJfLQzirgc2jIWdzg40Unxz/HzEUqM1WFzVlQSMF9kZZ2HboLQ==",
"dev": true
},
+ "node_modules/split-on-first": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz",
+ "integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/split-string": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
@@ -12060,6 +12406,14 @@
"node": ">= 0.10.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",
+ "integrity": "sha1-ucczDHBChi9rFC3CdLvMWGbONUY=",
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
@@ -12068,6 +12422,11 @@
"safe-buffer": "~5.1.0"
}
},
+ "node_modules/string-hash-64": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/string-hash-64/-/string-hash-64-1.0.3.tgz",
+ "integrity": "sha512-D5OKWKvDhyVWWn2x5Y9b+37NUllks34q1dCDhk/vYcso9fmhs+Tl3KR/gE4v5UNj2UA35cnX4KdVVGkG1deKqw=="
+ },
"node_modules/string-length": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz",
@@ -12604,6 +12963,24 @@
"node": ">=4.2.0"
}
},
+ "node_modules/ua-parser-js": {
+ "version": "0.7.28",
+ "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.28.tgz",
+ "integrity": "sha512-6Gurc1n//gjp9eQNXjD9O3M/sMwVtN5S8Lv9bvOYBfKfDNiIIhqiyi01vMBO45u4zkDE420w/e0se7Vs+sIg+g==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/ua-parser-js"
+ },
+ {
+ "type": "paypal",
+ "url": "https://paypal.me/faisalman"
+ }
+ ],
+ "engines": {
+ "node": "*"
+ }
+ },
"node_modules/uglify-es": {
"version": "3.3.9",
"resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.9.tgz",
@@ -12822,8 +13199,6 @@
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
- "dev": true,
- "optional": true,
"bin": {
"uuid": "dist/bin/uuid"
}
@@ -12909,6 +13284,11 @@
"makeerror": "1.0.x"
}
},
+ "node_modules/warn-once": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/warn-once/-/warn-once-0.1.0.tgz",
+ "integrity": "sha512-recZTSvuaH/On5ZU5ywq66y99lImWqzP93+AiUo9LUwG8gXHW+LJjhOd6REJHm7qb0niYqrEQJvbHSQfuJtTqA=="
+ },
"node_modules/wcwidth": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz",
@@ -14383,6 +14763,14 @@
"minimist": "^1.2.0"
}
},
+ "@egjs/hammerjs": {
+ "version": "2.0.17",
+ "resolved": "https://registry.npmjs.org/@egjs/hammerjs/-/hammerjs-2.0.17.tgz",
+ "integrity": "sha512-XQsZgjm2EcVUiZQf11UBJQfmZeEmOW8DpI1gsFeln6w0ae0ii4dMQEQ0kjl6DspdWX1aGY1/loyXnP0JS06e/A==",
+ "requires": {
+ "@types/hammerjs": "^2.0.36"
+ }
+ },
"@eslint/eslintrc": {
"version": "0.4.2",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.2.tgz",
@@ -15488,6 +15876,12 @@
"integrity": "sha512-W/J0fNYVO01tioHjvYWQ9m6RgndVtbElzYozBq1ZPrHO/iCzlqoySHl4gO/fpCl9QEFjvJfjPgtPMTMlsoq5DQ==",
"dev": true
},
+ "@react-native-community/masked-view": {
+ "version": "0.1.11",
+ "resolved": "https://registry.npmjs.org/@react-native-community/masked-view/-/masked-view-0.1.11.tgz",
+ "integrity": "sha512-rQfMIGSR/1r/SyN87+VD8xHHzDYeHaJq6elOSCAD+0iLagXkSI2pfA0LmSXP21uw5i3em7GkkRjfJ8wpqWXZNw==",
+ "requires": {}
+ },
"@react-native/assets": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@react-native/assets/-/assets-1.0.0.tgz",
@@ -15503,6 +15897,73 @@
"resolved": "https://registry.npmjs.org/@react-native/polyfills/-/polyfills-1.0.0.tgz",
"integrity": "sha512-0jbp4RxjYopTsIdLl+/Fy2TiwVYHy4mgeu07DG4b/LyM0OS/+lPP5c9sbnt/AMlnF6qz2JRZpPpGw1eMNS6A4w=="
},
+ "@react-navigation/bottom-tabs": {
+ "version": "5.11.11",
+ "resolved": "https://registry.npmjs.org/@react-navigation/bottom-tabs/-/bottom-tabs-5.11.11.tgz",
+ "integrity": "sha512-hThj6Vfw+ITzAVj5TgLEoxkVEcBD+gYeieWOe6FryBRgokgKNCzFQzqArJ5UCmNMxklNH0rstJfcdyHflLuPtw==",
+ "requires": {
+ "color": "^3.1.3",
+ "react-native-iphone-x-helper": "^1.3.0"
+ }
+ },
+ "@react-navigation/core": {
+ "version": "5.15.3",
+ "resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-5.15.3.tgz",
+ "integrity": "sha512-3ZdyDInh8qg1kygCNkmh9lFgpDf29lTvPsaMe2mm/qvmxLKSgttWBz07P2fc181aV9jTdgQpzYfWZ5KWT036zw==",
+ "requires": {
+ "@react-navigation/routers": "^5.7.2",
+ "escape-string-regexp": "^4.0.0",
+ "nanoid": "^3.1.15",
+ "query-string": "^6.13.6",
+ "react-is": "^16.13.0"
+ },
+ "dependencies": {
+ "escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="
+ },
+ "react-is": {
+ "version": "16.13.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
+ }
+ }
+ },
+ "@react-navigation/native": {
+ "version": "5.9.4",
+ "resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-5.9.4.tgz",
+ "integrity": "sha512-BUCrOXfZDdKWBqM8OhOKQhCX5we4HUo5XG6tCQtVqQAep+7UcApZmMUuemUXDxVe8NPESUpoUlB0RaEpyIdfTQ==",
+ "requires": {
+ "@react-navigation/core": "^5.15.3",
+ "escape-string-regexp": "^4.0.0",
+ "nanoid": "^3.1.15"
+ },
+ "dependencies": {
+ "escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="
+ }
+ }
+ },
+ "@react-navigation/routers": {
+ "version": "5.7.2",
+ "resolved": "https://registry.npmjs.org/@react-navigation/routers/-/routers-5.7.2.tgz",
+ "integrity": "sha512-BxNSMLHpU+oS37Xok0ql6rc9U7IC8aUD4+U5ZPbjDJ0pwzZxGGh0YOEBzfV4k/Ig3cbPdvVWbc1C9HHbCVr2oQ==",
+ "requires": {
+ "nanoid": "^3.1.15"
+ }
+ },
+ "@react-navigation/stack": {
+ "version": "5.14.5",
+ "resolved": "https://registry.npmjs.org/@react-navigation/stack/-/stack-5.14.5.tgz",
+ "integrity": "sha512-hpdn1SS0tc3/3atkV2Q2y++n5B4e0rUcCj4W43PODMu72yX2m0LkKAAcpkPDCWAvwnLLIoLAEl5BEifZigl/6A==",
+ "requires": {
+ "color": "^3.1.3",
+ "react-native-iphone-x-helper": "^1.3.0"
+ }
+ },
"@sideway/address": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.2.tgz",
@@ -15600,6 +16061,11 @@
"@types/node": "*"
}
},
+ "@types/hammerjs": {
+ "version": "2.0.39",
+ "resolved": "https://registry.npmjs.org/@types/hammerjs/-/hammerjs-2.0.39.tgz",
+ "integrity": "sha512-lYR2Y/tV2ujpk/WyUc7S0VLI0a9hrtVIN9EwnrNo5oSEJI2cK2/XrgwOQmXLL3eTulOESvh9qP6si9+DWM9cOA=="
+ },
"@types/istanbul-lib-coverage": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz",
@@ -15729,6 +16195,12 @@
"integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==",
"dev": true
},
+ "@types/uuid": {
+ "version": "8.3.0",
+ "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.0.tgz",
+ "integrity": "sha512-eQ9qFW/fhfGJF8WKHGEHZEyVWfZxrT+6CLIJGBcZPfxUh/+BnEj+UCGYMlr9qZuX/2AltsvwrGqp0LhEW8D0zQ==",
+ "dev": true
+ },
"@types/xmldom": {
"version": "0.1.30",
"resolved": "https://registry.npmjs.org/@types/xmldom/-/xmldom-0.1.30.tgz",
@@ -16665,6 +17137,15 @@
"object-visit": "^1.0.0"
}
},
+ "color": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/color/-/color-3.1.3.tgz",
+ "integrity": "sha512-xgXAcTHa2HeFCGLE9Xs/R82hujGtu9Jd9x4NW3T34+OMs7VoPsjwzRczKHvTAHeJwWFwX5j15+MgAppE8ztObQ==",
+ "requires": {
+ "color-convert": "^1.9.1",
+ "color-string": "^1.5.4"
+ }
+ },
"color-convert": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
@@ -16678,6 +17159,15 @@
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
},
+ "color-string": {
+ "version": "1.5.5",
+ "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.5.tgz",
+ "integrity": "sha512-jgIoum0OfQfq9Whcfc2z/VhCNcmQjWbey6qBX0vqt7YICflUmBCh9E9CiQD5GSJ+Uehixm3NUwHVhqUAWRivZg==",
+ "requires": {
+ "color-name": "^1.0.0",
+ "simple-swizzle": "^0.2.2"
+ }
+ },
"colorette": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz",
@@ -16846,6 +17336,14 @@
}
}
},
+ "cross-fetch": {
+ "version": "3.1.4",
+ "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.4.tgz",
+ "integrity": "sha512-1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ==",
+ "requires": {
+ "node-fetch": "2.6.1"
+ }
+ },
"cross-spawn": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
@@ -17788,6 +18286,11 @@
}
}
},
+ "fast-base64-decode": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fast-base64-decode/-/fast-base64-decode-1.0.0.tgz",
+ "integrity": "sha512-qwaScUgUGBYeDNRnbc/KyllVU88Jk1pRHPStuF/lO7B0/RTRLj7U0lkdTAutlBblY08rwZDff6tNU9cjv6j//Q=="
+ },
"fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
@@ -17820,6 +18323,35 @@
"bser": "2.1.1"
}
},
+ "fbjs": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-3.0.0.tgz",
+ "integrity": "sha512-dJd4PiDOFuhe7vk4F80Mba83Vr2QuK86FoxtgPmzBqEJahncp+13YCmfoa53KHCo6OnlXLG7eeMWPfB5CrpVKg==",
+ "requires": {
+ "cross-fetch": "^3.0.4",
+ "fbjs-css-vars": "^1.0.0",
+ "loose-envify": "^1.0.0",
+ "object-assign": "^4.1.0",
+ "promise": "^7.1.1",
+ "setimmediate": "^1.0.5",
+ "ua-parser-js": "^0.7.18"
+ },
+ "dependencies": {
+ "promise": {
+ "version": "7.3.1",
+ "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
+ "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
+ "requires": {
+ "asap": "~2.0.3"
+ }
+ }
+ }
+ },
+ "fbjs-css-vars": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz",
+ "integrity": "sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ=="
+ },
"file-entry-cache": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
@@ -17837,6 +18369,11 @@
"to-regex-range": "^5.0.1"
}
},
+ "filter-obj": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz",
+ "integrity": "sha1-mzERErxsYSehbgFsbF1/GeCAXFs="
+ },
"finalhandler": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
@@ -18202,6 +18739,21 @@
}
}
},
+ "hoist-non-react-statics": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
+ "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
+ "requires": {
+ "react-is": "^16.7.0"
+ },
+ "dependencies": {
+ "react-is": {
+ "version": "16.13.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
+ }
+ }
+ },
"hosted-git-info": {
"version": "2.8.9",
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
@@ -20709,11 +21261,21 @@
"minimist": "^1.2.5"
}
},
+ "mockdate": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/mockdate/-/mockdate-3.0.5.tgz",
+ "integrity": "sha512-iniQP4rj1FhBdBYS/+eQv7j1tadJ9lJtdzgOpvsOHng/GbcDh2Fhdeq+ZRldrPYdXvCyfFUmFeEwEGXZB5I/AQ=="
+ },
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
+ "nanoid": {
+ "version": "3.1.23",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.23.tgz",
+ "integrity": "sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw=="
+ },
"nanomatch": {
"version": "1.2.13",
"resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
@@ -21353,6 +21915,17 @@
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
"dev": true
},
+ "query-string": {
+ "version": "6.14.1",
+ "resolved": "https://registry.npmjs.org/query-string/-/query-string-6.14.1.tgz",
+ "integrity": "sha512-XDxAeVmpfu1/6IjyT/gXHOl+S0vQ9owggJ30hhWKdHAsNPOcasn5o9BW0eejZqL2e4vMjhAxoW3jVHcD6mbcYw==",
+ "requires": {
+ "decode-uri-component": "^0.2.0",
+ "filter-obj": "^1.1.0",
+ "split-on-first": "^1.0.0",
+ "strict-uri-encode": "^2.0.0"
+ }
+ },
"range-parser": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
@@ -21440,6 +22013,57 @@
"nullthrows": "^1.1.1"
}
},
+ "react-native-gesture-handler": {
+ "version": "1.10.3",
+ "resolved": "https://registry.npmjs.org/react-native-gesture-handler/-/react-native-gesture-handler-1.10.3.tgz",
+ "integrity": "sha512-cBGMi1IEsIVMgoox4RvMx7V2r6bNKw0uR1Mu1o7NbuHS6BRSVLq0dP34l2ecnPlC+jpWd3le6Yg1nrdCjby2Mw==",
+ "requires": {
+ "@egjs/hammerjs": "^2.0.17",
+ "fbjs": "^3.0.0",
+ "hoist-non-react-statics": "^3.3.0",
+ "invariant": "^2.2.4",
+ "prop-types": "^15.7.2"
+ }
+ },
+ "react-native-get-random-values": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/react-native-get-random-values/-/react-native-get-random-values-1.7.0.tgz",
+ "integrity": "sha512-zDhmpWUekGRFb9I+MQkxllHcqXN9HBSsgPwBQfrZ1KZYpzDspWLZ6/yLMMZrtq4pVqNR7C7N96L3SuLpXv1nhQ==",
+ "requires": {
+ "fast-base64-decode": "^1.0.0"
+ }
+ },
+ "react-native-iphone-x-helper": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/react-native-iphone-x-helper/-/react-native-iphone-x-helper-1.3.1.tgz",
+ "integrity": "sha512-HOf0jzRnq2/aFUcdCJ9w9JGzN3gdEg0zFE4FyYlp4jtidqU03D5X7ZegGKfT1EWteR0gPBGp9ye5T5FvSWi9Yg==",
+ "requires": {}
+ },
+ "react-native-reanimated": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-2.2.0.tgz",
+ "integrity": "sha512-lOJDd+5w1gY6DHGXG2jD1dsjzQmXQ2699HUc3IztvI2WP4zUT+UAA+zSG+5JiBS5DUnTL8YhhkmUQmr1KNGO5w==",
+ "requires": {
+ "@babel/plugin-transform-object-assign": "^7.10.4",
+ "fbjs": "^3.0.0",
+ "mockdate": "^3.0.2",
+ "string-hash-64": "^1.0.3"
+ }
+ },
+ "react-native-safe-area-context": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-3.2.0.tgz",
+ "integrity": "sha512-k2Nty4PwSnrg9HwrYeeE+EYqViYJoOFwEy9LxL5RIRfoqxAq/uQXNGwpUg2/u4gnKpBbEPa9eRh15KKMe/VHkA==",
+ "requires": {}
+ },
+ "react-native-screens": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-3.4.0.tgz",
+ "integrity": "sha512-cg+q9MRnVdeOcJyvJtqffoXLur/C2wHA/7IO2+FAipzTlgHbbM1mTuSM7qG+SeiQjoIs4mHOEf7A0ziPKW04sA==",
+ "requires": {
+ "warn-once": "^0.1.0"
+ }
+ },
"react-native-sqlite-storage": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/react-native-sqlite-storage/-/react-native-sqlite-storage-5.0.0.tgz",
@@ -22113,6 +22737,11 @@
}
}
},
+ "setimmediate": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
+ "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU="
+ },
"setprototypeof": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
@@ -22195,6 +22824,21 @@
"plist": "^3.0.1"
}
},
+ "simple-swizzle": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
+ "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=",
+ "requires": {
+ "is-arrayish": "^0.3.1"
+ },
+ "dependencies": {
+ "is-arrayish": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
+ "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="
+ }
+ }
+ },
"sisteransi": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
@@ -22425,6 +23069,11 @@
"integrity": "sha512-Ki212dKK4ogX+xDo4CtOZBVIwhsKBEfsEEcwmJfLQzirgc2jIWdzg40Unxz/HzEUqM1WFzVlQSMF9kZZ2HboLQ==",
"dev": true
},
+ "split-on-first": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz",
+ "integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw=="
+ },
"split-string": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
@@ -22555,6 +23204,11 @@
"resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-2.2.0.tgz",
"integrity": "sha1-kdX1Ew0c75bc+n9yaUUYh0HQnuQ="
},
+ "strict-uri-encode": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz",
+ "integrity": "sha1-ucczDHBChi9rFC3CdLvMWGbONUY="
+ },
"string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
@@ -22563,6 +23217,11 @@
"safe-buffer": "~5.1.0"
}
},
+ "string-hash-64": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/string-hash-64/-/string-hash-64-1.0.3.tgz",
+ "integrity": "sha512-D5OKWKvDhyVWWn2x5Y9b+37NUllks34q1dCDhk/vYcso9fmhs+Tl3KR/gE4v5UNj2UA35cnX4KdVVGkG1deKqw=="
+ },
"string-length": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz",
@@ -22971,6 +23630,11 @@
"integrity": "sha512-kdMjTiekY+z/ubJCATUPlRDl39vXYiMV9iyeMuEuXZh2we6zz80uovNN2WlAxmmdE/Z/YQe+EbOEXB5RHEED3w==",
"dev": true
},
+ "ua-parser-js": {
+ "version": "0.7.28",
+ "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.28.tgz",
+ "integrity": "sha512-6Gurc1n//gjp9eQNXjD9O3M/sMwVtN5S8Lv9bvOYBfKfDNiIIhqiyi01vMBO45u4zkDE420w/e0se7Vs+sIg+g=="
+ },
"uglify-es": {
"version": "3.3.9",
"resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.9.tgz",
@@ -23137,9 +23801,7 @@
"uuid": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
- "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
- "dev": true,
- "optional": true
+ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
},
"v8-compile-cache": {
"version": "2.3.0",
@@ -23212,6 +23874,11 @@
"makeerror": "1.0.x"
}
},
+ "warn-once": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/warn-once/-/warn-once-0.1.0.tgz",
+ "integrity": "sha512-recZTSvuaH/On5ZU5ywq66y99lImWqzP93+AiUo9LUwG8gXHW+LJjhOd6REJHm7qb0niYqrEQJvbHSQfuJtTqA=="
+ },
"wcwidth": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz",
diff --git a/package.json b/package.json
index a0ea4b9..3a664a5 100644
--- a/package.json
+++ b/package.json
@@ -10,11 +10,21 @@
"lint": "eslint . --ext .js,.jsx,.ts,.tsx"
},
"dependencies": {
+ "@react-native-community/masked-view": "^0.1.11",
+ "@react-navigation/bottom-tabs": "^5.11.11",
+ "@react-navigation/native": "^5.9.4",
+ "@react-navigation/stack": "^5.14.5",
"md5": "^2.3.0",
"react": "17.0.1",
"react-native": "0.64.1",
+ "react-native-gesture-handler": "^1.10.3",
+ "react-native-get-random-values": "^1.7.0",
+ "react-native-reanimated": "^2.2.0",
+ "react-native-safe-area-context": "^3.2.0",
+ "react-native-screens": "^3.4.0",
"react-native-sqlite-storage": "^5.0.0",
"recoil": "^0.3.1",
+ "uuid": "^8.3.2",
"xmldom": "^0.5.0"
},
"devDependencies": {
@@ -26,6 +36,7 @@
"@types/react-native": "^0.64.5",
"@types/react-native-sqlite-storage": "^5.0.0",
"@types/react-test-renderer": "^16.9.2",
+ "@types/uuid": "^8.3.0",
"@types/xmldom": "^0.1.30",
"babel-jest": "^26.6.3",
"eslint": "^7.14.0",
diff --git a/res/mic_on-fill.png b/res/mic_on-fill.png
new file mode 100644
index 0000000..648bb2f
Binary files /dev/null and b/res/mic_on-fill.png differ
diff --git a/res/mic_on.png b/res/mic_on.png
new file mode 100644
index 0000000..480fbe2
Binary files /dev/null and b/res/mic_on.png differ
diff --git a/res/music_notes-fill.png b/res/music_notes-fill.png
new file mode 100644
index 0000000..1bbd38e
Binary files /dev/null and b/res/music_notes-fill.png differ
diff --git a/res/music_notes.png b/res/music_notes.png
new file mode 100644
index 0000000..8119418
Binary files /dev/null and b/res/music_notes.png differ
diff --git a/res/settings-fill.png b/res/settings-fill.png
new file mode 100644
index 0000000..7ff813e
Binary files /dev/null and b/res/settings-fill.png differ
diff --git a/res/settings.png b/res/settings.png
new file mode 100644
index 0000000..8560ebd
Binary files /dev/null and b/res/settings.png differ
diff --git a/src/components/Settings.tsx b/src/components/Settings.tsx
index 72cbfb8..84fe933 100644
--- a/src/components/Settings.tsx
+++ b/src/components/Settings.tsx
@@ -1,29 +1,80 @@
-import React from 'react';
-import { Button, View } from 'react-native';
+import React, { useEffect, useState } from 'react';
+import { Button, TextInput, View, Text } from 'react-native';
+import { useRecoilState } from 'recoil';
+import { v4 as uuidv4 } from 'uuid';
+import md5 from 'md5';
import { musicDb, settingsDb } from '../clients';
+import { appSettingsState, serversState } from '../state/settings';
+import { DbStorage } from '../storage/db';
+import { StackScreenProps } from '@react-navigation/stack';
-const DbControls = () => {
+const RecreateDbButton: React.FC<{ db: DbStorage, title: string }> = ({ db, title }) => {
+ const [inProgress, setInProgress] = useState(false);
- const recreateMusicDb = async () => {
- try { await musicDb.deleteDb(); } catch {}
- await musicDb.createDb();
- }
-
- const recreateSettingsDb = async () => {
- try { await settingsDb.deleteDb(); } catch {}
- await settingsDb.createDb();
+ const recreateDb = async () => {
+ setInProgress(true);
+ try{
+ try { await db.deleteDb(); } catch {}
+ await db.createDb();
+ } finally {
+ setInProgress(false);
+ }
}
+ return (
+
+ )
+}
+
+const DbControls = () => {
return (
-
-
+
+
+ );
+}
+
+const ServerSettingsView = () => {
+ const [servers, setServers] = useRecoilState(serversState);
+ const [appSettings, setAppSettings] = useRecoilState(appSettingsState);
+
+ const bootstrapServer = () => {
+ if (servers.length !== 0) {
+ return;
+ }
+
+ const id = uuidv4();
+ const salt = uuidv4();
+ const address = 'http://demo.subsonic.org';
+
+ setServers([{
+ id, salt, address,
+ username: 'guest',
+ token: md5('guest' + salt),
+ }]);
+
+ setAppSettings({
+ server: id,
+ });
+ };
+
+ return (
+
+
+ {servers.map(s => (
+
+ {s.address}
+ {s.username}
+
+ ))}
);
}
@@ -31,6 +82,9 @@ const DbControls = () => {
const SettingsView = () => (
+ Loading...}>
+
+
)
diff --git a/src/state/artists.ts b/src/state/artists.ts
index fc71af6..9d8c24a 100644
--- a/src/state/artists.ts
+++ b/src/state/artists.ts
@@ -1,16 +1,11 @@
import md5 from 'md5';
-import { atom, selector, useSetRecoilState } from 'recoil';
+import { atom, selector, useRecoilValue, useSetRecoilState } from 'recoil';
import { SubsonicApiClient } from '../subsonic/api';
import { MusicDb } from '../storage/music';
+import { activeServer } from './settings'
const db = new MusicDb();
-const password = 'test';
-const salt = 'salty';
-const token = md5(password + salt);
-
-const client = new SubsonicApiClient('http://navidrome.home', 'austin', token, salt);
-
export interface ArtistState {
id: string;
name: string;
@@ -37,7 +32,14 @@ export const artistsState = atom({
export const useUpdateArtists = () => {
const setArtists = useSetRecoilState(artistsState);
+ const server = useRecoilValue(activeServer);
+
return async () => {
+ if (!server) {
+ return;
+ }
+
+ const client = new SubsonicApiClient(server.address, server.username, server.token, server.salt);
const response = await client.getArtists();
setArtists(response.data.artists.map(i => ({
diff --git a/src/state/settings.ts b/src/state/settings.ts
new file mode 100644
index 0000000..d8e54d3
--- /dev/null
+++ b/src/state/settings.ts
@@ -0,0 +1,47 @@
+import { atom, DefaultValue, selector } from 'recoil';
+import { settingsDb } from '../clients';
+import { AppSettings, ServerSettings } from '../storage/settings';
+
+export const serversState = atom({
+ key: 'serverState',
+ default: selector({
+ key: 'serversState/default',
+ get: () => settingsDb.getServers(),
+ }),
+ effects_UNSTABLE: [
+ ({ onSet }) => {
+ onSet((newValue) => {
+ if (!(newValue instanceof DefaultValue)) {
+ settingsDb.updateServers(newValue);
+ }
+ });
+ }
+ ],
+});
+
+export const appSettingsState = atom({
+ key: 'appSettingsState',
+ default: selector({
+ key: 'appSettingsState/default',
+ get: () => settingsDb.getApp(),
+ }),
+ effects_UNSTABLE: [
+ ({ onSet }) => {
+ onSet((newValue, oldValue) => {
+ if (!(newValue instanceof DefaultValue)) {
+ settingsDb.updateApp(newValue);
+ }
+ });
+ }
+ ],
+});
+
+export const activeServer = selector({
+ key: 'activeServer',
+ get: ({get}) => {
+ const appSettings = get(appSettingsState);
+ const servers = get(serversState);
+
+ return servers.find(x => x.id == appSettings.server);
+ }
+});
diff --git a/src/storage/db.ts b/src/storage/db.ts
index b9473f9..017009f 100644
--- a/src/storage/db.ts
+++ b/src/storage/db.ts
@@ -9,9 +9,9 @@ export abstract class DbStorage {
this.dbParams = dbParams;
}
- // abstract createDb(): Promise
+ abstract createDb(): Promise
- protected async createDb(scope: (tx: Transaction) => void): Promise {
+ protected async initDb(scope: (tx: Transaction) => void): Promise {
await this.transaction(tx => {
tx.executeSql(`
CREATE TABLE db_version (
diff --git a/src/storage/music.ts b/src/storage/music.ts
index 0ba3f05..8d868bc 100644
--- a/src/storage/music.ts
+++ b/src/storage/music.ts
@@ -6,7 +6,7 @@ export class MusicDb extends DbStorage {
}
async createDb(): Promise {
- super.createDb(tx => {
+ await this.initDb(tx => {
tx.executeSql(`
CREATE TABLE artists (
id TEXT PRIMARY KEY NOT NULL,
diff --git a/src/storage/settings.ts b/src/storage/settings.ts
index bc81f6d..682c721 100644
--- a/src/storage/settings.ts
+++ b/src/storage/settings.ts
@@ -18,7 +18,7 @@ export class SettingsDb extends DbStorage {
}
async createDb(): Promise {
- super.createDb(tx => {
+ await this.initDb(tx => {
tx.executeSql(`
CREATE TABLE servers (
id TEXT PRIMARY KEY NOT NULL,
@@ -56,32 +56,32 @@ export class SettingsDb extends DbStorage {
return (await this.getServers()).find(x => x.id === id);
}
- async addServer(server: ServerSettings): Promise {
- await this.executeSql(`
- INSERT INTO servers (id, address, username, token, salt)
- VALUES (?, ?, ?, ?, ?);
- `, [server.id, server.address, server.username, server.token, server.salt]);
- }
+ // async addServer(server: ServerSettings): Promise {
+ // await this.executeSql(`
+ // INSERT INTO servers (id, address, username, token, salt)
+ // VALUES (?, ?, ?, ?, ?);
+ // `, [server.id, server.address, server.username, server.token, server.salt]);
+ // }
- async removeServer(id: string): Promise {
- await this.executeSql(`
- DELETE FROM servers
- WHERE id = ?;
- `, [id]);
- }
+ // async removeServer(id: string): Promise {
+ // await this.executeSql(`
+ // DELETE FROM servers
+ // WHERE id = ?;
+ // `, [id]);
+ // }
- async updateServer(server: ServerSettings): Promise {
- await this.executeSql(`
- UPDATE servers SET
- address = ?,
- username = ?,
- token = ?,
- salt = ?
- WHERE id = ?;
- `, [
- server.address, server.username, server.token, server.salt,
- server.id,
- ]);
+ async updateServers(servers: ServerSettings[]): Promise {
+ await this.transaction((tx) => {
+ tx.executeSql(`
+ DELETE FROM servers
+ `);
+ for (const s of servers) {
+ tx.executeSql(`
+ INSERT INTO servers (id, address, username, token, salt)
+ VALUES (?, ?, ?, ?, ?);
+ `, [s.id, s.address, s.username, s.token, s.salt]);
+ }
+ });
}
async getApp(): Promise {