import { _ } from '../../locale'; import CommandService from '../CommandService'; import { ItemFlow, ListRenderer, OnClickEvent } from '../plugins/api/noteListType'; import checkboxPieCss from './checkboxPieCss'; import isNoteLockEnabled from '../noteLock/isNoteLockEnabled'; import isSyncDisabledConflict from './isSyncDisabledConflict'; import { cleanSnippet, formatNoteListDate } from './noteListSnippetUtils'; interface CheckboxStats { total: number; checked: number; percent: number; isComplete: boolean; } interface Props { note: { id: string; title: string; is_todo: number; todo_completed: number; is_locked: number; is_conflict: number; conflict_original_id: string; share_id: string; checkboxes: CheckboxStats | null; user_updated_time?: number; body?: string; is_pinned?: number; }; item: { // index: number; size: { height: number; }; selected: boolean; }; } const renderer: ListRenderer = { id: 'compact', label: async () => _('Compact'), flow: ItemFlow.TopToBottom, itemSize: { width: 0, height: 56, }, dependencies: [ // 'item.index', 'item.selected', 'item.size.height', 'note.checkboxes', 'note.id', 'note.is_conflict', 'note.is_locked', 'note.is_published', 'note.is_shared', 'note.share_id', 'note.conflict_original_id', 'note.is_todo', 'note.isWatched', 'note.title', 'note.todo_completed', 'note.todoStatusText', 'note.user_updated_time', 'note.body', 'note.is_pinned', ], itemCss: // css ` &:before { content: ''; border-bottom: 1px solid var(--joplin-divider-color); width: 90%; position: absolute; bottom: 0; left: 5%; } > .content.-selected { background-color: var(--joplin-selected-color); } &:hover, &.-focus-visible > .content { background-color: var(--joplin-background-color-hover3); } > .content { display: flex; box-sizing: border-box; position: relative; width: 100%; height: 100%; padding: 8px 16px; align-items: center; > .checkbox { display: flex; align-items: center; margin-right: 8px; > input { margin: 0; } } > .item-body { display: flex; flex-direction: column; justify-content: center; min-width: 0; flex: 1 1 0%; gap: 3px; > .title { font-family: var(--joplin-font-family); font-size: var(--joplin-font-size); text-decoration: none; color: var(--joplin-color); cursor: default; white-space: nowrap; display: flex; align-items: center; overflow: hidden; > .pinnedicon { padding-right: 6px; color: var(--joplin-color-accent, #007aff); font-size: 11px; } > .watchedicon { display: none; padding-right: 4px; color: var(--joplin-color); } > .lockedicon { padding-right: 4px; color: var(--joplin-color); } > .syncdisabledicon { background-color: var(--joplin-color-faded); display: inline-block; flex-shrink: 0; height: 14px; margin-right: 4px; mask: url('vendor/lib/images/cloud-offline-outline.svg') center / contain no-repeat; -webkit-mask: url('vendor/lib/images/cloud-offline-outline.svg') center / contain no-repeat; width: 14px; } > span { overflow: hidden; text-overflow: ellipsis; } } > .details { display: flex; align-items: baseline; gap: 6px; font-size: 12px; line-height: 1.3; color: var(--joplin-color-faded); overflow: hidden; white-space: nowrap; > .date { flex-shrink: 0; font-variant-numeric: tabular-nums; color: var(--joplin-color); opacity: 0.75; } > .snippet { overflow: hidden; text-overflow: ellipsis; opacity: 0.65; } } } > .checkbox-pie { display: flex; align-items: center; padding-right: 12px; padding-left: 8px; } } ${checkboxPieCss} > .content.-shared { > .item-body > .title { color: var(--joplin-color-warn3); } } > .content.-published { > .item-body > .title { color: var(--joplin-color4); } } > .content.-published.-selected { > .item-body > .title { color: var(--joplin-color); } } > .content.-completed { > .item-body > .title { opacity: 0.5; } } > .content.-watched { > .item-body > .title { > .watchedicon { display: inline; } } } `, headerTemplate: // html ` `, onHeaderClick: async (event: OnClickEvent) => { const field = event.elementId === 'title' ? 'title' : 'user_updated_time'; void CommandService.instance().execute('toggleNotesSortOrderField', field); }, itemTemplate: // html `
{{#note.is_todo}}
{{/note.is_todo}}
{{#note.is_pinned}}{{/note.is_pinned}} {{#note.syncDisabled}}{{/note.syncDisabled}} {{#note.is_locked}}{{/note.is_locked}} {{note.title}}
{{#note.formattedDate}}{{note.formattedDate}}{{/note.formattedDate}} {{note.snippet}}
{{#checkboxStats}}
{{#isComplete}}
✓
{{/isComplete}} {{^isComplete}}
{{/isComplete}}
{{/checkboxStats}}
`, onRenderNote: async (props: Props) => { const snippet = cleanSnippet(props.note.body || '', props.note.title); const formattedDate = props.note.user_updated_time ? formatNoteListDate(props.note.user_updated_time) : ''; return { ...props, note: { ...props.note, is_locked: isNoteLockEnabled() ? props.note.is_locked : 0, lockedLabel: _('Locked'), syncDisabled: isSyncDisabledConflict(props.note), syncDisabledLabel: _('Local only'), snippet, formattedDate, is_pinned: !!props.note.is_pinned, }, checkboxStats: props.note.checkboxes, }; }, }; export default renderer;