✌️
This commit is contained in:
@@ -1,15 +1,17 @@
|
||||
<template>
|
||||
<ul class="menu">
|
||||
<li v-for="(item, i) in menu" :class="item.type">
|
||||
<template v-if="item.type == 'item'">
|
||||
<p @click="click(item)"><span :class="$style.icon" v-if="item.icon" v-html="item.icon"></span>{{ item.text }}</p>
|
||||
</template>
|
||||
<template v-if="item.type == 'link'">
|
||||
<a :href="item.href" :target="item.target" @click="click(item)"><span :class="$style.icon" v-if="item.icon" v-html="item.icon"></span>{{ item.text }}</a>
|
||||
</template>
|
||||
<template v-else-if="item.type == 'nest'">
|
||||
<p><span :class="$style.icon" v-if="item.icon" v-html="item.icon"></span>{{ item.text }}...<span class="caret">%fa:caret-right%</span></p>
|
||||
<me-nu :menu="item.menu" @x="click"/>
|
||||
<li v-for="(item, i) in menu" :class="item ? item.type : item === null ? 'divider' : null">
|
||||
<template v-if="item">
|
||||
<template v-if="item.type == null || item.type == 'item'">
|
||||
<p @click="click(item)"><span :class="$style.icon" v-if="item.icon" v-html="item.icon"></span>{{ item.text }}</p>
|
||||
</template>
|
||||
<template v-else-if="item.type == 'link'">
|
||||
<a :href="item.href" :target="item.target" @click="click(item)"><span :class="$style.icon" v-if="item.icon" v-html="item.icon"></span>{{ item.text }}</a>
|
||||
</template>
|
||||
<template v-else-if="item.type == 'nest'">
|
||||
<p><span :class="$style.icon" v-if="item.icon" v-html="item.icon"></span>{{ item.text }}...<span class="caret">%fa:caret-right%</span></p>
|
||||
<me-nu :menu="item.menu" @x="click"/>
|
||||
</template>
|
||||
</template>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="context-menu" :style="{ left: `${x}px`, top: `${y}px` }" @contextmenu.prevent="() => {}">
|
||||
<div class="context-menu" @contextmenu.prevent="() => {}">
|
||||
<x-menu :menu="menu" @x="click"/>
|
||||
</div>
|
||||
</template>
|
||||
@@ -17,6 +17,23 @@ export default Vue.extend({
|
||||
props: ['x', 'y', 'menu'],
|
||||
mounted() {
|
||||
this.$nextTick(() => {
|
||||
const width = this.$el.offsetWidth;
|
||||
const height = this.$el.offsetHeight;
|
||||
|
||||
let x = this.x;
|
||||
let y = this.y;
|
||||
|
||||
if (x + width > window.innerWidth) {
|
||||
x = window.innerWidth - width;
|
||||
}
|
||||
|
||||
if (y + height > window.innerHeight) {
|
||||
y = window.innerHeight - height;
|
||||
}
|
||||
|
||||
this.$el.style.left = x + 'px';
|
||||
this.$el.style.top = y + 'px';
|
||||
|
||||
Array.from(document.querySelectorAll('body *')).forEach(el => {
|
||||
el.addEventListener('mousedown', this.onMousedown);
|
||||
});
|
||||
@@ -38,7 +55,7 @@ export default Vue.extend({
|
||||
return false;
|
||||
},
|
||||
click(item) {
|
||||
if (item.onClick) item.onClick();
|
||||
if (item.action) item.action();
|
||||
this.close();
|
||||
},
|
||||
close() {
|
||||
@@ -59,7 +76,6 @@ root(isDark)
|
||||
$item-height = 38px
|
||||
$padding = 10px
|
||||
|
||||
display none
|
||||
position fixed
|
||||
top 0
|
||||
left 0
|
||||
|
||||
@@ -66,37 +66,33 @@ export default Vue.extend({
|
||||
type: 'item',
|
||||
text: '%i18n:@contextmenu.rename%',
|
||||
icon: '%fa:i-cursor%',
|
||||
onClick: this.rename
|
||||
action: this.rename
|
||||
}, {
|
||||
type: 'item',
|
||||
text: '%i18n:@contextmenu.copy-url%',
|
||||
icon: '%fa:link%',
|
||||
onClick: this.copyUrl
|
||||
action: this.copyUrl
|
||||
}, {
|
||||
type: 'link',
|
||||
href: `${this.file.url}?download`,
|
||||
text: '%i18n:@contextmenu.download%',
|
||||
icon: '%fa:download%',
|
||||
}, {
|
||||
type: 'divider',
|
||||
}, {
|
||||
}, null, {
|
||||
type: 'item',
|
||||
text: '%i18n:common.delete%',
|
||||
icon: '%fa:R trash-alt%',
|
||||
onClick: this.deleteFile
|
||||
}, {
|
||||
type: 'divider',
|
||||
}, {
|
||||
action: this.deleteFile
|
||||
}, null, {
|
||||
type: 'nest',
|
||||
text: '%i18n:@contextmenu.else-files%',
|
||||
menu: [{
|
||||
type: 'item',
|
||||
text: '%i18n:@contextmenu.set-as-avatar%',
|
||||
onClick: this.setAsAvatar
|
||||
action: this.setAsAvatar
|
||||
}, {
|
||||
type: 'item',
|
||||
text: '%i18n:@contextmenu.set-as-banner%',
|
||||
onClick: this.setAsBanner
|
||||
action: this.setAsBanner
|
||||
}]
|
||||
}, {
|
||||
type: 'nest',
|
||||
@@ -104,7 +100,7 @@ export default Vue.extend({
|
||||
menu: [{
|
||||
type: 'item',
|
||||
text: '%i18n:@contextmenu.add-app%...',
|
||||
onClick: this.addApp
|
||||
action: this.addApp
|
||||
}]
|
||||
}], {
|
||||
closed: () => {
|
||||
|
||||
@@ -56,26 +56,22 @@ export default Vue.extend({
|
||||
type: 'item',
|
||||
text: '%i18n:@contextmenu.move-to-this-folder%',
|
||||
icon: '%fa:arrow-right%',
|
||||
onClick: this.go
|
||||
action: this.go
|
||||
}, {
|
||||
type: 'item',
|
||||
text: '%i18n:@contextmenu.show-in-new-window%',
|
||||
icon: '%fa:R window-restore%',
|
||||
onClick: this.newWindow
|
||||
}, {
|
||||
type: 'divider',
|
||||
}, {
|
||||
action: this.newWindow
|
||||
}, null, {
|
||||
type: 'item',
|
||||
text: '%i18n:@contextmenu.rename%',
|
||||
icon: '%fa:i-cursor%',
|
||||
onClick: this.rename
|
||||
}, {
|
||||
type: 'divider',
|
||||
}, {
|
||||
action: this.rename
|
||||
}, null, {
|
||||
type: 'item',
|
||||
text: '%i18n:common.delete%',
|
||||
icon: '%fa:R trash-alt%',
|
||||
onClick: this.deleteFolder
|
||||
action: this.deleteFolder
|
||||
}], {
|
||||
closed: () => {
|
||||
this.isContextmenuShowing = false;
|
||||
|
||||
@@ -140,17 +140,17 @@ export default Vue.extend({
|
||||
type: 'item',
|
||||
text: '%i18n:@contextmenu.create-folder%',
|
||||
icon: '%fa:R folder%',
|
||||
onClick: this.createFolder
|
||||
action: this.createFolder
|
||||
}, {
|
||||
type: 'item',
|
||||
text: '%i18n:@contextmenu.upload%',
|
||||
icon: '%fa:upload%',
|
||||
onClick: this.selectLocalFile
|
||||
action: this.selectLocalFile
|
||||
}, {
|
||||
type: 'item',
|
||||
text: '%i18n:@contextmenu.url-upload%',
|
||||
icon: '%fa:cloud-upload-alt%',
|
||||
onClick: this.urlUpload
|
||||
action: this.urlUpload
|
||||
}]);
|
||||
},
|
||||
|
||||
|
||||
Reference in New Issue
Block a user