fix: OneClient Skin Manager Crash when Invalid Account (#404)
* fix: oneclient skin manager crash when invalid account * fix: formatting
This commit is contained in:
parent
878f7ed5ab
commit
c07d4637d3
3 changed files with 41 additions and 16 deletions
|
|
@ -255,11 +255,8 @@ export type VersionType =
|
|||
*/
|
||||
"old_beta"
|
||||
|
||||
const ARGS_MAP = { 'folders':'{"fromCluster":["folder_name"],"openCluster":["folder_name"]}', 'oneclient':'{"openDevTools":[],"getClustersGroupedByMajor":[],"getBundlesFor":["cluster_id"]}', 'core':'{"createCluster":["options"],"writeSettings":["setting"],"getPackageBody":["provider","body"],"getUser":["uuid"],"getMultiplePackages":["provider","slugs"],"removeCape":["access_token"],"openMsaLogin":[],"installModpack":["modpack","cluster_id"],"fetchLoggedInProfile":["access_token"],"getLogByName":["id","name"],"getUsers":[],"uploadSkinBytes":["access_token","skin_data","image_format","skin_variant"],"killProcess":["pid"],"getClusters":[],"fetchMinecraftProfile":["uuid"],"getScreenshots":["id"],"getWorlds":["id"],"readSettings":[],"launchCluster":["id","uuid"],"getLoadersForVersion":["mc_version"],"getGameVersions":[],"getUsersFromAuthor":["provider","author"],"getRunningProcessesByClusterId":["cluster_id"],"changeCape":["access_token","cape_uuid"],"downloadPackage":["provider","package_id","version_id","cluster_id","skip_compatibility"],"getClusterById":["id"],"setDefaultUser":["uuid"],"getGlobalProfile":[],"updateClusterById":["id","request"],"removeCluster":["id"],"getRunningProcesses":[],"isClusterRunning":["cluster_id"],"updateClusterProfile":["name","profile"],"removeUser":["uuid"],"getLogs":["id"],"getDefaultUser":["fallback"],"searchPackages":["provider","query"],"getProfileOrDefault":["name"],"getPackageVersions":["provider","slug","mc_version","loader","offset","limit"],"open":["input"],"convertUsernameUUID":["username_uuid"],"createSettingsProfile":["name"],"changeSkin":["access_token","skin_url","skin_variant"],"getPackage":["provider","slug"]}', 'events':'{"process":["event"],"ingress":["event"],"message":["event"]}' }
|
||||
export type Router = { 'oneclient': { openDevTools: () => Promise<void>,
|
||||
getClustersGroupedByMajor: () => Promise<Partial<{ [key in number]: ClusterModel[] }>>,
|
||||
getBundlesFor: (clusterId: number) => Promise<ModpackArchive[]> },
|
||||
'core': { getClusters: () => Promise<ClusterModel[]>,
|
||||
const ARGS_MAP = { 'oneclient':'{"getClustersGroupedByMajor":[],"getBundlesFor":["cluster_id"],"openDevTools":[]}', 'core':'{"uploadSkinBytes":["access_token","skin_data","image_format","skin_variant"],"removeCape":["access_token"],"getGameVersions":[],"installModpack":["modpack","cluster_id"],"createSettingsProfile":["name"],"getPackageBody":["provider","body"],"getLogByName":["id","name"],"getScreenshots":["id"],"getWorlds":["id"],"getMultiplePackages":["provider","slugs"],"changeCape":["access_token","cape_uuid"],"convertUsernameUUID":["username_uuid"],"getPackageVersions":["provider","slug","mc_version","loader","offset","limit"],"fetchMinecraftProfile":["uuid"],"getPackage":["provider","slug"],"getUsersFromAuthor":["provider","author"],"createCluster":["options"],"getGlobalProfile":[],"getRunningProcesses":[],"setDefaultUser":["uuid"],"changeSkin":["access_token","skin_url","skin_variant"],"writeSettings":["setting"],"updateClusterById":["id","request"],"open":["input"],"readSettings":[],"getRunningProcessesByClusterId":["cluster_id"],"isClusterRunning":["cluster_id"],"getLoadersForVersion":["mc_version"],"removeCluster":["id"],"launchCluster":["id","uuid"],"getProfileOrDefault":["name"],"updateClusterProfile":["name","profile"],"getLogs":["id"],"downloadPackage":["provider","package_id","version_id","cluster_id","skip_compatibility"],"getUser":["uuid"],"searchPackages":["provider","query"],"killProcess":["pid"],"getClusterById":["id"],"getUsers":[],"getClusters":[],"openMsaLogin":[],"removeUser":["uuid"],"fetchLoggedInProfile":["access_token"],"getDefaultUser":["fallback"]}', 'folders':'{"openCluster":["folder_name"],"fromCluster":["folder_name"]}', 'events':'{"message":["event"],"process":["event"],"ingress":["event"]}' }
|
||||
export type Router = { 'core': { getClusters: () => Promise<ClusterModel[]>,
|
||||
getClusterById: (id: number) => Promise<ClusterModel | null>,
|
||||
removeCluster: (id: number) => Promise<null>,
|
||||
createCluster: (options: CreateCluster) => Promise<ClusterModel>,
|
||||
|
|
@ -307,7 +304,10 @@ open: (input: string) => Promise<null> },
|
|||
openCluster: (folderName: string) => Promise<null> },
|
||||
'events': { ingress: (event: IngressPayload) => Promise<void>,
|
||||
message: (event: MessagePayload) => Promise<void>,
|
||||
process: (event: ProcessPayload) => Promise<void> } };
|
||||
process: (event: ProcessPayload) => Promise<void> },
|
||||
'oneclient': { openDevTools: () => Promise<void>,
|
||||
getClustersGroupedByMajor: () => Promise<Partial<{ [key in number]: ClusterModel[] }>>,
|
||||
getBundlesFor: (clusterId: number) => Promise<ModpackArchive[]> } };
|
||||
|
||||
|
||||
export type { InferCommandOutput }
|
||||
|
|
|
|||
|
|
@ -2,39 +2,49 @@ import type { MinecraftCredentials } from '@/bindings.gen';
|
|||
import { LoaderSuspense } from '@/components';
|
||||
import { bindings } from '@/main';
|
||||
import { createFileRoute, Outlet } from '@tanstack/react-router';
|
||||
import { MissingAccountData } from './skins';
|
||||
|
||||
export interface AccountsRouteSearchParams {
|
||||
profile: MinecraftCredentials;
|
||||
profile: MinecraftCredentials | undefined;
|
||||
search: boolean;
|
||||
}
|
||||
|
||||
export const Route = createFileRoute('/app/account')({
|
||||
component: RouteComponent,
|
||||
validateSearch: (search): AccountsRouteSearchParams => {
|
||||
return {
|
||||
profile: search.profile as MinecraftCredentials,
|
||||
profile: search.profile as MinecraftCredentials | undefined,
|
||||
search: search.profile === undefined,
|
||||
};
|
||||
},
|
||||
async beforeLoad({ context, search }) {
|
||||
// TODO instead replace this with a refresh access_token function. Waiting on binding from @LynithDev
|
||||
const { profile, search: validSearch } = search;
|
||||
if (!profile)
|
||||
return { profileData: null, profile: null, validSearch };
|
||||
|
||||
const query = context.queryClient.ensureQueryData({
|
||||
queryKey: ['fetchLoggedInProfile', search.profile.access_token],
|
||||
queryFn: () => bindings.core.fetchLoggedInProfile(search.profile.access_token),
|
||||
queryKey: ['fetchLoggedInProfile', profile.access_token],
|
||||
queryFn: () => bindings.core.fetchLoggedInProfile(profile.access_token),
|
||||
});
|
||||
|
||||
const profileData = await query;
|
||||
return {
|
||||
profileData,
|
||||
profile: search.profile,
|
||||
profile,
|
||||
validSearch,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
function RouteComponent() {
|
||||
const { profileData, validSearch } = Route.useRouteContext();
|
||||
|
||||
return (
|
||||
<>
|
||||
<LoaderSuspense spinner={{ size: 'large' }}>
|
||||
<Outlet />
|
||||
{profileData === null ? <MissingAccountData validSearch={validSearch} /> : <Outlet />}
|
||||
</LoaderSuspense>
|
||||
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -102,26 +102,36 @@ function useSkinHistory() {
|
|||
return [skins, setSkins, loaded] as const;
|
||||
}
|
||||
|
||||
export function MissingAccountData({ validSearch }: { validSearch: boolean }) {
|
||||
return (
|
||||
<SheetPage headerLarge={<></>} headerSmall={<></>}>
|
||||
<h1>{validSearch ? 'Please select an account before going to the skins page' : 'Missing Profile auth. Please log out and log back in'}</h1>
|
||||
</SheetPage>
|
||||
);
|
||||
}
|
||||
|
||||
function RouteComponent() {
|
||||
const { profileData, profile, queryClient } = Route.useRouteContext();
|
||||
const { profileData, profile, queryClient, validSearch } = Route.useRouteContext();
|
||||
|
||||
const [capes, setCapes] = useState<Array<Cape>>([]);
|
||||
const [selectedCape, setSelectedCape] = useState<string>('');
|
||||
const [shouldShowElytra, setShouldShowElytra] = useState<boolean>(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (!profileData)
|
||||
return;
|
||||
setCapes([{ url: '', id: '' }, ...profileData.capes.map(cape => ({ url: cape.url, id: cape.id }))]);
|
||||
}, []);
|
||||
|
||||
const [skins, setSkins, loaded] = useSkinHistory();
|
||||
const [selectedSkin, setSelectedSkin] = useState<Skin>({ skin_url: getSkinUrl(null), is_slim: false });
|
||||
const skinData: Skin = { is_slim: profileData.skins[0].variant === 'slim', skin_url: getSkinUrl(profileData.skins[0].url) };
|
||||
const skinData: Skin = { is_slim: profileData?.skins[0].variant === 'slim', skin_url: getSkinUrl(profileData?.skins[0].url) };
|
||||
|
||||
useEffect(() => {
|
||||
if (!loaded)
|
||||
return;
|
||||
|
||||
setSkins(prev => [...prev, skinData]); // ✅ always merges with latest
|
||||
setSkins(prev => [...prev, skinData]);
|
||||
setSelectedSkin(skinData);
|
||||
}, [loaded]);
|
||||
|
||||
|
|
@ -155,6 +165,8 @@ function RouteComponent() {
|
|||
|
||||
const saveSkinToAccount = async () => {
|
||||
try {
|
||||
if (!profile)
|
||||
return;
|
||||
await bindings.core.changeSkin(profile.access_token, selectedSkin.skin_url, selectedSkin.is_slim ? 'slim' : 'classic');
|
||||
if (selectedCape === '') {
|
||||
await bindings.core.removeCape(profile.access_token);
|
||||
|
|
@ -200,6 +212,9 @@ function RouteComponent() {
|
|||
setAnimationName(data.name);
|
||||
};
|
||||
|
||||
if (profileData === null)
|
||||
return <MissingAccountData validSearch={validSearch} />;
|
||||
|
||||
return (
|
||||
<SheetPage
|
||||
headerLarge={(
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue