Skip to content

Commit

Permalink
feat: add file view (#1064)
Browse files Browse the repository at this point in the history
  • Loading branch information
amanharwara authored Jun 6, 2022
1 parent c20f0ad commit 92024ec
Show file tree
Hide file tree
Showing 33 changed files with 662 additions and 383 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import PremiumModalProvider from '@/Hooks/usePremiumModal'
import ConfirmSignoutContainer from '@/Components/ConfirmSignoutModal/ConfirmSignoutModal'
import TagsContextMenuWrapper from '@/Components/Tags/TagContextMenu'
import { ToastContainer } from '@standardnotes/stylekit'
import FilePreviewModalWrapper from '@/Components/Files/FilePreviewModal'
import FilePreviewModalWrapper from '@/Components/FilePreview/FilePreviewModal'
import ContentListView from '@/Components/ContentListView/ContentListView'
import FileContextMenuWrapper from '@/Components/FileContextMenu/FileContextMenu'
import PermissionsModalWrapper from '@/Components/PermissionsModal/PermissionsModalWrapper'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { WebApplication } from '@/Application/Application'
import { ViewControllerManager } from '@/Services/ViewControllerManager'
import { MENU_MARGIN_FROM_APP_BORDER } from '@/Constants/Constants'
import { Disclosure, DisclosureButton, DisclosurePanel } from '@reach/disclosure'
import VisuallyHidden from '@reach/visually-hidden'
Expand All @@ -14,20 +13,33 @@ import AttachedFilesPopover from './AttachedFilesPopover'
import { usePremiumModal } from '@/Hooks/usePremiumModal'
import { PopoverTabs } from './PopoverTabs'
import { isHandlingFileDrag } from '@/Utils/DragTypeCheck'
import { NotesController } from '@/Controllers/NotesController'
import { FilePreviewModalController } from '@/Controllers/FilePreviewModalController'
import { NavigationController } from '@/Controllers/Navigation/NavigationController'
import { FeaturesController } from '@/Controllers/FeaturesController'
import { FilesController } from '@/Controllers/FilesController'

type Props = {
application: WebApplication
viewControllerManager: ViewControllerManager
featuresController: FeaturesController
filePreviewModalController: FilePreviewModalController
filesController: FilesController
navigationController: NavigationController
notesController: NotesController
onClickPreprocessing?: () => Promise<void>
}

const AttachedFilesButton: FunctionComponent<Props> = ({
application,
viewControllerManager,
featuresController,
filesController,
filePreviewModalController,
navigationController,
notesController,
onClickPreprocessing,
}: Props) => {
const premiumModal = usePremiumModal()
const note: SNNote | undefined = viewControllerManager.notesController.firstSelectedNote
const note: SNNote | undefined = notesController.firstSelectedNote

const [open, setOpen] = useState(false)
const [position, setPosition] = useState({
Expand All @@ -41,14 +53,16 @@ const AttachedFilesButton: FunctionComponent<Props> = ({
const [closeOnBlur, keepMenuOpen] = useCloseOnBlur(containerRef, setOpen)

useEffect(() => {
if (viewControllerManager.filePreviewModalController.isOpen) {
if (filePreviewModalController.isOpen) {
keepMenuOpen(true)
} else {
keepMenuOpen(false)
}
}, [viewControllerManager.filePreviewModalController.isOpen, keepMenuOpen])
}, [filePreviewModalController.isOpen, keepMenuOpen])

const [currentTab, setCurrentTab] = useState(PopoverTabs.AttachedFiles)
const [currentTab, setCurrentTab] = useState(
navigationController.isInFilesView ? PopoverTabs.AllFiles : PopoverTabs.AttachedFiles,
)
const [allFiles, setAllFiles] = useState<FileItem[]>([])
const [attachedFiles, setAttachedFiles] = useState<FileItem[]>([])
const attachedFilesCount = attachedFiles.length
Expand Down Expand Up @@ -92,10 +106,10 @@ const AttachedFilesButton: FunctionComponent<Props> = ({
}, [onClickPreprocessing, open])

const prospectivelyShowFilesPremiumModal = useCallback(() => {
if (!viewControllerManager.featuresController.hasFiles) {
if (!featuresController.hasFiles) {
premiumModal.activate('Files')
}
}, [viewControllerManager.featuresController.hasFiles, premiumModal])
}, [featuresController.hasFiles, premiumModal])

const toggleAttachedFilesMenuWithEntitlementCheck = useCallback(async () => {
prospectivelyShowFilesPremiumModal()
Expand Down Expand Up @@ -192,7 +206,7 @@ const AttachedFilesButton: FunctionComponent<Props> = ({

setIsDraggingFiles(false)

if (!viewControllerManager.featuresController.hasFiles) {
if (!featuresController.hasFiles) {
prospectivelyShowFilesPremiumModal()
return
}
Expand All @@ -207,7 +221,7 @@ const AttachedFilesButton: FunctionComponent<Props> = ({
return
}

const uploadedFiles = await viewControllerManager.filesController.uploadNewFile(fileOrHandle)
const uploadedFiles = await filesController.uploadNewFile(fileOrHandle)

if (!uploadedFiles) {
return
Expand All @@ -225,8 +239,8 @@ const AttachedFilesButton: FunctionComponent<Props> = ({
}
},
[
viewControllerManager.filesController,
viewControllerManager.featuresController.hasFiles,
filesController,
featuresController.hasFiles,
attachFileToNote,
currentTab,
application,
Expand Down Expand Up @@ -283,13 +297,14 @@ const AttachedFilesButton: FunctionComponent<Props> = ({
{open && (
<AttachedFilesPopover
application={application}
filesController={viewControllerManager.filesController}
filesController={filesController}
attachedFiles={attachedFiles}
allFiles={allFiles}
closeOnBlur={closeOnBlur}
currentTab={currentTab}
isDraggingFiles={isDraggingFiles}
setCurrentTab={setCurrentTab}
attachedTabDisabled={navigationController.isInFilesView}
/>
)}
</DisclosurePanel>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ type Props = {
currentTab: PopoverTabs
isDraggingFiles: boolean
setCurrentTab: Dispatch<SetStateAction<PopoverTabs>>
attachedTabDisabled: boolean
}

const AttachedFilesPopover: FunctionComponent<Props> = ({
Expand All @@ -31,6 +32,7 @@ const AttachedFilesPopover: FunctionComponent<Props> = ({
currentTab,
isDraggingFiles,
setCurrentTab,
attachedTabDisabled,
}) => {
const [searchQuery, setSearchQuery] = useState('')
const searchInputRef = useRef<HTMLInputElement>(null)
Expand Down Expand Up @@ -81,11 +83,12 @@ const AttachedFilesPopover: FunctionComponent<Props> = ({
id={PopoverTabs.AttachedFiles}
className={`bg-default border-0 cursor-pointer px-3 py-2.5 relative focus:bg-info-backdrop focus:shadow-bottom ${
currentTab === PopoverTabs.AttachedFiles ? 'color-info font-medium shadow-bottom' : 'color-text'
}`}
} ${attachedTabDisabled ? 'color-neutral cursor-not-allowed' : ''}`}
onClick={() => {
setCurrentTab(PopoverTabs.AttachedFiles)
}}
onBlur={closeOnBlur}
disabled={attachedTabDisabled}
>
Attached
</button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,17 @@ const ContentList: FunctionComponent<Props> = ({
<ContentListItem
key={item.uuid}
application={application}
viewControllerManager={viewControllerManager}
item={item}
selected={!!selectedItems[item.uuid]}
hideDate={hideDate}
hidePreview={hideNotePreview}
hideTags={hideTags}
hideIcon={hideEditorIcon}
sortBy={sortBy}
filesController={viewControllerManager.filesController}
selectionController={viewControllerManager.selectionController}
navigationController={viewControllerManager.navigationController}
notesController={viewControllerManager.notesController}
/>
))}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const ContentListItem: FunctionComponent<AbstractListItemProps> = (props) => {
return []
}

const selectedTag = props.viewControllerManager.navigationController.selected
const selectedTag = props.navigationController.selected
if (!selectedTag) {
return []
}
Expand Down
29 changes: 9 additions & 20 deletions app/assets/javascripts/Components/ContentListView/FileListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import { DisplayableListItemProps } from './Types/DisplayableListItemProps'

const FileListItem: FunctionComponent<DisplayableListItemProps> = ({
application,
viewControllerManager,
filesController,
selectionController,
hideDate,
hideIcon,
hideTags,
Expand All @@ -21,40 +22,28 @@ const FileListItem: FunctionComponent<DisplayableListItemProps> = ({
}) => {
const openFileContextMenu = useCallback(
(posX: number, posY: number) => {
viewControllerManager.filesController.setFileContextMenuLocation({
filesController.setFileContextMenuLocation({
x: posX,
y: posY,
})
viewControllerManager.filesController.setShowFileContextMenu(true)
filesController.setShowFileContextMenu(true)
},
[viewControllerManager.filesController],
[filesController],
)

const openContextMenu = useCallback(
async (posX: number, posY: number) => {
const { didSelect } = await viewControllerManager.selectionController.selectItem(item.uuid)
const { didSelect } = await selectionController.selectItem(item.uuid)
if (didSelect) {
openFileContextMenu(posX, posY)
}
},
[viewControllerManager.selectionController, item.uuid, openFileContextMenu],
[selectionController, item.uuid, openFileContextMenu],
)

const onClick = useCallback(() => {
void viewControllerManager.selectionController.selectItem(item.uuid, true).then(({ didSelect }) => {
if (didSelect && viewControllerManager.selectionController.selectedItemsCount < 2) {
viewControllerManager.filePreviewModalController.activate(
item as FileItem,
viewControllerManager.filesController.allFiles,
)
}
})
}, [
viewControllerManager.filePreviewModalController,
viewControllerManager.filesController.allFiles,
viewControllerManager.selectionController,
item,
])
void selectionController.selectItem(item.uuid, true)
}, [item.uuid, selectionController])

const IconComponent = () =>
getFileIconComponent(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import { DisplayableListItemProps } from './Types/DisplayableListItemProps'

const NoteListItem: FunctionComponent<DisplayableListItemProps> = ({
application,
viewControllerManager,
notesController,
selectionController,
hideDate,
hideIcon,
hideTags,
Expand All @@ -27,16 +28,16 @@ const NoteListItem: FunctionComponent<DisplayableListItemProps> = ({
const hasFiles = application.items.getFilesForNote(item as SNNote).length > 0

const openNoteContextMenu = (posX: number, posY: number) => {
viewControllerManager.notesController.setContextMenuClickLocation({
notesController.setContextMenuClickLocation({
x: posX,
y: posY,
})
viewControllerManager.notesController.reloadContextMenuLayout()
viewControllerManager.notesController.setContextMenuOpen(true)
notesController.reloadContextMenuLayout()
notesController.setContextMenuOpen(true)
}

const openContextMenu = async (posX: number, posY: number) => {
const { didSelect } = await viewControllerManager.selectionController.selectItem(item.uuid, true)
const { didSelect } = await selectionController.selectItem(item.uuid, true)
if (didSelect) {
openNoteContextMenu(posX, posY)
}
Expand All @@ -49,7 +50,7 @@ const NoteListItem: FunctionComponent<DisplayableListItemProps> = ({
}`}
id={item.uuid}
onClick={() => {
void viewControllerManager.selectionController.selectItem(item.uuid, true)
void selectionController.selectItem(item.uuid, true)
}}
onContextMenu={(event) => {
event.preventDefault()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
import { WebApplication } from '@/Application/Application'
import { ViewControllerManager } from '@/Services/ViewControllerManager'
import { FilesController } from '@/Controllers/FilesController'
import { NavigationController } from '@/Controllers/Navigation/NavigationController'
import { NotesController } from '@/Controllers/NotesController'
import { SelectedItemsController } from '@/Controllers/SelectedItemsController'
import { SortableItem } from '@standardnotes/snjs'
import { ListableContentItem } from './ListableContentItem'

export type AbstractListItemProps = {
application: WebApplication
viewControllerManager: ViewControllerManager
filesController: FilesController
selectionController: SelectedItemsController
navigationController: NavigationController
notesController: NotesController
hideDate: boolean
hideIcon: boolean
hideTags: boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,13 @@ const FileMenuOptions: FunctionComponent<Props> = ({
<Icon type="trash" className="mr-2 color-danger" />
<span className="color-danger">Delete permanently</span>
</button>
{selectedFiles.length === 1 && (
<div className="px-3 pt-1.5 pb-0.5 text-xs color-neutral font-medium">
<div>
<span className="font-semibold">File ID:</span> {selectedFiles[0].uuid}
</div>
</div>
)}
</>
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { FileItem } from '@standardnotes/snjs'
import { MutableRefObject } from 'react'

export const createObjectURLWithRef = (
type: FileItem['mimeType'],
bytes: Uint8Array,
ref: MutableRefObject<string | undefined>,
) => {
const objectURL = URL.createObjectURL(
new Blob([bytes], {
type,
}),
)

ref.current = objectURL

return objectURL
}
Loading

0 comments on commit 92024ec

Please sign in to comment.