Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 3 additions & 3 deletions cypress/e2e/non-dav-files.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,9 @@ describe('Open non-dav files in viewer', function() {
cy.get('body > .viewer button.next').should('not.be.visible')
})

it('Does not see the menu or sidebar button', function() {
// Menu does not exist
cy.get('body > .viewer .modal-header button.action-item__menutoggle').should('not.exist')
it('See the menu but does not see the sidebar button', function() {
// Menu exists
cy.get('body > .viewer .modal-header button.action-item__menutoggle').should('be.visible')
cy.get('.action-button__icon.icon-menu-sidebar').should('not.exist')
})

Expand Down
14 changes: 11 additions & 3 deletions cypress/e2e/sharing/download-share.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,17 +78,25 @@ describe(`Download ${fileName} from viewer in link share`, function() {
.and('not.have.class', 'icon-loading')
})

it('See the download icon and title on the viewer header', function() {
it('See the title and the close icon on the viewer header', function() {
cy.get('body > .viewer .modal-title').should('contain', 'image1.jpg')
cy.get(`body > .viewer .modal-header a.action-item[href*='/s/${token}/download']`).should('be.visible')
cy.get('body > .viewer .modal-header button.header-close').should('be.visible')
})

it('See the menu on the viewer header and open it', function() {
cy.get('body > .viewer .modal-header button.action-item__menutoggle').should('be.visible').click()
})

it('See the full screen and download icons in the menu', function() {
cy.get('body > .v-popper__popper ul span.fullscreen-icon').should('be.visible')
cy.get(`body > .v-popper__popper ul a.action-link[href*='/s/${token}/download']`).should('be.visible')
})

it('Download the image', function() {
// https://github.com/cypress-io/cypress/issues/14857
cy.window().then((win) => { setTimeout(() => { win.location.reload() }, 5000) })
// download the file
cy.get('body > .viewer .modal-header a.action-item .download-icon').click()
cy.get(`body > .v-popper__popper a.action-link[href*='/s/${token}/download']`).click()
})

it('Compare downloaded file with asset by size', function() {
Expand Down
Binary file modified cypress/snapshots/base/visual-regression.cy.js/non-dav.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified cypress/snapshots/base/visual-regression.cy.js/video.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions js/viewer-main.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion js/viewer-main.js.map

Large diffs are not rendered by default.

98 changes: 97 additions & 1 deletion src/views/Viewer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,14 @@
{{ t('viewer', 'Edit') }}
</NcActionButton>
<!-- Menu items -->
<NcActionButton :close-after-click="true"
@click="toggleFullScreen">
<template #icon>
<Fullscreen v-if="!isFullscreenMode" :size="20" />
<FullscreenExit v-else :size="20" />
</template>
{{ isFullscreenMode ? t('viewer', 'Exit full screen') : t('viewer', 'Full screen') }}
</NcActionButton>
<NcActionButton v-if="Sidebar && sidebarOpenFilePath && !isSidebarShown"
:close-after-click="true"
icon="icon-menu-sidebar"
Expand Down Expand Up @@ -180,6 +188,8 @@ import logger from '../services/logger.js'

import Delete from 'vue-material-design-icons/Delete.vue'
import Download from 'vue-material-design-icons/Download.vue'
import Fullscreen from 'vue-material-design-icons/Fullscreen.vue'
import FullscreenExit from 'vue-material-design-icons/FullscreenExit.vue'
import Pencil from 'vue-material-design-icons/Pencil.vue'

export default {
Expand All @@ -189,6 +199,8 @@ export default {
Delete,
Download,
Error,
Fullscreen,
FullscreenExit,
NcActionButton,
NcActionLink,
NcModal,
Expand Down Expand Up @@ -228,6 +240,7 @@ export default {
// Flags
sidebarWidth: 0,
isSidebarShown: false,
isFullscreenMode: false,
canSwipe: true,
isStandalone: !(OCA && OCA.Files && 'fileActions' in OCA.Files),
theme: null,
Expand Down Expand Up @@ -278,6 +291,10 @@ export default {
return this.currentIndex === this.fileList.length - 1
},

isImage() {
return ['image/jpeg', 'image/png', 'image/webp'].includes(this.currentFile?.mime)
},

/**
* Returns the path to the current opened file in the sidebar.
*
Expand Down Expand Up @@ -327,7 +344,7 @@ export default {
return !this.isMobile
&& canDownload()
&& this.currentFile?.permissions?.includes('W')
&& ['image/jpeg', 'image/png', 'image/webp'].includes(this.currentFile?.mime)
&& this.isImage
},

modalClass() {
Expand All @@ -337,6 +354,7 @@ export default {
'theme--dark': this.theme === 'dark',
'theme--light': this.theme === 'light',
'theme--default': this.theme === 'default',
'image--fullscreen': this.isImage && this.isFullscreenMode,
}
},
},
Expand Down Expand Up @@ -407,6 +425,7 @@ export default {
}
}
},

},

beforeMount() {
Expand Down Expand Up @@ -447,6 +466,7 @@ export default {
window.addEventListener('keydown', this.keyboardDeleteFile)
window.addEventListener('keydown', this.keyboardDownloadFile)
window.addEventListener('keydown', this.keyboardEditFile)
this.addFullscreenEventListeners()
},

beforeDestroy() {
Expand All @@ -461,6 +481,7 @@ export default {
window.removeEventListener('keydown', this.keyboardDeleteFile)
window.removeEventListener('keydown', this.keyboardDownloadFile)
window.removeEventListener('keydown', this.keyboardEditFile)
this.removeFullscreenEventListeners()
},

methods: {
Expand Down Expand Up @@ -803,6 +824,10 @@ export default {
if (OCA?.Files?.Sidebar) {
OCA.Files.Sidebar.setFullScreenMode(false)
}

if (this.isFullscreenMode) {
this.exitFullscreen()
}
},

keyboardDeleteFile(event) {
Expand Down Expand Up @@ -977,6 +1002,55 @@ export default {
handleTrapElementsChange(element) {
this.trapElements.push(element)
},

// Support full screen API on standard-compliant browsers and Safari (apparently except iPhone).
// Implementation based on:
// https://developer.mozilla.org/en-US/docs/Web/API/Fullscreen_API/Guide

toggleFullScreen() {
if (this.isFullscreenMode) {
this.exitFullscreen()
} else {
this.requestFullscreen()
}
},

requestFullscreen() {
const el = document.documentElement
if (el.requestFullscreen) {
el.requestFullscreen()
} else if (el.webkitRequestFullscreen) {
el.webkitRequestFullscreen()
}
},

exitFullscreen() {
if (document.exitFullscreen) {
document.exitFullscreen()
} else if (document.webkitExitFullscreen) {
document.webkitExitFullscreen()
}
},

addFullscreenEventListeners() {
document.addEventListener('fullscreenchange', this.onFullscreenchange)
document.addEventListener('webkitfullscreenchange', this.onFullscreenchange)
},

removeFullscreenEventListeners() {
document.addEventListener('fullscreenchange', this.onFullscreenchange)
document.addEventListener('webkitfullscreenchange', this.onFullscreenchange)
},

onFullscreenchange() {
if (document.fullscreenElement === document.documentElement
|| document.webkitFullscreenElement === document.documentElement) {
this.isFullscreenMode = true
} else {
this.isFullscreenMode = false
}
},

},
}
</script>
Expand Down Expand Up @@ -1064,6 +1138,28 @@ export default {
}
}
}

&.image--fullscreen {
// Special display mode for images in full screen
:deep(.modal-header) {
.modal-title {
// Hide file name
opacity: 0;
}
.icons-menu {
// Semi-transparent background for icons only
background-color: rgba(0, 0, 0, 0.2);
}
}
:deep(.modal-wrapper) {
.modal-container {
// Use entire screen height
top: 0;
bottom: 0;
height: 100%;
}
}
}
}

</style>
Expand Down