176 lines
5.4 KiB
TypeScript
176 lines
5.4 KiB
TypeScript
import React, { createContext, useContext, useState, useEffect } from 'react';
|
|
|
|
export interface Account {
|
|
_id: string;
|
|
steamId: string;
|
|
personaName: string;
|
|
loginName?: string;
|
|
steamLoginSecure?: string;
|
|
loginConfig?: any;
|
|
sessionUpdatedAt?: string;
|
|
autoCheckCooldown: boolean;
|
|
avatar: string;
|
|
localAvatar?: string;
|
|
profileUrl: string;
|
|
status: string;
|
|
vacBanned: boolean;
|
|
gameBans: number;
|
|
lastBanCheck: string;
|
|
lastScrapeTime?: string;
|
|
cooldownExpiresAt?: string;
|
|
authError?: boolean;
|
|
notes?: string;
|
|
}
|
|
|
|
export interface ServerConfig {
|
|
url: string;
|
|
token?: string;
|
|
serverSteamId?: string;
|
|
enabled: boolean;
|
|
}
|
|
|
|
interface AccountsContextType {
|
|
accounts: Account[];
|
|
serverConfig: ServerConfig | null;
|
|
isLoading: boolean;
|
|
isSyncing: boolean;
|
|
addAccount: (data: { identifier: string }) => Promise<void>;
|
|
updateAccount: (id: string, data: Partial<Account>) => Promise<void>;
|
|
deleteAccount: (id: string) => Promise<void>;
|
|
switchAccount: (loginName: string) => Promise<void>;
|
|
openSteamLogin: (steamId: string) => Promise<void>;
|
|
shareAccountWithUser: (steamId: string, targetSteamId: string) => Promise<any>;
|
|
|
|
// Server Methods
|
|
updateServerConfig: (config: Partial<ServerConfig>) => Promise<void>;
|
|
loginToServer: () => Promise<void>;
|
|
syncNow: () => Promise<void>;
|
|
getCommunityAccounts: () => Promise<any[]>;
|
|
getServerUsers: () => Promise<any[]>;
|
|
refreshAccounts: (showLoading?: boolean) => Promise<void>;
|
|
}
|
|
|
|
const AccountsContext = createContext<AccountsContextType | undefined>(undefined);
|
|
|
|
export const AccountsProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
|
|
const [accounts, setAccounts] = useState<Account[]>([]);
|
|
const [serverConfig, setServerConfig] = useState<ServerConfig | null>(null);
|
|
const [isLoading, setIsLoading] = useState(true);
|
|
const [isSyncing, setIsSyncing] = useState(false);
|
|
|
|
const refreshAccounts = async (showLoading = false) => {
|
|
if (showLoading) setIsLoading(true);
|
|
try {
|
|
const api = (window as any).electronAPI;
|
|
if (!api) {
|
|
console.warn("[useAccounts] electronAPI not found in window");
|
|
return;
|
|
}
|
|
|
|
console.log("[useAccounts] Fetching data from main process...");
|
|
const accData = await api.getAccounts();
|
|
const configData = await api.getServerConfig();
|
|
|
|
setAccounts(Array.isArray(accData) ? accData : []);
|
|
setServerConfig(configData || null);
|
|
} catch (error) {
|
|
console.error("[useAccounts] Error loading accounts:", error);
|
|
} finally {
|
|
setIsLoading(false);
|
|
}
|
|
};
|
|
|
|
useEffect(() => {
|
|
refreshAccounts(true);
|
|
const api = (window as any).electronAPI;
|
|
if (api?.onAccountsUpdated) {
|
|
const cleanup = api.onAccountsUpdated((updatedAccounts: Account[]) => {
|
|
setAccounts(Array.isArray(updatedAccounts) ? updatedAccounts : []);
|
|
});
|
|
return typeof cleanup === 'function' ? cleanup : undefined;
|
|
}
|
|
}, []);
|
|
|
|
const syncNow = async () => {
|
|
setIsSyncing(true);
|
|
try {
|
|
await (window as any).electronAPI.syncNow();
|
|
await refreshAccounts();
|
|
} catch (e) {
|
|
console.error("[useAccounts] Sync failed", e);
|
|
} finally {
|
|
setIsSyncing(false);
|
|
}
|
|
};
|
|
|
|
const addAccount = async (data: { identifier: string }) => {
|
|
await (window as any).electronAPI.addAccount(data);
|
|
await refreshAccounts();
|
|
await syncNow();
|
|
};
|
|
|
|
const updateAccount = async (id: string, data: Partial<Account>) => {
|
|
await (window as any).electronAPI.updateAccount(id, data);
|
|
await refreshAccounts();
|
|
};
|
|
|
|
const deleteAccount = async (id: string) => {
|
|
if (!window.confirm("Are you sure you want to remove this account?")) return;
|
|
await (window as any).electronAPI.deleteAccount(id);
|
|
await refreshAccounts();
|
|
};
|
|
|
|
const switchAccount = async (loginName: string) => {
|
|
if (!loginName) return;
|
|
await (window as any).electronAPI.switchAccount(loginName);
|
|
};
|
|
|
|
const openSteamLogin = async (steamId: string) => {
|
|
await (window as any).electronAPI.openSteamLogin(steamId);
|
|
await syncNow();
|
|
};
|
|
|
|
const shareAccountWithUser = async (steamId: string, targetSteamId: string) => {
|
|
const res = await (window as any).electronAPI.shareAccountWithUser(steamId, targetSteamId);
|
|
await syncNow();
|
|
return res;
|
|
};
|
|
|
|
const updateServerConfig = async (config: Partial<ServerConfig>) => {
|
|
const updated = await (window as any).electronAPI.updateServerConfig(config);
|
|
setServerConfig(updated);
|
|
};
|
|
|
|
const loginToServer = async () => {
|
|
await (window as any).electronAPI.loginToServer();
|
|
await refreshAccounts();
|
|
await syncNow();
|
|
};
|
|
|
|
const getCommunityAccounts = async () => {
|
|
return await (window as any).electronAPI.getCommunityAccounts();
|
|
};
|
|
|
|
const getServerUsers = async () => {
|
|
return await (window as any).electronAPI.getServerUsers();
|
|
};
|
|
|
|
return (
|
|
<AccountsContext.Provider value={{
|
|
accounts, serverConfig, isLoading, isSyncing, addAccount, updateAccount, deleteAccount,
|
|
switchAccount, openSteamLogin, updateServerConfig, loginToServer,
|
|
getCommunityAccounts, getServerUsers, shareAccountWithUser, syncNow, refreshAccounts
|
|
}}>
|
|
{children}
|
|
</AccountsContext.Provider>
|
|
);
|
|
};
|
|
|
|
export const useAccounts = () => {
|
|
const context = useContext(AccountsContext);
|
|
if (context === undefined) {
|
|
throw new Error('useAccounts must be used within an AccountsProvider');
|
|
}
|
|
return context;
|
|
};
|