tabs on tabs??

moving storage/model/stuff around
This commit is contained in:
austinried
2021-06-19 11:32:23 +09:00
parent d41fb5b9e7
commit f19cbabac4
34 changed files with 355 additions and 73 deletions

View File

@@ -1,9 +1,10 @@
import React from 'react';
import { Button, FlatList, Text, View } from 'react-native';
import { useRecoilValue, useResetRecoilState } from 'recoil';
import { artistsState, ArtistState, useUpdateArtists } from '../state/artists';
import { artistsState, useUpdateArtists } from '../state/artists';
import { Artist } from '../models/music';
const ArtistItem: React.FC<{ item: ArtistState } > = ({ item }) => (
const ArtistItem: React.FC<{ item: Artist } > = ({ item }) => (
<View>
<Text>{item.id}</Text>
<Text style={{
@@ -16,7 +17,7 @@ const ArtistItem: React.FC<{ item: ArtistState } > = ({ item }) => (
const List = () => {
const artists = useRecoilValue(artistsState);
const renderItem: React.FC<{ item: ArtistState }> = ({ item }) => (
const renderItem: React.FC<{ item: Artist }> = ({ item }) => (
<ArtistItem item={item} />
);

View File

@@ -1,5 +1,7 @@
import React from 'react';
import { Text, View, Image } from 'react-native';
import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';
import { NavigationContainer } from '@react-navigation/native';
const SectionHeader: React.FC<{ title: string }> = ({ title }) => {
return (
@@ -14,9 +16,8 @@ const SectionHeader: React.FC<{ title: string }> = ({ title }) => {
}}>
<Text style={{
color: 'white',
fontSize: 34,
fontWeight: 'normal',
fontFamily: 'Rubik-VariableFont_wght',
fontSize: 22,
fontFamily: 'Lato-Black',
}}>{title}</Text>
<Image
style={{
@@ -24,25 +25,39 @@ const SectionHeader: React.FC<{ title: string }> = ({ title }) => {
height: 32,
tintColor: 'white',
}}
source={require('../../res/chevron_right.png')}
source={require('../../res/chevron_right-fill.png')}
/>
</View>
);
}
const AlbumCoverList = () => {
}
const Tab = createMaterialTopTabNavigator();
const Albums = () => (
<SectionHeader title='Albums' />
);
const Artists = () => (
<SectionHeader title='Artists' />
);
const Playlists = () => (
<SectionHeader title='Playlists' />
);
const Library = () => (
<View style={{
flex: 1,
backgroundColor: '#3b3b3b',
}}>
<SectionHeader title='Albums' />
<SectionHeader title='Artists' />
<SectionHeader title='Playlists' />
</View>
<Tab.Navigator>
<Tab.Screen
name='Albums'
component={Albums}
/>
<Tab.Screen
name='Artists'
component={Artists}
/>
<Tab.Screen
name='Playlists'
component={Playlists}
/>
</Tab.Navigator>
);
export default Library;

4
src/models/music.ts Normal file
View File

@@ -0,0 +1,4 @@
export interface Artist {
id: string;
name: string;
}

11
src/models/settings.ts Normal file
View File

@@ -0,0 +1,11 @@
export interface ServerSettings {
id: string;
address: string;
username: string;
token: string;
salt: string;
}
export interface AppSettings {
server?: string;
}

View File

@@ -1,33 +1,24 @@
import md5 from 'md5';
import { atom, selector, useRecoilValue, useSetRecoilState } from 'recoil';
import { atom, DefaultValue, selector, useRecoilValue, useSetRecoilState } from 'recoil';
import { SubsonicApiClient } from '../subsonic/api';
import { MusicDb } from '../storage/music';
import { activeServer } from './settings'
import { Artist } from '../models/music';
import { musicDb } from '../clients';
const db = new MusicDb();
export interface ArtistState {
id: string;
name: string;
}
export const artistsState = atom<ArtistState[]>({
export const artistsState = atom<Artist[]>({
key: 'artistsState',
default: selector({
key: 'artistsState/default',
get: async () => {
await prepopulate();
const results = await db.executeSql(`
SELECT * FROM artists;
`);
return results[0].rows.raw().map(i => ({
id: i.id,
name: i.name,
}));
},
get: () => musicDb.getArtists(),
}),
effects_UNSTABLE: [
({ onSet }) => {
onSet((newValue) => {
if (!(newValue instanceof DefaultValue)) {
musicDb.updateArtists(newValue);
}
});
}
],
});
export const useUpdateArtists = () => {
@@ -48,20 +39,3 @@ export const useUpdateArtists = () => {
})));
};
};
async function prepopulate() {
try { await db.deleteDb() } catch {}
await db.createDb();
await db.executeSql(`
INSERT INTO artists (id, name, starred)
VALUES (?, ?, ?);
`,
[1, 'good guy', true]
);
await db.executeSql(`
INSERT INTO artists (id, name, starred)
VALUES (?, ?, ?);
`,
[2, 'bad guy', false]
);
}

View File

@@ -1,6 +1,6 @@
import { atom, DefaultValue, selector } from 'recoil';
import { settingsDb } from '../clients';
import { AppSettings, ServerSettings } from '../storage/settings';
import { AppSettings, ServerSettings } from '../models/settings';
export const serversState = atom<ServerSettings[]>({
key: 'serverState',

View File

@@ -1,3 +1,4 @@
import { Artist } from '../models/music';
import { DbStorage } from './db';
export class MusicDb extends DbStorage {
@@ -16,4 +17,27 @@ export class MusicDb extends DbStorage {
`);
});
}
async getArtists(): Promise<Artist[]> {
return (await this.executeSql(`
SELECT * FROM artists;
`))[0].rows.raw().map(x => ({
id: x.id,
name: x.name,
}));
}
async updateArtists(artists: Artist[]): Promise<void> {
await this.transaction((tx) => {
tx.executeSql(`
DELETE FROM artists
`);
for (const a of artists) {
tx.executeSql(`
INSERT INTO artists (id, name, starred)
VALUES (?, ?, ?);
`, [a.id, a.name, false]);
}
});
}
}

View File

@@ -1,17 +1,6 @@
import { AppSettings, ServerSettings } from '../models/settings';
import { DbStorage } from './db';
export interface ServerSettings {
id: string;
address: string;
username: string;
token: string;
salt: string;
}
export interface AppSettings {
server?: string;
}
export class SettingsDb extends DbStorage {
constructor() {
super({ name: 'settings.db', location: 'Library' });