basic tab navigation

other things
This commit is contained in:
austinried 2021-06-18 13:00:12 +09:00
parent de5b479c47
commit 0f1e10d50f
16 changed files with 912 additions and 59 deletions

71
App.tsx
View File

@ -1,10 +1,79 @@
import React from 'react'; 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 { RecoilRoot } from 'recoil';
import SettingsView from './src/components/Settings'; 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 }) => (
<Image
style={{
height: 32,
width: 32,
}}
source={focused ? require('./res/settings-fill.png') : require('./res/settings.png')} />
);
const NowPlayingIcon: React.FC<{ focused: boolean }> = ({ focused }) => (
<Image
style={{
height: 32,
width: 32,
}}
source={focused ? require('./res/music_notes-fill.png') : require('./res/music_notes.png')} />
);
const ArtistsIcon: React.FC<{ focused: boolean }> = ({ focused }) => (
<Image
style={{
height: 32,
width: 32,
}}
source={focused ? require('./res/mic_on-fill.png') : require('./res/mic_on.png')} />
);
const Tab = createBottomTabNavigator();
const App = () => ( const App = () => (
<RecoilRoot> <RecoilRoot>
<SettingsView /> <NavigationContainer>
<Tab.Navigator>
<Tab.Screen
name='Settings'
component={SettingsView}
options={{
tabBarIcon: SettingsIcon,
}}
/>
<Tab.Screen
name='Artists'
component={ArtistsList}
options={{
tabBarIcon: ArtistsIcon,
tabBarVisibilityAnimationConfig: {
show: {
animation: 'spring',
},
hide: {
animation: 'spring',
}
}
}}
/>
<Tab.Screen
name='Now Playing'
component={NowPlayingLayout}
options={{
tabBarIcon: NowPlayingIcon,
}}
/>
</Tab.Navigator>
</NavigationContainer>
</RecoilRoot> </RecoilRoot>
); );

View File

@ -1,3 +1,6 @@
import 'react-native-gesture-handler';
import 'react-native-get-random-values';
import { AppRegistry, LogBox } from 'react-native'; import { AppRegistry, LogBox } from 'react-native';
// ignore recoil's timer warning on android: // ignore recoil's timer warning on android:

677
package-lock.json generated
View File

