зеркало из https://github.com/nextcloud/server.git
Use svg icons
Signed-off-by: Louis Chemineau <louis@chmn.me>
This commit is contained in:
Родитель
8829019101
Коммит
a28838b866
|
@ -20,14 +20,14 @@
|
|||
*
|
||||
*/
|
||||
|
||||
import MessageReplyText from 'vue-material-design-icons/MessageReplyText.vue'
|
||||
import MessageReplyText from '@mdi/svg/svg/message-reply-text.svg?raw'
|
||||
|
||||
// Init Comments tab component
|
||||
let TabInstance = null
|
||||
const commentTab = new OCA.Files.Sidebar.Tab({
|
||||
id: 'comments',
|
||||
name: t('comments', 'Comments'),
|
||||
icon: 'icon-comment',
|
||||
iconSvg: MessageReplyText,
|
||||
|
||||
async mount(el, fileInfo, context) {
|
||||
if (TabInstance) {
|
||||
|
|
|
@ -19,12 +19,14 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
import { sanitizeSVG } from '@skjnldsv/sanitize-svg'
|
||||
|
||||
export default class Tab {
|
||||
|
||||
_id
|
||||
_name
|
||||
_icon
|
||||
_iconSvgSanitized
|
||||
_mount
|
||||
_update
|
||||
_destroy
|
||||
|
@ -37,14 +39,15 @@ export default class Tab {
|
|||
* @param {object} options destructuring object
|
||||
* @param {string} options.id the unique id of this tab
|
||||
* @param {string} options.name the translated tab name
|
||||
* @param {string} options.icon the vue component
|
||||
* @param {?string} options.icon the icon css class
|
||||
* @param {?string} options.iconSvg the icon in svg format
|
||||
* @param {Function} options.mount function to mount the tab
|
||||
* @param {Function} options.update function to update the tab
|
||||
* @param {Function} options.destroy function to destroy the tab
|
||||
* @param {Function} [options.enabled] define conditions whether this tab is active. Must returns a boolean
|
||||
* @param {Function} [options.scrollBottomReached] executed when the tab is scrolled to the bottom
|
||||
*/
|
||||
constructor({ id, name, icon, mount, update, destroy, enabled, scrollBottomReached } = {}) {
|
||||
constructor({ id, name, icon, iconSvg, mount, update, destroy, enabled, scrollBottomReached } = {}) {
|
||||
if (enabled === undefined) {
|
||||
enabled = () => true
|
||||
}
|
||||
|
@ -59,8 +62,8 @@ export default class Tab {
|
|||
if (typeof name !== 'string' || name.trim() === '') {
|
||||
throw new Error('The name argument is not a valid string')
|
||||
}
|
||||
if ((typeof icon !== 'string' || icon.trim() === '') && typeof icon !== 'object') {
|
||||
throw new Error('The icon argument is not a valid string or vuejs component')
|
||||
if ((typeof icon !== 'string' || icon.trim() === '') && typeof iconSvg !== 'string') {
|
||||
throw new Error('Missing valid string for icon or iconSvg argument')
|
||||
}
|
||||
if (typeof mount !== 'function') {
|
||||
throw new Error('The mount argument should be a function')
|
||||
|
@ -81,12 +84,20 @@ export default class Tab {
|
|||
this._id = id
|
||||
this._name = name
|
||||
this._icon = icon
|
||||
this._iconSvg = iconSvg
|
||||
this._mount = mount
|
||||
this._update = update
|
||||
this._destroy = destroy
|
||||
this._enabled = enabled
|
||||
this._scrollBottomReached = scrollBottomReached
|
||||
|
||||
if (typeof iconSvg === 'string') {
|
||||
sanitizeSVG(iconSvg)
|
||||
.then(sanitizedSvg => {
|
||||
this._iconSvgSanitized = sanitizedSvg
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
get id() {
|
||||
|
@ -97,14 +108,14 @@ export default class Tab {
|
|||
return this._name
|
||||
}
|
||||
|
||||
get isIconClass() {
|
||||
return typeof this._icon === 'string'
|
||||
}
|
||||
|
||||
get icon() {
|
||||
return this._icon
|
||||
}
|
||||
|
||||
get iconSvg() {
|
||||
return this._iconSvgSanitized
|
||||
}
|
||||
|
||||
get mount() {
|
||||
return this._mount
|
||||
}
|
||||
|
|
|
@ -67,14 +67,15 @@
|
|||
:id="tab.id"
|
||||
:key="tab.id"
|
||||
:name="tab.name"
|
||||
:icon="tab.isIconClass ? tab.icon : undefined"
|
||||
:icon="tab.icon"
|
||||
:on-mount="tab.mount"
|
||||
:on-update="tab.update"
|
||||
:on-destroy="tab.destroy"
|
||||
:on-scroll-bottom-reached="tab.scrollBottomReached"
|
||||
:file-info="fileInfo">
|
||||
<template #icon v-if="!tab.isIconClass">
|
||||
<component :is="tab.icon" />
|
||||
<template v-if="tab.iconSvg !== undefined" #icon>
|
||||
<!-- eslint-disable-next-line vue/no-v-html -->
|
||||
<span class="svg-icon" v-html="tab.iconSvg" />
|
||||
</template>
|
||||
</SidebarTab>
|
||||
</template>
|
||||
|
@ -512,5 +513,13 @@ export default {
|
|||
top: 0 !important;
|
||||
height: 100% !important;
|
||||
}
|
||||
|
||||
.svg-icon {
|
||||
::v-deep svg {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
fill: var(--color-main-text);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -31,7 +31,7 @@ import ExternalLinkActions from './services/ExternalLinkActions.js'
|
|||
import ExternalShareActions from './services/ExternalShareActions.js'
|
||||
import TabSections from './services/TabSections.js'
|
||||
|
||||
import ShareVariant from 'vue-material-design-icons/ShareVariant.vue'
|
||||
import ShareVariant from '@mdi/svg/svg/share-variant.svg?raw'
|
||||
|
||||
// Init Sharing Tab Service
|
||||
if (!window.OCA.Sharing) {
|
||||
|
@ -55,7 +55,7 @@ window.addEventListener('DOMContentLoaded', function() {
|
|||
OCA.Files.Sidebar.registerTab(new OCA.Files.Sidebar.Tab({
|
||||
id: 'sharing',
|
||||
name: t('files_sharing', 'Sharing'),
|
||||
icon: ShareVariant,
|
||||
iconSvg: ShareVariant,
|
||||
|
||||
async mount(el, fileInfo, context) {
|
||||
if (TabInstance) {
|
||||
|
|
|
@ -22,7 +22,7 @@ import { translate as t, translatePlural as n } from '@nextcloud/l10n'
|
|||
|
||||
import VersionTab from './views/VersionTab.vue'
|
||||
import VTooltip from 'v-tooltip'
|
||||
import BackupRestore from 'vue-material-design-icons/BackupRestore.vue'
|
||||
import BackupRestore from '@mdi/svg/svg/backup-restore.svg?raw'
|
||||
|
||||
Vue.prototype.t = t
|
||||
Vue.prototype.n = n
|
||||
|
@ -38,7 +38,7 @@ window.addEventListener('DOMContentLoaded', function() {
|
|||
OCA.Files.Sidebar.registerTab(new OCA.Files.Sidebar.Tab({
|
||||
id: 'version_vue',
|
||||
name: t('files_versions', 'Version'),
|
||||
icon: BackupRestore,
|
||||
iconSvg: BackupRestore,
|
||||
|
||||
async mount(el, fileInfo, context) {
|
||||
if (TabInstance) {
|
||||
|
|
|
@ -19,8 +19,8 @@
|
|||
<div>
|
||||
<ul>
|
||||
<NcListItem v-for="version in versions"
|
||||
:key="version.dateTime.unix()"
|
||||
class="version"
|
||||
key="version.url"
|
||||
:title="version.title"
|
||||
:href="version.url">
|
||||
<template #icon>
|
||||
|
@ -47,7 +47,7 @@
|
|||
</template>
|
||||
{{ t('files_versions', 'Download version') }}
|
||||
</NcActionLink>
|
||||
<NcActionButton @click="restoreVersion(version)" v-if="!version.isCurrent">
|
||||
<NcActionButton v-if="!version.isCurrent" @click="restoreVersion(version)">
|
||||
<template #icon>
|
||||
<BackupRestore :size="22" />
|
||||
</template>
|
||||
|
@ -73,7 +73,6 @@ import { generateRemoteUrl, generateUrl } from '@nextcloud/router'
|
|||
import { getCurrentUser } from '@nextcloud/auth'
|
||||
import BackupRestore from 'vue-material-design-icons/BackupRestore.vue'
|
||||
import Download from 'vue-material-design-icons/Download.vue'
|
||||
import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
|
||||
import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton.js'
|
||||
import NcActionLink from '@nextcloud/vue/dist/Components/NcActionLink.js'
|
||||
import NcListItem from '@nextcloud/vue/dist/Components/NcListItem.js'
|
||||
|
@ -108,6 +107,9 @@ function getDavRequest() {
|
|||
|
||||
/**
|
||||
* Format version
|
||||
*
|
||||
* @param version
|
||||
* @param fileInfo
|
||||
*/
|
||||
function formatVersion(version, fileInfo) {
|
||||
const fileVersion = basename(version.filename)
|
||||
|
@ -117,7 +119,8 @@ function formatVersion(version, fileInfo) {
|
|||
? generateUrl('/core/preview?fileId={fileId}&c={fileEtag}&x=250&y=250&forceIcon=0&a=0', {
|
||||
fileId: fileInfo.id,
|
||||
fileEtag: fileInfo.etag,
|
||||
}) : generateUrl('/apps/files_versions/preview?file={file}&version={fileVersion}', {
|
||||
})
|
||||
: generateUrl('/apps/files_versions/preview?file={file}&version={fileVersion}', {
|
||||
file: joinPaths(fileInfo.path, fileInfo.name),
|
||||
fileVersion,
|
||||
})
|
||||
|
@ -151,7 +154,6 @@ const client = createClient(remote)
|
|||
export default {
|
||||
name: 'VersionTab',
|
||||
components: {
|
||||
NcButton,
|
||||
NcEmptyContent,
|
||||
NcActionLink,
|
||||
NcActionButton,
|
||||
|
@ -205,7 +207,7 @@ export default {
|
|||
async restoreVersion(version) {
|
||||
try {
|
||||
logger.debug('restoring version', version.url)
|
||||
const response = await client.moveFile(
|
||||
await client.moveFile(
|
||||
`/versions/${getCurrentUser().uid}/versions/${this.fileInfo.id}/${version.fileVersion}`,
|
||||
`/versions/${getCurrentUser().uid}/restore/target`
|
||||
)
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
"license": "AGPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
"@chenfengyuan/vue-qrcode": "^1.0.2",
|
||||
"@mdi/svg": "^7.0.96",
|
||||
"@nextcloud/auth": "^1.3.0",
|
||||
"@nextcloud/axios": "^1.10.0",
|
||||
"@nextcloud/browser-storage": "^0.1.1",
|
||||
|
@ -29,6 +30,7 @@
|
|||
"@nextcloud/sharing": "^0.1.0",
|
||||
"@nextcloud/vue": "^7.1.0-beta.2",
|
||||
"@nextcloud/vue-dashboard": "^2.0.1",
|
||||
"@skjnldsv/sanitize-svg": "^1.0.2",
|
||||
"autosize": "^5.0.1",
|
||||
"backbone": "^1.4.1",
|
||||
"blueimp-md5": "^2.19.0",
|
||||
|
@ -3469,6 +3471,11 @@
|
|||
"@jridgewell/sourcemap-codec": "^1.4.10"
|
||||
}
|
||||
},
|
||||
"node_modules/@mdi/svg": {
|
||||
"version": "7.0.96",
|
||||
"resolved": "https://registry.npmjs.org/@mdi/svg/-/svg-7.0.96.tgz",
|
||||
"integrity": "sha512-5DC+w7Kl2C82j4aTWCUf6wtHzgY60WBf1gT1qrpkLaMNcH6Vj9FpYPAXdSmtdkmSMvVMs8i1Rtv9cXWcHFQYpw=="
|
||||
},
|
||||
"node_modules/@nextcloud/auth": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@nextcloud/auth/-/auth-1.3.0.tgz",
|
||||
|
@ -4433,6 +4440,18 @@
|
|||
"integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@skjnldsv/sanitize-svg": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@skjnldsv/sanitize-svg/-/sanitize-svg-1.0.2.tgz",
|
||||
"integrity": "sha512-blfdQZ9jr4K9IOhifF0FVhKf9LCFH0L8wWR/vEgdA53q8DGNEbjUGMNo4VU1QugglaoQdFy65O2abODRFflsSg==",
|
||||
"dependencies": {
|
||||
"is-svg": "^4.3.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.0.0",
|
||||
"npm": "^7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@socket.io/component-emitter": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz",
|
||||
|
@ -10711,6 +10730,20 @@
|
|||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/is-svg": {
|
||||
"version": "4.3.2",
|
||||
"resolved": "https://registry.npmjs.org/is-svg/-/is-svg-4.3.2.tgz",
|
||||
"integrity": "sha512-mM90duy00JGMyjqIVHu9gNTjywdZV+8qNasX8cm/EEYZ53PHDgajvbBwNVvty5dwSAxLUD3p3bdo+7sR/UMrpw==",
|
||||
"dependencies": {
|
||||
"fast-xml-parser": "^3.19.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/is-symbol": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz",
|
||||
|
@ -22697,6 +22730,11 @@
|
|||
"@jridgewell/sourcemap-codec": "^1.4.10"
|
||||
}
|
||||
},
|
||||
"@mdi/svg": {
|
||||
"version": "7.0.96",
|
||||
"resolved": "https://registry.npmjs.org/@mdi/svg/-/svg-7.0.96.tgz",
|
||||
"integrity": "sha512-5DC+w7Kl2C82j4aTWCUf6wtHzgY60WBf1gT1qrpkLaMNcH6Vj9FpYPAXdSmtdkmSMvVMs8i1Rtv9cXWcHFQYpw=="
|
||||
},
|
||||
"@nextcloud/auth": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@nextcloud/auth/-/auth-1.3.0.tgz",
|
||||
|
@ -23453,6 +23491,14 @@
|
|||
"integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@skjnldsv/sanitize-svg": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@skjnldsv/sanitize-svg/-/sanitize-svg-1.0.2.tgz",
|
||||
"integrity": "sha512-blfdQZ9jr4K9IOhifF0FVhKf9LCFH0L8wWR/vEgdA53q8DGNEbjUGMNo4VU1QugglaoQdFy65O2abODRFflsSg==",
|
||||
"requires": {
|
||||
"is-svg": "^4.3.2"
|
||||
}
|
||||
},
|
||||
"@socket.io/component-emitter": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz",
|
||||
|
@ -28314,6 +28360,14 @@
|
|||
"has-tostringtag": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"is-svg": {
|
||||
"version": "4.3.2",
|
||||
"resolved": "https://registry.npmjs.org/is-svg/-/is-svg-4.3.2.tgz",
|
||||
"integrity": "sha512-mM90duy00JGMyjqIVHu9gNTjywdZV+8qNasX8cm/EEYZ53PHDgajvbBwNVvty5dwSAxLUD3p3bdo+7sR/UMrpw==",
|
||||
"requires": {
|
||||
"fast-xml-parser": "^3.19.0"
|
||||
}
|
||||
},
|
||||
"is-symbol": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz",
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
"license": "AGPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
"@chenfengyuan/vue-qrcode": "^1.0.2",
|
||||
"@mdi/svg": "^7.0.96",
|
||||
"@nextcloud/auth": "^1.3.0",
|
||||
"@nextcloud/axios": "^1.10.0",
|
||||
"@nextcloud/browser-storage": "^0.1.1",
|
||||
|
@ -49,6 +50,7 @@
|
|||
"@nextcloud/sharing": "^0.1.0",
|
||||
"@nextcloud/vue": "^7.1.0-beta.2",
|
||||
"@nextcloud/vue-dashboard": "^2.0.1",
|
||||
"@skjnldsv/sanitize-svg": "^1.0.2",
|
||||
"autosize": "^5.0.1",
|
||||
"backbone": "^1.4.1",
|
||||
"blueimp-md5": "^2.19.0",
|
||||
|
|
|
@ -116,7 +116,10 @@ module.exports = {
|
|||
test: /\.handlebars/,
|
||||
loader: 'handlebars-loader',
|
||||
},
|
||||
|
||||
{
|
||||
resourceQuery: /raw/,
|
||||
type: 'asset/source',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче