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

Implement file actions menu #15

Closed
wants to merge 1 commit into from
Closed
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
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ module.exports = {
jest: true
},
globals: {
$: true,
t: true,
n: true,
OC: true,
Expand Down
19 changes: 0 additions & 19 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,7 @@
"mime-types": "^2.1.22",
"nextcloud-server": "^0.15.9",
"nextcloud-vue": "^0.8.0",
"vue": "^2.6.7",
"xml2js": "^0.4.19"
"vue": "^2.6.7"
},
"browserslist": [
"last 2 versions",
Expand Down
2 changes: 2 additions & 0 deletions src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import ViewerService from 'Services/Viewer'

import { generateFilePath } from 'nextcloud-server/dist/router'

Vue.prototype.$ = $

Vue.prototype.t = t
Vue.prototype.n = n

Expand Down
46 changes: 35 additions & 11 deletions src/services/FileList.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
*/

import axios from 'axios'
import { parseString } from 'xml2js'

/**
*
Expand All @@ -36,17 +35,42 @@ export default async function(user, path, mimes) {
headers: {
requesttoken: OC.requestToken,
'content-Type': 'text/xml'
}
},
data: `<?xml version="1.0"?>
<d:propfind xmlns:d="DAV:"
xmlns:oc="http://owncloud.org/ns"
xmlns:nc="http://nextcloud.org/ns"
xmlns:ocs="http://open-collaboration-services.org/ns">
<d:prop>
<d:getlastmodified />
<d:getetag />
<d:getcontenttype />
<d:resourcetype />
<oc:fileid />
<oc:permissions />
<oc:size />
<d:getcontentlength />
<nc:has-preview />
<nc:mount-type />
<nc:is-encrypted />
<ocs:share-permissions />
<oc:tags />
<oc:favorite />
<oc:comments-unread />
<oc:owner-id />
<oc:owner-display-name />
<oc:share-types />
</d:prop>
</d:propfind>`
})

let files = []
await parseString(response.data, (error, data) => {
files = data['d:multistatus']['d:response']
if (error) {
console.error(error)
}
})

return files.filter(file => file['d:propstat'][0]['d:prop'][0]['d:getcontenttype'] && mimes.indexOf(file['d:propstat'][0]['d:prop'][0]['d:getcontenttype'][0]) !== -1)
let files = OCA.Files.App.fileList.filesClient._client.parseMultiStatus(response.data)

return files
.map(file => {
const fileInfo = OCA.Files.App.fileList.filesClient._parseFileInfo(file)
fileInfo.href = file.href
return fileInfo
})
.filter(file => file.mimetype && mimes.indexOf(file.mimetype) !== -1)
}
121 changes: 95 additions & 26 deletions src/views/Viewer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -132,14 +132,37 @@ export default {
}
return ''
},
/**
* Map the FIles action to a usable action vue component object
*
* @returns {Object[]} the list of actions
*/
actionsAll() {
return this.fileList[this.currentIndex]
? Object.values(OCA.Files.App.fileList.fileActions.actions.all)
.filter(action => !action.render)
.map(action => {
return this.mapFileAction(action, this.fileList[this.currentIndex])
})
: []
},
actionsCurrent() {
const actions = OCA.Files.App.fileList.fileActions.actions[this.currentFile.mime]
return actions && this.fileList[this.currentIndex]
? Object.values(actions)
.filter(action => !action.render)
.map(action => {
return this.mapFileAction(action, this.fileList[this.currentIndex])
})
: []
},
actions() {
return [
{
text: t('viewer', 'Share'),
icon: 'icon-share-white-forced',
action: this.showSharingSidebar
}
]
const defaultAction = OCA.Files.App.fileList.fileActions.defaults[this.currentFile.mime]
return this.actionsAll.concat(this.actionsCurrent)
.filter(name => name.id !== defaultAction)
.sort((actionA, actionB) => {
return actionA.order - actionB.order
})
}
},

Expand All @@ -158,6 +181,25 @@ export default {
})
})

