Files
OrionTV/stores/settingsStore.ts

121 lines
3.9 KiB
TypeScript

import { create } from "zustand";
import { SettingsManager } from "@/services/storage";
import { api, ServerConfig } from "@/services/api";
import { storageConfig } from "@/services/storageConfig";
import AsyncStorage from "@react-native-async-storage/async-storage";
import Logger from "@/utils/Logger";
const logger = Logger.withTag('SettingsStore');
interface SettingsState {
apiBaseUrl: string;
m3uUrl: string;
remoteInputEnabled: boolean;
videoSource: {
enabledAll: boolean;
sources: {
[key: string]: boolean;
};
};
isModalVisible: boolean;
serverConfig: ServerConfig | null;
isLoadingServerConfig: boolean;
loadSettings: () => Promise<void>;
fetchServerConfig: () => Promise<void>;
setApiBaseUrl: (url: string) => void;
setM3uUrl: (url: string) => void;
setRemoteInputEnabled: (enabled: boolean) => void;
saveSettings: () => Promise<void>;
setVideoSource: (config: { enabledAll: boolean; sources: { [key: string]: boolean } }) => void;
showModal: () => void;
hideModal: () => void;
}
export const useSettingsStore = create<SettingsState>((set, get) => ({
apiBaseUrl: "",
m3uUrl: "",
liveStreamSources: [],
remoteInputEnabled: false,
isModalVisible: false,
serverConfig: null,
isLoadingServerConfig: false,
videoSource: {
enabledAll: true,
sources: {},
},
loadSettings: async () => {
const settings = await SettingsManager.get();
set({
apiBaseUrl: settings.apiBaseUrl,
m3uUrl: settings.m3uUrl,
remoteInputEnabled: settings.remoteInputEnabled || false,
videoSource: settings.videoSource || {
enabledAll: true,
sources: {},
},
});
if (settings.apiBaseUrl) {
api.setBaseUrl(settings.apiBaseUrl);
await get().fetchServerConfig();
}
},
fetchServerConfig: async () => {
set({ isLoadingServerConfig: true });
try {
const config = await api.getServerConfig();
if (config) {
storageConfig.setStorageType(config.StorageType);
set({ serverConfig: config });
}
} catch (error) {
set({ serverConfig: null });
logger.error("Failed to fetch server config:", error);
} finally {
set({ isLoadingServerConfig: false });
}
},
setApiBaseUrl: (url) => set({ apiBaseUrl: url }),
setM3uUrl: (url) => set({ m3uUrl: url }),
setRemoteInputEnabled: (enabled) => set({ remoteInputEnabled: enabled }),
setVideoSource: (config) => set({ videoSource: config }),
saveSettings: async () => {
const { apiBaseUrl, m3uUrl, remoteInputEnabled, videoSource } = get();
const currentSettings = await SettingsManager.get()
const currentApiBaseUrl = currentSettings.apiBaseUrl;
let processedApiBaseUrl = apiBaseUrl.trim();
if (processedApiBaseUrl.endsWith("/")) {
processedApiBaseUrl = processedApiBaseUrl.slice(0, -1);
}
if (!/^https?:\/\//i.test(processedApiBaseUrl)) {
const hostPart = processedApiBaseUrl.split("/")[0];
// Simple check for IP address format.
const isIpAddress = /^((\d{1,3}\.){3}\d{1,3})(:\d+)?$/.test(hostPart);
// Check if the domain includes a port.
const hasPort = /:\d+/.test(hostPart);
if (isIpAddress || hasPort) {
processedApiBaseUrl = "http://" + processedApiBaseUrl;
} else {
processedApiBaseUrl = "https://" + processedApiBaseUrl;
}
}
await SettingsManager.save({
apiBaseUrl: processedApiBaseUrl,
m3uUrl,
remoteInputEnabled,
videoSource,
});
if ( currentApiBaseUrl !== processedApiBaseUrl) {
await AsyncStorage.setItem('authCookies', '');
}
api.setBaseUrl(processedApiBaseUrl);
// Also update the URL in the state so the input field shows the processed URL
set({ isModalVisible: false, apiBaseUrl: processedApiBaseUrl });
await get().fetchServerConfig();
},
showModal: () => set({ isModalVisible: true }),
hideModal: () => set({ isModalVisible: false }),
}));