feat(layout/nav): add reset-to-default menu order action

This commit is contained in:
Slinetrac 2025-12-17 11:18:46 +08:00
parent 721929a2a1
commit a9e6391417
No known key found for this signature in database
18 changed files with 62 additions and 1 deletions

View File

@ -39,6 +39,7 @@
- 日志页面支持按时间倒序
- 增加「重新激活订阅」的全局快捷键
- WebView2 Runtime 修复构建升级到 133.0.3065.92
- 侧边栏右键新增「恢复默认排序」
</details>

View File

@ -13,6 +13,7 @@
},
"menu": {
"reorderMode": "Menu reorder mode",
"restoreDefaultOrder": "Restore default order",
"unlock": "Unlock menu order",
"lock": "Lock menu order"
}

View File

@ -13,6 +13,7 @@
},
"menu": {
"reorderMode": "Menu reorder mode",
"restoreDefaultOrder": "Restore default order",
"unlock": "Unlock menu order",
"lock": "Lock menu order"
}

View File

@ -13,6 +13,7 @@
},
"menu": {
"reorderMode": "Menu reorder mode",
"restoreDefaultOrder": "Restore default order",
"unlock": "Unlock menu order",
"lock": "Lock menu order"
}

View File

@ -13,6 +13,7 @@
},
"menu": {
"reorderMode": "Menu reorder mode",
"restoreDefaultOrder": "Restore default order",
"unlock": "Unlock menu order",
"lock": "Lock menu order"
}

View File

@ -13,6 +13,7 @@
},
"menu": {
"reorderMode": "Menu reorder mode",
"restoreDefaultOrder": "Restore default order",
"unlock": "Unlock menu order",
"lock": "Lock menu order"
}

View File

@ -13,6 +13,7 @@
},
"menu": {
"reorderMode": "Menu reorder mode",
"restoreDefaultOrder": "Restore default order",
"unlock": "Unlock menu order",
"lock": "Lock menu order"
}

View File

@ -13,6 +13,7 @@
},
"menu": {
"reorderMode": "Menu reorder mode",
"restoreDefaultOrder": "Restore default order",
"unlock": "Unlock menu order",
"lock": "Lock menu order"
}

View File

@ -13,6 +13,7 @@
},
"menu": {
"reorderMode": "메뉴 재정렬 모드",
"restoreDefaultOrder": "Restore default order",
"unlock": "메뉴 순서 잠금 해제",
"lock": "메뉴 순서 잠금"
}

View File

@ -13,6 +13,7 @@
},
"menu": {
"reorderMode": "Menu reorder mode",
"restoreDefaultOrder": "Restore default order",
"unlock": "Unlock menu order",
"lock": "Lock menu order"
}

View File

@ -13,6 +13,7 @@
},
"menu": {
"reorderMode": "Menu reorder mode",
"restoreDefaultOrder": "Restore default order",
"unlock": "Unlock menu order",
"lock": "Lock menu order"
}

View File

@ -13,6 +13,7 @@
},
"menu": {
"reorderMode": "Menu reorder mode",
"restoreDefaultOrder": "Restore default order",
"unlock": "Unlock menu order",
"lock": "Lock menu order"
}

View File

@ -13,6 +13,7 @@
},
"menu": {
"reorderMode": "菜单排序模式",
"restoreDefaultOrder": "恢复默认排序",
"unlock": "解锁菜单排序",
"lock": "锁定菜单排序"
}

View File

@ -13,6 +13,7 @@
},
"menu": {
"reorderMode": "選單排序模式",
"restoreDefaultOrder": "恢復預設排序",
"unlock": "解鎖選單排序",
"lock": "鎖定選單排序"
}

View File

@ -154,7 +154,13 @@ const Layout = () => {
[patchVerge],
);
const { menuOrder, navItemMap, handleMenuDragEnd } = useNavMenuOrder({
const {
menuOrder,
navItemMap,
handleMenuDragEnd,
isDefaultOrder,
resetMenuOrder,
} = useNavMenuOrder({
enabled: menuUnlocked,
items: navItems,
storedOrder: verge?.menu_order,
@ -175,6 +181,11 @@ const Layout = () => {
setMenuContextPosition(null);
}, []);
const handleResetMenuOrder = useCallback(() => {
setMenuContextPosition(null);
void resetMenuOrder();
}, [resetMenuOrder]);
const handleUnlockMenu = useCallback(() => {
setMenuUnlocked(true);
setMenuContextPosition(null);
@ -427,6 +438,13 @@ const Layout = () => {
? t("layout.components.navigation.menu.lock")
: t("layout.components.navigation.menu.unlock")}
</MenuItem>
<MenuItem
onClick={handleResetMenuOrder}
dense
disabled={isDefaultOrder}
>
{t("layout.components.navigation.menu.restoreDefaultOrder")}
</MenuItem>
</Menu>
<div className="the-traffic">

View File

@ -82,6 +82,11 @@ export const useNavMenuOrder = <T extends { path: string }>({
dispatchMenuOrder({ type: "sync", payload: configMenuOrder });
}, [configMenuOrder]);
const isDefaultOrder = useMemo(
() => areOrdersEqual(menuOrder, defaultOrder),
[menuOrder, defaultOrder],
);
const handleMenuDragEnd = useCallback(
async (event: DragEndEvent) => {
if (!enabled) {
@ -120,9 +125,31 @@ export const useNavMenuOrder = <T extends { path: string }>({
[enabled, menuOrder, onOptimisticUpdate, onPersist],
);
const resetMenuOrder = useCallback(async () => {
if (isDefaultOrder) {
return;
}
const previousOrder = [...menuOrder];
const nextOrder = [...defaultOrder];
dispatchMenuOrder({ type: "sync", payload: nextOrder });
onOptimisticUpdate?.(nextOrder);
try {
await onPersist(nextOrder);
} catch (error) {
console.error("Failed to reset menu order:", error);
dispatchMenuOrder({ type: "sync", payload: previousOrder });
onOptimisticUpdate?.(previousOrder);
}
}, [defaultOrder, isDefaultOrder, menuOrder, onOptimisticUpdate, onPersist]);
return {
menuOrder,
navItemMap,
handleMenuDragEnd,
isDefaultOrder,
resetMenuOrder,
};
};

View File

@ -105,6 +105,7 @@ export const translationKeys = [
"layout.components.navigation.tabs.unlock",
"layout.components.navigation.tabs.settings",
"layout.components.navigation.menu.reorderMode",
"layout.components.navigation.menu.restoreDefaultOrder",
"layout.components.navigation.menu.unlock",
"layout.components.navigation.menu.lock",
"logs.page.title",

View File

@ -181,6 +181,7 @@ export interface TranslationResources {
menu: {
lock: string;
reorderMode: string;
restoreDefaultOrder: string;
unlock: string;
};
tabs: {