diff --git a/src/drive/web/modules/filelist/File.jsx b/src/drive/web/modules/filelist/File.jsx index c3d90cc2ee..8d32693601 100644 --- a/src/drive/web/modules/filelist/File.jsx +++ b/src/drive/web/modules/filelist/File.jsx @@ -62,10 +62,26 @@ const File = props => { } const open = (event, attributes) => { - const { onFolderOpen, onFileOpen, isAvailableOffline } = props + console.log('open') + + const { + onFolderOpen, + onFileOpen, + isAvailableOffline, + folderUrlToNavigate + } = props event.stopPropagation() if (isDirectory(attributes)) { - onFolderOpen(attributes.id) + console.log('is directory') + + if (event.ctrlKey || event.metaKey || event.shiftKey) { + const openInNewTab = url => window.open(url, '_blank') + const folderUrl = + folderUrlToNavigate(attributes.id) || `/folder/${attributes.id}` + openInNewTab(`/#${folderUrl}`) + } else { + onFolderOpen(attributes.id) + } } else { onFileOpen({ event, @@ -92,7 +108,9 @@ const File = props => { refreshFolderContent, isInSyncFromSharing, extraColumns, - breakpoints: { isExtraLarge, isMobile } + breakpoints: { isExtraLarge, isMobile }, + fileUrlToNavigate, + folderUrlToNavigate } = props const isImage = attributes.class === 'image' @@ -132,6 +150,8 @@ const File = props => { open={open} toggle={toggle} isRenaming={isRenaming} + fileUrlToNavigate={fileUrlToNavigate} + folderUrlToNavigate={folderUrlToNavigate} > { formattedUpdatedAt={formattedUpdatedAt} refreshFolderContent={refreshFolderContent} isInSyncFromSharing={isInSyncFromSharing} + folderUrlToNavigate={folderUrlToNavigate} + open={open} /> { return getParentDiv(element.parentNode) } -export const getParentLink = element => { - if (!element) { - return null - } - - if (element.nodeName.toLowerCase() === 'a') { - return element - } - - return getParentLink(element.parentNode) -} - const enableTouchEvents = ev => { // remove event when you rename a file if (['INPUT', 'BUTTON'].indexOf(ev.target.nodeName) !== -1) { @@ -43,7 +31,10 @@ const enableTouchEvents = ev => { } // Check if the clicked element is a file path, in that case the FileOpener has nothing to handle - if (ev.srcEvent.target.closest('[class^="fil-file-path"]')) return false + if (ev.srcEvent.target.closest('[class^="fil-file-path"]')) { + console.log('case 3') + return false + } return true } @@ -56,7 +47,9 @@ const FileOpener = ({ open, selectionModeActive, isRenaming, - children + children, + folderUrlToNavigate, + fileUrlToNavigate }) => { const rowRef = useRef() @@ -66,14 +59,20 @@ const FileOpener = ({ const gesturesHandler = propagating(new Hammer(rowRef.current)) gesturesHandler.on('tap press singletap', ev => { + console.log('tap press singletap') + if (actionMenuVisible || disabled) return + console.log('RETURN PASSE') if (enableTouchEvents(ev)) { + console.log('TOUCH EVENT ENABLE') ev.preventDefault() // prevent a ghost click if (ev.type === 'press' || selectionModeActive) { + console.log('PRESS') ev.srcEvent.stopImmediatePropagation() toggle(ev.srcEvent) } else { ev.srcEvent.stopImmediatePropagation() + console.log('open') if (!isRenaming) open(ev.srcEvent, file) } } @@ -110,15 +109,47 @@ const FileOpener = ({ ) } + const isFolder = file => + file.attributes && file.attributes.type === 'directory' + const isFile = file => + (file.attributes && file.attributes.type === 'file') || + file._type === 'io.cozy.files' + const isShortcut = file => file.class === 'shortcut' + const isNote = file => file.name.endsWith('.cozy-note') + let buildHref = '' + if (isFolder(file)) { + buildHref = `/#${folderUrlToNavigate(file.id)}` + } else if (isNote(file)) { + // DO NOTHING + // http://drive.cozy.localhost:8080/#/folder/io.cozy.files.root-dir/file/682e64b839470826fda67a4abc022ff4 + // notes.cozy.localhost:8080/#/n/682e64b839470826fda67a4abc022ff4 + } else if (isShortcut(file)) { + // generate external file <= + // DO NOTHING + } else if (isFile(file)) { + buildHref = `/#${fileUrlToNavigate(file.dir_id)(file)}` + } else { + console.log('NOT FILE') + console.log({ file }) + console.log('file._type, ', file._type) + buildHref = '' + } + return ( - { + console.log('on click file opener') + + ev.preventDefault() + }} > {children} - + ) } diff --git a/src/drive/web/modules/filelist/FileOpener.spec.jsx b/src/drive/web/modules/filelist/FileOpener.spec.jsx index 812375050c..10f5f1f4b0 100644 --- a/src/drive/web/modules/filelist/FileOpener.spec.jsx +++ b/src/drive/web/modules/filelist/FileOpener.spec.jsx @@ -8,7 +8,7 @@ import { shouldBeOpenedByOnlyOffice } from 'cozy-client/dist/models/file' import AppLike from 'test/components/AppLike' import { generateFile } from 'test/generate' -import FileOpener, { getParentLink } from './FileOpener' +import FileOpener from './FileOpener' jest.mock('cozy-client/dist/models/file', () => ({ ...jest.requireActual('cozy-client/dist/models/file'), @@ -49,26 +49,3 @@ describe('FileOpener', () => { expect(queryByTestId('not-onlyoffice-span')).toBeTruthy() }) }) - -describe('getParentLink function', () => { - it('should return the first link in the element ancestors', () => { - const div = document.createElement('div') - const link = document.createElement('a') - link.className = 'my-link' - const span = document.createElement('span') - const span2 = document.createElement('span') - div.appendChild(link) - link.appendChild(span) - span.appendChild(span2) - const result = getParentLink(span2) - expect(result).toEqual(link) - }) - - it('should return null if there is no link in the element ancestors', () => { - const div = document.createElement('div') - const span = document.createElement('span') - div.appendChild(span) - const result = getParentLink(span) - expect(result).toBeNull() - }) -}) diff --git a/src/drive/web/modules/filelist/cells/FileName.jsx b/src/drive/web/modules/filelist/cells/FileName.jsx index cac6ffc623..80ea94e521 100644 --- a/src/drive/web/modules/filelist/cells/FileName.jsx +++ b/src/drive/web/modules/filelist/cells/FileName.jsx @@ -1,6 +1,5 @@ import React, { useCallback } from 'react' import cx from 'classnames' -import { Link } from 'react-router' import get from 'lodash/get' import { useClient } from 'cozy-client' @@ -81,7 +80,9 @@ const FileName = ({ formattedSize, formattedUpdatedAt, refreshFolderContent, - isInSyncFromSharing + isInSyncFromSharing, + folderUrlToNavigate, + open }) => { const classes = cx( styles['fil-content-cell'], @@ -128,13 +129,16 @@ const FileName = ({ ) : ( - { + ev.preventDefault() + console.log('on click') + open(ev, { type: 'directory', id: attributes.dir_id }) + }} > - + ))} {!withFilePath && (isDirectory(attributes) || ( diff --git a/src/drive/web/modules/views/Drive/index.jsx b/src/drive/web/modules/views/Drive/index.jsx index 644814383c..96324e1c3c 100644 --- a/src/drive/web/modules/views/Drive/index.jsx +++ b/src/drive/web/modules/views/Drive/index.jsx @@ -53,6 +53,10 @@ import AddMenuProvider from 'drive/web/modules/drive/AddMenu/AddMenuProvider' const desktopExtraColumnsNames = ['carbonCopy', 'electronicSafe'] const mobileExtraColumnsNames = [] +const folderUrlToNavigate = folderId => `/folder/${folderId}` +const fileUrlToNavigate = currentFolderId => file => + `/folder/${currentFolderId}/file/${file.id}` + const DriveView = ({ currentFolderId, router, @@ -105,14 +109,14 @@ const DriveView = ({ const navigateToFolder = useCallback( folderId => { - router.push(`/folder/${folderId}`) + router.push(folderUrlToNavigate(folderId)) }, [router] ) const navigateToFile = useCallback( file => { - router.push(`/folder/${currentFolderId}/file/${file.id}`) + router.push(fileUrlToNavigate(currentFolderId)(file)) }, [router, currentFolderId] ) @@ -202,6 +206,8 @@ const DriveView = ({ { const { router } = useRouter() const { isDesktop } = useBreakpoints() @@ -71,6 +73,7 @@ const FolderViewBody = ({ const handleFileOpen = useCallback( ({ event, file, isAvailableOffline }) => { + console.log('handleFileOpen') return createFileOpeningHandler({ client, isFlatDomain, @@ -79,7 +82,8 @@ const FolderViewBody = ({ replaceCurrentUrl: url => (window.location.href = url), openInNewTab: url => window.open(url, '_blank'), routeTo: url => router.push(url), - isOnlyOfficeEnabled: isOnlyOfficeEnabled() + isOnlyOfficeEnabled: isOnlyOfficeEnabled(), + fileUrlToNavigate })({ event, file, @@ -185,7 +189,7 @@ const FolderViewBody = ({ {/* TODO FolderViewBody should not have the responsability to chose which empty component to display. It should be done by the "view" itself. But adding a new prop like )} @@ -214,6 +218,8 @@ const FolderViewBody = ({ attributes={file} withSelectionCheckbox onFolderOpen={navigateToFolder} + fileUrlToNavigate={fileUrlToNavigate} + folderUrlToNavigate={folderUrlToNavigate} onFileOpen={handleFileOpen} withFilePath={withFilePath} thumbnailSizeBig={isBigThumbnail} diff --git a/src/drive/web/modules/views/Folder/createFileOpeningHandler.js b/src/drive/web/modules/views/Folder/createFileOpeningHandler.js index 6e40cf25f5..b54719347d 100644 --- a/src/drive/web/modules/views/Folder/createFileOpeningHandler.js +++ b/src/drive/web/modules/views/Folder/createFileOpeningHandler.js @@ -15,9 +15,19 @@ const createFileOpeningHandler = ({ replaceCurrentUrl, openInNewTab, routeTo, - isOnlyOfficeEnabled + isOnlyOfficeEnabled, + fileUrlToNavigate }) => async ({ event, file, isAvailableOffline }) => { + console.log('createFileOpeningHandler') + const fileUrl = + fileUrlToNavigate(file.dir_id)(file) || + `/folder/${file.dir_id}/file/${file.id}` + + console.log('fireUrl') + if (isAvailableOffline) { + console.log('isAvailableOffline') + return dispatch(openLocalFile(client, file)) } @@ -25,7 +35,11 @@ const createFileOpeningHandler = ({ const isShortcut = models.file.isShortcut(file) const isOnlyOffice = models.file.shouldBeOpenedByOnlyOffice(file) + console.log('super') + const shouldOpenInNewTab = event.ctrlKey || event.metaKey || event.shiftKey + if (isShortcut) { + console.log('isShortcut') if (isMobileApp()) { try { const resp = await client.query( @@ -39,20 +53,38 @@ const createFileOpeningHandler = ({ const url = generateShortcutUrl({ file, client, isFlatDomain }) openInNewTab(url) } - } else if (isNote) { - try { - replaceCurrentUrl(await models.note.fetchURL(client, file)) - } catch (e) { - Alerter.error('alert.offline') - } - } else if (isOnlyOffice && isOnlyOfficeEnabled) { - if (event.ctrlKey || event.metaKey || event.shiftKey) { - openInNewTab(makeOnlyOfficeFileRoute(file)) + } else { + if (isNote) { + console.log('isNote') + try { + const routeToNote = await models.note.fetchURL(client, file) + if (shouldOpenInNewTab) { + console.log('shouldOpenInNewTab') + openInNewTab(routeToNote) + } else { + console.log('should NOT OpenInNewTab') + replaceCurrentUrl(routeToNote) + } + } catch (e) { + Alerter.error('alert.offline') + } + } else if (isOnlyOffice && isOnlyOfficeEnabled) { + console.log('isOnlyOffice') + if (shouldOpenInNewTab) { + openInNewTab(makeOnlyOfficeFileRoute(file)) + } else { + routeTo(makeOnlyOfficeFileRoute(file, true)) + } } else { - routeTo(makeOnlyOfficeFileRoute(file, true)) + console.log('here') + if (shouldOpenInNewTab) { + console.log('shouldOpenInNewTab') + openInNewTab(`/#${fileUrl}`) + } else { + console.log('should not OpenInNewTab') + navigateToFile(file) + } } - } else { - navigateToFile(file) } } diff --git a/src/drive/web/modules/views/Public/index.jsx b/src/drive/web/modules/views/Public/index.jsx index 0c85a4a2d0..9390b6bb7e 100644 --- a/src/drive/web/modules/views/Public/index.jsx +++ b/src/drive/web/modules/views/Public/index.jsx @@ -8,10 +8,8 @@ import uniqBy from 'lodash/uniqBy' import { useClient, models } from 'cozy-client' import { SharingContext } from 'cozy-sharing' -import { isMobileApp } from 'cozy-device-helper' import { useI18n } from 'cozy-ui/transpiled/react/I18n' import { Content, Overlay } from 'cozy-ui/transpiled/react' -import Alerter from 'cozy-ui/transpiled/react/Alerter' import useBreakpoints from 'cozy-ui/transpiled/react/hooks/useBreakpoints' import { SharingBannerPlugin, useSharingInfos } from 'cozy-sharing' @@ -62,6 +60,7 @@ const getBreadcrumbPath = (t, displayedFolder, parentFolder) => const desktopExtraColumnsNames = ['carbonCopy', 'electronicSafe'] const mobileExtraColumnsNames = [] +const folderUrlToNavigate = folderId => `/folder/${folderId}` const PublicFolderView = ({ currentFolderId, @@ -101,28 +100,14 @@ const PublicFolderView = ({ const navigateToFolder = useCallback( folderId => { - router.push(`/folder/${folderId}`) + router.push(folderUrlToNavigate(folderId)) }, [router] ) const navigateToFile = async file => { - const isNote = models.file.isNote(file) - if (isNote) { - try { - const noteUrl = await models.note.fetchURL(client, file) - const url = new URL(noteUrl) - if (!isMobileApp()) { - url.searchParams.set('returnUrl', window.location.href) - } - window.location.href = url.toString() - } catch (e) { - Alerter.error('alert.offline') - } - } else { - showInViewer(file) - setViewerOpened(true) - } + showInViewer(file) + setViewerOpened(true) } const showInViewer = useCallback( @@ -229,6 +214,7 @@ const PublicFolderView = ({ `/folder/${folderId}` +const fileUrlToNavigate = () => file => `/recent/file/${file.id}` + export const RecentView = ({ router, location, children }) => { const { t } = useI18n() const { isMobile } = useBreakpoints() @@ -55,14 +58,14 @@ export const RecentView = ({ router, location, children }) => { const navigateToFolder = useCallback( folderId => { - router.push(`/folder/${folderId}`) + router.push(folderUrlToNavigate(folderId)) }, [router] ) const navigateToFile = useCallback( file => { - router.push(`/recent/file/${file.id}`) + router.push(fileUrlToNavigate(file)) }, [router] ) @@ -110,6 +113,8 @@ export const RecentView = ({ router, location, children }) => { + folderId ? `/sharings/${folderId}` : '/sharings' +const fileUrlToNavigate = currentFolderId => file => + `/sharings/${currentFolderId}/file/${file.id}` + const desktopExtraColumnsNames = ['carbonCopy', 'electronicSafe'] const mobileExtraColumnsNames = [] @@ -77,15 +82,14 @@ const SharingsFolderView = ({ const navigateToFolder = useCallback( folderId => { - if (folderId) router.push(`/sharings/${folderId}`) - else router.push('/sharings') + router.push(folderUrlToNavigate(folderId)) }, [router] ) const navigateToFile = useCallback( file => { - router.push(`/sharings/${currentFolderId}/file/${file.id}`) + router.push(fileUrlToNavigate(currentFolderId)(file)) }, [router, currentFolderId] ) @@ -132,6 +136,8 @@ const SharingsFolderView = ({ `/sharings/${folderId}` +const fileUrlToNavigate = () => file => `/sharings/file/${file.id}` + export const SharingsView = ({ router, location, @@ -67,14 +70,14 @@ export const SharingsView = ({ const navigateToFolder = useCallback( folderId => { - router.push(`/sharings/${folderId}`) + router.push(folderUrlToNavigate(folderId)) }, [router] ) const navigateToFile = useCallback( file => { - router.push(`/sharings/file/${file.id}`) + router.push(fileUrlToNavigate(file)) }, [router] ) @@ -113,6 +116,8 @@ export const SharingsView = ({ `/trash/${folderId}` +const fileUrlToNavigate = currentFolderId => file => + `/trash/${currentFolderId}/file/${file.id}` + const TrashFolderView = ({ currentFolderId, displayedFolder, @@ -72,14 +76,14 @@ const TrashFolderView = ({ const navigateToFolder = useCallback( folderId => { - router.push(`/trash/${folderId}`) + router.push(folderUrlToNavigate(folderId)) }, [router] ) const navigateToFile = useCallback( file => { - router.push(`/trash/${currentFolderId}/file/${file.id}`) + router.push(fileUrlToNavigate(currentFolderId)(file)) }, [router, currentFolderId] ) @@ -118,6 +122,8 @@ const TrashFolderView = ({ displayedFolder={displayedFolder} navigateToFolder={navigateToFolder} navigateToFile={navigateToFile} + fileUrlToNavigate={fileUrlToNavigate} + folderUrlToNavigate={folderUrlToNavigate} actions={actions} queryResults={[foldersResult, filesResult]} canSort