@ -8,11 +8,21 @@
"name": "subsonify", "name": "subsonify",
"version": "0.0.1", "version": "0.0.1",
"dependencies": { "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", "md5": "^2.3.0",
"react": "17.0.1", "react": "17.0.1",
"react-native": "0.64.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", "react-native-sqlite-storage": "^5.0.0",
"recoil": "^0.3.1", "recoil": "^0.3.1",
"uuid": "^8.3.2",
"xmldom": "^0.5.0" "xmldom": "^0.5.0"
}, },
"devDependencies": { "devDependencies": {
@ -24,6 +34,7 @@
"@types/react-native": "^0.64.5", "@types/react-native": "^0.64.5",
"@types/react-native-sqlite-storage": "^5.0.0", "@types/react-native-sqlite-storage": "^5.0.0",
"@types/react-test-renderer": "^16.9.2", "@types/react-test-renderer": "^16.9.2",
"@types/uuid": "^8.3.0",
"@types/xmldom": "^0.1.30", "@types/xmldom": "^0.1.30",
"babel-jest": "^26.6.3", "babel-jest": "^26.6.3",
"eslint": "^7.14.0", "eslint": "^7.14.0",
@ -1504,6 +1515,17 @@
"node": ">=0.1.95" "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": { "node_modules/@eslint/eslintrc": {
"version": "0.4.2", "version": "0.4.2",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.2.tgz", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.2.tgz",
@ -2925,6 +2947,15 @@
"integrity": "sha512-W/J0fNYVO01tioHjvYWQ9m6RgndVtbElzYozBq1ZPrHO/iCzlqoySHl4gO/fpCl9QEFjvJfjPgtPMTMlsoq5DQ==", "integrity": "sha512-W/J0fNYVO01tioHjvYWQ9m6RgndVtbElzYozBq1ZPrHO/iCzlqoySHl4gO/fpCl9QEFjvJfjPgtPMTMlsoq5DQ==",
"dev": true "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": { "node_modules/@react-native/assets": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/@react-native/assets/-/assets-1.0.0.tgz", "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", "resolved": "https://registry.npmjs.org/@react-native/polyfills/-/polyfills-1.0.0.tgz",
"integrity": "sha512-0jbp4RxjYopTsIdLl+/Fy2TiwVYHy4mgeu07DG4b/LyM0OS/+lPP5c9sbnt/AMlnF6qz2JRZpPpGw1eMNS6A4w==" "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": { "node_modules/@sideway/address": {
"version": "4.1.2", "version": "4.1.2",
"resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.2.tgz", "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.2.tgz",
@ -3040,6 +3169,11 @@
"@types/node": "*" "@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": { "node_modules/@types/istanbul-lib-coverage": {
"version": "2.0.3", "version": "2.0.3",
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", "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==", "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==",
"dev": true "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": { "node_modules/@types/xmldom": {
"version": "0.1.30", "version": "0.1.30",
"resolved": "https://registry.npmjs.org/@types/xmldom/-/xmldom-0.1.30.tgz", "resolved": "https://registry.npmjs.org/@types/xmldom/-/xmldom-0.1.30.tgz",
@ -4439,6 +4579,15 @@
"node": ">=0.10.0" "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": { "node_modules/color-convert": {
"version": "1.9.3", "version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "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", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" "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": { "node_modules/colorette": {
"version": "1.2.2", "version": "1.2.2",
"resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz",
@ -4646,6 +4804,14 @@
"node": ">=4" "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": { "node_modules/cross-spawn": {
"version": "7.0.3", "version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
@ -5909,6 +6075,11 @@
"node": ">=0.10.0" "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": { "node_modules/fast-deep-equal": {
"version": "3.1.3", "version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
@ -5941,6 +6112,33 @@
"bser": "2.1.1" "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": { "node_modules/file-entry-cache": {
"version": "6.0.1", "version": "6.0.1",
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
@ -5964,6 +6162,14 @@
"node": ">=8" "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": { "node_modules/finalhandler": {
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
@ -6449,6 +6655,19 @@
"node": ">= 8" "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": { "node_modules/hosted-git-info": {
"version": "2.8.9", "version": "2.8.9",
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
@ -9699,11 +9918,27 @@
"mkdirp": "bin/cmd.js" "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": { "node_modules/ms": {
"version": "2.1.2", "version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" "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": { "node_modules/nanomatch": {
"version": "1.2.13", "version": "1.2.13",
"resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
@ -10556,6 +10791,23 @@
"node": ">=6" "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": { "node_modules/range-parser": {
"version": "1.2.1", "version": "1.2.1",
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
@ -10648,6 +10900,74 @@
"nullthrows": "^1.1.1" "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": { "node_modules/react-native-sqlite-storage": {
"version": "5.0.0", "version": "5.0.0",
"resolved": "https://registry.npmjs.org/react-native-sqlite-storage/-/react-native-sqlite-storage-5.0.0.tgz", "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": ">=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": { "node_modules/setprototypeof": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
@ -11623,6 +11948,19 @@
"plist": "^3.0.1" "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": { "node_modules/sisteransi": {
"version": "1.0.5", "version": "1.0.5",
"resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
@ -11895,6 +12233,14 @@
"integrity": "sha512-Ki212dKK4ogX+xDo4CtOZBVIwhsKBEfsEEcwmJfLQzirgc2jIWdzg40Unxz/HzEUqM1WFzVlQSMF9kZZ2HboLQ==", "integrity": "sha512-Ki212dKK4ogX+xDo4CtOZBVIwhsKBEfsEEcwmJfLQzirgc2jIWdzg40Unxz/HzEUqM1WFzVlQSMF9kZZ2HboLQ==",
"dev": true "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": { "node_modules/split-string": {
"version": "3.1.0", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
@ -12060,6 +12406,14 @@
"node": ">= 0.10.0" "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": { "node_modules/string_decoder": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
@ -12068,6 +12422,11 @@
"safe-buffer": "~5.1.0" "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": { "node_modules/string-length": {
"version": "4.0.2", "version": "4.0.2",
"resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz",
@ -12604,6 +12963,24 @@
"node": ">=4.2.0" "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": { "node_modules/uglify-es": {
"version": "3.3.9", "version": "3.3.9",
"resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.9.tgz", "resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.9.tgz",
@ -12822,8 +13199,6 @@
"version": "8.3.2", "version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
"dev": true,
"optional": true,
"bin": { "bin": {
"uuid": "dist/bin/uuid" "uuid": "dist/bin/uuid"
} }
@ -12909,6 +13284,11 @@
"makeerror": "1.0.x" "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": { "node_modules/wcwidth": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz",
@ -14383,6 +14763,14 @@
"minimist": "^1.2.0" "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": { "@eslint/eslintrc": {
"version": "0.4.2", "version": "0.4.2",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.2.tgz", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.2.tgz",
@ -15488,6 +15876,12 @@
"integrity": "sha512-W/J0fNYVO01tioHjvYWQ9m6RgndVtbElzYozBq1ZPrHO/iCzlqoySHl4gO/fpCl9QEFjvJfjPgtPMTMlsoq5DQ==", "integrity": "sha512-W/J0fNYVO01tioHjvYWQ9m6RgndVtbElzYozBq1ZPrHO/iCzlqoySHl4gO/fpCl9QEFjvJfjPgtPMTMlsoq5DQ==",
"dev": true "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": { "@react-native/assets": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/@react-native/assets/-/assets-1.0.0.tgz", "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", "resolved": "https://registry.npmjs.org/@react-native/polyfills/-/polyfills-1.0.0.tgz",
"integrity": "sha512-0jbp4RxjYopTsIdLl+/Fy2TiwVYHy4mgeu07DG4b/LyM0OS/+lPP5c9sbnt/AMlnF6qz2JRZpPpGw1eMNS6A4w==" "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": { "@sideway/address": {
"version": "4.1.2", "version": "4.1.2",
"resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.2.tgz", "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.2.tgz",
@ -15600,6 +16061,11 @@
"@types/node": "*" "@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": { "@types/istanbul-lib-coverage": {
"version": "2.0.3", "version": "2.0.3",
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", "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==", "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==",
"dev": true "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": { "@types/xmldom": {
"version": "0.1.30", "version": "0.1.30",
"resolved": "https://registry.npmjs.org/@types/xmldom/-/xmldom-0.1.30.tgz", "resolved": "https://registry.npmjs.org/@types/xmldom/-/xmldom-0.1.30.tgz",
@ -16665,6 +17137,15 @@
"object-visit": "^1.0.0" "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": { "color-convert": {
"version": "1.9.3", "version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "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", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" "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": { "colorette": {
"version": "1.2.2", "version": "1.2.2",
"resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", "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": { "cross-spawn": {
"version": "7.0.3", "version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "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": { "fast-deep-equal": {
"version": "3.1.3", "version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
@ -17820,6 +18323,35 @@
"bser": "2.1.1" "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": { "file-entry-cache": {
"version": "6.0.1", "version": "6.0.1",
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", "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" "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": { "finalhandler": {
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", "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": { "hosted-git-info": {
"version": "2.8.9", "version": "2.8.9",
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
@ -20709,11 +21261,21 @@
"minimist": "^1.2.5" "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": { "ms": {
"version": "2.1.2", "version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" "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": { "nanomatch": {
"version": "1.2.13", "version": "1.2.13",
"resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
@ -21353,6 +21915,17 @@
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
"dev": true "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": { "range-parser": {
"version": "1.2.1", "version": "1.2.1",
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
@ -21440,6 +22013,57 @@
"nullthrows": "^1.1.1" "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": { "react-native-sqlite-storage": {
"version": "5.0.0", "version": "5.0.0",
"resolved": "https://registry.npmjs.org/react-native-sqlite-storage/-/react-native-sqlite-storage-5.0.0.tgz", "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": { "setprototypeof": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
@ -22195,6 +22824,21 @@
"plist": "^3.0.1" "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": { "sisteransi": {
"version": "1.0.5", "version": "1.0.5",
"resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
@ -22425,6 +23069,11 @@
"integrity": "sha512-Ki212dKK4ogX+xDo4CtOZBVIwhsKBEfsEEcwmJfLQzirgc2jIWdzg40Unxz/HzEUqM1WFzVlQSMF9kZZ2HboLQ==", "integrity": "sha512-Ki212dKK4ogX+xDo4CtOZBVIwhsKBEfsEEcwmJfLQzirgc2jIWdzg40Unxz/HzEUqM1WFzVlQSMF9kZZ2HboLQ==",
"dev": true "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": { "split-string": {
"version": "3.1.0", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", "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", "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-2.2.0.tgz",
"integrity": "sha1-kdX1Ew0c75bc+n9yaUUYh0HQnuQ=" "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": { "string_decoder": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
@ -22563,6 +23217,11 @@
"safe-buffer": "~5.1.0" "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": { "string-length": {
"version": "4.0.2", "version": "4.0.2",
"resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", "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==", "integrity": "sha512-kdMjTiekY+z/ubJCATUPlRDl39vXYiMV9iyeMuEuXZh2we6zz80uovNN2WlAxmmdE/Z/YQe+EbOEXB5RHEED3w==",
"dev": true "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": { "uglify-es": {
"version": "3.3.9", "version": "3.3.9",
"resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.9.tgz", "resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.9.tgz",
@ -23137,9 +23801,7 @@
"uuid": { "uuid": {
"version": "8.3.2", "version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
"dev": true,
"optional": true
}, },
"v8-compile-cache": { "v8-compile-cache": {
"version": "2.3.0", "version": "2.3.0",
@ -23212,6 +23874,11 @@
"makeerror": "1.0.x" "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": { "wcwidth": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz",

View File

@ -10,11 +10,21 @@
"lint": "eslint . --ext .js,.jsx,.ts,.tsx" "lint": "eslint . --ext .js,.jsx,.ts,.tsx"
}, },
"dependencies": { "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", "md5": "^2.3.0",
"react": "17.0.1", "react": "17.0.1",
"react-native": "0.64.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", "react-native-sqlite-storage": "^5.0.0",
"recoil": "^0.3.1", "recoil": "^0.3.1",
"uuid": "^8.3.2",
"xmldom": "^0.5.0" "xmldom": "^0.5.0"
}, },
"devDependencies": { "devDependencies": {
@ -26,6 +36,7 @@
"@types/react-native": "^0.64.5", "@types/react-native": "^0.64.5",
"@types/react-native-sqlite-storage": "^5.0.0", "@types/react-native-sqlite-storage": "^5.0.0",
"@types/react-test-renderer": "^16.9.2", "@types/react-test-renderer": "^16.9.2",
"@types/uuid": "^8.3.0",
"@types/xmldom": "^0.1.30", "@types/xmldom": "^0.1.30",
"babel-jest": "^26.6.3", "babel-jest": "^26.6.3",
"eslint": "^7.14.0", "eslint": "^7.14.0",

BIN
res/mic_on-fill.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

BIN
res/mic_on.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

BIN
res/music_notes-fill.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

BIN
res/music_notes.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

BIN
res/settings-fill.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

BIN
res/settings.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -1,29 +1,80 @@
import React from 'react'; import React, { useEffect, useState } from 'react';
import { Button, View } from 'react-native'; 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 { 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 () => { const recreateDb = async () => {
try { await musicDb.deleteDb(); } catch {} setInProgress(true);
await musicDb.createDb(); try{
} try { await db.deleteDb(); } catch {}
await db.createDb();
const recreateSettingsDb = async () => { } finally {
try { await settingsDb.deleteDb(); } catch {} setInProgress(false);
await settingsDb.createDb(); }
} }
return (
<Button
title={`Recreate ${title} DB`}
onPress={recreateDb}
disabled={inProgress}
/>
)
}
const DbControls = () => {
return ( return (
<View> <View>
<Button <RecreateDbButton db={musicDb} title='Music' />
title='Recreate Music DB' <RecreateDbButton db={settingsDb} title='Settings' />
onPress={recreateMusicDb} </View>
/> );
<Button }
title='Recreate Settings DB'
onPress={recreateSettingsDb} 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 (
<View>
<Button
title='Add default server'
onPress={bootstrapServer}
/> />
{servers.map(s => (
<View key={s.id}>
<Text>{s.address}</Text>
<Text>{s.username}</Text>
</View>
))}
</View> </View>
); );
} }
@ -31,6 +82,9 @@ const DbControls = () => {
const SettingsView = () => ( const SettingsView = () => (
<View> <View>
<DbControls /> <DbControls />
<React.Suspense fallback={<Text>Loading...</Text>}>
<ServerSettingsView />
</React.Suspense>
</View> </View>
) )

View File

@ -1,16 +1,11 @@
import md5 from 'md5'; import md5 from 'md5';
import { atom, selector, useSetRecoilState } from 'recoil'; import { atom, selector, useRecoilValue, useSetRecoilState } from 'recoil';
import { SubsonicApiClient } from '../subsonic/api'; import { SubsonicApiClient } from '../subsonic/api';
import { MusicDb } from '../storage/music'; import { MusicDb } from '../storage/music';
import { activeServer } from './settings'
const db = new MusicDb(); 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 { export interface ArtistState {
id: string; id: string;
name: string; name: string;
@ -37,7 +32,14 @@ export const artistsState = atom<ArtistState[]>({
export const useUpdateArtists = () => { export const useUpdateArtists = () => {
const setArtists = useSetRecoilState(artistsState); const setArtists = useSetRecoilState(artistsState);
const server = useRecoilValue(activeServer);
return async () => { return async () => {
if (!server) {
return;
}
const client = new SubsonicApiClient(server.address, server.username, server.token, server.salt);
const response = await client.getArtists(); const response = await client.getArtists();
setArtists(response.data.artists.map(i => ({ setArtists(response.data.artists.map(i => ({

47
src/state/settings.ts Normal file
View File

@ -0,0 +1,47 @@
import { atom, DefaultValue, selector } from 'recoil';
import { settingsDb } from '../clients';
import { AppSettings, ServerSettings } from '../storage/settings';
export const serversState = atom<ServerSettings[]>({
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<AppSettings>({
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<ServerSettings | undefined>({
key: 'activeServer',
get: ({get}) => {
const appSettings = get(appSettingsState);
const servers = get(serversState);
return servers.find(x => x.id == appSettings.server);
}
});

View File

@ -9,9 +9,9 @@ export abstract class DbStorage {
this.dbParams = dbParams; this.dbParams = dbParams;
} }
// abstract createDb(): Promise<void> abstract createDb(): Promise<void>
protected async createDb(scope: (tx: Transaction) => void): Promise<void> { protected async initDb(scope: (tx: Transaction) => void): Promise<void> {
await this.transaction(tx => { await this.transaction(tx => {
tx.executeSql(` tx.executeSql(`
CREATE TABLE db_version ( CREATE TABLE db_version (

View File

@ -6,7 +6,7 @@ export class MusicDb extends DbStorage {
} }
async createDb(): Promise<void> { async createDb(): Promise<void> {
super.createDb(tx => { await this.initDb(tx => {
tx.executeSql(` tx.executeSql(`
CREATE TABLE artists ( CREATE TABLE artists (
id TEXT PRIMARY KEY NOT NULL, id TEXT PRIMARY KEY NOT NULL,

View File

@ -18,7 +18,7 @@ export class SettingsDb extends DbStorage {
} }
async createDb(): Promise<void> { async createDb(): Promise<void> {
super.createDb(tx => { await this.initDb(tx => {
tx.executeSql(` tx.executeSql(`
CREATE TABLE servers ( CREATE TABLE servers (
id TEXT PRIMARY KEY NOT NULL, id TEXT PRIMARY KEY NOT NULL,
@ -56,32 +56,32 @@ export class SettingsDb extends DbStorage {
return (await this.getServers()).find(x => x.id === id); return (await this.getServers()).find(x => x.id === id);
} }
async addServer(server: ServerSettings): Promise<void> { // async addServer(server: ServerSettings): Promise<void> {
await this.executeSql(` // await this.executeSql(`
INSERT INTO servers (id, address, username, token, salt) // INSERT INTO servers (id, address, username, token, salt)
VALUES (?, ?, ?, ?, ?); // VALUES (?, ?, ?, ?, ?);
`, [server.id, server.address, server.username, server.token, server.salt]); // `, [server.id, server.address, server.username, server.token, server.salt]);
} // }
async removeServer(id: string): Promise<void> { // async removeServer(id: string): Promise<void> {
await this.executeSql(` // await this.executeSql(`
DELETE FROM servers // DELETE FROM servers
WHERE id = ?; // WHERE id = ?;
`, [id]); // `, [id]);
} // }
async updateServer(server: ServerSettings): Promise<void> { async updateServers(servers: ServerSettings[]): Promise<void> {
await this.executeSql(` await this.transaction((tx) => {
UPDATE servers SET tx.executeSql(`
address = ?, DELETE FROM servers
username = ?, `);
token = ?, for (const s of servers) {
salt = ? tx.executeSql(`
WHERE id = ?; INSERT INTO servers (id, address, username, token, salt)
`, [ VALUES (?, ?, ?, ?, ?);
server.address, server.username, server.token, server.salt, `, [s.id, s.address, s.username, s.token, s.salt]);
server.id, }
]); });
} }
async getApp(): Promise<AppSettings> { async getApp(): Promise<AppSettings> {