forked from Ninjalama/streamyfin_mirror
95 lines
2.5 KiB
TypeScript
95 lines
2.5 KiB
TypeScript
import { useQuery } from "@tanstack/react-query";
|
|
import { atomWithStorage, createJSONStorage } from "jotai/utils";
|
|
import type React from "react";
|
|
import { createContext, useContext } from "react";
|
|
import { storage } from "./mmkv";
|
|
|
|
export type LogLevel = "INFO" | "WARN" | "ERROR" | "DEBUG";
|
|
|
|
interface LogEntry {
|
|
timestamp: string;
|
|
level: LogLevel;
|
|
message: string;
|
|
data?: any;
|
|
}
|
|
|
|
const mmkvStorage = createJSONStorage(() => ({
|
|
getItem: (key: string) => storage.getString(key) || null,
|
|
setItem: (key: string, value: string) => storage.set(key, value),
|
|
removeItem: (key: string) => storage.delete(key),
|
|
}));
|
|
const logsAtom = atomWithStorage("logs", [], mmkvStorage);
|
|
|
|
const LogContext = createContext<ReturnType<typeof useLogProvider> | null>(
|
|
null,
|
|
);
|
|
const DownloadContext = createContext<ReturnType<typeof useLogProvider> | null>(
|
|
null,
|
|
);
|
|
|
|
function useLogProvider() {
|
|
const { data: logs } = useQuery({
|
|
queryKey: ["logs"],
|
|
queryFn: async () => readFromLog(),
|
|
refetchInterval: 1000,
|
|
});
|
|
|
|
return {
|
|
logs,
|
|
};
|
|
}
|
|
|
|
export const writeToLog = (level: LogLevel, message: string, data?: any) => {
|
|
const newEntry: LogEntry = {
|
|
timestamp: new Date().toISOString(),
|
|
level: level,
|
|
message: message,
|
|
data: data,
|
|
};
|
|
|
|
const currentLogs = storage.getString("logs");
|
|
const logs: LogEntry[] = currentLogs ? JSON.parse(currentLogs) : [];
|
|
logs.push(newEntry);
|
|
|
|
const maxLogs = 100;
|
|
const recentLogs = logs.slice(Math.max(logs.length - maxLogs, 0));
|
|
|
|
storage.set("logs", JSON.stringify(recentLogs));
|
|
console.log(message);
|
|
};
|
|
|
|
export const writeInfoLog = (message: string, data?: any) =>
|
|
writeToLog("INFO", message, data);
|
|
export const writeErrorLog = (message: string, data?: any) =>
|
|
writeToLog("ERROR", message, data);
|
|
export const writeDebugLog = (message: string, data?: any) => {
|
|
if (process.env.EXPO_PUBLIC_WRITE_DEBUG === "1") {
|
|
writeToLog("DEBUG", message, data);
|
|
}
|
|
};
|
|
|
|
export const readFromLog = (): LogEntry[] => {
|
|
const logs = storage.getString("logs");
|
|
return logs ? JSON.parse(logs) : [];
|
|
};
|
|
|
|
export const clearLogs = () => {
|
|
storage.delete("logs");
|
|
};
|
|
|
|
export function useLog() {
|
|
const context = useContext(LogContext);
|
|
if (context === null) {
|
|
throw new Error("useLog must be used within a LogProvider");
|
|
}
|
|
return context;
|
|
}
|
|
|
|
export function LogProvider({ children }: { children: React.ReactNode }) {
|
|
const provider = useLogProvider();
|
|
|
|
return <LogContext.Provider value={provider}>{children}</LogContext.Provider>;
|
|
}
|
|
|
|
export default logsAtom;
|