mirror of
https://github.com/austinried/subtracks.git
synced 2026-03-28 15:22:44 +01:00
basic tab navigation
other things
This commit is contained in:
@@ -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 (
|
||||
<Button
|
||||
title={`Recreate ${title} DB`}
|
||||
onPress={recreateDb}
|
||||
disabled={inProgress}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
const DbControls = () => {
|
||||
return (
|
||||
<View>
|
||||
<Button
|
||||
title='Recreate Music DB'
|
||||
onPress={recreateMusicDb}
|
||||
/>
|
||||
<Button
|
||||
title='Recreate Settings DB'
|
||||
onPress={recreateSettingsDb}
|
||||
<RecreateDbButton db={musicDb} title='Music' />
|
||||
<RecreateDbButton db={settingsDb} title='Settings' />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
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>
|
||||
);
|
||||
}
|
||||
@@ -31,6 +82,9 @@ const DbControls = () => {
|
||||
const SettingsView = () => (
|
||||
<View>
|
||||
<DbControls />
|
||||
<React.Suspense fallback={<Text>Loading...</Text>}>
|
||||
<ServerSettingsView />
|
||||
</React.Suspense>
|
||||
</View>
|
||||
)
|
||||
|
||||
|
||||
@@ -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<ArtistState[]>({
|
||||
|
||||
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 => ({
|
||||
|
||||
47
src/state/settings.ts
Normal file
47
src/state/settings.ts
Normal 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);
|
||||
}
|
||||
});
|
||||
@@ -9,9 +9,9 @@ export abstract class DbStorage {
|
||||
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 => {
|
||||
tx.executeSql(`
|
||||
CREATE TABLE db_version (
|
||||
|
||||
@@ -6,7 +6,7 @@ export class MusicDb extends DbStorage {
|
||||
}
|
||||
|
||||
async createDb(): Promise<void> {
|
||||
super.createDb(tx => {
|
||||
await this.initDb(tx => {
|
||||
tx.executeSql(`
|
||||
CREATE TABLE artists (
|
||||
id TEXT PRIMARY KEY NOT NULL,
|
||||
|
||||
@@ -18,7 +18,7 @@ export class SettingsDb extends DbStorage {
|
||||
}
|
||||
|
||||
async createDb(): Promise<void> {
|
||||
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<void> {
|
||||
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<void> {
|
||||
// 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<void> {
|
||||
await this.executeSql(`
|
||||
DELETE FROM servers
|
||||
WHERE id = ?;
|
||||
`, [id]);
|
||||
}
|
||||
// async removeServer(id: string): Promise<void> {
|
||||
// await this.executeSql(`
|
||||
// DELETE FROM servers
|
||||
// WHERE id = ?;
|
||||
// `, [id]);
|
||||
// }
|
||||
|
||||
async updateServer(server: ServerSettings): Promise<void> {
|
||||
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<void> {
|
||||
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<AppSettings> {
|
||||
|
||||
Reference in New Issue
Block a user