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

Full screen mode #1588

Merged
merged 16 commits into from
May 3, 2023
Merged
Show file tree
Hide file tree
Changes from 14 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.
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.

109 changes: 108 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 Down Expand Up @@ -407,6 +424,27 @@ export default {
}
}
},

isFullscreenMode(mode) {
if (!this.isImage) {
return
}

// Use 100% of screen height to display images and make the header semitransparent
//
// NOTE: This fragment depends on internal structure of the NcModal component.
//
const modalHeader = document.getElementsByClassName('modal-header').item(0)
const modalContainer = document.getElementsByClassName('modal-container').item(0)
if (mode) {
modalHeader.classList.add('modal-header--semitransparent')
modalContainer.classList.add('modal-container--fullscreen')
} else {
modalHeader.classList.remove('modal-header--semitransparent')
modalContainer.classList.remove('modal-container--fullscreen')
}
skjnldsv marked this conversation as resolved.
Show resolved Hide resolved
},

},

beforeMount() {
Expand Down Expand Up @@ -447,6 +485,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 +500,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 +843,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 +1021,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
skjnldsv marked this conversation as resolved.
Show resolved Hide resolved
if (el.requestFullscreen) {
el.requestFullscreen()
} else if (el.webkitRequestFullscreen) {
el.webkitRequestFullscreen()
}
},

exitFullscreen() {
if (document.exitFullscreen) {
document.exitFullscreen()
} else if (document.webkitExitFullscreen) {
document.webkitExitFullscreen()
}
skjnldsv marked this conversation as resolved.
Show resolved Hide resolved
},

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 All @@ -993,6 +1086,15 @@ export default {
cursor: pointer;
}

:deep(.modal-header--semitransparent) {
.modal-title {
opacity: 0;
}
.icons-menu {
background-color: rgba(0, 0, 0, 0.2);
}
}

:deep(.modal-wrapper) {
.modal-container {
// Ensure some space at the bottom
Expand All @@ -1003,6 +1105,11 @@ export default {
background-color: transparent;
box-shadow: none;
}
.modal-container--fullscreen {
top: 0;
bottom: 0;
height: 100%;
}
}

&__content {
Expand Down