const showAppsSidebar = OC.Apps.showAppSidebar
OC.Apps.showAppSidebar = () => {
showAppsSidebar()
const sidebar = document.getElementById('app-sidebar')
if (sidebar) {
sidebar.style.zIndex = 10001
this.openedSidebar = true
}
}

const hideAppSidebar = OC.Apps.hideAppSidebar
OC.Apps.hideAppSidebar = () => {
const sidebar = document.getElementById('app-sidebar')
if (sidebar) {
sidebar.style.zIndex = null
this.openedSidebar = false
}
hideAppSidebar()
}
},

methods: {
Expand Down Expand Up @@ -190,8 +232,10 @@ export default {
// retrieve and store file List
this.fileList = await FileList(OC.getCurrentUser().uid, fileInfo.dir, mimes)

console.debug(this.fileList)

// store current position
this.currentIndex = this.fileList.findIndex(file => decodeURI(file['d:href'][0]) === this.root + relativePath)
this.currentIndex = this.fileList.findIndex(file => decodeURI(file.href) === this.root + relativePath)

this.updatePreviousNext()
},
Expand All @@ -202,7 +246,7 @@ export default {
* @param {Object} fileInfo the opened file info
*/
openFileFromList(fileInfo) {
const path = fileInfo['d:href'][0]
const path = fileInfo.href
const mime = this.getMime(path)
const modal = this.components[mime]

Expand All @@ -214,9 +258,9 @@ export default {
failed: false
}

// if the sidebar is already opened, change the current file
// if the sidebar is already opened, hide it
if (this.openedSidebar) {
OCA.Files.App.fileList.showDetailsView(this.currentFileName, 'shareTabView')
OCA.Apps.hideAppSidebar()
}
}

Expand All @@ -232,7 +276,7 @@ export default {
const next = this.fileList[this.currentIndex + 1]

if (prev) {
const path = prev['d:href'][0]
const path = prev.href
const mime = this.getMime(path)
const modal = this.components[mime]

Expand All @@ -250,7 +294,7 @@ export default {
}

if (next) {
const path = next['d:href'][0]
const path = next.href
const mime = this.getMime(path)
const modal = this.components[mime]

Expand Down Expand Up @@ -413,23 +457,48 @@ export default {
},

/**
* Show the sharing sidebar
* Map an OCA.Files.App action to a usable vue action object
*
* @param {Object} data the action object
* @param {String} data.action the action
* @param {String} data.altText altText property
* @param {String} data.displayName the displayName of the action
* @param {String} data.name the id of the action
* @param {String} data.iconClass the icon class
* @param {Int} data.order the order
* @param {OCA.Files.FileInfo} currentFileInfo the current file Infos
* @returns {Object}
*/
mapFileAction({ action, altText, displayName, name, iconClass, order }, currentFileInfo) {
const fileInfoModel = new OCA.Files.FileInfoModel(currentFileInfo)
const $file = $(document.querySelector(`[data-file="${currentFileInfo.name}"]`))
const context = {
fileActions: OCA.Files.App.fileList.fileActions,
fileList: OCA.Files.App.fileList,
$file,
fileInfoModel,
dir: fileInfoModel.get('path')
}

showSharingSidebar() {
// Open the sidebar sharing tab
OCA.Files.App.fileList.showDetailsView(this.currentFileName, 'shareTabView')
let text = typeof displayName === 'function'
? displayName(context)
: displayName

const sidebar = document.getElementById('app-sidebar')
const closeButton = sidebar.querySelector('.icon-close')
if (!text) {
text = altText
}

// Sidebar above the modal
sidebar.style.zIndex = 10001
this.openedSidebar = true
closeButton.addEventListener('click', e => {
sidebar.style.zIndex = null
this.openedSidebar = false
})
return {
text,
id: name,
icon: typeof iconClass === 'function'
? iconClass(currentFileInfo.name, context)
: iconClass,
action: function() {
OCA.Files.App.fileList.fileActions.triggerAction(name, fileInfoModel, OCA.Files.App.fileList)
},
order
}
}
}
}
Expand Down