Skip to content

Commit

Permalink
feat: add files button to multiple selection view (#1067)
Browse files Browse the repository at this point in the history
  • Loading branch information
amanharwara authored Jun 6, 2022
1 parent 59dcca1 commit 218e7a3
Show file tree
Hide file tree
Showing 14 changed files with 222 additions and 96 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,12 @@ const ApplicationView: FunctionComponent<Props> = ({ application, mainApplicatio
{renderChallenges()}

<>
<NotesContextMenu application={application} viewControllerManager={viewControllerManager} />
<NotesContextMenu
application={application}
navigationController={viewControllerManager.navigationController}
notesController={viewControllerManager.notesController}
noteTagsController={viewControllerManager.noteTagsController}
/>
<TagsContextMenuWrapper viewControllerManager={viewControllerManager} />
<FileContextMenuWrapper
filesController={viewControllerManager.filesController}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { observer } from 'mobx-react-lite'
import { FunctionComponent, useCallback, useEffect, useRef, useState } from 'react'
import Icon from '@/Components/Icon/Icon'
import { useCloseOnBlur } from '@/Hooks/useCloseOnBlur'
import { ContentType, FileItem, SNNote } from '@standardnotes/snjs'
import { FileItem, SNNote } from '@standardnotes/snjs'
import { addToast, ToastType } from '@standardnotes/stylekit'
import { StreamingFileReader } from '@standardnotes/filepicker'
import AttachedFilesPopover from './AttachedFilesPopover'
Expand All @@ -18,6 +18,7 @@ import { FilePreviewModalController } from '@/Controllers/FilePreviewModalContro
import { NavigationController } from '@/Controllers/Navigation/NavigationController'
import { FeaturesController } from '@/Controllers/FeaturesController'
import { FilesController } from '@/Controllers/FilesController'
import { SelectedItemsController } from '@/Controllers/SelectedItemsController'

type Props = {
application: WebApplication
Expand All @@ -26,6 +27,7 @@ type Props = {
filesController: FilesController
navigationController: NavigationController
notesController: NotesController
selectionController: SelectedItemsController
onClickPreprocessing?: () => Promise<void>
}

Expand All @@ -36,8 +38,12 @@ const AttachedFilesButton: FunctionComponent<Props> = ({
filePreviewModalController,
navigationController,
notesController,
selectionController,
onClickPreprocessing,
}: Props) => {
const { allFiles, attachedFiles } = filesController
const attachedFilesCount = attachedFiles.length

const premiumModal = usePremiumModal()
const note: SNNote | undefined = notesController.firstSelectedNote

Expand All @@ -63,22 +69,14 @@ const AttachedFilesButton: FunctionComponent<Props> = ({
const [currentTab, setCurrentTab] = useState(
navigationController.isInFilesView ? PopoverTabs.AllFiles : PopoverTabs.AttachedFiles,
)
const [allFiles, setAllFiles] = useState<FileItem[]>([])
const [attachedFiles, setAttachedFiles] = useState<FileItem[]>([])
const attachedFilesCount = attachedFiles.length

useEffect(() => {
const unregisterFileStream = application.streamItems(ContentType.File, () => {
setAllFiles(application.items.getDisplayableFiles())
if (note) {
setAttachedFiles(application.items.getFilesForNote(note))
}
})
const isAttachedTabDisabled = navigationController.isInFilesView || selectionController.selectedItemsCount > 1

return () => {
unregisterFileStream()
useEffect(() => {
if (isAttachedTabDisabled && currentTab === PopoverTabs.AttachedFiles) {
setCurrentTab(PopoverTabs.AllFiles)
}
}, [application, note])
}, [currentTab, isAttachedTabDisabled])

const toggleAttachedFilesMenu = useCallback(async () => {
const rect = buttonRef.current?.getBoundingClientRect()
Expand Down Expand Up @@ -304,7 +302,7 @@ const AttachedFilesButton: FunctionComponent<Props> = ({
currentTab={currentTab}
isDraggingFiles={isDraggingFiles}
setCurrentTab={setCurrentTab}
attachedTabDisabled={navigationController.isInFilesView}
attachedTabDisabled={isAttachedTabDisabled}
/>
)}
</DisclosurePanel>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ const FileViewWithoutProtection = ({ application, viewControllerManager, file }:
filesController={viewControllerManager.filesController}
navigationController={viewControllerManager.navigationController}
notesController={viewControllerManager.notesController}
selectionController={viewControllerManager.selectionController}
/>
</div>
<FileOptionsPanel
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,32 @@ import { useCallback } from 'react'
import FileOptionsPanel from '../FileContextMenu/FileOptionsPanel'
import { FilesController } from '@/Controllers/FilesController'
import { SelectedItemsController } from '@/Controllers/SelectedItemsController'
import { WebApplication } from '@/Application/Application'
import { FeaturesController } from '@/Controllers/FeaturesController'
import { FilePreviewModalController } from '@/Controllers/FilePreviewModalController'
import { NavigationController } from '@/Controllers/Navigation/NavigationController'
import { NotesController } from '@/Controllers/NotesController'
import AttachedFilesButton from '../AttachedFilesPopover/AttachedFilesButton'

type Props = {
application: WebApplication
featuresController: FeaturesController
filePreviewModalController: FilePreviewModalController
filesController: FilesController
navigationController: NavigationController
notesController: NotesController
selectionController: SelectedItemsController
}

const MultipleSelectedFiles = ({ filesController, selectionController }: Props) => {
const MultipleSelectedFiles = ({
application,
filesController,
featuresController,
filePreviewModalController,
navigationController,
notesController,
selectionController,
}: Props) => {
const count = selectionController.selectedFilesCount

const cancelMultipleSelection = useCallback(() => {
Expand All @@ -23,6 +42,17 @@ const MultipleSelectedFiles = ({ filesController, selectionController }: Props)
<div className="flex items-center justify-between p-4 w-full">
<h1 className="sk-h1 font-bold m-0">{count} selected files</h1>
<div className="flex">
<div className="mr-3">
<AttachedFilesButton
application={application}
featuresController={featuresController}
filePreviewModalController={filePreviewModalController}
filesController={filesController}
navigationController={navigationController}
notesController={notesController}
selectionController={selectionController}
/>
</div>
<FileOptionsPanel filesController={filesController} selectionController={selectionController} />
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,33 +1,71 @@
import { ViewControllerManager } from '@/Services/ViewControllerManager'
import { IlNotesIcon } from '@standardnotes/icons'
import { observer } from 'mobx-react-lite'
import NotesOptionsPanel from '@/Components/NotesOptions/NotesOptionsPanel'
import { WebApplication } from '@/Application/Application'
import PinNoteButton from '@/Components/PinNoteButton/PinNoteButton'
import Button from '../Button/Button'
import { useCallback } from 'react'
import AttachedFilesButton from '../AttachedFilesPopover/AttachedFilesButton'
import { FeaturesController } from '@/Controllers/FeaturesController'
import { FilePreviewModalController } from '@/Controllers/FilePreviewModalController'
import { FilesController } from '@/Controllers/FilesController'
import { NavigationController } from '@/Controllers/Navigation/NavigationController'
import { NotesController } from '@/Controllers/NotesController'
import { SelectedItemsController } from '@/Controllers/SelectedItemsController'
import { NoteTagsController } from '@/Controllers/NoteTagsController'

type Props = {
application: WebApplication
viewControllerManager: ViewControllerManager
featuresController: FeaturesController
filePreviewModalController: FilePreviewModalController
filesController: FilesController
navigationController: NavigationController
notesController: NotesController
noteTagsController: NoteTagsController
selectionController: SelectedItemsController
}

const MultipleSelectedNotes = ({ application, viewControllerManager }: Props) => {
const count = viewControllerManager.notesController.selectedNotesCount
const MultipleSelectedNotes = ({
application,
featuresController,
filePreviewModalController,
filesController,
navigationController,
notesController,
noteTagsController,
selectionController,
}: Props) => {
const count = notesController.selectedNotesCount

const cancelMultipleSelection = useCallback(() => {
viewControllerManager.selectionController.cancelMultipleSelection()
}, [viewControllerManager])
selectionController.cancelMultipleSelection()
}, [selectionController])

return (
<div className="flex flex-col h-full items-center">
<div className="flex items-center justify-between p-4 w-full">
<h1 className="sk-h1 font-bold m-0">{count} selected notes</h1>
<div className="flex">
<div className="mr-3">
<PinNoteButton viewControllerManager={viewControllerManager} />
<AttachedFilesButton
application={application}
featuresController={featuresController}
filePreviewModalController={filePreviewModalController}
filesController={filesController}
navigationController={navigationController}
notesController={notesController}
selectionController={selectionController}
/>
</div>
<NotesOptionsPanel application={application} viewControllerManager={viewControllerManager} />
<div className="mr-3">
<PinNoteButton notesController={notesController} />
</div>
<NotesOptionsPanel
application={application}
navigationController={navigationController}
notesController={notesController}
noteTagsController={noteTagsController}
/>
</div>
</div>
<div className="flex-grow flex flex-col justify-center items-center w-full max-w-md">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,27 @@ class NoteGroupView extends PureComponent<Props, State> {
return (
<div id={ElementIds.EditorColumn} className="h-full app-column app-column-third">
{this.state.showMultipleSelectedNotes && (
<MultipleSelectedNotes application={this.application} viewControllerManager={this.viewControllerManager} />
<MultipleSelectedNotes
application={this.application}
filesController={this.viewControllerManager.filesController}
selectionController={this.viewControllerManager.selectionController}
featuresController={this.viewControllerManager.featuresController}
filePreviewModalController={this.viewControllerManager.filePreviewModalController}
navigationController={this.viewControllerManager.navigationController}
notesController={this.viewControllerManager.notesController}
noteTagsController={this.viewControllerManager.noteTagsController}
/>
)}

{this.state.showMultipleSelectedFiles && (
<MultipleSelectedFiles
application={this.application}
filesController={this.viewControllerManager.filesController}
selectionController={this.viewControllerManager.selectionController}
featuresController={this.viewControllerManager.featuresController}
filePreviewModalController={this.viewControllerManager.filePreviewModalController}
navigationController={this.viewControllerManager.navigationController}
notesController={this.viewControllerManager.notesController}
/>
)}

Expand Down
7 changes: 5 additions & 2 deletions app/assets/javascripts/Components/NoteView/NoteView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -950,6 +950,7 @@ class NoteView extends PureComponent<NoteViewProps, State> {
filesController={this.viewControllerManager.filesController}
navigationController={this.viewControllerManager.navigationController}
notesController={this.viewControllerManager.notesController}
selectionController={this.viewControllerManager.selectionController}
/>
</div>
<div className="mr-3">
Expand All @@ -961,13 +962,15 @@ class NoteView extends PureComponent<NoteViewProps, State> {
</div>
<div className="mr-3">
<PinNoteButton
viewControllerManager={this.viewControllerManager}
notesController={this.viewControllerManager.notesController}
onClickPreprocessing={this.ensureNoteIsInsertedBeforeUIAction}
/>
</div>
<NotesOptionsPanel
application={this.application}
viewControllerManager={this.viewControllerManager}
navigationController={this.viewControllerManager.navigationController}
notesController={this.viewControllerManager.notesController}
noteTagsController={this.viewControllerManager.noteTagsController}
onClickPreprocessing={this.ensureNoteIsInsertedBeforeUIAction}
/>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,29 +1,31 @@
import { ViewControllerManager } from '@/Services/ViewControllerManager'
import { useCloseOnBlur } from '@/Hooks/useCloseOnBlur'
import { useCloseOnClickOutside } from '@/Hooks/useCloseOnClickOutside'
import { observer } from 'mobx-react-lite'
import NotesOptions from '@/Components/NotesOptions/NotesOptions'
import { useCallback, useEffect, useRef } from 'react'
import { WebApplication } from '@/Application/Application'
import { NotesController } from '@/Controllers/NotesController'
import { NavigationController } from '@/Controllers/Navigation/NavigationController'
import { NoteTagsController } from '@/Controllers/NoteTagsController'

type Props = {
application: WebApplication
viewControllerManager: ViewControllerManager
navigationController: NavigationController
notesController: NotesController
noteTagsController: NoteTagsController
}

const NotesContextMenu = ({ application, viewControllerManager }: Props) => {
const { contextMenuOpen, contextMenuPosition, contextMenuMaxHeight } = viewControllerManager.notesController
const NotesContextMenu = ({ application, navigationController, notesController, noteTagsController }: Props) => {
const { contextMenuOpen, contextMenuPosition, contextMenuMaxHeight } = notesController

const contextMenuRef = useRef<HTMLDivElement>(null)
const [closeOnBlur] = useCloseOnBlur(contextMenuRef, (open: boolean) =>
viewControllerManager.notesController.setContextMenuOpen(open),
)
const [closeOnBlur] = useCloseOnBlur(contextMenuRef, (open: boolean) => notesController.setContextMenuOpen(open))

useCloseOnClickOutside(contextMenuRef, () => viewControllerManager.notesController.setContextMenuOpen(false))
useCloseOnClickOutside(contextMenuRef, () => notesController.setContextMenuOpen(false))

const reloadContextMenuLayout = useCallback(() => {
viewControllerManager.notesController.reloadContextMenuLayout()
}, [viewControllerManager])
notesController.reloadContextMenuLayout()
}, [notesController])

useEffect(() => {
window.addEventListener('resize', reloadContextMenuLayout)
Expand All @@ -41,7 +43,13 @@ const NotesContextMenu = ({ application, viewControllerManager }: Props) => {
maxHeight: contextMenuMaxHeight,
}}
>
<NotesOptions application={application} viewControllerManager={viewControllerManager} closeOnBlur={closeOnBlur} />
<NotesOptions
application={application}
closeOnBlur={closeOnBlur}
navigationController={navigationController}
notesController={notesController}
noteTagsController={noteTagsController}
/>
</div>
) : null
}
Expand Down
22 changes: 13 additions & 9 deletions app/assets/javascripts/Components/NotesOptions/AddTagOption.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
import { ViewControllerManager } from '@/Services/ViewControllerManager'
import { calculateSubmenuStyle, SubmenuStyle } from '@/Utils/CalculateSubmenuStyle'
import { Disclosure, DisclosureButton, DisclosurePanel } from '@reach/disclosure'
import { observer } from 'mobx-react-lite'
import { FunctionComponent, useCallback, useEffect, useRef, useState } from 'react'
import Icon from '@/Components/Icon/Icon'
import { useCloseOnBlur } from '@/Hooks/useCloseOnBlur'
import { NavigationController } from '@/Controllers/Navigation/NavigationController'
import { NotesController } from '@/Controllers/NotesController'
import { NoteTagsController } from '@/Controllers/NoteTagsController'

type Props = {
viewControllerManager: ViewControllerManager
navigationController: NavigationController
notesController: NotesController
noteTagsController: NoteTagsController
}

const AddTagOption: FunctionComponent<Props> = ({ viewControllerManager }) => {
const AddTagOption: FunctionComponent<Props> = ({ navigationController, notesController, noteTagsController }) => {
const menuContainerRef = useRef<HTMLDivElement>(null)
const menuRef = useRef<HTMLDivElement>(null)
const menuButtonRef = useRef<HTMLButtonElement>(null)
Expand Down Expand Up @@ -84,22 +88,22 @@ const AddTagOption: FunctionComponent<Props> = ({ viewControllerManager }) => {
}}
className="sn-dropdown min-w-80 flex flex-col py-2 max-h-120 max-w-xs fixed overflow-y-auto"
>
{viewControllerManager.navigationController.tags.map((tag) => (
{navigationController.tags.map((tag) => (
<button
key={tag.uuid}
className="sn-dropdown-item sn-dropdown-item--no-icon max-w-80"
onBlur={closeOnBlur}
onClick={() => {
viewControllerManager.notesController.isTagInSelectedNotes(tag)
? viewControllerManager.notesController.removeTagFromSelectedNotes(tag).catch(console.error)
: viewControllerManager.notesController.addTagToSelectedNotes(tag).catch(console.error)
notesController.isTagInSelectedNotes(tag)
? notesController.removeTagFromSelectedNotes(tag).catch(console.error)
: notesController.addTagToSelectedNotes(tag).catch(console.error)
}}
>
<span
className={`whitespace-nowrap overflow-hidden overflow-ellipsis
${viewControllerManager.notesController.isTagInSelectedNotes(tag) ? 'font-bold' : ''}`}
${notesController.isTagInSelectedNotes(tag) ? 'font-bold' : ''}`}
>
{viewControllerManager.noteTagsController.getLongTitle(tag)}
{noteTagsController.getLongTitle(tag)}
</span>
</button>
))}
Expand Down
Loading

0 comments on commit 218e7a3

Please sign in to comment.