Cleanup and manage video errors (#94)

Cleanup and manage video errors
This commit is contained in:
John Molakvoæ 2019-05-07 11:56:59 +02:00 коммит произвёл GitHub
Родитель a844b5e50a 96d22d2160
Коммит ee0981176d
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
5 изменённых файлов: 83 добавлений и 138 удалений

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -22,36 +22,35 @@
<template> <template>
<video <video
v-if="path && canPlay" v-if="path"
:autoplay="active" :autoplay="active"
:controls="visibleControls" :controls="visibleControls"
:poster="livePhotoPath" :poster="livePhotoPath"
:preload="true" :preload="true"
:src="davPath"
:style="{ :style="{
height: height + 'px', height: height + 'px',
width: width + 'px' width: width + 'px'
}" }"
@canplay="doneLoading" @ended="donePlaying"
@click.prevent="playPause" @click.prevent="playPause"
@dblclick.prevent="toggleFullScreen" @dblclick.prevent="toggleFullScreen"
@ended="donePlaying" @canplay="doneLoading"
@loadedmetadata="updateVideoSize"
@mouseenter="showControls" @mouseenter="showControls"
@mouseleave="hideControls"> @mouseleave="hideControls"
@loadedmetadata="updateVideoSize">
<source :src="davPath" :type="mime"> <!-- Omitting `type` on purpose because most of the
browsers auto detect the appropriate codec.
Having it set force the browser to comply to
the provided mime instead of detecting a potential
compatibility. -->
{{ t('viewer', 'Your browser does not support the video tag.') }} {{ t('viewer', 'Your browser does not support the video tag.') }}
</video> </video>
<!-- Browser cannot play this file -->
<Error v-else>
{{ t('viewer', 'This video is not playable in your browser') }}
</Error>
</template> </template>
<script> <script>
import Error from 'Components/Error'
import Mime from 'Mixins/Mime' import Mime from 'Mixins/Mime'
import PreviewUrl from 'Mixins/PreviewUrl' import PreviewUrl from 'Mixins/PreviewUrl'
@ -60,15 +59,10 @@ const liveExt = ['jpg', 'jpeg', 'png']
export default { export default {
name: 'Videos', name: 'Videos',
components: {
Error
},
mixins: [Mime, PreviewUrl], mixins: [Mime, PreviewUrl],
data() { data() {
return { return {
canPlay: true,
visibleControls: false visibleControls: false
} }
}, },
@ -77,12 +71,13 @@ export default {
livePhoto() { livePhoto() {
return this.fileList.find(file => { return this.fileList.find(file => {
// if same filename and extension is allowed // if same filename and extension is allowed
return file.name.startsWith(this.name) return file.href !== this.davPath
&& liveExt.indexOf(file.name.split('.')[1] > -1) && file.name.startsWith(this.name)
&& liveExt.indexOf(file.name.split('.')[1]) > -1
}) })
}, },
livePhotoPath() { livePhotoPath() {
return this.getPreviewIfAny(this.livePhoto) return this.livePhoto && this.getPreviewIfAny(this.livePhoto)
} }
}, },
@ -90,25 +85,15 @@ export default {
active: function(val, old) { active: function(val, old) {
// the item was hidden before and is now the current view // the item was hidden before and is now the current view
if (val === true && old === false) { if (val === true && old === false) {
// if we cannot play the file, we announce we're done loading this.$el.play()
this.canPlayCheck()
if (this.canPlay) {
this.$el.play()
}
// the item was playing before and is now hidden // the item was playing before and is now hidden
} else if (val === false && old === true) { } else if (val === false && old === true) {
if (this.canPlay) { this.$el.pause()
this.$el.pause()
}
} }
} }
}, },
mounted() {
this.canPlayCheck()
},
methods: { methods: {
// Updates the dimensions of the modal // Updates the dimensions of the modal
updateVideoSize() { updateVideoSize() {
@ -138,16 +123,6 @@ export default {
// reset and show poster after play // reset and show poster after play
this.$el.autoplay = false this.$el.autoplay = false
this.$el.load() this.$el.load()
},
canPlayCheck() {
if (this.$el.canPlayType
&& this.$el.canPlayType(this.mime) !== '') {
this.canPlay = true
} else {
this.canPlay = false
this.doneLoading()
}
} }
} }
} }

