Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add file view #1064

Merged
merged 25 commits into from
Jun 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
369530b
feat: add file view
amanharwara Jun 3, 2022
5db4e8c
refactor: rename
amanharwara Jun 3, 2022
7596e6c
feat: file view
amanharwara Jun 3, 2022
e925c38
feat: add file uuid
amanharwara Jun 3, 2022
b4b32fb
fix: protected overlay
amanharwara Jun 3, 2022
831d88c
feat: add new utility class
amanharwara Jun 3, 2022
fade133
fix: styles
amanharwara Jun 3, 2022
a5373e7
fix: object url revocation
amanharwara Jun 3, 2022
5449e2c
fix: audio sizing
amanharwara Jun 3, 2022
0c0211f
fix: text preview sizing
amanharwara Jun 3, 2022
9a0dff6
fix: file image/video preview size
amanharwara Jun 3, 2022
214b854
fix: image zoom
amanharwara Jun 3, 2022
9ed5939
feat: use common FilePreview component
amanharwara Jun 3, 2022
5e06b0d
feat: make loading the default state
amanharwara Jun 3, 2022
dc19977
refactor: pass in controllers instead of controller manager
amanharwara Jun 3, 2022
59f3e98
refactor: move create[..]Ref function into new file
amanharwara Jun 3, 2022
d438e42
refactor: move condition to named const
amanharwara Jun 3, 2022
b0508b3
refactor: move to separate file
amanharwara Jun 3, 2022
3d51c5d
refactor: move conditional into named const
amanharwara Jun 3, 2022
177a73b
Merge branch 'develop' of github.com:standardnotes/web into feat/file…
amanharwara Jun 3, 2022
1613bd2
fix: file title change
amanharwara Jun 3, 2022
a7d7992
refactor: rename variable to attachedTabDisabled
amanharwara Jun 6, 2022
2285c30
refactor: rename file view
amanharwara Jun 6, 2022
1be3850
fix: remove unnecessary conditional
amanharwara Jun 6, 2022
a0938fd
feat: rename file only on submit
amanharwara Jun 6, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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