mirror of
https://github.com/Jellify-Music/App.git
synced 2026-04-16 14:33:31 -05:00
setting query client persister, player backend changes to work with MMKV, react navigation theming
This commit is contained in:
15
App.tsx
15
App.tsx
@@ -1,22 +1,25 @@
|
||||
import './gesture-handler';
|
||||
import React from 'react';
|
||||
import "react-native-url-polyfill/auto";
|
||||
|
||||
import { PersistQueryClientProvider } from '@tanstack/react-query-persist-client'
|
||||
import Jellify from './components/jellify';
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||
import { TamaguiProvider, Theme } from 'tamagui';
|
||||
import { ToastProvider } from '@tamagui/toast'
|
||||
import { useColorScheme } from 'react-native';
|
||||
import jellifyConfig from './tamagui.config';
|
||||
import { clientPersister } from './constants/storage';
|
||||
import { queryClient } from './constants/query-client';
|
||||
|
||||
export default function App(): React.JSX.Element {
|
||||
|
||||
const queryClient = new QueryClient();
|
||||
|
||||
const isDarkMode = useColorScheme() === 'dark';
|
||||
|
||||
return (
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<PersistQueryClientProvider
|
||||
client={queryClient}
|
||||
persistOptions={{
|
||||
persister: clientPersister
|
||||
}}>
|
||||
<TamaguiProvider config={jellifyConfig}>
|
||||
<Theme name={isDarkMode ? 'dark' : 'light'}>
|
||||
<ToastProvider
|
||||
@@ -27,6 +30,6 @@ export default function App(): React.JSX.Element {
|
||||
</ToastProvider>
|
||||
</Theme>
|
||||
</TamaguiProvider>
|
||||
</QueryClientProvider>
|
||||
</PersistQueryClientProvider>
|
||||
);
|
||||
}
|
||||
@@ -18,7 +18,7 @@ export default function Artist({ artistId, artistName }: { artistId: string, art
|
||||
|
||||
<FlatList
|
||||
data={albums}
|
||||
numColumns={3} // TODO: Make this adjustable
|
||||
numColumns={2} // TODO: Make this adjustable
|
||||
renderItem={({ item: album }) => {
|
||||
return (
|
||||
<Avatar itemId={album.Id!} subheading={album.Name}>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { ScrollView, YStack } from "tamagui";
|
||||
import _ from "lodash";
|
||||
import { H2, Text } from "../Global/text";
|
||||
import { H2 } from "../Global/text";
|
||||
import RecentlyPlayed from "./helpers/recently-played";
|
||||
import { useApiClientContext } from "../jellyfin-api-provider";
|
||||
import RecentArtists from "./helpers/recent-artists";
|
||||
@@ -10,22 +10,20 @@ import { createNativeStackNavigator } from "@react-navigation/native-stack";
|
||||
import { HomeStackParamList, ProvidedHomeProps } from "./types";
|
||||
import { HomeArtistScreen } from "./screens/artist";
|
||||
import { SafeAreaView } from "react-native-safe-area-context";
|
||||
import { Colors } from "../../enums/colors";
|
||||
|
||||
export const Stack = createNativeStackNavigator<HomeStackParamList>();
|
||||
export const HomeStack = createNativeStackNavigator<HomeStackParamList>();
|
||||
|
||||
export default function Home(): React.JSX.Element {
|
||||
|
||||
return (
|
||||
<HomeProvider>
|
||||
<Stack.Navigator
|
||||
<HomeStack.Navigator
|
||||
id="Home"
|
||||
initialRouteName="Home"
|
||||
screenOptions={{
|
||||
navigationBarColor: Colors.Primary
|
||||
}}
|
||||
>
|
||||
<Stack.Screen
|
||||
<HomeStack.Screen
|
||||
name="Home"
|
||||
component={ProvidedHome}
|
||||
options={{
|
||||
@@ -33,7 +31,7 @@ export default function Home(): React.JSX.Element {
|
||||
}}
|
||||
/>
|
||||
|
||||
<Stack.Screen
|
||||
<HomeStack.Screen
|
||||
name="Artist"
|
||||
component={HomeArtistScreen}
|
||||
options={({ route }) => ({
|
||||
@@ -44,7 +42,7 @@ export default function Home(): React.JSX.Element {
|
||||
}
|
||||
})}
|
||||
/>
|
||||
</Stack.Navigator>
|
||||
</HomeStack.Navigator>
|
||||
</HomeProvider>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@ import Navigation from "./navigation";
|
||||
import Login from "./Login/component";
|
||||
import { JellyfinAuthenticationProvider } from "./Login/provider";
|
||||
import { SafeAreaProvider } from "react-native-safe-area-context";
|
||||
import { JellifyTheme } from "./theme";
|
||||
import { PlayerProvider } from "../player/provider";
|
||||
|
||||
export default function Jellify(): React.JSX.Element {
|
||||
|
||||
@@ -22,15 +24,17 @@ export default function Jellify(): React.JSX.Element {
|
||||
|
||||
function App(): React.JSX.Element {
|
||||
|
||||
const isDarkMode = useColorScheme() === 'dark';
|
||||
|
||||
// If library hasn't been set, we haven't completed the auth flow
|
||||
const { library } = useApiClientContext();
|
||||
|
||||
return (
|
||||
<NavigationContainer theme={isDarkMode ? DarkTheme : DefaultTheme}>
|
||||
<NavigationContainer theme={JellifyTheme}>
|
||||
<SafeAreaProvider>
|
||||
{ library ? <Navigation /> : (
|
||||
{ library ? (
|
||||
<PlayerProvider>
|
||||
<Navigation />
|
||||
</PlayerProvider>
|
||||
) : (
|
||||
<JellyfinAuthenticationProvider>
|
||||
<Login />
|
||||
</JellyfinAuthenticationProvider>
|
||||
|
||||
10
components/theme.ts
Normal file
10
components/theme.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { DarkTheme } from "@react-navigation/native";
|
||||
import { Colors } from "../enums/colors";
|
||||
|
||||
export const JellifyTheme = {
|
||||
...DarkTheme,
|
||||
colors: {
|
||||
...DarkTheme.colors,
|
||||
primary: Colors.Primary,
|
||||
},
|
||||
};
|
||||
9
constants/query-client.ts
Normal file
9
constants/query-client.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { QueryClient } from "@tanstack/react-query";
|
||||
|
||||
export const queryClient = new QueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
gcTime: (1000 * 60 * 24 * 24) * 5 // 5 days
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -1,3 +1,19 @@
|
||||
import { MMKV } from "react-native-mmkv";
|
||||
import { createSyncStoragePersister } from "@tanstack/query-sync-storage-persister";
|
||||
|
||||
export const storage = new MMKV();
|
||||
export const storage = new MMKV();
|
||||
|
||||
const clientStorage = {
|
||||
setItem: (key: string, value: string | number | boolean | Uint8Array) => {
|
||||
storage.set(key, value);
|
||||
},
|
||||
getItem: (key: string) => {
|
||||
const value = storage.getString(key);
|
||||
return value === undefined ? null : value;
|
||||
},
|
||||
removeItem: (key: string) => {
|
||||
storage.delete(key);
|
||||
},
|
||||
};
|
||||
|
||||
export const clientPersister = createSyncStoragePersister({ storage: clientStorage });
|
||||
62
package-lock.json
generated
62
package-lock.json
generated
@@ -19,7 +19,9 @@
|
||||
"@react-navigation/stack": "^6.4.1",
|
||||
"@tamagui/config": "^1.115.5",
|
||||
"@tamagui/toast": "^1.115.5",
|
||||
"@tanstack/query-sync-storage-persister": "^5.62.0",
|
||||
"@tanstack/react-query": "^5.52.1",
|
||||
"@tanstack/react-query-persist-client": "^5.62.0",
|
||||
"burnt": "^0.12.2",
|
||||
"lodash": "^4.17.21",
|
||||
"react": "18.3.1",
|
||||
@@ -8977,22 +8979,49 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@tanstack/query-core": {
|
||||
"version": "5.59.9",
|
||||
"resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.59.9.tgz",
|
||||
"integrity": "sha512-vFGnblfJOKlOPyTR5M0ohWKb/03eGubh5KuGyzsDfc7VQ6F0nsB75kQIoLpwp3Wfj6fKv0wGoTUX8BsIfhxDfw==",
|
||||
"version": "5.62.0",
|
||||
"resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.62.0.tgz",
|
||||
"integrity": "sha512-sx38bGrqF9bop92AXOvzDr0L9fWDas5zXdPglxa9cuqeVSWS7lY6OnVyl/oodfXjgOGRk79IfCpgVmxrbHuFHg==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/tannerlinsley"
|
||||
}
|
||||
},
|
||||
"node_modules/@tanstack/react-query": {
|
||||
"version": "5.59.9",
|
||||
"resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.59.9.tgz",
|
||||
"integrity": "sha512-g2cbiw/ZIIrnUaQqhGtarTAsuLdKDNLtY5HNfRHVWY9kHDj96M4qs4ygJxHc119tPQpzZe4i9W7d2Gc2Gvng2A==",
|
||||
"node_modules/@tanstack/query-persist-client-core": {
|
||||
"version": "5.62.0",
|
||||
"resolved": "https://registry.npmjs.org/@tanstack/query-persist-client-core/-/query-persist-client-core-5.62.0.tgz",
|
||||
"integrity": "sha512-yEDvJjVHqo+IizSjNkdu5fSL4ANOd16o8Tk2NOeaD7kGS1fXjf47j3XOXLIypZ7nmPTjZf9vyZi1WP3VB4saGg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@tanstack/query-core": "5.59.9"
|
||||
"@tanstack/query-core": "5.62.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/tannerlinsley"
|
||||
}
|
||||
},
|
||||
"node_modules/@tanstack/query-sync-storage-persister": {
|
||||
"version": "5.62.0",
|
||||
"resolved": "https://registry.npmjs.org/@tanstack/query-sync-storage-persister/-/query-sync-storage-persister-5.62.0.tgz",
|
||||
"integrity": "sha512-VDTdldUrthWE4th6FjwziYgADaYkOzN2UbOw8gBZejVnGJrSnBZ/ZC+0SBv7Gy09TU5wKaDlT69RNk15dlmJ1g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@tanstack/query-core": "5.62.0",
|
||||
"@tanstack/query-persist-client-core": "5.62.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/tannerlinsley"
|
||||
}
|
||||
},
|
||||
"node_modules/@tanstack/react-query": {
|
||||
"version": "5.62.0",
|
||||
"resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.62.0.tgz",
|
||||
"integrity": "sha512-tj2ltjAn2a3fs+Dqonlvs6GyLQ/LKVJE2DVSYW+8pJ3P6/VCVGrfqv5UEchmlP7tLOvvtZcOuSyI2ooVlR5Yqw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@tanstack/query-core": "5.62.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
@@ -9002,6 +9031,23 @@
|
||||
"react": "^18 || ^19"
|
||||
}
|
||||
},
|
||||
"node_modules/@tanstack/react-query-persist-client": {
|
||||
"version": "5.62.0",
|
||||
"resolved": "https://registry.npmjs.org/@tanstack/react-query-persist-client/-/react-query-persist-client-5.62.0.tgz",
|
||||
"integrity": "sha512-yv7Oe0vNkGDTVFkq9bbdGQO9EoHwXYKIYuj845v1bOmK/Npvcov3yaS0AirOlNklsapDtr0v+x1ev2aJBIbm7A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@tanstack/query-persist-client-core": "5.62.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/tannerlinsley"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tanstack/react-query": "^5.62.0",
|
||||
"react": "^18 || ^19"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/babel__core": {
|
||||
"version": "7.20.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
|
||||
|
||||
@@ -21,7 +21,9 @@
|
||||
"@react-navigation/stack": "^6.4.1",
|
||||
"@tamagui/config": "^1.115.5",
|
||||
"@tamagui/toast": "^1.115.5",
|
||||
"@tanstack/query-sync-storage-persister": "^5.62.0",
|
||||
"@tanstack/react-query": "^5.52.1",
|
||||
"@tanstack/react-query-persist-client": "^5.62.0",
|
||||
"burnt": "^0.12.2",
|
||||
"lodash": "^4.17.21",
|
||||
"react": "18.3.1",
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
import AsyncStorage from "@react-native-async-storage/async-storage";
|
||||
import { AsyncStorageKeys } from "../../../../enums/async-storage-keys";
|
||||
import { JellifyTrack } from "../../../../types/JellifyTrack";
|
||||
|
||||
/**
|
||||
* Stores the play queue for referencing in the UI and for loading at launch
|
||||
* @param queue The queue of tracks to store
|
||||
* @returns
|
||||
*/
|
||||
export async function storePlayQueue(queue: JellifyTrack[]) : Promise<void> {
|
||||
return AsyncStorage.setItem(AsyncStorageKeys.PlayQueue, JSON.stringify(queue));
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the stored play queue for referencing in the UI and for loading at launch
|
||||
* @returns An array of the stored tracks or an empty array if nothing is stored
|
||||
*/
|
||||
export async function fetchPlayQueue() : Promise<JellifyTrack[]> {
|
||||
|
||||
let storedQueue = await AsyncStorage.getItem(AsyncStorageKeys.PlayQueue);
|
||||
|
||||
return storedQueue != null ? JSON.parse(storedQueue as string) : [];
|
||||
}
|
||||
@@ -3,20 +3,17 @@
|
||||
*/
|
||||
|
||||
import { useMutation } from "@tanstack/react-query";
|
||||
import AsyncStorage from "@react-native-async-storage/async-storage";
|
||||
import { MMKVStorageKeys } from "../../enums/mmkv-storage-keys";
|
||||
import { JellifyTrack } from "../../types/JellifyTrack";
|
||||
import { add, getQueue, remove, removeUpcomingTracks } from "react-native-track-player/lib/src/trackPlayer";
|
||||
import { fetchPlayQueue, storePlayQueue } from "./helpers/storage";
|
||||
import { add, remove, removeUpcomingTracks } from "react-native-track-player/lib/src/trackPlayer";
|
||||
import { findPlayNextIndexStart, findPlayQueueIndexStart } from "./helpers";
|
||||
import { usePlayerContext } from "../provider";
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export const addToPlayNext = useMutation({
|
||||
mutationFn: async (tracks: JellifyTrack[]) => {
|
||||
|
||||
let playQueue = await fetchPlayQueue();
|
||||
const { queue : playQueue, setQueue } = usePlayerContext();
|
||||
let insertIndex = findPlayNextIndexStart(playQueue);
|
||||
|
||||
add(tracks, insertIndex);
|
||||
@@ -25,7 +22,7 @@ export const addToPlayNext = useMutation({
|
||||
playQueue.splice(insertIndex, 0, track);
|
||||
});
|
||||
|
||||
await storePlayQueue(playQueue)
|
||||
setQueue(playQueue)
|
||||
}
|
||||
});
|
||||
|
||||
@@ -35,7 +32,7 @@ export const addToPlayNext = useMutation({
|
||||
export const addToPlayQueue = useMutation({
|
||||
mutationFn: async (tracks: JellifyTrack[]) => {
|
||||
|
||||
let playQueue = await fetchPlayQueue();
|
||||
const { queue : playQueue, setQueue } = usePlayerContext();
|
||||
let insertIndex = findPlayQueueIndexStart(playQueue);
|
||||
|
||||
add(tracks, insertIndex);
|
||||
@@ -44,7 +41,7 @@ export const addToPlayQueue = useMutation({
|
||||
playQueue.splice(insertIndex, 0, track);
|
||||
});
|
||||
|
||||
await storePlayQueue(playQueue)
|
||||
setQueue(playQueue)
|
||||
}
|
||||
});
|
||||
|
||||
@@ -52,20 +49,12 @@ export const removeFromPlayQueue = useMutation({
|
||||
mutationFn: async (indexes: number[]) => {
|
||||
// Remove from the player first thing
|
||||
remove(indexes);
|
||||
let cachedQueue = await AsyncStorage.getItem(MMKVStorageKeys.PlayQueue);
|
||||
let { queue, setQueue } = usePlayerContext();
|
||||
|
||||
if (cachedQueue === null) {
|
||||
// Warn, not a showstopper as we'll just cache it at the end of this, this should hopefully never happen
|
||||
console.warn("Queue cache was null, setting...");
|
||||
|
||||
storePlayQueue((await getQueue()) as JellifyTrack[]);
|
||||
} else {
|
||||
let queue : Array<JellifyTrack> = JSON.parse(cachedQueue);
|
||||
indexes.forEach(index => {
|
||||
queue.splice(index, 1); // Returns deleted queue items
|
||||
})
|
||||
storePlayQueue(queue);
|
||||
}
|
||||
indexes.forEach(index => {
|
||||
queue.splice(index, 1); // Returns deleted queue items
|
||||
})
|
||||
setQueue(queue);
|
||||
},
|
||||
onError: () => {
|
||||
|
||||
@@ -80,7 +69,8 @@ export const removeFromPlayQueue = useMutation({
|
||||
|
||||
export const clearPlayQueue = useMutation({
|
||||
mutationFn: async () => {
|
||||
const { setQueue } = usePlayerContext();
|
||||
removeUpcomingTracks()
|
||||
await storePlayQueue([]);
|
||||
setQueue([]);
|
||||
}
|
||||
})
|
||||
64
player/provider.tsx
Normal file
64
player/provider.tsx
Normal file
@@ -0,0 +1,64 @@
|
||||
import { createContext, ReactNode, SetStateAction, useContext, useState } from "react";
|
||||
import { JellifyTrack } from "../types/JellifyTrack";
|
||||
import { storage } from "../constants/storage";
|
||||
import { MMKVStorageKeys } from "../enums/mmkv-storage-keys";
|
||||
|
||||
interface PlayerContext {
|
||||
showPlayer: boolean;
|
||||
setShowPlayer: React.Dispatch<SetStateAction<boolean>>;
|
||||
showMiniplayer: boolean;
|
||||
setShowMiniplayer: React.Dispatch<SetStateAction<boolean>>;
|
||||
queue: JellifyTrack[];
|
||||
setQueue: React.Dispatch<SetStateAction<JellifyTrack[]>>;
|
||||
}
|
||||
|
||||
const PlayerContextInitializer = () => {
|
||||
|
||||
const queueJson = storage.getString(MMKVStorageKeys.PlayQueue);
|
||||
|
||||
const [showPlayer, setShowPlayer] = useState<boolean>(false);
|
||||
const [showMiniplayer, setShowMiniplayer] = useState<boolean>(false);
|
||||
const [queue, setQueue] = useState<JellifyTrack[]>(queueJson ? JSON.parse(queueJson) : []);
|
||||
|
||||
return {
|
||||
showPlayer,
|
||||
setShowPlayer,
|
||||
showMiniplayer,
|
||||
setShowMiniplayer,
|
||||
queue,
|
||||
setQueue
|
||||
}
|
||||
}
|
||||
|
||||
export const PlayerContext = createContext<PlayerContext>({
|
||||
showPlayer: false,
|
||||
setShowPlayer: () => {},
|
||||
showMiniplayer: false,
|
||||
setShowMiniplayer: () => {},
|
||||
queue: [],
|
||||
setQueue: () => {}
|
||||
});
|
||||
|
||||
export const PlayerProvider: ({ children }: { children: ReactNode }) => React.JSX.Element = ({ children }: { children: ReactNode }) => {
|
||||
const {
|
||||
showPlayer,
|
||||
setShowPlayer,
|
||||
showMiniplayer,
|
||||
setShowMiniplayer,
|
||||
queue,
|
||||
setQueue
|
||||
} = PlayerContextInitializer();
|
||||
|
||||
return <PlayerContext.Provider value={{
|
||||
showPlayer,
|
||||
setShowPlayer,
|
||||
showMiniplayer,
|
||||
setShowMiniplayer,
|
||||
queue,
|
||||
setQueue
|
||||
}}>
|
||||
{ children }
|
||||
</PlayerContext.Provider>
|
||||
}
|
||||
|
||||
export const usePlayerContext = () => useContext(PlayerContext);
|
||||
@@ -1,9 +1,10 @@
|
||||
import { useQueries, useQuery, UseQueryOptions, UseQueryResult } from "@tanstack/react-query"
|
||||
import { getActiveTrack, getProgress, pause, play, removeUpcomingTracks, setupPlayer } from "react-native-track-player/lib/src/trackPlayer"
|
||||
import { getActiveTrack, getProgress, pause, play } from "react-native-track-player/lib/src/trackPlayer"
|
||||
import { getPlaystateApi } from "@jellyfin/sdk/lib/utils/api/playstate-api"
|
||||
import { useApi } from "../../api/queries";
|
||||
import { Progress, Track } from "react-native-track-player";
|
||||
import { QueryKeys } from "../../enums/query-keys";
|
||||
import { Api } from "@jellyfin/sdk";
|
||||
import { useApiClientContext } from "../../components/jellyfin-api-provider";
|
||||
|
||||
const usePause : UseQueryOptions = {
|
||||
queryKey: [QueryKeys.Pause],
|
||||
@@ -26,11 +27,11 @@ const useProgress : UseQueryResult<Progress, Error> = useQuery({
|
||||
.then((progress => {
|
||||
if (!!!progress)
|
||||
throw new Error("Tried to fetch progress when there wasn't a currently active track");
|
||||
}))
|
||||
}));
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
const useReportPlaybackStarted : UseQueryOptions = {
|
||||
const useReportPlaybackStarted = {
|
||||
queryKey: [QueryKeys.ReportPlaybackStarted],
|
||||
queryFn: () => {
|
||||
getActiveTrack()
|
||||
@@ -41,12 +42,18 @@ const useReportPlaybackStarted : UseQueryOptions = {
|
||||
return track as Track;
|
||||
})
|
||||
.then(track => {
|
||||
getPlaystateApi(useApi.data!).reportPlaybackStart({playbackStartInfo: { ItemId: track.id, PositionTicks: useProgress.data!.position }})
|
||||
})
|
||||
getPlaystateApi(useApiClientContext().apiClient!)
|
||||
.reportPlaybackStart({
|
||||
playbackStartInfo: {
|
||||
ItemId: track.id,
|
||||
PositionTicks: useProgress.data!.position
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const useReportPlaybackStopped : UseQueryOptions = {
|
||||
const useReportPlaybackStopped = {
|
||||
queryKey: [QueryKeys.ReportPlaybackStopped],
|
||||
queryFn: () => {
|
||||
getActiveTrack()
|
||||
@@ -57,12 +64,18 @@ const useReportPlaybackStopped : UseQueryOptions = {
|
||||
return track as Track;
|
||||
})
|
||||
.then(track => {
|
||||
getPlaystateApi(useApi.data!).reportPlaybackStopped({playbackStopInfo: { ItemId: track.id, PositionTicks: useProgress.data!.position }})
|
||||
})
|
||||
getPlaystateApi(useApiClientContext().apiClient!)
|
||||
.reportPlaybackStopped({
|
||||
playbackStopInfo: {
|
||||
ItemId: track.id,
|
||||
PositionTicks: useProgress.data!.position
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const useReportPlaybackProgress : UseQueryResult = useQuery({
|
||||
export const useReportPlaybackProgress = {
|
||||
queryKey: [QueryKeys.ReportPlaybackPosition],
|
||||
queryFn: () => {
|
||||
getActiveTrack()
|
||||
@@ -73,15 +86,21 @@ export const useReportPlaybackProgress : UseQueryResult = useQuery({
|
||||
return track as Track;
|
||||
})
|
||||
.then(track => {
|
||||
getPlaystateApi(useApi.data!).reportPlaybackProgress({playbackProgressInfo: { ItemId: track.id, PositionTicks: useProgress.data!.position }})
|
||||
})
|
||||
getPlaystateApi(useApiClientContext().apiClient!)
|
||||
.reportPlaybackProgress({
|
||||
playbackProgressInfo: {
|
||||
ItemId: track.id,
|
||||
PositionTicks: useProgress.data!.position
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const usePauseAndReportPlaybackStopped = useQueries({
|
||||
queries: [useReportPlaybackStopped, usePause]
|
||||
})
|
||||
|
||||
export const usePlayAndReportPlayback = useQueries({
|
||||
export const usePlayAndReportPlayback = (api: Api) => useQueries({
|
||||
queries: [useReportPlaybackStarted, usePlay]
|
||||
})
|
||||
@@ -1,13 +0,0 @@
|
||||
import { useQuery, UseQueryResult } from "@tanstack/react-query";
|
||||
import AsyncStorage from "@react-native-async-storage/async-storage";
|
||||
import { MMKVStorageKeys } from "../../enums/mmkv-storage-keys";
|
||||
|
||||
import { JellifyTrack } from "../../types/JellifyTrack";
|
||||
import { QueryKeys } from "../../enums/query-keys";
|
||||
|
||||
export const useStoredQueue: UseQueryResult<JellifyTrack[]> = useQuery({
|
||||
queryKey: [QueryKeys.PlayQueue],
|
||||
queryFn: (() => {
|
||||
return AsyncStorage.getItem(MMKVStorageKeys.PlayQueue);
|
||||
})
|
||||
});
|
||||
Reference in New Issue
Block a user