feat: starred notes (#1813)
This commit is contained in:
@@ -8,6 +8,7 @@ type Props = {
|
||||
trashed: ListableContentItem['trashed']
|
||||
archived: ListableContentItem['archived']
|
||||
pinned: ListableContentItem['pinned']
|
||||
starred: ListableContentItem['starred']
|
||||
}
|
||||
hasFiles?: boolean
|
||||
}
|
||||
@@ -40,6 +41,11 @@ const ListItemFlagIcons: FunctionComponent<Props> = ({ item, hasFiles = false })
|
||||
<Icon ariaLabel="Files" type="attachment-file" className="text-info" size="small" />
|
||||
</span>
|
||||
)}
|
||||
{item.starred && (
|
||||
<span className="ml-1.5 flex items-center" title="Starred">
|
||||
<Icon ariaLabel="Starred" type="star-filled" className="text-warning" size="small" />
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -201,6 +201,7 @@ const NotesOptions = ({
|
||||
const notTrashed = notes.some((note) => !note.trashed)
|
||||
const pinned = notes.some((note) => note.pinned)
|
||||
const unpinned = notes.some((note) => !note.pinned)
|
||||
const starred = notes.some((note) => note.starred)
|
||||
|
||||
const editorForNote = useMemo(
|
||||
() => (notes[0] ? application.componentManager.editorForNote(notes[0]) : undefined),
|
||||
@@ -330,6 +331,17 @@ const NotesOptions = ({
|
||||
linkingController={linkingController}
|
||||
/>
|
||||
)}
|
||||
|
||||
<button
|
||||
className="flex w-full cursor-pointer items-center border-0 bg-transparent px-3 py-1.5 text-left text-mobile-menu-item text-text hover:bg-contrast hover:text-foreground focus:bg-info-backdrop focus:shadow-none md:text-menu-item"
|
||||
onClick={() => {
|
||||
notesController.setStarSelectedNotes(!starred)
|
||||
}}
|
||||
>
|
||||
<Icon type="star" className={iconClass} />
|
||||
{starred ? 'Unstar' : 'Star'}
|
||||
</button>
|
||||
|
||||
{unpinned && (
|
||||
<button
|
||||
className="flex w-full cursor-pointer items-center border-0 bg-transparent px-3 py-1.5 text-left text-mobile-menu-item text-text hover:bg-contrast hover:text-foreground focus:bg-info-backdrop focus:shadow-none md:text-menu-item"
|
||||
|
||||
@@ -27,23 +27,24 @@ const PADDING_BASE_PX = 14
|
||||
const PADDING_PER_LEVEL_PX = 21
|
||||
|
||||
const smartViewIconType = (view: SmartView, isSelected: boolean): IconType => {
|
||||
if (view.uuid === SystemViewId.AllNotes) {
|
||||
return isSelected ? 'notes-filled' : 'notes'
|
||||
}
|
||||
if (view.uuid === SystemViewId.Files) {
|
||||
return 'folder'
|
||||
}
|
||||
if (view.uuid === SystemViewId.ArchivedNotes) {
|
||||
return 'archive'
|
||||
}
|
||||
if (view.uuid === SystemViewId.TrashedNotes) {
|
||||
return 'trash'
|
||||
}
|
||||
if (view.uuid === SystemViewId.UntaggedNotes) {
|
||||
return 'hashtag-off'
|
||||
const mapping: Record<SystemViewId, IconType> = {
|
||||
[SystemViewId.AllNotes]: isSelected ? 'notes-filled' : 'notes',
|
||||
[SystemViewId.Files]: 'folder',
|
||||
[SystemViewId.ArchivedNotes]: 'archive',
|
||||
[SystemViewId.TrashedNotes]: 'trash',
|
||||
[SystemViewId.UntaggedNotes]: 'hashtag-off',
|
||||
[SystemViewId.StarredNotes]: 'star-filled',
|
||||
}
|
||||
|
||||
return 'hashtag'
|
||||
return mapping[view.uuid as SystemViewId] || 'hashtag'
|
||||
}
|
||||
|
||||
const getIconClass = (view: SmartView, isSelected: boolean): string => {
|
||||
const mapping: Partial<Record<SystemViewId, string>> = {
|
||||
[SystemViewId.StarredNotes]: 'text-warning',
|
||||
}
|
||||
|
||||
return mapping[view.uuid as SystemViewId] || (isSelected ? 'text-info' : 'text-neutral')
|
||||
}
|
||||
|
||||
const SmartViewsListItem: FunctionComponent<Props> = ({ view, tagsState }) => {
|
||||
@@ -108,6 +109,7 @@ const SmartViewsListItem: FunctionComponent<Props> = ({ view, tagsState }) => {
|
||||
|
||||
const isFaded = false
|
||||
const iconType = smartViewIconType(view, isSelected)
|
||||
const iconClass = getIconClass(view, isSelected)
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -122,7 +124,7 @@ const SmartViewsListItem: FunctionComponent<Props> = ({ view, tagsState }) => {
|
||||
>
|
||||
<div className="tag-info">
|
||||
<div className={'tag-icon mr-2'}>
|
||||
<Icon type={iconType} className={isSelected ? 'text-info' : 'text-neutral'} />
|
||||
<Icon type={iconType} className={iconClass} />
|
||||
</div>
|
||||
{isEditing ? (
|
||||
<input
|
||||
|
||||
@@ -259,6 +259,12 @@ export class NotesController extends AbstractViewController {
|
||||
}).catch(console.error)
|
||||
}
|
||||
|
||||
setStarSelectedNotes(starred: boolean): void {
|
||||
this.changeSelectedNotes((mutator) => {
|
||||
mutator.starred = starred
|
||||
}).catch(console.error)
|
||||
}
|
||||
|
||||
async setArchiveSelectedNotes(archived: boolean): Promise<void> {
|
||||
if (this.getSelectedNotesList().some((note) => note.locked)) {
|
||||
this.application.alertService
|
||||
|
||||
Reference in New Issue
Block a user