mirror of
https://github.com/laurent22/joplin.git
synced 2025-01-29 19:13:59 +02:00
additional props
This commit is contained in:
parent
1503415ca2
commit
ada5977afa
@ -74,7 +74,8 @@ const NoteList = (props: Props) => {
|
||||
props.selectedNoteIds,
|
||||
itemSize,
|
||||
listRenderer,
|
||||
props.highlightedWords
|
||||
props.highlightedWords,
|
||||
props.watchedNoteFiles
|
||||
);
|
||||
|
||||
const noteItemStyle = useMemo(() => {
|
||||
@ -202,6 +203,7 @@ const NoteList = (props: Props) => {
|
||||
onDragOver={onDragOver}
|
||||
style={noteItemStyle}
|
||||
highlightedWords={highlightedWords}
|
||||
isProvisional={props.provisionalNoteIds.includes(note.id)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -24,4 +24,8 @@
|
||||
border-right: none;
|
||||
border-left: none;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.note-list-item-wrapper.-provisional {
|
||||
opacity: 0.5;
|
||||
}
|
@ -32,7 +32,9 @@ const defaultItemRenderer: ListRenderer = {
|
||||
'item.selected',
|
||||
'item.size.height',
|
||||
'note.id',
|
||||
'note.is_shared',
|
||||
'note.is_todo',
|
||||
'note.isWatched',
|
||||
'note.titleHtml',
|
||||
'note.todo_completed',
|
||||
],
|
||||
@ -82,19 +84,47 @@ const defaultItemRenderer: ListRenderer = {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
overflow: hidden;
|
||||
|
||||
> .watchedicon {
|
||||
display: none;
|
||||
padding-right: 4px;
|
||||
color: var(--joplin-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
> .content.-shared {
|
||||
> .title {
|
||||
color: var(--joplin-color-warn3);
|
||||
}
|
||||
}
|
||||
|
||||
> .content.-completed {
|
||||
> .title {
|
||||
opacity: 0.5;
|
||||
text-decoration: line-through;
|
||||
}
|
||||
}
|
||||
|
||||
> .content.-watched {
|
||||
> .title {
|
||||
> .watchedicon {
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
|
||||
itemTemplate: `
|
||||
<div class="content -default {{#item.selected}}-selected{{/item.selected}}">
|
||||
<div class="content -default {{#item.selected}}-selected{{/item.selected}} {{#note.is_shared}}-shared{{/note.is_shared}} {{#note.todo_completed}}-completed{{/note.todo_completed}} {{#note.isWatched}}-watched{{/note.isWatched}}">
|
||||
{{#note.is_todo}}
|
||||
<div class="checkbox">
|
||||
<input id="todo-checkbox" type="checkbox" {{#note.todo_completed}}checked="checked"{{/note.todo_completed}}>
|
||||
</div>
|
||||
{{/note.is_todo}}
|
||||
<a href="#" class="title" draggable="true" data-id="{{note.id}}">
|
||||
<span>{{item.index}} {{{note.titleHtml}}}</span>
|
||||
<i class="watchedicon fa fa-share-square"></i>
|
||||
<span>{{{note.titleHtml}}}</span>
|
||||
</a>
|
||||
</div>
|
||||
`,
|
||||
|
@ -2,7 +2,7 @@ import { ListRendererDepependency } from './types';
|
||||
import { NoteEntity } from '@joplin/lib/services/database/types';
|
||||
import { Size } from '@joplin/utils/types';
|
||||
|
||||
const prepareViewProps = async (dependencies: ListRendererDepependency[], note: NoteEntity, itemSize: Size, selected: boolean, itemIndex: number, noteTitleHtml: string) => {
|
||||
const prepareViewProps = async (dependencies: ListRendererDepependency[], note: NoteEntity, itemSize: Size, selected: boolean, itemIndex: number, noteTitleHtml: string, noteIsWatched: boolean) => {
|
||||
const output: any = {};
|
||||
|
||||
for (const dep of dependencies) {
|
||||
@ -14,6 +14,8 @@ const prepareViewProps = async (dependencies: ListRendererDepependency[], note:
|
||||
if (!output.note) output.note = {};
|
||||
if (dep === 'note.titleHtml') {
|
||||
output.note.titleHtml = noteTitleHtml;
|
||||
} else if (dep === 'note.isWatched') {
|
||||
output.note.isWatched = noteIsWatched;
|
||||
} else {
|
||||
if (!(propName in note)) throw new Error(`Invalid dependency name: ${dep}`);
|
||||
output.note[propName] = (note as any)[propName];
|
||||
|
@ -8,7 +8,7 @@ export interface Props {
|
||||
selectedNoteIds: string[];
|
||||
notes: NoteEntity[];
|
||||
dispatch: Dispatch;
|
||||
watchedNoteFiles: any[];
|
||||
watchedNoteFiles: string[];
|
||||
plugins: PluginStates;
|
||||
selectedFolderId: string;
|
||||
customCss: string;
|
||||
@ -47,7 +47,14 @@ export interface OnChangeEvent {
|
||||
export type OnRenderNoteHandler = (props: any)=> Promise<RenderNoteView>;
|
||||
export type OnChangeHandler = (context: Context, elementId: string, event: OnChangeEvent)=> Promise<void>;
|
||||
|
||||
export type ListRendererDepependency = ItemRendererDatabaseDependency | 'item.size.width' | 'item.size.height' | 'item.selected' | 'item.index' | 'note.titleHtml';
|
||||
export type ListRendererDepependency =
|
||||
ItemRendererDatabaseDependency |
|
||||
'item.size.width' |
|
||||
'item.size.height' |
|
||||
'item.selected' |
|
||||
'item.index' |
|
||||
'note.titleHtml' |
|
||||
'note.isWatched';
|
||||
|
||||
export interface ListRenderer {
|
||||
flow: ItemFlow;
|
||||
|
@ -19,7 +19,7 @@ const hashContent = (content: any) => {
|
||||
return createHash('sha1').update(JSON.stringify(content)).digest('hex');
|
||||
};
|
||||
|
||||
const useRenderedNotes = (startNoteIndex: number, endNoteIndex: number, notes: NoteEntity[], selectedNoteIds: string[], itemSize: Size, listRenderer: ListRenderer, highlightedWords: string[]) => {
|
||||
const useRenderedNotes = (startNoteIndex: number, endNoteIndex: number, notes: NoteEntity[], selectedNoteIds: string[], itemSize: Size, listRenderer: ListRenderer, highlightedWords: string[], watchedNoteFiles: string[]) => {
|
||||
const [renderedNotes, setRenderedNotes] = useState<Record<string, RenderedNote>>({});
|
||||
|
||||
useAsyncEffect(async (event) => {
|
||||
@ -31,7 +31,8 @@ const useRenderedNotes = (startNoteIndex: number, endNoteIndex: number, notes: N
|
||||
itemSize,
|
||||
selectedNoteIds.includes(note.id),
|
||||
noteIndex,
|
||||
titleHtml
|
||||
titleHtml,
|
||||
watchedNoteFiles.includes(note.id)
|
||||
);
|
||||
const view = await listRenderer.onRenderNote(viewProps);
|
||||
|
||||
@ -61,7 +62,7 @@ const useRenderedNotes = (startNoteIndex: number, endNoteIndex: number, notes: N
|
||||
}
|
||||
|
||||
await Promise.all(promises);
|
||||
}, [startNoteIndex, endNoteIndex, notes, selectedNoteIds, itemSize, listRenderer]);
|
||||
}, [startNoteIndex, endNoteIndex, notes, selectedNoteIds, itemSize, listRenderer, watchedNoteFiles]);
|
||||
|
||||
return renderedNotes;
|
||||
};
|
||||
|
@ -8,19 +8,20 @@ import useItemEventHandlers from './utils/useItemEventHandlers';
|
||||
import { OnCheckboxChange } from './utils/types';
|
||||
|
||||
interface NoteItemProps {
|
||||
dragIndex: number;
|
||||
highlightedWords: string[];
|
||||
index: number;
|
||||
isProvisional: boolean;
|
||||
itemSize: Size;
|
||||
noteCount: number;
|
||||
noteHtml: string;
|
||||
noteId: string;
|
||||
onChange: OnChangeHandler;
|
||||
onClick: MouseEventHandler<HTMLDivElement>;
|
||||
onContextMenu: MouseEventHandler;
|
||||
onDragStart: DragEventHandler;
|
||||
onDragOver: DragEventHandler;
|
||||
onDragStart: DragEventHandler;
|
||||
style: CSSProperties;
|
||||
index: number;
|
||||
dragIndex: number;
|
||||
noteCount: number;
|
||||
highlightedWords: string[];
|
||||
}
|
||||
|
||||
const NoteListItem = (props: NoteItemProps, ref: LegacyRef<HTMLDivElement>) => {
|
||||
@ -60,12 +61,24 @@ const NoteListItem = (props: NoteItemProps, ref: LegacyRef<HTMLDivElement>) => {
|
||||
};
|
||||
}, [props.dragIndex, props.index, props.noteCount]);
|
||||
|
||||
const className = useMemo(() => {
|
||||
return [
|
||||
'note-list-item-wrapper',
|
||||
|
||||
// This is not used by the app, but kept here because it may be used
|
||||
// by users for custom CSS.
|
||||
(props.index + 1) % 2 === 0 ? 'even' : 'odd',
|
||||
|
||||
props.isProvisional && '-provisional',
|
||||
].filter(e => !!e).join(' ');
|
||||
}, [props.index, props.isProvisional]);
|
||||
|
||||
return <div
|
||||
id={elementId}
|
||||
ref={ref}
|
||||
tabIndex={0}
|
||||
style={style}
|
||||
className="note-list-item-wrapper"
|
||||
className={className}
|
||||
data-id={props.noteId}
|
||||
onContextMenu={props.onContextMenu}
|
||||
onDragStart={props.onDragStart}
|
||||
|
Loading…
x
Reference in New Issue
Block a user