fix: dock calendar event detail on desktop
This commit is contained in:
+13
-12
@@ -98,9 +98,9 @@ const desktopViewportWidth = ref(window.innerWidth)
|
||||
const sidebarWidth = ref(readDesktopPaneWidth(window.localStorage, SIDEBAR_WIDTH_STORAGE_KEY, 236))
|
||||
const detailWidth = ref(readDesktopPaneWidth(window.localStorage, DETAIL_WIDTH_STORAGE_KEY, 350))
|
||||
const resizingPane = ref<DesktopPane | null>(null)
|
||||
const sidebarMaxWidth = computed(() => getDesktopPaneMax('sidebar', desktopViewportWidth.value, selectedTask.value || habitDetailOpen.value ? detailWidth.value : 0))
|
||||
const sidebarMaxWidth = computed(() => getDesktopPaneMax('sidebar', desktopViewportWidth.value, selectedTask.value || habitDetailOpen.value || calendarDetailOpen.value ? detailWidth.value : 0))
|
||||
const detailMaxWidth = computed(() => getDesktopPaneMax('detail', desktopViewportWidth.value, sidebarCollapsed.value ? 0 : sidebarWidth.value))
|
||||
const detailSeparatorLabel = computed(() => habitDetailOpen.value && !selectedTask.value ? '调整习惯详情宽度' : '调整任务详情宽度')
|
||||
const detailSeparatorLabel = computed(() => calendarDetailOpen.value ? '调整日程详情宽度' : habitDetailOpen.value && !selectedTask.value ? '调整习惯详情宽度' : '调整任务详情宽度')
|
||||
const shellStyle = computed(() => ({ '--sidebar-width': `${sidebarWidth.value}px`, '--detail-width': `${detailWidth.value}px` }))
|
||||
let paneResizePointerId: number | null = null
|
||||
let paneResizeCaptureTarget: HTMLElement | null = null
|
||||
@@ -194,6 +194,7 @@ const memoPanel = ref<InstanceType<typeof MemoPanel> | null>(null)
|
||||
const memoTrash = ref(false)
|
||||
const memoDetailOpen = ref(false)
|
||||
const habitDetailOpen = ref(false)
|
||||
const calendarDetailOpen = ref(false)
|
||||
const compactLayout = ref(desktopViewportWidth.value <= 930)
|
||||
const memoShellState = computed(() => deriveMemoShellState({ view: activeView.value, detailOpen: memoDetailOpen.value, compact: compactLayout.value, trash: memoTrash.value }))
|
||||
const memoBackgroundInert = computed(() => memoShellState.value.backgroundInert)
|
||||
@@ -365,11 +366,11 @@ function movePaneResize(event: PointerEvent) {
|
||||
if (!resizingPane.value || event.pointerId !== paneResizePointerId) return
|
||||
if (event.buttons === 0) { stopPaneResize(); return }
|
||||
const nextWidth = resizingPane.value === 'sidebar' ? event.clientX : window.innerWidth - event.clientX
|
||||
if (resizingPane.value === 'sidebar') sidebarWidth.value = clampDesktopPaneWidth('sidebar', nextWidth, window.innerWidth, selectedTask.value || habitDetailOpen.value ? detailWidth.value : 0)
|
||||
if (resizingPane.value === 'sidebar') sidebarWidth.value = clampDesktopPaneWidth('sidebar', nextWidth, window.innerWidth, selectedTask.value || habitDetailOpen.value || calendarDetailOpen.value ? detailWidth.value : 0)
|
||||
else detailWidth.value = clampDesktopPaneWidth('detail', nextWidth, window.innerWidth, sidebarCollapsed.value ? 0 : sidebarWidth.value)
|
||||
}
|
||||
function startPaneResize(pane: DesktopPane, event: PointerEvent) {
|
||||
if (event.button !== 0 || compactLayout.value || (pane === 'detail' && !selectedTask.value && !habitDetailOpen.value)) return
|
||||
if (event.button !== 0 || compactLayout.value || (pane === 'detail' && !selectedTask.value && !habitDetailOpen.value && !calendarDetailOpen.value)) return
|
||||
event.preventDefault()
|
||||
paneResizeCaptureTarget = event.currentTarget as HTMLElement
|
||||
paneResizeCaptureTarget.setPointerCapture?.(event.pointerId)
|
||||
@@ -380,7 +381,7 @@ function resizePaneWithKeyboard(pane: DesktopPane, event: KeyboardEvent) {
|
||||
if (!['ArrowLeft', 'ArrowRight'].includes(event.key)) return
|
||||
event.preventDefault()
|
||||
const direction = event.key === 'ArrowRight' ? 1 : -1
|
||||
if (pane === 'sidebar') sidebarWidth.value = clampDesktopPaneWidth('sidebar', sidebarWidth.value + direction * 12, window.innerWidth, selectedTask.value || habitDetailOpen.value ? detailWidth.value : 0)
|
||||
if (pane === 'sidebar') sidebarWidth.value = clampDesktopPaneWidth('sidebar', sidebarWidth.value + direction * 12, window.innerWidth, selectedTask.value || habitDetailOpen.value || calendarDetailOpen.value ? detailWidth.value : 0)
|
||||
else detailWidth.value = clampDesktopPaneWidth('detail', detailWidth.value - direction * 12, window.innerWidth, sidebarCollapsed.value ? 0 : sidebarWidth.value)
|
||||
writeDesktopPaneWidth(window.localStorage, pane === 'sidebar' ? SIDEBAR_WIDTH_STORAGE_KEY : DETAIL_WIDTH_STORAGE_KEY, pane === 'sidebar' ? sidebarWidth.value : detailWidth.value)
|
||||
}
|
||||
@@ -770,7 +771,7 @@ async function switchView(view: View, listId?: string) {
|
||||
if (listId) activeList.value = listId
|
||||
writeStoredNavigation(window.localStorage, NAVIGATION_STORAGE_KEY, view, activeList.value)
|
||||
page.value = 1
|
||||
habitComposer.value?.closeHabitDetail(true); selectedTask.value = null; habitDetailOpen.value = false; taskSelectionGeneration.value += 1; mobileSidebar.value = false; mobileDetail.value = false; taskComposeGeneration.value += 1; taskComposeOpen.value = false; sidebarCreateOpen.value = false; sidebarAction.value = null
|
||||
habitComposer.value?.closeHabitDetail(true); selectedTask.value = null; habitDetailOpen.value = false; calendarDetailOpen.value = false; taskSelectionGeneration.value += 1; mobileSidebar.value = false; mobileDetail.value = false; taskComposeGeneration.value += 1; taskComposeOpen.value = false; sidebarCreateOpen.value = false; sidebarAction.value = null
|
||||
if (view !== 'memos') memoDetailOpen.value = false
|
||||
if (view === 'trash') await loadTrash()
|
||||
else if (view === 'today') await loadTodayView()
|
||||
@@ -1664,13 +1665,13 @@ async function nextPage() {
|
||||
|
||||
function reconcileDesktopPaneWidths() {
|
||||
if (compactLayout.value) return
|
||||
if (selectedTask.value || habitDetailOpen.value) {
|
||||
if (selectedTask.value || habitDetailOpen.value || calendarDetailOpen.value) {
|
||||
detailWidth.value = clampDesktopPaneWidth('detail', detailWidth.value, desktopViewportWidth.value, sidebarCollapsed.value ? 0 : sidebarWidth.value)
|
||||
}
|
||||
sidebarWidth.value = clampDesktopPaneWidth('sidebar', sidebarWidth.value, desktopViewportWidth.value, selectedTask.value || habitDetailOpen.value ? detailWidth.value : 0)
|
||||
sidebarWidth.value = clampDesktopPaneWidth('sidebar', sidebarWidth.value, desktopViewportWidth.value, selectedTask.value || habitDetailOpen.value || calendarDetailOpen.value ? detailWidth.value : 0)
|
||||
}
|
||||
|
||||
watch([selectedTask, habitDetailOpen, sidebarCollapsed], reconcileDesktopPaneWidths)
|
||||
watch([selectedTask, habitDetailOpen, calendarDetailOpen, sidebarCollapsed], reconcileDesktopPaneWidths)
|
||||
|
||||
function handlePaneResizeBlur() { stopPaneResize() }
|
||||
|
||||
@@ -1725,7 +1726,7 @@ onUnmounted(() => {
|
||||
<p v-if="initialized" class="auth-footnote">登录后继续你的清单</p>
|
||||
</form>
|
||||
</div>
|
||||
<div v-else class="shell" :class="{ 'today-active': activeView==='today', 'sidebar-collapsed': sidebarCollapsed, 'detail-open': Boolean(selectedTask) || habitDetailOpen, 'memo-detail-open': activeView==='memos' && memoDetailOpen, 'mobile-sidebar-open': mobileSidebar, 'pane-resizing': Boolean(resizingPane) }" :style="shellStyle">
|
||||
<div v-else class="shell" :class="{ 'today-active': activeView==='today', 'sidebar-collapsed': sidebarCollapsed, 'detail-open': Boolean(selectedTask) || habitDetailOpen || calendarDetailOpen, 'memo-detail-open': activeView==='memos' && memoDetailOpen, 'mobile-sidebar-open': mobileSidebar, 'pane-resizing': Boolean(resizingPane) }" :style="shellStyle">
|
||||
<div v-if="mobileSidebar || mobileDetail" class="scrim" @click="mobileSidebar=false;mobileDetail=false" />
|
||||
<aside class="sidebar" :inert="memoBackgroundInert ? true : undefined" :class="{ open: mobileSidebar }" @keydown.esc="sidebarCreateOpen=false;closeArchivedListAction();closeSidebarAction()">
|
||||
<div class="brand-row"><div class="brand small brand-lockup"><img class="brand-logo" src="/dodo-logo.svg" alt=""><span class="brand-wordmark">dodo</span></div><button class="icon mobile-only" aria-label="关闭菜单" @click="mobileSidebar=false"><X /></button></div>
|
||||
@@ -1799,7 +1800,7 @@ onUnmounted(() => {
|
||||
<MvpPanel ref="habitComposer" :key="activeView" :view="activeView as 'habits'|'settings'" :show-completed="showCompleted" :compact-layout="compactLayout" @update:show-completed="showCompleted=$event" @detail="handleHabitDetail" @changed="refreshAll" @notice="toast" @logout="completeLogout" />
|
||||
</template>
|
||||
<MemoPanel v-else-if="activeView==='memos'" ref="memoPanel" :request="api" @scope="memoTrash=$event==='trash'" @detail="memoDetailOpen=$event" @notice="toast" />
|
||||
<CalendarPanel v-else-if="activeView==='calendar'" @notice="toast" />
|
||||
<CalendarPanel v-else-if="activeView==='calendar'" :compact-layout="compactLayout" @detail="calendarDetailOpen=$event" @notice="toast" />
|
||||
<CountdownPanel ref="countdownComposer" v-else-if="activeView==='countdowns'" @notice="toast" />
|
||||
<template v-else>
|
||||
<section v-if="activeView==='today'" class="today-context" aria-label="今日概览">
|
||||
@@ -1862,7 +1863,7 @@ onUnmounted(() => {
|
||||
</div>
|
||||
</template>
|
||||
</main>
|
||||
<div v-if="selectedTask || habitDetailOpen" class="pane-resizer pane-resizer--detail" role="separator" :aria-label="detailSeparatorLabel" aria-orientation="vertical" aria-valuemin="300" :aria-valuemax="detailMaxWidth" :aria-valuenow="detailWidth" tabindex="0" @pointerdown="startPaneResize('detail',$event)" @lostpointercapture="handlePaneLostPointerCapture" @keydown="resizePaneWithKeyboard('detail',$event)" />
|
||||
<div v-if="selectedTask || habitDetailOpen || calendarDetailOpen" class="pane-resizer pane-resizer--detail" role="separator" :aria-label="detailSeparatorLabel" aria-orientation="vertical" aria-valuemin="300" :aria-valuemax="detailMaxWidth" :aria-valuenow="detailWidth" tabindex="0" @pointerdown="startPaneResize('detail',$event)" @lostpointercapture="handlePaneLostPointerCapture" @keydown="resizePaneWithKeyboard('detail',$event)" />
|
||||
|
||||
<AppSheet v-if="selectedTask" :open="true" :modal="compactLayout" variant="detail" panel-class="detail" title-id="task-detail-title" :close-on-scrim="compactLayout" :busy="taskDetailBusy" @close="closeTaskDetail" @submit.prevent="saveSelectedTaskChanges">
|
||||
<div class="detail-head"><span id="task-detail-title">任务详情</span><button class="icon" type="button" :disabled="taskDetailBusy" aria-label="关闭详情" @click="closeTaskDetail"><X/></button></div>
|
||||
|
||||
Reference in New Issue
Block a user