Security: - Fix path traversal via backslash bypass in sync validate_sync_path() - Replace silent HTTP client fallback with proper error propagation - Add 64KB YAML frontmatter size limit to prevent DoS via crafted files Data integrity: - Reorder delete operations: update metadata before removing files to prevent orphaned metadata entries on crash - Fix task deduplication to use file mtime as tiebreaker when versions are equal, preventing non-deterministic data loss - Add rollback on conflict recovery failure (remove orphaned duplicate files when metadata update fails) - Clean up temp files on atomic write rename failure - Add file-based sync lock to prevent concurrent sync operations - Use saturating_add for task version to prevent overflow Error handling: - Surface move_task rollback failures as structured errors instead of silent warnings - Log WebDAV parallel request failures instead of silently swallowing - Emit watcher-error events to frontend instead of only printing to stderr Frontend: - Fix focus listener leak in auto-sync (clean up if stopAutoSync called while promise pending) - Add prefers-reduced-motion CSS media query for accessibility - Add ARIA labels, roles, and keyboard handlers to TaskItem, BottomSheet, and ConfirmDialog components - Replace BottomSheet children: any with Snippet type https://claude.ai/code/session_01AJoK28N4vqLqzskq6ybGri
43 lines
1,017 B
Svelte
43 lines
1,017 B
Svelte
<script lang="ts">
|
|
import type { Snippet } from "svelte";
|
|
let { onclose, children }: { onclose: () => void; children: Snippet } = $props();
|
|
</script>
|
|
|
|
<!-- Backdrop -->
|
|
<div
|
|
class="fixed inset-0 z-40 bg-black/40"
|
|
role="button"
|
|
tabindex="-1"
|
|
aria-label="Close sheet"
|
|
onclick={onclose}
|
|
onkeydown={(e) => { if (e.key === "Escape") onclose(); }}
|
|
></div>
|
|
|
|
<!-- Sheet -->
|
|
<div
|
|
role="dialog"
|
|
aria-modal="true"
|
|
class="fixed bottom-0 left-0 right-0 z-50 max-h-[70vh] overflow-y-auto rounded-t-2xl bg-surface-light shadow-xl dark:bg-card-dark animate-slide-up"
|
|
>
|
|
<!-- Drag handle -->
|
|
<div class="flex justify-center py-2">
|
|
<div class="h-1 w-8 rounded-full bg-gray-300 dark:bg-gray-600"></div>
|
|
</div>
|
|
{@render children()}
|
|
<div class="h-[env(safe-area-inset-bottom)]"></div>
|
|
</div>
|
|
|
|
<style>
|
|
@keyframes slide-up {
|
|
from {
|
|
transform: translateY(100%);
|
|
}
|
|
to {
|
|
transform: translateY(0);
|
|
}
|
|
}
|
|
.animate-slide-up {
|
|
animation: slide-up 0.25s ease-out;
|
|
}
|
|
</style>
|