зеркало из https://github.com/nextcloud/text.git
button in menu bubble to link to files
Since the menu bubble deals with links it makes more sense to add the button here. Moved it to the initial part of the menu bubble as an alternative to the link form. Hand current path to menu bubble and use it * to start from there when picking the file to link to * to calculate the relative path. Signed-off-by: Azul <azul@riseup.net>
This commit is contained in:
Родитель
8d9535fd7c
Коммит
03ccc8aa03
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -50,7 +50,9 @@
|
|||
<slot name="header" />
|
||||
</MenuBar>
|
||||
<div>
|
||||
<MenuBubble v-if="!readOnly && isRichEditor" :editor="tiptap" />
|
||||
<MenuBubble v-if="!readOnly && isRichEditor"
|
||||
:editor="tiptap"
|
||||
:filePath="relativePath" />
|
||||
<EditorContent v-show="initialLoading"
|
||||
class="editor__content"
|
||||
:editor="tiptap" />
|
||||
|
|
|
@ -75,6 +75,7 @@
|
|||
import { EditorMenuBar } from 'tiptap'
|
||||
import Tooltip from '@nextcloud/vue/dist/Directives/Tooltip'
|
||||
import menuBarIcons from './../mixins/menubar'
|
||||
import { optimalPath } from './../helpers/files'
|
||||
|
||||
import Actions from '@nextcloud/vue/dist/Components/Actions'
|
||||
import ActionButton from '@nextcloud/vue/dist/Components/ActionButton'
|
||||
|
@ -158,14 +159,6 @@ export default {
|
|||
action: (commands) => {
|
||||
this.showImagePrompt(commands.image)
|
||||
},
|
||||
}, {
|
||||
label: t('text', 'Insert link'),
|
||||
class: 'icon-link',
|
||||
isActive: () => {
|
||||
},
|
||||
action: (commands) => {
|
||||
this.showLinkPrompt(commands.link)
|
||||
},
|
||||
}]
|
||||
},
|
||||
childPopoverMenu() {
|
||||
|
@ -207,10 +200,6 @@ export default {
|
|||
return this.lastImagePath
|
||||
|| this.filePath.split('/').slice(0, -1).join('/')
|
||||
},
|
||||
linkPath() {
|
||||
return this.lastLinkPath
|
||||
|| this.filePath.split('/').slice(0, -1).join('/')
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
window.addEventListener('resize', this.getWindowWidth)
|
||||
|
@ -266,7 +255,7 @@ export default {
|
|||
mimetype: fileInfo.mimetype,
|
||||
hasPreview: fileInfo.hasPreview,
|
||||
}
|
||||
const path = this.optimalPathTo(`${fileInfo.path}/${fileInfo.name}`)
|
||||
const path = optimalPath(this.filePath, `${fileInfo.path}/${fileInfo.name}`)
|
||||
const encodedPath = path.split('/').map(encodeURIComponent).join('/')
|
||||
const meta = Object.entries(appendMeta).map(([key, val]) => `${key}=${encodeURIComponent(val)}`).join('&')
|
||||
const src = `${encodedPath}?fileId=${fileInfo.id}#${meta}`
|
||||
|
|
|
@ -27,16 +27,16 @@
|
|||
@hide="hideLinkMenu">
|
||||
<div class="menububble" :class="{ 'is-active': menu.isActive }" :style="`left: ${menu.left}px; bottom: ${menu.bottom}px;`">
|
||||
<form v-if="linkMenuIsActive" class="menububble__form" @submit.prevent="setLinkUrl(commands.link, linkUrl)">
|
||||
<button
|
||||
class="icon-file"
|
||||
@click="selectFile(commands.link)" />
|
||||
<input ref="linkInput"
|
||||
v-model="linkUrl"
|
||||
class="menububble__input"
|
||||
type="text"
|
||||
placeholder="https://"
|
||||
@keydown.esc="hideLinkMenu">
|
||||
<button class="menububble__button icon-confirm" type="button" @click="setLinkUrl(commands.link, linkUrl)" />
|
||||
<button class="menububble__button icon-confirm"
|
||||
type="button"
|
||||
tabindex="0"
|
||||
@click="setLinkUrl(commands.link, linkUrl)" />
|
||||
</form>
|
||||
|
||||
<template v-else>
|
||||
|
@ -45,7 +45,16 @@
|
|||
:class="{ 'is-active': isActive.link() }"
|
||||
@click="showLinkMenu(getMarkAttrs('link'))">
|
||||
<span v-tooltip="isActive.link() ? 'Update Link' : 'Add Link'" class="icon-link" />
|
||||
<span class="menububble__buttontext">{{ t('text', 'Add link') }}</span>
|
||||
<span class="menububble__buttontext">
|
||||
{{ t('text', isActive.link() ? 'Update Link' : 'Add Link') }}
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="menububble__button"
|
||||
:class="{ 'is-active': isActive.link() }"
|
||||
@click="selectFile(commands.link)">
|
||||
<span v-tooltip="'Link file'" class="icon-file" />
|
||||
<span class="menububble__buttontext">{{ t('text', 'Link file') }}</span>
|
||||
</button>
|
||||
</template>
|
||||
</div>
|
||||
|
@ -55,6 +64,7 @@
|
|||
<script>
|
||||
import { EditorMenuBubble } from 'tiptap'
|
||||
import Tooltip from '@nextcloud/vue/dist/Directives/Tooltip'
|
||||
import { optimalPath } from './../helpers/files'
|
||||
|
||||
export default {
|
||||
name: 'MenuBubble',
|
||||
|
@ -70,6 +80,11 @@ export default {
|
|||
required: false,
|
||||
default: null,
|
||||
},
|
||||
filePath: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
data: () => {
|
||||
return {
|
||||
|
@ -89,27 +104,33 @@ export default {
|
|||
this.linkUrl = null
|
||||
this.linkMenuIsActive = false
|
||||
},
|
||||
|
||||
selectFile(command) {
|
||||
const currentUser = OC.getCurrentUser()
|
||||
if (!currentUser) {
|
||||
return
|
||||
}
|
||||
const startPath = this.filePath.split('/').slice(0, -1).join('/')
|
||||
OC.dialogs.filepicker('Select file to link to', (file) => {
|
||||
const client = OC.Files.getClient()
|
||||
client.getFileInfo(file).then((_status, fileInfo) => {
|
||||
// todo: use optimal path
|
||||
const path = (`${fileInfo.path}/${fileInfo.name}`)
|
||||
const path = optimalPath(this.filePath, `${fileInfo.path}/${fileInfo.name}`)
|
||||
const encodedPath = path.split('/').map(encodeURIComponent).join('/')
|
||||
const href = `${encodedPath}?fileId=${fileInfo.id}`
|
||||
|
||||
this.setLinkUrl(command, href)
|
||||
command({ href: `${encodedPath}?fileId=${fileInfo.id}` })
|
||||
this.hideLinkMenu()
|
||||
})
|
||||
}, false, [], true)
|
||||
// todo: , undefined, this.linkPath)
|
||||
}, false, [], true, undefined, startPath)
|
||||
},
|
||||
setLinkUrl(command, url) {
|
||||
if (url && !url.match(/^[a-zA-Z]+:\/\//) && !url.match(/^\//)) {
|
||||
// Heuristics for determining if we need a https:// prefix.
|
||||
const noPrefixes = [
|
||||
/^[a-zA-Z]+:/, // url with protocol ("mailTo:email@domain.tld")
|
||||
/^\//, // absolute path
|
||||
/\?fileId=/, // relative link with fileId
|
||||
/^\.\.?\//, // relative link starting with ./ or ../
|
||||
/^[^.]*[/$]/, // no dots before first '/' - not a domain name
|
||||
/^#/, // url fragment
|
||||
]
|
||||
if (url && !noPrefixes.find(regex => url.match(regex))) {
|
||||
url = 'https://' + url
|
||||
}
|
||||
command({ href: url })
|
||||
|
|
|
@ -30,6 +30,21 @@ import { imagePath } from '@nextcloud/router'
|
|||
|
||||
const FILE_ACTION_IDENTIFIER = 'Edit with text app'
|
||||
|
||||
const optimalPath = function(from, to) {
|
||||
const current = from.split('/')
|
||||
const target = to.split('/')
|
||||
current.pop() // ignore filename
|
||||
while (current[0] === target[0]) {
|
||||
current.shift()
|
||||
target.shift()
|
||||
}
|
||||
const relativePath = current.fill('..').concat(target)
|
||||
const absolutePath = to.split('/')
|
||||
return relativePath.length < absolutePath.length
|
||||
? relativePath.join('/')
|
||||
: to
|
||||
}
|
||||
|
||||
const registerFileCreate = () => {
|
||||
const newFileMenuPlugin = {
|
||||
attach(menu) {
|
||||
|
@ -157,6 +172,7 @@ const FilesWorkspacePlugin = {
|
|||
}
|
||||
|
||||
export {
|
||||
optimalPath,
|
||||
registerFileActionFallback,
|
||||
registerFileCreate,
|
||||
FilesWorkspacePlugin,
|
||||
|
|
Загрузка…
Ссылка в новой задаче