favoriting

This commit is contained in:
2026-03-06 13:53:26 -06:00
parent 10d76eb3c1
commit 09557d49a4
8 changed files with 155 additions and 29 deletions
+24 -4
View File
@@ -1,9 +1,9 @@
import { type Component, createEffect, createSignal, For, createMemo, onCleanup } from "solid-js";
import { Sheet, SheetContent } from "@/components/ui/sheet";
import { type Task, removeTask, restoreTask, updateTask, saveTaskAsTemplate, shareTask, revokeShare, splitTask, loadTaskContent, currentTaskContext, cleanupTaskAttachments } from "@/store";
import { type Task, removeTask, restoreTask, updateTask, saveTaskAsTemplate, shareTask, revokeShare, splitTask, loadTaskContent, currentTaskContext, cleanupTaskAttachments, getFavoriteTag } from "@/store";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { ArrowUpCircle, Clock, Calendar, Type, Trash2, X, Copy, MoreHorizontal, Gauge, Share2, UserMinus, GitBranch, Tag, Settings } from "lucide-solid";
import { ArrowUpCircle, Clock, Calendar, Type, Trash2, X, Copy, MoreHorizontal, Gauge, Share2, UserMinus, GitBranch, Tag, Settings, Star } from "lucide-solid";
import { StatusCircle } from "./StatusCircle";
import { calculateDateFromUrgency, calculateUrgencyFromDate } from "@/store";
import { Button } from "./ui/button";
@@ -201,10 +201,10 @@ export const TaskDetail: Component<TaskDetailProps> = (props) => {
// We are in a bucket view. Hide the tag that matches this bucket's name.
// Buckets are now tagged with '@' + name.
const bucketTagName = `@${(ctx as { name: string }).name.toLowerCase()}`;
return tags.filter(t => t.toLowerCase() !== bucketTagName);
return tags.filter(t => t.toLowerCase() !== bucketTagName && !t.endsWith("_favorite__"));
}
return tags;
return tags.filter(t => !t.endsWith("_favorite__"));
});
const statusOptions = createMemo(() => getStatusOptionsForTask(props.task.recurrence));
@@ -361,6 +361,26 @@ export const TaskDetail: Component<TaskDetailProps> = (props) => {
</Select>
</div>
{/* Favorite */}
<div class="flex items-center gap-1 group shrink-0">
<span class="text-[0.625rem] uppercase font-bold tracking-wider text-muted-foreground/70 hidden sm:inline">Favorite</span>
<Button
variant="ghost"
size="sm"
class={cn("h-8 px-1 sm:px-2 text-[0.625rem] font-bold uppercase tracking-wider transition-colors shrink-0", props.task.tags?.includes(getFavoriteTag()) ? "text-amber-500 hover:bg-amber-500/10" : "text-muted-foreground hover:bg-muted/50 hover:text-foreground")}
onClick={() => {
const favTag = getFavoriteTag();
const currentTags = props.task.tags || [];
const isFav = currentTags.includes(favTag);
const newTags = isFav ? currentTags.filter(t => t !== favTag) : [...currentTags, favTag];
updateTags(newTags);
}}
>
<Star size={14} class={cn("opacity-70 group-hover:opacity-100 transition-opacity shrink-0", props.task.tags?.includes(getFavoriteTag()) && "fill-amber-500")} />
<span class="hidden sm:inline sm:ml-1.5">{props.task.tags?.includes(getFavoriteTag()) ? "Starred" : "Star"}</span>
</Button>
</div>
{/* Commands Shortcut */}
<div class="flex items-center gap-1 shrink-0">
<Button