32
src/models/file.js Normal file
Просмотреть файл

@ -0,0 +1,32 @@
/**
* @copyright Copyright (c) 2019 John Molakvoæ <skjnldsv@protonmail.com>
*
* @author John Molakvoæ <skjnldsv@protonmail.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
export default function(fileInfo, mime, component) {
this.path = fileInfo.href
this.id = fileInfo.id
this.name = fileInfo.name
this.hasPreview = fileInfo.hasPreview
this.mime = mime
this.modal = component
this.failed = false
this.loaded = false
}

Просмотреть файл

@ -31,7 +31,7 @@
:spread-navigation="true" :spread-navigation="true"
:has-previous="hasPrevious" :has-previous="hasPrevious"
:has-next="hasNext" :has-next="hasNext"
:title="currentFileName" :title="currentFile.name"
:enable-swipe="canSwipe" :enable-swipe="canSwipe"
:size="isMobile || isFullscreen ? 'full' : 'large'" :size="isMobile || isFullscreen ? 'full' : 'large'"
:style="{width: showSidebar ? `calc(100% - ${sidebarWidth}px)` : null}" :style="{width: showSidebar ? `calc(100% - ${sidebarWidth}px)` : null}"
@ -41,7 +41,7 @@
<!-- PREVIOUS --> <!-- PREVIOUS -->
<component <component
:is="previousFile.modal" :is="previousFile.modal"
v-if="!previousFile.failed" v-if="previousFile && !previousFile.failed"
:key="getPreviewIfAny(previousFile)" :key="getPreviewIfAny(previousFile)"
ref="previous-content" ref="previous-content"
:dav-path="previousFile.path" :dav-path="previousFile.path"
@ -53,8 +53,9 @@
class="hidden-visually file-view" class="hidden-visually file-view"
@error="previousFailed" /> @error="previousFailed" />
<Error <Error
v-else v-else-if="previousFile"
class="hidden-visually" /> class="hidden-visually"
:name="previousFile.name" />
<!-- CURRENT --> <!-- CURRENT -->
<component <component
@ -77,12 +78,12 @@
@error="currentFailed" /> @error="currentFailed" />
<Error <Error
v-else v-else
:name="currentFileName" /> :name="currentFile.name" />
<!-- NEXT --> <!-- NEXT -->
<component <component
:is="nextFile.modal" :is="nextFile.modal"
v-if="!nextFile.failed" v-if="nextFile && !nextFile.failed"
:key="getPreviewIfAny(nextFile)" :key="getPreviewIfAny(nextFile)"
ref="next-content" ref="next-content"
:dav-path="nextFile.path" :dav-path="nextFile.path"
@ -94,7 +95,7 @@
class="hidden-visually file-view" class="hidden-visually file-view"
@error="nextFailed" /> @error="nextFailed" />
<Error <Error
v-else v-else-if="nextFile"
class="hidden-visually" /> class="hidden-visually" />
</Modal> </Modal>
</template> </template>
@ -107,6 +108,7 @@ import { generateRemoteUrl } from 'nextcloud-server/dist/router'
import Error from 'Components/Error' import Error from 'Components/Error'
import PreviewUrl from 'Mixins/PreviewUrl' import PreviewUrl from 'Mixins/PreviewUrl'
import File from 'Models/file'
import FileList from 'Services/FileList' import FileList from 'Services/FileList'
import Modal from 'nextcloud-vue/dist/Components/Modal' import Modal from 'nextcloud-vue/dist/Components/Modal'
@ -154,12 +156,6 @@ export default {
hasNext() { hasNext() {
return this.fileList.length > 1 return this.fileList.length > 1
}, },
currentFileName() {
if (this.currentFile) {
return this.currentFile.name
}
return ''
},
actions() { actions() {
return OCA.Sharing return OCA.Sharing
? [ ? [
@ -209,13 +205,10 @@ export default {
* @param {Object} fileInfo the opened file info * @param {Object} fileInfo the opened file info
*/ */
async openFile(fileName, fileInfo) { async openFile(fileName, fileInfo) {
this.failed = false
// prevent scrolling while opened // prevent scrolling while opened
document.body.style.overflow = 'hidden' document.body.style.overflow = 'hidden'
const relativePath = `${fileInfo.dir !== '/' ? fileInfo.dir : ''}/${fileName}` const relativePath = `${fileInfo.dir !== '/' ? fileInfo.dir : ''}/${fileName}`
const path = `${this.root}${relativePath}`
let mime = fileInfo.$file.data('mime') let mime = fileInfo.$file.data('mime')
@ -243,19 +236,11 @@ export default {
mime = this.getAliasIfAny(mime) mime = this.getAliasIfAny(mime)
if (this.components[mime]) { if (this.components[mime]) {
this.currentFile = { this.currentFile = new File(fileInfo, mime, this.components[mime])
relativePath,
path,
mime,
hasPreview: fileInfo.hasPreview,
id: fileInfo.id,
name: fileInfo.name,
modal: this.components[mime],
loaded: false
}
this.updatePreviousNext() this.updatePreviousNext()
} else { } else {
console.error(`The following file could not be displayed because to view matches its mime type`, fileName, fileInfo) console.error(`The following file could not be displayed`, fileName, fileInfo)
this.currentFile.failed = true
} }
}, },
@ -265,24 +250,9 @@ export default {
* @param {Object} fileInfo the opened file info * @param {Object} fileInfo the opened file info
*/ */
openFileFromList(fileInfo) { openFileFromList(fileInfo) {
const path = fileInfo.href // override mimetype if existing alias
const id = fileInfo.id
const name = fileInfo.name
const hasPreview = fileInfo.hasPreview
const mime = this.getAliasIfAny(fileInfo.mimetype) const mime = this.getAliasIfAny(fileInfo.mimetype)
const modal = this.components[mime] this.currentFile = new File(fileInfo, mime, this.components[mime])
if (modal) {
this.currentFile = {
path,
mime,
id,
name,
hasPreview,
modal,
failed: false,
loaded: false
}
}
this.updatePreviousNext() this.updatePreviousNext()
}, },
@ -294,51 +264,23 @@ export default {
const next = this.fileList[this.currentIndex + 1] const next = this.fileList[this.currentIndex + 1]
if (prev) { if (prev) {
const path = prev.href
const id = prev.id
const name = prev.name
const hasPreview = prev.hasPreview
const mime = this.getAliasIfAny(prev.mimetype) const mime = this.getAliasIfAny(prev.mimetype)
const modal = this.components[mime] if (this.components[mime]) {
this.previousFile = new File(prev, mime, this.components[mime])
if (modal) {
this.previousFile = {
path,
mime,
id,
name,
hasPreview,
modal,
failed: false
}
} }
// RESET
} else { } else {
this.previousFile = {} // RESET
this.previousFile = null
} }
if (next) { if (next) {
const path = next.href
const id = next.id
const name = next.name
const hasPreview = next.hasPreview
const mime = this.getAliasIfAny(next.mimetype) const mime = this.getAliasIfAny(next.mimetype)
const modal = this.components[mime] if (this.components[mime]) {
this.nextFile = new File(next, mime, this.components[mime])
if (modal) {
this.nextFile = {
path,
mime,
id,
name,
hasPreview,
modal,
failed: false
}
} }
// RESET
} else { } else {
this.nextFile = {} // RESET
this.nextFile = null
} }
}, },
@ -458,8 +400,6 @@ export default {
* Open previous available file * Open previous available file
*/ */
previous() { previous() {
this.failed = false
this.currentIndex-- this.currentIndex--
if (this.currentIndex < 0) { if (this.currentIndex < 0) {
this.currentIndex = this.fileList.length - 1 this.currentIndex = this.fileList.length - 1
@ -472,8 +412,6 @@ export default {
* Open next available file * Open next available file
*/ */
next() { next() {
this.failed = false
this.currentIndex++ this.currentIndex++
if (this.currentIndex > this.fileList.length - 1) { if (this.currentIndex > this.fileList.length - 1) {
this.currentIndex = 0 this.currentIndex = 0