Skip to content

Commit

Permalink
Add new ExternalShareActions API
Browse files Browse the repository at this point in the history
Signed-off-by: John Molakvoæ <skjnldsv@protonmail.com>
  • Loading branch information
skjnldsv committed Sep 16, 2021
1 parent 959e4cb commit 164b006
Show file tree
Hide file tree
Showing 5 changed files with 178 additions and 8 deletions.
63 changes: 63 additions & 0 deletions apps/files_sharing/src/components/ExternalShareAction.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<!--
- @copyright Copyright (c) 2021 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/>.
-
-->

<template>
<Component :is="data.is"
v-bind="data"
v-on="action.handlers">
{{ data.text }}
</Component>
</template>

<script>
import Share from '../models/Share'
export default {
name: 'ExternalShareAction',
props: {
id: {
type: String,
required: true,
},
action: {
type: Object,
default: () => ({}),
},
fileInfo: {
type: Object,
default: () => {},
required: true,
},
share: {
type: Share,
default: null,
},
},
computed: {
data() {
return this.action.data(this)
},
},
}
</script>
39 changes: 31 additions & 8 deletions apps/files_sharing/src/components/SharingEntryLink.vue
Original file line number Diff line number Diff line change
Expand Up @@ -285,8 +285,16 @@
@submit="onNoteSubmit" />
</template>

<!-- external sharing via url (social...) -->
<ActionLink v-for="({icon, url, name}, index) in externalActions"
<!-- external actions -->
<ExternalShareAction v-for="action in externalLinkActions"
:id="action.id"
:key="action.id"
:action="action"
:file-info="fileInfo"
:share="share" />

<!-- external legacy sharing via url (social...) -->
<ActionLink v-for="({icon, url, name}, index) in externalLegacyLinkActions"
:key="index"
:href="url(shareLink)"
:icon="icon"
Expand Down Expand Up @@ -328,15 +336,16 @@ import Vue from 'vue'
import ActionButton from '@nextcloud/vue/dist/Components/ActionButton'
import ActionCheckbox from '@nextcloud/vue/dist/Components/ActionCheckbox'
import ActionRadio from '@nextcloud/vue/dist/Components/ActionRadio'
import ActionInput from '@nextcloud/vue/dist/Components/ActionInput'
import ActionLink from '@nextcloud/vue/dist/Components/ActionLink'
import ActionRadio from '@nextcloud/vue/dist/Components/ActionRadio'
import ActionText from '@nextcloud/vue/dist/Components/ActionText'
import ActionTextEditable from '@nextcloud/vue/dist/Components/ActionTextEditable'
import ActionLink from '@nextcloud/vue/dist/Components/ActionLink'
import Actions from '@nextcloud/vue/dist/Components/Actions'
import Avatar from '@nextcloud/vue/dist/Components/Avatar'
import Tooltip from '@nextcloud/vue/dist/Directives/Tooltip'
import ExternalShareAction from './ExternalShareAction'
import GeneratePassword from '../utils/GeneratePassword'
import Share from '../models/Share'
import SharesMixin from '../mixins/SharesMixin'
Expand All @@ -354,6 +363,7 @@ export default {
ActionText,
ActionTextEditable,
Avatar,
ExternalShareAction,
},
directives: {
Expand Down Expand Up @@ -381,7 +391,8 @@ export default {
publicUploadRValue: OC.PERMISSION_READ,
publicUploadWValue: OC.PERMISSION_CREATE,
ExternalLinkActions: OCA.Sharing.ExternalLinkActions.state,
ExternalLegacyLinkActions: OCA.Sharing.ExternalLinkActions.state,
ExternalShareActions: OCA.Sharing.ExternalShareActions.state,
}
},
Expand Down Expand Up @@ -621,11 +632,23 @@ export default {
},
/**
* External aditionnal actions for the menu
* External additionnai actions for the menu
* @deprecated use OCA.Sharing.ExternalShareActions
* @returns {Array}
*/
externalLegacyLinkActions() {
return this.ExternalLegacyLinkActions.actions
},
/**
* Additional actions for the menu
* @returns {Array}
*/
externalActions() {
return this.ExternalLinkActions.actions
externalLinkActions() {
// filter only the registered actions for said link
return this.ExternalShareActions.actions
.filter(action => action.shareType.includes(OC.Share.SHARE_TYPE_LINK)
|| action.shareType.includes(OC.Share.SHARE_TYPE_EMAIL))
},
isPasswordPolicyEnabled() {
Expand Down
2 changes: 2 additions & 0 deletions apps/files_sharing/src/files_sharing_tab.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import { translate as t, translatePlural as n } from '@nextcloud/l10n'
import SharingTab from './views/SharingTab'
import ShareSearch from './services/ShareSearch'
import ExternalLinkActions from './services/ExternalLinkActions'
import ExternalShareActions from './services/ExternalShareActions'
import TabSections from './services/TabSections'

// Init Sharing Tab Service
Expand All @@ -36,6 +37,7 @@ if (!window.OCA.Sharing) {
}
Object.assign(window.OCA.Sharing, { ShareSearch: new ShareSearch() })
Object.assign(window.OCA.Sharing, { ExternalLinkActions: new ExternalLinkActions() })
Object.assign(window.OCA.Sharing, { ExternalShareActions: new ExternalShareActions() })
Object.assign(window.OCA.Sharing, { ShareTabSections: new TabSections() })

Vue.prototype.t = t
Expand Down
2 changes: 2 additions & 0 deletions apps/files_sharing/src/services/ExternalLinkActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ export default class ExternalLinkActions {
* @returns {boolean}
*/
registerAction(action) {
console.warn('OCA.Sharing.ExternalLinkActions is deprecated, use OCA.Sharing.ExternalShareAction instead')

if (typeof action === 'object' && action.icon && action.name && action.url) {
this._state.actions.push(action)
return true
Expand Down
80 changes: 80 additions & 0 deletions apps/files_sharing/src/services/ExternalShareActions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/**
* @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 class ExternalShareActions {

_state;

constructor() {
// init empty state
this._state = {}

// init default values
this._state.actions = []
console.debug('OCA.Sharing.ExternalShareActions initialized')
}

/**
* Get the state
*
* @readonly
* @memberof ExternalLinkActions
* @returns {Object} the data state
*/
get state() {
return this._state
}

/**
* Register a new option/entry for the a given share type
*
* @param {Object} action new action component to register
* @param {string} action.id unique action id
* @param {Function} action.data data to bind the component to
* @param {Array} action.shareType list of OC.Share.SHARE_XXX to be mounted on
* @param {Object} action.handlers list of listeners
* @returns {boolean}
*/
registerAction(action) {
// Validate action
if (typeof action !== 'object'
|| typeof action.id !== 'string'
|| typeof action.data !== 'function' // () => {disabled: true}
|| !Array.isArray(action.shareType) // [OC.Share.SHARE_TYPE_LINK, ...]
|| typeof action.handlers !== 'object' // {click: () => {}, ...}
|| !Object.values(action.handlers).every(handler => typeof handler === 'function')) {
console.error('Invalid action provided', action)
return false
}

// Check duplicates
const hasDuplicate = this._state.actions.findIndex(check => check.id === action.id) > -1
if (hasDuplicate) {
console.error(`An action with the same id ${action.id} already exists`, action)
return false
}

this._state.actions.push(action)
return true
}

}

0 comments on commit 164b006

Please sign in to comment.