diff --git a/src/components/TaskItem.tsx b/src/components/TaskItem.tsx index 9b70771..99f833c 100644 --- a/src/components/TaskItem.tsx +++ b/src/components/TaskItem.tsx @@ -4,19 +4,20 @@ import dayjs from 'dayjs'; import Checkbox from 'rc-checkbox'; import { InfoCircle } from 'tabler-icons-react'; import useUserConfigs from '../hooks/useUserConfigs'; -import useTask, { Task } from '../hooks/useTask'; +import useTask from '../hooks/useTask'; import 'rc-checkbox/assets/index.css'; +import { TaskEntityObject } from '../models/TaskEntity'; export interface ITaskItemProps { - item: Task; - onChange(task: Task): void; + item: TaskEntityObject; + onChange(task: TaskEntityObject): void; } const TaskItem: React.FC = (props) => { const { item: task, onChange } = props; const { preferredDateFormat } = useUserConfigs(); - const { uuid, isDone, scheduled, content, toggle } = useTask(task); - const [checked, setChecked] = React.useState(isDone); + const { uuid, completed, scheduled, content, toggle } = useTask(task); + const [checked, setChecked] = React.useState(completed); const isExpiredTask = useMemo(() => { if (!scheduled) { @@ -37,7 +38,7 @@ const TaskItem: React.FC = (props) => { window.logseq.hideMainUI(); }; - const contentClassName = classnames('line-clamp-4', { + const contentClassName = classnames('line-clamp-3', { 'line-through': checked, 'text-gray-400': checked, }); diff --git a/src/hooks/useTask.ts b/src/hooks/useTask.ts index 71462aa..700683d 100644 --- a/src/hooks/useTask.ts +++ b/src/hooks/useTask.ts @@ -1,18 +1,9 @@ -import { BlockEntity } from '@logseq/libs/dist/LSPlugin.user'; import { useCallback, useMemo } from 'react'; +import { TaskEntityObject, TaskMarker } from '../models/TaskEntity'; import useUserConfigs from './useUserConfigs'; -export type Task = BlockEntity; - -export enum TaskMarker { - LATER = 'LATER', - NOW = 'NOW', - TODO = 'TODO', - DONE = 'DONE', -} - -const useTask = (task: Task) => { - const { uuid, marker, scheduled } = task; +const useTask = (task: TaskEntityObject) => { + const { uuid, marker, scheduled, completed } = task; const { preferredTodo } = useUserConfigs(); const content = useMemo(() => { @@ -24,22 +15,20 @@ const useTask = (task: Task) => { return content.trim(); }, [task]); - const isDone = useMemo(() => task.marker === TaskMarker.DONE, [task]); - const toggle = useCallback(async () => { - const nextMarker = isDone ? preferredTodo : TaskMarker.DONE; + const nextMarker = completed ? preferredTodo : TaskMarker.DONE; await window.logseq.Editor.updateBlock( uuid, - task.content.replace(task.marker, nextMarker), + task.content.replace(marker, nextMarker), ); - }, [isDone, preferredTodo, task]); + }, [completed, preferredTodo, task]); return { uuid, marker, content, scheduled, - isDone, + completed, toggle, }; }; diff --git a/src/hooks/useTaskQuery.ts b/src/hooks/useTaskQuery.ts index ff72861..d182e4f 100644 --- a/src/hooks/useTaskQuery.ts +++ b/src/hooks/useTaskQuery.ts @@ -1,29 +1,26 @@ import { BlockEntity, PageEntity } from '@logseq/libs/dist/LSPlugin.user'; import useSwr from 'swr'; - -export function getBlockUUID(block: BlockEntity) { - if (typeof block.uuid === 'string') { - return block.uuid; - } - // @ts-ignore - return block.uuid.$uuid$; -} +import TaskEntity from '../models/TaskEntity'; +import { getBlockUUID } from '../utils'; const useTaskQuery = (query: string) => { const { data, error, mutate } = useSwr(query, async (query) => { const collections = await window.logseq.DB.datascriptQuery(query); const tasks = await Promise.all( - collections.map(async ([block]) => { - const uuid = getBlockUUID(block); - const taskBlock = await window.logseq.Editor.getBlock(uuid, { includeChildren: true }); - const scheduled = taskBlock?.scheduled ?? taskBlock?.deadline ?? (taskBlock?.page as PageEntity)?.journalDay; - return { - ...taskBlock, - scheduled, - } as BlockEntity; + collections.map(async ([item]) => { + const uuid = getBlockUUID(item); + const block = await window.logseq.Editor.getBlock(uuid, { includeChildren: true }); + const page = await window.logseq.Editor.getPage((block?.page as PageEntity).name); + return new TaskEntity(block!, page!); }), ); - return tasks.sort((a, b) => b.scheduled - a.scheduled); + return ( + tasks + // @ts-ignore + .filter((task) => !task.getPageProperty('todoIgnore')) + .sort((a, b) => b.scheduled - a.scheduled) + .map((task) => task.toObject()) + ); }); return { diff --git a/src/models/TaskEntity.ts b/src/models/TaskEntity.ts new file mode 100644 index 0000000..96d70a4 --- /dev/null +++ b/src/models/TaskEntity.ts @@ -0,0 +1,64 @@ +import { BlockEntity, PageEntity } from '@logseq/libs/dist/LSPlugin.user'; +import { getBlockUUID } from '../utils'; + +export enum TaskMarker { + LATER = 'LATER', + NOW = 'NOW', + TODO = 'TODO', + DONE = 'DONE', +} + +export interface TaskEntityObject { + uuid: string; + content: string; + marker: TaskMarker; + scheduled: number; + completed: boolean; +} + +class TaskEntity { + private block: BlockEntity; + private page: PageEntity; + + constructor(block: BlockEntity, page: PageEntity) { + this.block = block; + this.page = page; + } + + public get uuid() { + return getBlockUUID(this.block); + } + + public get content() { + return this.block.content; + } + + public get marker() { + return this.block.marker; + } + + public get scheduled() { + return this.block.scheduled ?? this.block.deadline ?? this.page.journalDay; + } + + public get completed() { + return this.marker === TaskMarker.DONE; + } + + public getPageProperty(key: string) { + // @ts-ignore + return this.page.properties?.[key]; + } + + public toObject(): TaskEntityObject { + return { + uuid: this.uuid, + content: this.content, + marker: this.marker, + scheduled: this.scheduled, + completed: this.completed, + }; + } +} + +export default TaskEntity; diff --git a/src/utils.ts b/src/utils.ts new file mode 100644 index 0000000..5bc3a88 --- /dev/null +++ b/src/utils.ts @@ -0,0 +1,9 @@ +import { BlockEntity } from "@logseq/libs/dist/LSPlugin"; + +export function getBlockUUID(block: BlockEntity) { + if (typeof block.uuid === 'string') { + return block.uuid; + } + // @ts-ignore + return block.uuid.$uuid$; +}