From 081cddaf54b4d525b7983ae2b91b0233bb143f2d Mon Sep 17 00:00:00 2001 From: bboysoul Date: Mon, 7 Sep 2026 15:16:29 +0800 Subject: [PATCH] fix: declutter today view and task rows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Drop redundant

page titles in 习惯 / 倒数日 / 设置与数据 - Wrap today view in three
sub-blocks: 今日任务 / 今日习惯 / 倒数日提醒 (7 天内 countdowns) - Reduce task row noise: priority becomes a colored dot, priority select and priority-text removed; delete action is desktop-only - Hide task row inline actions and pager when only a single page - Add a row-level More menu on sidebar list / folder rows (rename, archive, delete) and a 'archived' toggle that appears only when archived lists exist - Add 'archived-heading' / 'page-subtitle' / 'today-block' / 'priority-dot' / 'task-delete{display:none}' / 'row-menu' styles and a mobile 'min-height:44px' hit area for sidebar row actions - Refresh unit tests in src/style.test.ts to cover the cleanup --- frontend/src/App.vue | 68 ++++++++++++++++----------------- frontend/src/CountdownPanel.vue | 12 ++++-- frontend/src/MvpPanel.vue | 10 ++--- frontend/src/style.css | 10 ++--- frontend/src/style.test.ts | 44 ++++++++++++++++++++- 5 files changed, 96 insertions(+), 48 deletions(-) diff --git a/frontend/src/App.vue b/frontend/src/App.vue index ded6582..7b5a7d7 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -2,7 +2,7 @@ import { computed, nextTick, onMounted, ref, watch } from 'vue' import { ArchiveRestore, CalendarDays, CalendarHeart, Check, ChevronDown, ChevronRight, Folder, - GripVertical, Inbox, ListChecks, ListTodo, Menu, Pencil, Plus, Search, + GripVertical, Inbox, ListChecks, ListTodo, Menu, MoreHorizontal, Pencil, Plus, Search, Settings, Trash2, X, Repeat2, } from 'lucide-vue-next' import { filterTasks, fromDateTimeLocal, groupTaskTree, renderMarkdown, toDateTimeLocal } from './lib/task-utils' @@ -37,7 +37,6 @@ const loading = ref(false) const mobileSidebar = ref(false) const sidebarCollapsed = ref(false) const mobileDetail = ref(false) -const mobileMore = ref(false) const moreSettingsOpen = ref(false) const markdownPreview = ref(false) const showCompleted = ref(true) @@ -51,6 +50,8 @@ const taskSwipeStart = ref<{ id: string; x: number; y: number } | null>(null) const taskPointerStart = ref<{ id: string; x: number; y: number } | null>(null) const taskSwipeOffsets = ref>({}) const taskComposeOpen = ref(false) +const sidebarActionMenu = ref('') +const archivedListsOpen = ref(false) const composeTitle = ref('') const composeListId = ref('') const composeDueAt = ref('') @@ -295,7 +296,7 @@ async function switchView(view: View, listId?: string) { activeView.value = view if (listId) activeList.value = listId page.value = 1 - selectedTask.value = null; mobileSidebar.value = false; mobileDetail.value = false; mobileMore.value = false; taskComposeOpen.value = false + selectedTask.value = null; mobileSidebar.value = false; mobileDetail.value = false; taskComposeOpen.value = false if (view === 'trash') await loadTrash() else if (view === 'today') await loadTodayView() else if (!isTaskView(view)) tasks.value = [] @@ -459,6 +460,8 @@ async function restoreList(item: TaskList) { try { await api(`/lists/${item.id}/restore`, { method: 'POST' }); await loadArchivedLists(); await refreshAll(); toast('清单已恢复') } catch (reason) { fail(reason) } } function toggleFolder(id: string) { const next = new Set(expandedFolders.value); next.has(id) ? next.delete(id) : next.add(id); expandedFolders.value = next } +function toggleSidebarActionMenu(id: string) { sidebarActionMenu.value = sidebarActionMenu.value === id ? '' : id } +function closeSidebarActionMenu() { sidebarActionMenu.value = '' } function formatDue(value: string | null) { return value ? new Intl.DateTimeFormat('zh-CN', { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' }).format(new Date(value)) : '' } function previousPage() { if (page.value <= 1 || loading.value) return @@ -487,7 +490,7 @@ onMounted(bootstrap)
-