From 2779b62f31a82d1de10974c8b28e99263229b504 Mon Sep 17 00:00:00 2001
From: Yuzu
Date: Tue, 30 Jun 2026 21:47:49 +0700
Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20auto=20format?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/main/config/appConfig.ts | 5 +-
src/main/ipc/handlers.ts | 3 +-
src/main/vrchat/avatarService.ts | 6 +-
src/main/vrchat/errors.ts | 6 +-
src/main/vrchat/worldService.ts | 24 +-
src/renderer/src/components/ui/CheckBox.tsx | 4 +-
.../features/account/useAccountSettings.ts | 10 +-
.../src/features/auth/AccountSwitcher.tsx | 8 +-
.../src/features/avatar/AvatarActions.tsx | 16 +-
.../src/features/avatar/AvatarCard.tsx | 4 +-
.../src/features/avatar/AvatarView.tsx | 7 +-
.../src/features/avatar/AvatarsView.tsx | 99 ++++--
.../src/features/avatar/FolderEditModal.tsx | 4 +-
.../src/features/friends/FriendsSidebar.tsx | 21 +-
.../src/features/profile/ProfileView.tsx | 323 +++++++++---------
.../src/features/profile/useFavoriteWorlds.ts | 3 +-
.../src/features/settings/SettingsView.tsx | 9 +-
.../world/MyFavoriteWorldsSection.tsx | 20 +-
src/renderer/src/features/world/WorldCard.tsx | 6 +-
src/renderer/src/features/world/WorldView.tsx | 199 ++++++-----
src/renderer/src/lib/AppConfigContext.tsx | 10 +-
src/renderer/src/lib/ThemeContext.tsx | 13 +-
src/renderer/src/lib/api.ts | 9 +-
src/renderer/src/lib/i18n/index.ts | 8 +-
.../src/lib/i18n/locales/en/avatar.json | 2 +-
.../src/lib/i18n/locales/en/world.json | 2 +-
.../src/lib/i18n/locales/ja/avatar.json | 2 +-
.../src/lib/i18n/locales/ja/world.json | 2 +-
.../src/lib/i18n/locales/th/avatar.json | 2 +-
src/renderer/src/store/worldFavorites.ts | 3 +-
src/shared/ipc.ts | 5 +-
31 files changed, 484 insertions(+), 351 deletions(-)
diff --git a/src/main/config/appConfig.ts b/src/main/config/appConfig.ts
index 15b825d..ed8acd1 100644
--- a/src/main/config/appConfig.ts
+++ b/src/main/config/appConfig.ts
@@ -27,7 +27,10 @@ function normalizePreferences(raw: Partial | undefined): AppPref
const locale = raw?.locale;
const accent = raw?.accent?.trim() || null;
return {
- schemeMode: schemeMode === "light" || schemeMode === "dark" || schemeMode === "auto" ? schemeMode : "auto",
+ schemeMode:
+ schemeMode === "light" || schemeMode === "dark" || schemeMode === "auto"
+ ? schemeMode
+ : "auto",
accent: accent && /^#[\da-f]{6}$/i.test(accent) ? accent : null,
locale: isAppLocale(locale) ? locale : DEFAULT_LOCALE,
showDebugNav: raw?.showDebugNav === true,
diff --git a/src/main/ipc/handlers.ts b/src/main/ipc/handlers.ts
index 5da4e9e..415b364 100644
--- a/src/main/ipc/handlers.ts
+++ b/src/main/ipc/handlers.ts
@@ -81,7 +81,8 @@ const handlers = {
"avatar:select": (avatarId) => guard(() => avatars.selectAvatar(avatarId)),
"avatar:update": ({ avatarId, edit }) => guard(() => avatars.updateAvatar(avatarId, edit)),
"avatar:delete": (avatarId) => guard(() => avatars.deleteAvatar(avatarId)),
- "avatar:favorite": ({ avatarId, folder }) => guard(() => avatars.favoriteAvatar(avatarId, folder)),
+ "avatar:favorite": ({ avatarId, folder }) =>
+ guard(() => avatars.favoriteAvatar(avatarId, folder)),
"avatar:unfavorite": (avatarId) => guard(() => avatars.unfavoriteAvatar(avatarId)),
"avatar:reloadFavorites": () => guard(() => avatars.reloadFavorites()),
"avatar:moveFavorite": ({ avatarId, folder, reload }) =>
diff --git a/src/main/vrchat/avatarService.ts b/src/main/vrchat/avatarService.ts
index 8eb0fe0..57ba885 100644
--- a/src/main/vrchat/avatarService.ts
+++ b/src/main/vrchat/avatarService.ts
@@ -305,7 +305,11 @@ async function restoreAvatarFavorite(
fav: { favoriteId: string; tags: string[] },
): Promise {
await vrc.addFavorite({
- body: { type: "avatar", favoriteId: fav.favoriteId, tags: fav.tags.length ? fav.tags : ["avatars1"] },
+ body: {
+ type: "avatar",
+ favoriteId: fav.favoriteId,
+ tags: fav.tags.length ? fav.tags : ["avatars1"],
+ },
throwOnError: true,
});
}
diff --git a/src/main/vrchat/errors.ts b/src/main/vrchat/errors.ts
index f36fefa..912d258 100644
--- a/src/main/vrchat/errors.ts
+++ b/src/main/vrchat/errors.ts
@@ -54,7 +54,11 @@ export function toApiError(err: unknown): ApiError {
else if (status === undefined && /network|fetch|ENOTFOUND|ECONN/i.test(message)) code = "network";
if (status === 429) {
- return { code, message: "VRChat API rate limit hit. Try again shortly.", retryAfter: retryAfterOf(e) };
+ return {
+ code,
+ message: "VRChat API rate limit hit. Try again shortly.",
+ retryAfter: retryAfterOf(e),
+ };
}
if (status !== undefined && status >= 500) {
return { code, message: "VRChat API is temporarily unavailable. Try again shortly." };
diff --git a/src/main/vrchat/worldService.ts b/src/main/vrchat/worldService.ts
index 7639ddf..d7d4f96 100644
--- a/src/main/vrchat/worldService.ts
+++ b/src/main/vrchat/worldService.ts
@@ -260,7 +260,13 @@ function fillSlots(existing: FavoriteGroupInput[], caps: WorldFavoriteCaps): Fav
for (let i = 1; mine.length < max && i <= max; i++) {
const name = `${prefix}${i}`;
if (taken.has(name)) continue;
- mine.push({ name, displayName: prettyFolderName(name), visibility: "private", worlds: [], vrcPlus });
+ mine.push({
+ name,
+ displayName: prettyFolderName(name),
+ visibility: "private",
+ worlds: [],
+ vrcPlus,
+ });
}
out.push(...mine);
}
@@ -354,10 +360,7 @@ export async function unfavoriteWorlds(worldIds: string[]): Promise {
await reloadMyFavorites();
}
-export async function moveWorldsToFolder(
- worldIds: string[],
- folder: string,
-): Promise {
+export async function moveWorldsToFolder(worldIds: string[], folder: string): Promise {
const vrc = requireActiveClient();
const me = await currentUser();
const records = await favoriteRecords(vrc);
@@ -458,10 +461,11 @@ async function favoriteTypeForExistingFolder(
query: { ownerId: userId, n: 100 },
throwOnError: true,
});
- return (
- data.find((g) => g.name === folder && isWorldGroupType(g.type))?.type ??
- favoriteTypeForFolder(folder)
+ const group = data.find(
+ (g): g is (typeof data)[number] & { type: WorldFavoriteGroupType } =>
+ g.name === folder && isWorldGroupType(g.type),
);
+ return group?.type ?? favoriteTypeForFolder(folder);
}
type AddFavoriteBody = NonNullable[0]>["body"];
@@ -487,7 +491,9 @@ async function favoriteRecordEntries(vrc: VRChat): Promise isWorldGroupType(g.type));
+ const groups = rawGroups.filter((g): g is (typeof rawGroups)[number] & { type: WorldFavoriteGroupType } =>
+ isWorldGroupType(g.type),
+ );
const pageSize = 100;
const entries: WorldFavoriteRecord[] = [];
for (const group of groups) {
diff --git a/src/renderer/src/components/ui/CheckBox.tsx b/src/renderer/src/components/ui/CheckBox.tsx
index 266fd5e..58a9802 100644
--- a/src/renderer/src/components/ui/CheckBox.tsx
+++ b/src/renderer/src/components/ui/CheckBox.tsx
@@ -23,7 +23,9 @@ export function CheckBox({
onChange();
}}
className={`flex size-5 items-center justify-center rounded-md border transition-colors ${
- on ? "border-accent bg-accent text-on-accent" : "border-border bg-surface-2/80 hover:border-accent"
+ on
+ ? "border-accent bg-accent text-on-accent"
+ : "border-border bg-surface-2/80 hover:border-accent"
}`}
>
{indeterminate ? : checked ? : null}
diff --git a/src/renderer/src/features/account/useAccountSettings.ts b/src/renderer/src/features/account/useAccountSettings.ts
index 9fba324..e829715 100644
--- a/src/renderer/src/features/account/useAccountSettings.ts
+++ b/src/renderer/src/features/account/useAccountSettings.ts
@@ -15,15 +15,9 @@ export function useAccountSettings(): {
const [nonce, setNonce] = useState(0);
const [override, setOverride] = useState(null);
- const fetched = useAsync(
- () => api.settings.get(),
- [activeId, nonce],
- "Failed to load settings.",
- );
+ const fetched = useAsync(() => api.settings.get(), [activeId, nonce], "Failed to load settings.");
- const state: Async = override
- ? { status: "ready", data: override }
- : fetched;
+ const state: Async = override ? { status: "ready", data: override } : fetched;
const reload = useCallback(() => {
setOverride(null);
diff --git a/src/renderer/src/features/auth/AccountSwitcher.tsx b/src/renderer/src/features/auth/AccountSwitcher.tsx
index 21b6e02..d67dce5 100644
--- a/src/renderer/src/features/auth/AccountSwitcher.tsx
+++ b/src/renderer/src/features/auth/AccountSwitcher.tsx
@@ -26,7 +26,9 @@ export function AccountSwitcher() {
const status = self?.status ?? "offline";
const activeName = active ? (demoMode ? demoName(active.id) : active.displayName) : "Account";
const activeIcon = demoMode ? undefined : active?.userIcon;
- const activeSub = demoMode ? statusMeta[status].label : self?.statusDescription || statusMeta[status].label;
+ const activeSub = demoMode
+ ? statusMeta[status].label
+ : self?.statusDescription || statusMeta[status].label;
function close() {
setOpen(false);
@@ -57,9 +59,7 @@ export function AccountSwitcher() {
{activeName}
-
- {activeSub}
-
+ {activeSub}
{isOwner ? (
<>
-
: null}
{favoriteOpen ? (
- setFavoriteOpen(false)} />
+ setFavoriteOpen(false)}
+ />
) : null}
- {editOpen ? (
- setEditOpen(false)} />
- ) : null}
+ {editOpen ? setEditOpen(false)} /> : null}
{selected ? : null}
diff --git a/src/renderer/src/features/avatar/AvatarView.tsx b/src/renderer/src/features/avatar/AvatarView.tsx
index b498615..9418446 100644
--- a/src/renderer/src/features/avatar/AvatarView.tsx
+++ b/src/renderer/src/features/avatar/AvatarView.tsx
@@ -17,7 +17,8 @@ export function AvatarView({ avatarId }: { avatarId: string }) {
const { avatar, failed } = useAvatar(avatarId);
if (avatar) return ;
- if (failed) return {t("avatar:detail.unavailable")};
+ if (failed)
+ return {t("avatar:detail.unavailable")};
return ;
}
@@ -55,7 +56,9 @@ function AvatarDetail({ avatar }: { avatar: Avatar }) {
{avatar.releaseStatus !== "public" ? (
{avatar.releaseStatus}
) : null}
- {avatar.featured ? {t("avatar:detail.featured")} : null}
+ {avatar.featured ? (
+ {t("avatar:detail.featured")}
+ ) : null}
{avatar.platforms?.pc ? PC : null}
{avatar.platforms?.android ? Quest : null}
diff --git a/src/renderer/src/features/avatar/AvatarsView.tsx b/src/renderer/src/features/avatar/AvatarsView.tsx
index 0d1867e..9d18a83 100644
--- a/src/renderer/src/features/avatar/AvatarsView.tsx
+++ b/src/renderer/src/features/avatar/AvatarsView.tsx
@@ -126,7 +126,13 @@ function BulkBar({ ids, onDone }: { ids: string[]; onDone: () => void }) {
return (
{busy ? (
-
+
{t("avatar:bulk.unfavoritingProgress", { done: deleteProgress, total: ids.length })}
@@ -164,7 +170,10 @@ function BulkBar({ ids, onDone }: { ids: string[]; onDone: () => void }) {
{busy ? (
- {t("avatar:bulk.unfavoritingProgress", { done: deleteProgress, total: ids.length })}
+ {t("avatar:bulk.unfavoritingProgress", {
+ done: deleteProgress,
+ total: ids.length,
+ })}
, onClick: () => nav.openAvatar(avatar.id) },
- { label: t("avatar:actions.wearing"), icon:
, disabled: true, onClick: () => {} },
+ {
+ label: t("avatar:context.open"),
+ icon:
,
+ onClick: () => nav.openAvatar(avatar.id),
+ },
+ {
+ label: t("avatar:actions.wearing"),
+ icon:
,
+ disabled: true,
+ onClick: () => {},
+ },
{ separator: true },
{
label: folder ? t("avatar:actions.manageFavorite") : t("avatar:actions.favorite"),
@@ -214,15 +232,19 @@ function CurrentAvatarSection() {
onClick: () => setFavoriteOpen(true),
},
...(isOwner
- ? [
- { label: t("avatar:actions.edit"), icon:
, onClick: () => setEditOpen(true) },
+ ? ([
+ {
+ label: t("avatar:actions.edit"),
+ icon:
,
+ onClick: () => setEditOpen(true),
+ },
{
label: t("avatar:actions.delete"),
icon:
,
danger: true,
onClick: () => setDeleteOpen(true),
},
- ] satisfies ContextMenuEntry[]
+ ] satisfies ContextMenuEntry[])
: []),
];
@@ -241,7 +263,11 @@ function CurrentAvatarSection() {
/>
{favoriteOpen ? (
-
setFavoriteOpen(false)} />
+ setFavoriteOpen(false)}
+ />
) : null}
{editOpen ? setEditOpen(false)} /> : null}
(null);
+ const [contextMenu, setContextMenu] = useState<{ x: number; y: number; avatar: Avatar } | null>(
+ null,
+ );
const [editAvatar, setEditAvatar] = useState(null);
const [deleteAvatar, setDeleteAvatar] = useState(null);
@@ -276,9 +304,21 @@ function UploadedTab({ filter }: { filter: AvatarFilter }) {
if (!shown.length) return {t("avatar:empty")}
;
const menuItems = (avatar: Avatar): ContextMenuEntry[] => [
- { label: t("avatar:context.open"), icon: , onClick: () => nav.openAvatar(avatar.id) },
- { label: t("avatar:actions.wear"), icon: , onClick: () => void api.avatar.select(avatar.id) },
- { label: t("avatar:actions.edit"), icon: , onClick: () => setEditAvatar(avatar) },
+ {
+ label: t("avatar:context.open"),
+ icon: ,
+ onClick: () => nav.openAvatar(avatar.id),
+ },
+ {
+ label: t("avatar:actions.wear"),
+ icon: ,
+ onClick: () => void api.avatar.select(avatar.id),
+ },
+ {
+ label: t("avatar:actions.edit"),
+ icon: ,
+ onClick: () => setEditAvatar(avatar),
+ },
{ separator: true },
{
label: t("avatar:actions.delete"),
@@ -363,7 +403,9 @@ function FavoritesTab({ filter, searching }: { filter: AvatarFilter; searching:
setSelected(
new Set(
shown.flatMap((folder) =>
- folder.avatars.filter((avatar) => avatar.releaseStatus === status).map((avatar) => avatar.id),
+ folder.avatars
+ .filter((avatar) => avatar.releaseStatus === status)
+ .map((avatar) => avatar.id),
),
),
);
@@ -387,7 +429,7 @@ function FavoritesTab({ filter, searching }: { filter: AvatarFilter; searching:
setSelected((s) => {
const next = new Set(s);
const all = ids.every((id) => next.has(id));
- for (const id of ids) (all ? next.delete(id) : next.add(id));
+ for (const id of ids) all ? next.delete(id) : next.add(id);
return next;
});
@@ -398,9 +440,21 @@ function FavoritesTab({ filter, searching }: { filter: AvatarFilter; searching:
};
const menuItems = (avatar: Avatar, folder: string): ContextMenuEntry[] => [
- { label: t("avatar:context.open"), icon: , onClick: () => nav.openAvatar(avatar.id) },
- { label: t("avatar:context.select"), icon: , onClick: () => selectOne(avatar.id) },
- { label: t("avatar:actions.wear"), icon: , onClick: () => void api.avatar.select(avatar.id) },
+ {
+ label: t("avatar:context.open"),
+ icon: ,
+ onClick: () => nav.openAvatar(avatar.id),
+ },
+ {
+ label: t("avatar:context.select"),
+ icon: ,
+ onClick: () => selectOne(avatar.id),
+ },
+ {
+ label: t("avatar:actions.wear"),
+ icon: ,
+ onClick: () => void api.avatar.select(avatar.id),
+ },
{ separator: true },
{
label: t("avatar:actions.manageFavorite"),
@@ -480,7 +534,12 @@ function FavoritesTab({ filter, searching }: { filter: AvatarFilter; searching:
? undefined
: (e) => {
e.preventDefault();
- setContextMenu({ x: e.clientX, y: e.clientY, avatar: a, folder: folder.name });
+ setContextMenu({
+ x: e.clientX,
+ y: e.clientY,
+ avatar: a,
+ folder: folder.name,
+ });
}
}
/>
@@ -529,9 +588,7 @@ function FavoritesTab({ filter, searching }: { filter: AvatarFilter; searching:
/>
) : null}
- {selecting && selected.size > 0 ? (
-
- ) : null}
+ {selecting && selected.size > 0 ? : null}
);
}
diff --git a/src/renderer/src/features/avatar/FolderEditModal.tsx b/src/renderer/src/features/avatar/FolderEditModal.tsx
index 0827ec9..757c618 100644
--- a/src/renderer/src/features/avatar/FolderEditModal.tsx
+++ b/src/renderer/src/features/avatar/FolderEditModal.tsx
@@ -65,7 +65,9 @@ export function FolderEditModal({
onChange={(e) => setDisplayName(e.target.value)}
/>