Skip to content

Commit

Permalink
feat: Compare files side by side
Browse files Browse the repository at this point in the history
Signed-off-by: Julius Härtl <[email protected]>
  • Loading branch information
juliusknorr committed Aug 4, 2023
1 parent 621722b commit d19eaed
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 4 deletions.
55 changes: 54 additions & 1 deletion src/services/Viewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,18 @@ import Images from '../models/images.js'
import Videos from '../models/videos.js'
import Audios from '../models/audios.js'

/**
* Handler type definition
*
* @typedef {object} Handler
* @property {string} id unique identifier for the handler
* @property {string[]} mimes list of mime types that are supported for opening
* @property {object} component Vue component to render the file
* @property {string} group group identifier to combine for navigating to the next/previous files
* @property {?string} theme viewer modal theme (one of 'dark', 'light', 'default')
* @property {boolean} canCompare Indicate support for comparing two files
*/

/**
* File info type definition
*
Expand All @@ -41,12 +53,15 @@ export default class Viewer {

_state
_mimetypes
_mimetypesCompare

constructor() {
this._mimetypes = []
this._mimetypesCompare = []
this._state = {}
this._state.file = ''
this._state.fileInfo = null
this._state.compareFileInfo = null
this._state.files = []
this._state.enableSidebar = true
this._state.el = null
Expand All @@ -71,6 +86,7 @@ export default class Viewer {
*
* @readonly
* @memberof Viewer
* @return {Handler[]}
*/
get availableHandlers() {
return this._state.handlers
Expand All @@ -80,11 +96,14 @@ export default class Viewer {
* Register a new handler
*
* @memberof Viewer
* @param {object} handler a new unregistered handler
* @param {Handler} handler a new unregistered handler
*/
registerHandler(handler) {
this._state.handlers.push(handler)
this._mimetypes.push.apply(this._mimetypes, handler.mimes)
if (handler?.canCompare === true) {
this._mimetypesCompare.push.apply(this._mimetypesCompare, handler.mimes)
}
}

/**
Expand All @@ -107,6 +126,16 @@ export default class Viewer {
return this._state.fileInfo
}

/**
* Get the current comparison view opened file fileInfo
*
* @memberof Viewer
* @return {?Fileinfo} the currently opened file fileInfo
*/
get compareFileInfo() {
return this._state.compareFileInfo
}

/**
* Get the current files list
*
Expand Down Expand Up @@ -147,6 +176,16 @@ export default class Viewer {
return this._mimetypes
}

/**
* Get the supported mimetypes that can be opened side by side for comparison
*
* @memberof Viewer
* @return {Array} list of mimetype strings that the viewer can open side by side for comparison
*/
get mimetypesCompare() {
return this._mimetypesCompare
}

/**
* Return the method provided to fetch more results
*
Expand Down Expand Up @@ -291,6 +330,20 @@ export default class Viewer {
this.open(options)
}

/**
* Open the viewer with two files side by side
*
* @memberof Viewer
* @param {Fileinfo} fileInfo current file
* @param {Fileinfo} compareFileInfo older file to compare
*/
compare(fileInfo, compareFileInfo) {
this.open({
fileInfo,
})
this._state.compareFileInfo = compareFileInfo
}

/**
* Close the opened file
*
Expand Down
56 changes: 53 additions & 3 deletions src/views/Viewer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,22 @@
</NcActionButton>
</template>

<div class="viewer__content" @click.self.exact="close">
<div class="viewer__content" :class="contentClass" @click.self.exact="close">
<component :is="comparisonFile.modal"
v-if="comparisonFile && !comparisonFile.failed && showComparison"
:key="comparisonFile.fileid"
ref="content"
v-bind="comparisonFile"
:active="true"
:can-swipe="false"
:can-zoom="false"
:editing="false"
:is-full-screen="isFullscreen"
:is-sidebar-shown="isSidebarShown"
:loaded.sync="comparisonFile.loaded"
class="viewer__file viewer__file--active"
@error="currentFailed" />

<!-- PREVIOUS -->
<component :is="previousFile.modal"
v-if="previousFile && !previousFile.failed"
Expand Down Expand Up @@ -230,6 +245,7 @@ export default {
currentIndex: 0,
previousFile: {},
currentFile: {},
comparisonFile: {},
nextFile: {},
fileList: [],
Expand Down Expand Up @@ -274,6 +290,9 @@ export default {
fileInfo() {
return this.Viewer.fileInfo
},
comparisonFileInfo() {
return this.Viewer.compareFileInfo
},
files() {
return this.Viewer.files
},
Expand Down Expand Up @@ -365,6 +384,16 @@ export default {
'image--fullscreen': this.isImage && this.isFullscreenMode,
}
},
showComparison() {
return !this.isMobile
},
contentClass() {
return {
'viewer--split': this.comparisonFile,
}
},
},
watch: {
Expand Down Expand Up @@ -406,6 +435,16 @@ export default {
}
},
comparisonFileInfo(fileInfo) {
if (fileInfo) {
logger.info('Opening viewer for comparisonFileInfo ', { fileInfo })
this.compareFile(fileInfo)
} else {
// object is undefined, we're closing!
this.cleanup()
}
},
files(fileList) {
// the files list changed, let's update the current opened index
const currentIndex = fileList.findIndex(file => file.basename === this.currentFile.basename)
Expand Down Expand Up @@ -516,7 +555,7 @@ export default {
this.cancelRequestFile()
// do not open the same file again
if (path === this.currentFile.path) {
if (path === this.currentFile.path && !this.currentFile.source) { // need to still run when switching from version to current file
return
}
Expand Down Expand Up @@ -567,7 +606,7 @@ export default {
this.cancelRequestFolder()
// do not open the same file info again
if (fileInfo.basename === this.currentFile.basename) {
if (fileInfo.basename === this.currentFile.basename && fileInfo.source !== this.currentFile.source) {
return
}
Expand Down Expand Up @@ -637,6 +676,7 @@ export default {
// show file
this.currentFile = new File(fileInfo, mime, handler.component)
this.comparisonFile = null
this.updatePreviousNext()
// if sidebar was opened before, let's update the file
Expand All @@ -656,6 +696,10 @@ export default {
this.updatePreviousNext()
},
async compareFile(fileInfo) {
this.comparisonFile = new File(fileInfo, fileInfo.mime, this.components[fileInfo.mime])
},
/**
* Show sidebar if available and a file is already opened
*/
Expand Down Expand Up @@ -1085,6 +1129,12 @@ export default {
cursor: pointer;
}
&--split {
.viewer__file--active {
width: 50%;
}
}
:deep(.modal-wrapper) {
.modal-container {
// Ensure some space at the bottom
Expand Down

0 comments on commit d19eaed

Please sign in to comment.