Skip to content

Commit

Permalink
feat: ability to favorite tags (#1852)
Browse files Browse the repository at this point in the history
  • Loading branch information
moughxyz committed Oct 20, 2022
1 parent 9cc3304 commit 4f3b258
Show file tree
Hide file tree
Showing 7 changed files with 81 additions and 27 deletions.
1 change: 1 addition & 0 deletions packages/web/src/javascripts/Components/Icon/Icon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ export const ICONS = {
eye: icons.EyeIcon,
file: icons.FileIcon,
folder: icons.FolderIcon,
fullscreen: icons.FullscreenIcon,
hashtag: icons.HashtagIcon,
help: icons.HelpIcon,
history: icons.HistoryIcon,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ const smartViewIconType = (view: SmartView, isSelected: boolean): IconType => {
[SystemViewId.StarredNotes]: 'star-filled',
}

return mapping[view.uuid as SystemViewId] || 'hashtag'
return mapping[view.uuid as SystemViewId] || 'window'
}

const getIconClass = (view: SmartView, isSelected: boolean): string => {
Expand Down
11 changes: 11 additions & 0 deletions packages/web/src/javascripts/Components/Tags/TagContextMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ const TagContextMenu = ({ navigationController, isEntitledToFolders, selectedTag
navigationController.remove(selectedTag, true).catch(console.error)
}, [navigationController, selectedTag])

const onClickStar = useCallback(() => {
navigationController.setFavorite(selectedTag, !selectedTag.starred).catch(console.error)
navigationController.setContextMenuOpen(false)
}, [navigationController, selectedTag])

const tagLastModified = useMemo(
() => formatDateForContextMenu(selectedTag.userModifiedDate),
[selectedTag.userModifiedDate],
Expand All @@ -62,6 +67,12 @@ const TagContextMenu = ({ navigationController, isEntitledToFolders, selectedTag
>
<div ref={contextMenuRef}>
<Menu a11yLabel="Tag context menu" isOpen={contextMenuOpen}>
<MenuItem type={MenuItemType.IconButton} className={'justify-between py-1.5'} onClick={onClickStar}>
<div className="flex items-center">
<Icon type="star" className="mr-2 text-neutral" />
{selectedTag.starred ? 'Unfavorite' : 'Favorite'}
</div>
</MenuItem>
<MenuItem type={MenuItemType.IconButton} className={'justify-between py-1.5'} onClick={onClickAddSubtag}>
<div className="flex items-center">
<Icon type="add" className="mr-2 text-neutral" />
Expand Down
20 changes: 12 additions & 8 deletions packages/web/src/javascripts/Components/Tags/TagsList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@ import { TagsListItem } from './TagsListItem'

type Props = {
viewControllerManager: ViewControllerManager
type: 'all' | 'favorites'
}

const TagsList: FunctionComponent<Props> = ({ viewControllerManager }: Props) => {
const tagsState = viewControllerManager.navigationController
const allTags = tagsState.allLocalRootTags
const TagsList: FunctionComponent<Props> = ({ viewControllerManager, type }: Props) => {
const navigationController = viewControllerManager.navigationController
const allTags = type === 'all' ? navigationController.allLocalRootTags : navigationController.starredTags

const backend = HTML5Backend

Expand Down Expand Up @@ -49,17 +50,20 @@ const TagsList: FunctionComponent<Props> = ({ viewControllerManager }: Props) =>
level={0}
key={tag.uuid}
tag={tag}
tagsState={tagsState}
type={type}
tagsState={navigationController}
features={viewControllerManager.featuresController}
linkingController={viewControllerManager.linkingController}
onContextMenu={onContextMenu}
/>
)
})}
<RootTagDropZone
tagsState={viewControllerManager.navigationController}
featuresState={viewControllerManager.featuresController}
/>
{type === 'all' && (
<RootTagDropZone
tagsState={viewControllerManager.navigationController}
featuresState={viewControllerManager.featuresController}
/>
)}
</>
)}
</DndProvider>
Expand Down
17 changes: 15 additions & 2 deletions packages/web/src/javascripts/Components/Tags/TagsListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { LinkingController } from '@/Controllers/LinkingController'

type Props = {
tag: SNTag
type: 'all' | 'favorites'
tagsState: NavigationController
features: FeaturesController
linkingController: LinkingController
Expand All @@ -40,7 +41,7 @@ const PADDING_BASE_PX = 14
const PADDING_PER_LEVEL_PX = 21

export const TagsListItem: FunctionComponent<Props> = observer(
({ tag, features, tagsState, level, onContextMenu, linkingController }) => {
({ tag, type, features, tagsState, level, onContextMenu, linkingController }) => {
const { toggleAppPane } = useResponsiveAppPane()

const [title, setTitle] = useState(tag.title || '')
Expand Down Expand Up @@ -263,7 +264,18 @@ export const TagsListItem: FunctionComponent<Props> = observer(
</div>
)}
<div className={'tag-icon draggable mr-2'} ref={dragRef}>
<Icon type="hashtag" className={`${isSelected ? 'text-info' : 'text-neutral'}`} />
<Icon
type="hashtag"
className={`${
type === 'favorites'
? isSelected
? 'text-warning'
: 'text-info'
: isSelected
? 'text-info'
: 'text-neutral'
}`}
/>
</div>
{isEditing ? (
<input
Expand Down Expand Up @@ -335,6 +347,7 @@ export const TagsListItem: FunctionComponent<Props> = observer(
level={level + 1}
key={tag.uuid}
tag={tag}
type={type}
tagsState={tagsState}
features={features}
linkingController={linkingController}
Expand Down
45 changes: 30 additions & 15 deletions packages/web/src/javascripts/Components/Tags/TagsSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,22 +52,37 @@ const TagsSection: FunctionComponent<Props> = ({ viewControllerManager }) => {
}, [viewControllerManager, checkIfMigrationNeeded])

return (
<section>
<div className={'section-title-bar'}>
<div className="section-title-bar-header">
<TagsSectionTitle
features={viewControllerManager.featuresController}
hasMigration={hasMigration}
onClickMigration={runMigration}
/>
<TagsSectionAddButton
tags={viewControllerManager.navigationController}
features={viewControllerManager.featuresController}
/>
<>
{viewControllerManager.navigationController.starredTags.length > 0 && (
<section>
<div className={'section-title-bar'}>
<div className="section-title-bar-header">
<div className="title text-sm">
<span className="font-bold">Favorites</span>
</div>
</div>
</div>
<TagsList type="favorites" viewControllerManager={viewControllerManager} />
</section>
)}

<section>
<div className={'section-title-bar'}>
<div className="section-title-bar-header">
<TagsSectionTitle
features={viewControllerManager.featuresController}
hasMigration={hasMigration}
onClickMigration={runMigration}
/>
<TagsSectionAddButton
tags={viewControllerManager.navigationController}
features={viewControllerManager.featuresController}
/>
</div>
</div>
</div>
<TagsList viewControllerManager={viewControllerManager} />
</section>
<TagsList type="all" viewControllerManager={viewControllerManager} />
</section>
</>
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export class NavigationController
{
tags: SNTag[] = []
smartViews: SmartView[] = []
starredTags: SNTag[] = []
allNotesCount_ = 0
selectedUuid: AnyTag['uuid'] | undefined = undefined
selected_: AnyTag | undefined
Expand Down Expand Up @@ -66,6 +67,7 @@ export class NavigationController

makeObservable(this, {
tags: observable,
starredTags: observable,
smartViews: observable.ref,
hasAtLeastOneFolder: computed,
allNotesCount_: observable,
Expand Down Expand Up @@ -111,7 +113,7 @@ export class NavigationController
this.application.streamItems([ContentType.Tag, ContentType.SmartView], ({ changed, removed }) => {
runInAction(() => {
this.tags = this.application.items.getDisplayableTags()

this.starredTags = this.tags.filter((tag) => tag.starred)
this.smartViews = this.application.items.getSmartViews()

const currentSelectedTag = this.selected_
Expand Down Expand Up @@ -476,6 +478,14 @@ export class NavigationController
.catch(console.error)
}

public async setFavorite(tag: SNTag, favorite: boolean) {
return this.application.mutator
.changeAndSaveItem<TagMutator>(tag, (mutator) => {
mutator.starred = favorite
})
.catch(console.error)
}

public get editingTag(): SNTag | SmartView | undefined {
return this.editing_
}
Expand Down

0 comments on commit 4f3b258

Please sign in to comment.