diff --git a/android/app/src/main/assets/fonts/Ubuntu-Bold.ttf b/android/app/src/main/assets/fonts/Ubuntu-Bold.ttf new file mode 100644 index 0000000..4af149a Binary files /dev/null and b/android/app/src/main/assets/fonts/Ubuntu-Bold.ttf differ diff --git a/android/app/src/main/assets/fonts/Ubuntu-BoldItalic.ttf b/android/app/src/main/assets/fonts/Ubuntu-BoldItalic.ttf new file mode 100644 index 0000000..a68afb6 Binary files /dev/null and b/android/app/src/main/assets/fonts/Ubuntu-BoldItalic.ttf differ diff --git a/android/app/src/main/assets/fonts/Ubuntu-Italic.ttf b/android/app/src/main/assets/fonts/Ubuntu-Italic.ttf new file mode 100644 index 0000000..b022726 Binary files /dev/null and b/android/app/src/main/assets/fonts/Ubuntu-Italic.ttf differ diff --git a/android/app/src/main/assets/fonts/Ubuntu-Light.ttf b/android/app/src/main/assets/fonts/Ubuntu-Light.ttf new file mode 100644 index 0000000..0e9f90d Binary files /dev/null and b/android/app/src/main/assets/fonts/Ubuntu-Light.ttf differ diff --git a/android/app/src/main/assets/fonts/Ubuntu-LightItalic.ttf b/android/app/src/main/assets/fonts/Ubuntu-LightItalic.ttf new file mode 100644 index 0000000..2e007de Binary files /dev/null and b/android/app/src/main/assets/fonts/Ubuntu-LightItalic.ttf differ diff --git a/android/app/src/main/assets/fonts/Ubuntu-Medium.ttf b/android/app/src/main/assets/fonts/Ubuntu-Medium.ttf new file mode 100644 index 0000000..5296045 Binary files /dev/null and b/android/app/src/main/assets/fonts/Ubuntu-Medium.ttf differ diff --git a/android/app/src/main/assets/fonts/Ubuntu-MediumItalic.ttf b/android/app/src/main/assets/fonts/Ubuntu-MediumItalic.ttf new file mode 100644 index 0000000..5dc193d Binary files /dev/null and b/android/app/src/main/assets/fonts/Ubuntu-MediumItalic.ttf differ diff --git a/android/app/src/main/assets/fonts/Ubuntu-Regular.ttf b/android/app/src/main/assets/fonts/Ubuntu-Regular.ttf new file mode 100644 index 0000000..dbb834a Binary files /dev/null and b/android/app/src/main/assets/fonts/Ubuntu-Regular.ttf differ diff --git a/assets/fonts/Ubuntu-Bold.ttf b/assets/fonts/Ubuntu-Bold.ttf new file mode 100644 index 0000000..4af149a Binary files /dev/null and b/assets/fonts/Ubuntu-Bold.ttf differ diff --git a/assets/fonts/Ubuntu-BoldItalic.ttf b/assets/fonts/Ubuntu-BoldItalic.ttf new file mode 100644 index 0000000..a68afb6 Binary files /dev/null and b/assets/fonts/Ubuntu-BoldItalic.ttf differ diff --git a/assets/fonts/Ubuntu-Italic.ttf b/assets/fonts/Ubuntu-Italic.ttf new file mode 100644 index 0000000..b022726 Binary files /dev/null and b/assets/fonts/Ubuntu-Italic.ttf differ diff --git a/assets/fonts/Ubuntu-Light.ttf b/assets/fonts/Ubuntu-Light.ttf new file mode 100644 index 0000000..0e9f90d Binary files /dev/null and b/assets/fonts/Ubuntu-Light.ttf differ diff --git a/assets/fonts/Ubuntu-LightItalic.ttf b/assets/fonts/Ubuntu-LightItalic.ttf new file mode 100644 index 0000000..2e007de Binary files /dev/null and b/assets/fonts/Ubuntu-LightItalic.ttf differ diff --git a/assets/fonts/Ubuntu-Medium.ttf b/assets/fonts/Ubuntu-Medium.ttf new file mode 100644 index 0000000..5296045 Binary files /dev/null and b/assets/fonts/Ubuntu-Medium.ttf differ diff --git a/assets/fonts/Ubuntu-MediumItalic.ttf b/assets/fonts/Ubuntu-MediumItalic.ttf new file mode 100644 index 0000000..5dc193d Binary files /dev/null and b/assets/fonts/Ubuntu-MediumItalic.ttf differ diff --git a/assets/fonts/Ubuntu-Regular.ttf b/assets/fonts/Ubuntu-Regular.ttf new file mode 100644 index 0000000..dbb834a Binary files /dev/null and b/assets/fonts/Ubuntu-Regular.ttf differ diff --git a/ios/SubSonify.xcodeproj/project.pbxproj b/ios/SubSonify.xcodeproj/project.pbxproj index b2f91bb..4ae4150 100644 --- a/ios/SubSonify.xcodeproj/project.pbxproj +++ b/ios/SubSonify.xcodeproj/project.pbxproj @@ -22,6 +22,14 @@ 496B4B9B91BC401DB51B3EC8 /* Lato-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = F4F4A1F14BEF4BFAA4E8820C /* Lato-Regular.ttf */; }; 65CF38EF987D48FE87417D95 /* Lato-Thin.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 02B784765C954771AFD3D736 /* Lato-Thin.ttf */; }; 14DD6760CD4745C5BE5F4BE8 /* Lato-ThinItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 88AF24D136144BE4866DE912 /* Lato-ThinItalic.ttf */; }; + FE9FA81B39A64124AED77EA4 /* Ubuntu-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = E4F99098BF914E1A931626C4 /* Ubuntu-Bold.ttf */; }; + BD8F136628F04F9DB5C97EAA /* Ubuntu-BoldItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 63EFC089F68F4855AAD51042 /* Ubuntu-BoldItalic.ttf */; }; + 34B5978651964F458F13B159 /* Ubuntu-Italic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 9AB4011E8C8D457C96C60260 /* Ubuntu-Italic.ttf */; }; + 1FAA1C3FB1E3484A9BC95DEA /* Ubuntu-Light.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 0453473C29104FFE89072356 /* Ubuntu-Light.ttf */; }; + D27F67A28A5F4FB49E94D881 /* Ubuntu-LightItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = B95CE032E2AD4CF296A08240 /* Ubuntu-LightItalic.ttf */; }; + C775139A328B487880547BF7 /* Ubuntu-Medium.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 54F543DA45B14889BB58F889 /* Ubuntu-Medium.ttf */; }; + 7156B9E946AD49D8A71B576A /* Ubuntu-MediumItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = F6F917F33913423F90E92389 /* Ubuntu-MediumItalic.ttf */; }; + D26C3BD0DD4A46A19FC194A7 /* Ubuntu-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 9C7D70BCA0BC439CAC9BD94B /* Ubuntu-Regular.ttf */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -114,6 +122,14 @@ F4F4A1F14BEF4BFAA4E8820C /* Lato-Regular.ttf */ = {isa = PBXFileReference; name = "Lato-Regular.ttf"; path = "../assets/fonts/Lato-Regular.ttf"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; 02B784765C954771AFD3D736 /* Lato-Thin.ttf */ = {isa = PBXFileReference; name = "Lato-Thin.ttf"; path = "../assets/fonts/Lato-Thin.ttf"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; 88AF24D136144BE4866DE912 /* Lato-ThinItalic.ttf */ = {isa = PBXFileReference; name = "Lato-ThinItalic.ttf"; path = "../assets/fonts/Lato-ThinItalic.ttf"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; + E4F99098BF914E1A931626C4 /* Ubuntu-Bold.ttf */ = {isa = PBXFileReference; name = "Ubuntu-Bold.ttf"; path = "../assets/fonts/Ubuntu-Bold.ttf"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; + 63EFC089F68F4855AAD51042 /* Ubuntu-BoldItalic.ttf */ = {isa = PBXFileReference; name = "Ubuntu-BoldItalic.ttf"; path = "../assets/fonts/Ubuntu-BoldItalic.ttf"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; + 9AB4011E8C8D457C96C60260 /* Ubuntu-Italic.ttf */ = {isa = PBXFileReference; name = "Ubuntu-Italic.ttf"; path = "../assets/fonts/Ubuntu-Italic.ttf"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; + 0453473C29104FFE89072356 /* Ubuntu-Light.ttf */ = {isa = PBXFileReference; name = "Ubuntu-Light.ttf"; path = "../assets/fonts/Ubuntu-Light.ttf"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; + B95CE032E2AD4CF296A08240 /* Ubuntu-LightItalic.ttf */ = {isa = PBXFileReference; name = "Ubuntu-LightItalic.ttf"; path = "../assets/fonts/Ubuntu-LightItalic.ttf"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; + 54F543DA45B14889BB58F889 /* Ubuntu-Medium.ttf */ = {isa = PBXFileReference; name = "Ubuntu-Medium.ttf"; path = "../assets/fonts/Ubuntu-Medium.ttf"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; + F6F917F33913423F90E92389 /* Ubuntu-MediumItalic.ttf */ = {isa = PBXFileReference; name = "Ubuntu-MediumItalic.ttf"; path = "../assets/fonts/Ubuntu-MediumItalic.ttf"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; + 9C7D70BCA0BC439CAC9BD94B /* Ubuntu-Regular.ttf */ = {isa = PBXFileReference; name = "Ubuntu-Regular.ttf"; path = "../assets/fonts/Ubuntu-Regular.ttf"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -274,6 +290,14 @@ F4F4A1F14BEF4BFAA4E8820C /* Lato-Regular.ttf */, 02B784765C954771AFD3D736 /* Lato-Thin.ttf */, 88AF24D136144BE4866DE912 /* Lato-ThinItalic.ttf */, + E4F99098BF914E1A931626C4 /* Ubuntu-Bold.ttf */, + 63EFC089F68F4855AAD51042 /* Ubuntu-BoldItalic.ttf */, + 9AB4011E8C8D457C96C60260 /* Ubuntu-Italic.ttf */, + 0453473C29104FFE89072356 /* Ubuntu-Light.ttf */, + B95CE032E2AD4CF296A08240 /* Ubuntu-LightItalic.ttf */, + 54F543DA45B14889BB58F889 /* Ubuntu-Medium.ttf */, + F6F917F33913423F90E92389 /* Ubuntu-MediumItalic.ttf */, + 9C7D70BCA0BC439CAC9BD94B /* Ubuntu-Regular.ttf */, ); name = Resources; sourceTree = ""; @@ -437,6 +461,14 @@ 496B4B9B91BC401DB51B3EC8 /* Lato-Regular.ttf in Resources */, 65CF38EF987D48FE87417D95 /* Lato-Thin.ttf in Resources */, 14DD6760CD4745C5BE5F4BE8 /* Lato-ThinItalic.ttf in Resources */, + FE9FA81B39A64124AED77EA4 /* Ubuntu-Bold.ttf in Resources */, + BD8F136628F04F9DB5C97EAA /* Ubuntu-BoldItalic.ttf in Resources */, + 34B5978651964F458F13B159 /* Ubuntu-Italic.ttf in Resources */, + 1FAA1C3FB1E3484A9BC95DEA /* Ubuntu-Light.ttf in Resources */, + D27F67A28A5F4FB49E94D881 /* Ubuntu-LightItalic.ttf in Resources */, + C775139A328B487880547BF7 /* Ubuntu-Medium.ttf in Resources */, + 7156B9E946AD49D8A71B576A /* Ubuntu-MediumItalic.ttf in Resources */, + D26C3BD0DD4A46A19FC194A7 /* Ubuntu-Regular.ttf in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/ios/SubSonify/Info.plist b/ios/SubSonify/Info.plist index 15a236f..29a3f17 100644 --- a/ios/SubSonify/Info.plist +++ b/ios/SubSonify/Info.plist @@ -63,6 +63,14 @@ Lato-Regular.ttf Lato-Thin.ttf Lato-ThinItalic.ttf + Ubuntu-Bold.ttf + Ubuntu-BoldItalic.ttf + Ubuntu-Italic.ttf + Ubuntu-Light.ttf + Ubuntu-LightItalic.ttf + Ubuntu-Medium.ttf + Ubuntu-MediumItalic.ttf + Ubuntu-Regular.ttf diff --git a/package-lock.json b/package-lock.json index 0325052..b644c8d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,6 +18,7 @@ "react-native": "0.64.1", "react-native-gesture-handler": "^1.10.3", "react-native-get-random-values": "^1.7.0", + "react-native-linear-gradient": "^2.5.6", "react-native-reanimated": "^2.2.0", "react-native-safe-area-context": "^3.2.0", "react-native-screens": "^3.4.0", @@ -10949,6 +10950,14 @@ "react-native": ">=0.42.0" } }, + "node_modules/react-native-linear-gradient": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/react-native-linear-gradient/-/react-native-linear-gradient-2.5.6.tgz", + "integrity": "sha512-HDwEaXcQIuXXCV70O+bK1rizFong3wj+5Q/jSyifKFLg0VWF95xh8XQgfzXwtq0NggL9vNjPKXa016KuFu+VFg==", + "peerDependencies": { + "react-native": ">=0.55" + } + }, "node_modules/react-native-reanimated": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-2.2.0.tgz", @@ -22076,6 +22085,12 @@ "integrity": "sha512-HOf0jzRnq2/aFUcdCJ9w9JGzN3gdEg0zFE4FyYlp4jtidqU03D5X7ZegGKfT1EWteR0gPBGp9ye5T5FvSWi9Yg==", "requires": {} }, + "react-native-linear-gradient": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/react-native-linear-gradient/-/react-native-linear-gradient-2.5.6.tgz", + "integrity": "sha512-HDwEaXcQIuXXCV70O+bK1rizFong3wj+5Q/jSyifKFLg0VWF95xh8XQgfzXwtq0NggL9vNjPKXa016KuFu+VFg==", + "requires": {} + }, "react-native-reanimated": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-2.2.0.tgz", diff --git a/package.json b/package.json index f98d517..369ece4 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "react-native": "0.64.1", "react-native-gesture-handler": "^1.10.3", "react-native-get-random-values": "^1.7.0", + "react-native-linear-gradient": "^2.5.6", "react-native-reanimated": "^2.2.0", "react-native-safe-area-context": "^3.2.0", "react-native-screens": "^3.4.0", diff --git a/src/components/FocusableIcon.tsx b/src/components/FocusableIcon.tsx index aa1cf60..b7365ad 100644 --- a/src/components/FocusableIcon.tsx +++ b/src/components/FocusableIcon.tsx @@ -1,5 +1,6 @@ import React from 'react'; import { Image, ImageSourcePropType } from 'react-native'; +import { primary } from '../styles/colors'; export type FocusableIconProps = { focused: boolean, @@ -11,12 +12,16 @@ export type FocusableIconProps = { const FocusableIcon: React.FC = (props) => { props.focusedSource = props.focusedSource || props.source; - props.width = props.width || 32; - props.height = props.height || 32; + props.width = props.width || 26; + props.height = props.height || 26; return ( ); diff --git a/src/components/Library.tsx b/src/components/Library.tsx index 3746fca..7efcf92 100644 --- a/src/components/Library.tsx +++ b/src/components/Library.tsx @@ -1,63 +1,144 @@ -import React from 'react'; -import { Text, View, Image } from 'react-native'; -import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs'; +import React, { ReactComponentElement } from 'react'; +import { Text, View, Image, FlatList } from 'react-native'; +import { createMaterialTopTabNavigator, MaterialTopTabBarProps } from '@react-navigation/material-top-tabs'; import { NavigationContainer } from '@react-navigation/native'; +import { Artist } from '../models/music'; +import { useRecoilValue } from 'recoil'; +import { artistsState } from '../state/artists'; +import LinearGradient from 'react-native-linear-gradient'; +import { primary } from '../styles/colors'; +import text from '../styles/text'; -const SectionHeader: React.FC<{ title: string }> = ({ title }) => { +const TabView: React.FC<{}> = ({ children }) => ( + + {children} + +); + +const Albums = () => ( + + +); +const Playlists = () => ( + + +); + +const ArtistItem: React.FC<{ item: Artist } > = ({ item }) => ( + + + {item.name} + +); + +const Artists = () => { + const artists = useRecoilValue(artistsState); + + const renderItem: React.FC<{ item: Artist }> = ({ item }) => ( + + ); + + return ( + + item.id} + /> + + ); +} + +const TabBar: React.FC = ({ state, descriptors }) => { return ( - {title} - + {state.routes.map((route, index) => { + const { options } = descriptors[route.key]; + const label = + options.tabBarLabel !== undefined + ? options.tabBarLabel + : options.title !== undefined + ? options.title + : route.name; + + const isFocused = state.index === index; + const fontFamily = isFocused ? 'Ubuntu-Regular' : 'Ubuntu-Light'; + const color = isFocused ? primary.focused : primary.blurred; + const borderBottomColor = isFocused ? primary.focused : '#383838'; + + return ( + + {label} + + ); + })} ); } const Tab = createMaterialTopTabNavigator(); -const Albums = () => ( - -); -const Artists = () => ( - -); -const Playlists = () => ( - -); - const Library = () => ( - - - - - + + + + + + + ); export default Library; diff --git a/src/components/TabNavigator.tsx b/src/components/TabNavigator.tsx index 0447a18..609f34f 100644 --- a/src/components/TabNavigator.tsx +++ b/src/components/TabNavigator.tsx @@ -10,7 +10,15 @@ const Tab = createBottomTabNavigator(); const TabNavigator = () => { return ( - + ({ + key: 'albumsState', + default: selector({ + key: 'albumsState/default', + get: () => musicDb.getAlbums(), + }), + effects_UNSTABLE: [ + ({ onSet }) => { + onSet((newValue) => { + if (!(newValue instanceof DefaultValue)) { + musicDb.updateAlbums(newValue); + } + }); + } + ], +}); + +// export const useUpdateAlbums = () => { +// const setAlbums = useSetRecoilState(albumsState); +// 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.getAlbums(); + +// setAlbums(response.data.albums.map(i => ({ +// id: i.id, +// name: i.name, +// }))); +// }; +// }; diff --git a/src/state/artists.ts b/src/state/artists.ts index 02c5bea..f88cb31 100644 --- a/src/state/artists.ts +++ b/src/state/artists.ts @@ -33,9 +33,10 @@ export const useUpdateArtists = () => { const client = new SubsonicApiClient(server.address, server.username, server.token, server.salt); const response = await client.getArtists(); - setArtists(response.data.artists.map(i => ({ - id: i.id, - name: i.name, + setArtists(response.data.artists.map(x => ({ + id: x.id, + name: x.name, + coverArt: x.coverArt, }))); }; }; diff --git a/src/storage/music.ts b/src/storage/music.ts index b5b1609..b5f88e0 100644 --- a/src/storage/music.ts +++ b/src/storage/music.ts @@ -1,4 +1,4 @@ -import { Artist } from '../models/music'; +import { Album, Artist } from '../models/music'; import { DbStorage } from './db'; export class MusicDb extends DbStorage { @@ -10,6 +10,14 @@ export class MusicDb extends DbStorage { await this.initDb(tx => { tx.executeSql(` CREATE TABLE artists ( + id TEXT PRIMARY KEY NOT NULL, + name TEXT NOT NULL, + starred INTEGER NOT NULL, + coverArt TEXT + ); + `); + tx.executeSql(` + CREATE TABLE albums ( id TEXT PRIMARY KEY NOT NULL, name TEXT NOT NULL, starred INTEGER NOT NULL @@ -24,6 +32,7 @@ export class MusicDb extends DbStorage { `))[0].rows.raw().map(x => ({ id: x.id, name: x.name, + coverArt: x.coverArt || undefined, })); } @@ -34,7 +43,30 @@ export class MusicDb extends DbStorage { `); for (const a of artists) { tx.executeSql(` - INSERT INTO artists (id, name, starred) + INSERT INTO artists (id, name, starred, coverArt) + VALUES (?, ?, ?, ?); + `, [a.id, a.name, false, a.coverArt || null]); + } + }); + } + + async getAlbums(): Promise { + return (await this.executeSql(` + SELECT * FROM albums; + `))[0].rows.raw().map(x => ({ + id: x.id, + name: x.name, + })); + } + + async updateAlbums(albums: Album[]): Promise { + await this.transaction((tx) => { + tx.executeSql(` + DELETE FROM albums + `); + for (const a of albums) { + tx.executeSql(` + INSERT INTO albums (id, name, starred) VALUES (?, ?, ?); `, [a.id, a.name, false]); } diff --git a/src/styles/colors.ts b/src/styles/colors.ts new file mode 100644 index 0000000..a8c2b1b --- /dev/null +++ b/src/styles/colors.ts @@ -0,0 +1,6 @@ +import { StyleSheet } from "react-native"; + +export const primary = { + focused: '#fff', + blurred: '#bababa', +} diff --git a/src/styles/text.ts b/src/styles/text.ts new file mode 100644 index 0000000..98fe548 --- /dev/null +++ b/src/styles/text.ts @@ -0,0 +1,21 @@ +import { StyleSheet, TextStyle } from "react-native"; + +const regular: TextStyle = { + fontFamily: 'Ubuntu-Light', + fontSize: 18, + color: '#fff', +}; + +const header: TextStyle = { + ...regular, + fontSize: 22, +}; + +export type TextStyles = { + [key: string]: TextStyle, +} + +export default { + regular, + header, +};