Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Next Next commit
Add download button in actions menu
Signed-off-by: Florent Fayolle <[email protected]>
Signed-off-by: Robbert Gurdeep Singh <[email protected]>
  • Loading branch information
fflorent authored and skjnldsv committed Apr 8, 2021
commit 3869da49d01030fe8d5a96a803e28b71867082da
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ yarn-error.log*
build/
coverage/

cypress/downloads
cypress/screenshots
cypress/snapshots
cypress/videos
vendor
.php_cs.cache
2 changes: 1 addition & 1 deletion cypress/integration/delete.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
import { randHash } from '../utils'
const randUser = randHash()

describe('Open image.png in viewer', function() {
describe('Delete image.png in viewer', function() {
before(function() {
// Init user
cy.nextcloudCreateUser(randUser, 'password')
Expand Down
81 changes: 81 additions & 0 deletions cypress/integration/download.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/**
* @copyright Copyright (c) 2020 Florent Fayolle <[email protected]>
*
* @author Florent Fayolle <[email protected]>
*
* @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/>.
*
*/

import { randHash } from '../utils'
import * as path from 'path';
const randUser = randHash()
const fileName = "image.png"
const fileSize = 4531680; // du -b image.png

describe(`Download ${fileName} in viewer`, function() {
before(function() {
// Init user
cy.nextcloudCreateUser(randUser, 'password')
cy.login(randUser, 'password')

// Upload test files
cy.uploadFile(fileName, 'image/png')
cy.visit('/apps/files')

// wait a bit for things to be settled
cy.wait(2000)
})

after(function() {
cy.logout()
})

it(`See "${fileName}" in the list`, function() {
cy.get(`#fileList tr[data-file="${fileName}"]`, { timeout: 10000 })
.should('contain', fileName)
})

it('Open the viewer on file click', function() {
cy.openFile(fileName)
cy.get('body > .viewer').should('be.visible')
})

it('Does not see a loading animation', function() {
cy.get('body > .viewer', { timeout: 10000 })
.should('be.visible')
.and('have.class', 'modal-mask')
.and('not.have.class', 'icon-loading')
})

it('Download the image', function() {
// open the menu
cy.get('body > .viewer .modal-header button.action-item__menutoggle').click()
// download the file
cy.get('.action-link__icon.icon-download').click()
})

it('Compare downloaded file with asset by size', function() {
const downloadsFolder = Cypress.config('downloadsFolder')
const downloadedFileName = path.join(downloadsFolder, fileName)
cy.readFile(downloadedFileName, 'binary', { timeout: 15000 })
.should((buffer) => {
if (buffer.length !== fileSize) {
throw new Error(`File size ${buffer.length} is not ${fileSize}`)
}
})
})
})
15 changes: 7 additions & 8 deletions src/mixins/PreviewUrl.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
*
*/
import { generateUrl } from '@nextcloud/router'
import { getRootPath, getToken, isPublic } from '../utils/davUtils'
import { encodeFilePath } from '../utils/fileUtils'
import { getToken, isPublic } from '../utils/davUtils'
import { encodeFilePath, getDavPath } from '../utils/fileUtils'

export default {
computed: {
Expand All @@ -44,13 +44,12 @@ export default {
* @returns {string}
*/
davPath() {
// TODO: allow proper dav access without the need of basic auth
// https://github.com/nextcloud/server/issues/19700
if (isPublic()) {
return generateUrl(`/s/${getToken()}/download?path=${this.filename.replace(this.basename, '')}&files=${this.basename}`)
}
return getRootPath() + this.filename
return getDavPath({
filename: this.filename,
basename: this.basename,
})
},

},
methods: {
/**
Expand Down
2 changes: 2 additions & 0 deletions src/models/file.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
import { getDavPath } from '../utils/fileUtils'

export default function(fileInfo, mime, component) {
const data = {
mime,
modal: component,
failed: false,
loaded: false,
davPath: getDavPath(fileInfo),
}

return Object.assign({}, fileInfo, data)
Expand Down
20 changes: 19 additions & 1 deletion src/utils/fileUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
import { dirname } from '@nextcloud/paths'
import { generateUrl } from '@nextcloud/router'

import camelcase from 'camelcase'
import { getRootPath, getToken, isPublic } from './davUtils'
import { isNumber } from './numberUtil'

/**
Expand Down Expand Up @@ -119,4 +123,18 @@ const genFileInfo = function(obj) {
return fileInfo
}

export { encodeFilePath, extractFilePaths, sortCompare, genFileInfo }
/**
* Generate absolute dav remote path of the file
* @param {object} fileInfo The fileInfo
* @returns {string}
*/
const getDavPath = function({ filename, basename }) {
// TODO: allow proper dav access without the need of basic auth
// https://github.com/nextcloud/server/issues/19700
if (isPublic()) {
return generateUrl(`/s/${getToken()}/download?path=${dirname(filename)}&files=${basename}`)
}
return getRootPath() + filename
}

export { encodeFilePath, extractFilePaths, sortCompare, genFileInfo, getDavPath }
9 changes: 9 additions & 0 deletions src/views/Viewer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,13 @@
@click="showSidebar">
{{ t('viewer', 'Open sidebar') }}
</ActionButton>
<ActionLink
download
icon="icon-download"
:close-after-click="true"
:href="currentFile.davPath">
{{ t('viewer', 'Download') }}
</ActionLink>
<ActionButton
v-if="canDelete"
:close-after-click="true"
Expand Down Expand Up @@ -120,6 +127,7 @@ import '@nextcloud/dialogs/styles/toast.scss'
import { showError } from '@nextcloud/dialogs'

import ActionButton from '@nextcloud/vue/dist/Components/ActionButton'
import ActionLink from '@nextcloud/vue/dist/Components/ActionLink'
import isFullscreen from '@nextcloud/vue/dist/Mixins/isFullscreen'
import isMobile from '@nextcloud/vue/dist/Mixins/isMobile'
import Modal from '@nextcloud/vue/dist/Components/Modal'
Expand All @@ -139,6 +147,7 @@ export default {

components: {
ActionButton,
ActionLink,
Modal,
Error,
},
Expand Down