mirror of
https://github.com/streamyfin/streamyfin.git
synced 2025-08-20 18:37:18 +02:00
145 lines
4.5 KiB
TypeScript
145 lines
4.5 KiB
TypeScript
import type {
|
|
CultureDto,
|
|
UserConfiguration,
|
|
UserDto,
|
|
} from "@jellyfin/sdk/lib/generated-client/models";
|
|
import { getLocalizationApi, getUserApi } from "@jellyfin/sdk/lib/utils/api";
|
|
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
|
import { useAtomValue } from "jotai";
|
|
import { createContext, type ReactNode, useContext, useEffect } from "react";
|
|
import { apiAtom } from "@/providers/JellyfinProvider";
|
|
import { type Settings, useSettings } from "@/utils/atoms/settings";
|
|
|
|
interface MediaContextType {
|
|
settings: Settings | null;
|
|
updateSettings: (update: Partial<Settings>) => void;
|
|
user: UserDto | undefined;
|
|
cultures: CultureDto[];
|
|
}
|
|
|
|
const MediaContext = createContext<MediaContextType | undefined>(undefined);
|
|
|
|
export const useMedia = () => {
|
|
const context = useContext(MediaContext);
|
|
if (!context) {
|
|
throw new Error("useMedia must be used within a MediaProvider");
|
|
}
|
|
return context;
|
|
};
|
|
|
|
export const MediaProvider = ({ children }: { children: ReactNode }) => {
|
|
const [settings, updateSettings] = useSettings();
|
|
const api = useAtomValue(apiAtom);
|
|
const queryClient = useQueryClient();
|
|
|
|
const updateSetingsWrapper = (update: Partial<Settings>) => {
|
|
const updateUserConfiguration = async (
|
|
update: Partial<UserConfiguration>,
|
|
) => {
|
|
if (api && user) {
|
|
try {
|
|
await getUserApi(api).updateUserConfiguration({
|
|
userConfiguration: {
|
|
...user.Configuration,
|
|
...update,
|
|
},
|
|
});
|
|
queryClient.invalidateQueries({ queryKey: ["authUser"] });
|
|
} catch (_error) {}
|
|
}
|
|
};
|
|
|
|
updateSettings(update);
|
|
|
|
const updatePayload = {
|
|
SubtitleMode: update?.subtitleMode ?? settings?.subtitleMode,
|
|
PlayDefaultAudioTrack:
|
|
update?.playDefaultAudioTrack ?? settings?.playDefaultAudioTrack,
|
|
RememberAudioSelections:
|
|
update?.rememberAudioSelections ?? settings?.rememberAudioSelections,
|
|
RememberSubtitleSelections:
|
|
update?.rememberSubtitleSelections ??
|
|
settings?.rememberSubtitleSelections,
|
|
} as Partial<UserConfiguration>;
|
|
|
|
updatePayload.AudioLanguagePreference =
|
|
update?.defaultAudioLanguage === null
|
|
? ""
|
|
: update?.defaultAudioLanguage?.ThreeLetterISOLanguageName ||
|
|
settings?.defaultAudioLanguage?.ThreeLetterISOLanguageName ||
|
|
"";
|
|
|
|
updatePayload.SubtitleLanguagePreference =
|
|
update?.defaultSubtitleLanguage === null
|
|
? ""
|
|
: update?.defaultSubtitleLanguage?.ThreeLetterISOLanguageName ||
|
|
settings?.defaultSubtitleLanguage?.ThreeLetterISOLanguageName ||
|
|
"";
|
|
|
|
updateUserConfiguration(updatePayload);
|
|
};
|
|
|
|
const { data: user } = useQuery({
|
|
queryKey: ["authUser"],
|
|
queryFn: async () => {
|
|
if (!api) return;
|
|
const userApi = await getUserApi(api).getCurrentUser();
|
|
return userApi.data;
|
|
},
|
|
enabled: !!api,
|
|
staleTime: 0,
|
|
});
|
|
|
|
const { data: cultures = [], isFetched: isCulturesFetched } = useQuery({
|
|
queryKey: ["cultures"],
|
|
queryFn: async () => {
|
|
if (!api) return [];
|
|
const localizationApi = await getLocalizationApi(api).getCultures();
|
|
const cultures = localizationApi.data;
|
|
return cultures;
|
|
},
|
|
enabled: !!api,
|
|
staleTime: 43200000, // 12 hours
|
|
});
|
|
|
|
// Set default settings from user configuration.s
|
|
useEffect(() => {
|
|
if (!user || cultures.length === 0) return;
|
|
const userSubtitlePreference =
|
|
user?.Configuration?.SubtitleLanguagePreference;
|
|
const userAudioPreference = user?.Configuration?.AudioLanguagePreference;
|
|
|
|
const subtitlePreference = cultures.find(
|
|
(x) => x.ThreeLetterISOLanguageName === userSubtitlePreference,
|
|
);
|
|
const audioPreference = cultures.find(
|
|
(x) => x.ThreeLetterISOLanguageName === userAudioPreference,
|
|
);
|
|
|
|
updateSettings({
|
|
defaultSubtitleLanguage: subtitlePreference,
|
|
defaultAudioLanguage: audioPreference,
|
|
subtitleMode: user?.Configuration?.SubtitleMode,
|
|
playDefaultAudioTrack: user?.Configuration?.PlayDefaultAudioTrack,
|
|
rememberAudioSelections: user?.Configuration?.RememberAudioSelections,
|
|
rememberSubtitleSelections:
|
|
user?.Configuration?.RememberSubtitleSelections,
|
|
});
|
|
}, [user, isCulturesFetched]);
|
|
|
|
if (!api) return null;
|
|
|
|
return (
|
|
<MediaContext.Provider
|
|
value={{
|
|
settings,
|
|
updateSettings: updateSetingsWrapper,
|
|
user,
|
|
cultures,
|
|
}}
|
|
>
|
|
{children}
|
|
</MediaContext.Provider>
|
|
);
|
|
};
|