mirror of
https://git.joinsharkey.org/Sharkey/Sharkey.git
synced 2024-12-23 21:53:09 +02:00
✌️
This commit is contained in:
parent
335ab5ab54
commit
ebeb7f8578
11 changed files with 117 additions and 81 deletions
|
@ -4,7 +4,7 @@
|
|||
<div class="popover" :class="{ hukidasi }" ref="popover">
|
||||
<template v-for="item in items">
|
||||
<div v-if="item === null"></div>
|
||||
<button v-if="item" @click="clicked(item.onClick)" v-html="item.content"></button>
|
||||
<button v-if="item" @click="clicked(item.action)" v-html="item.icon ? item.icon + ' ' + item.text : item.text"></button>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -13,23 +13,23 @@ export default Vue.extend({
|
|||
items() {
|
||||
const items = [];
|
||||
items.push({
|
||||
content: '%i18n:@favorite%',
|
||||
onClick: this.favorite
|
||||
text: '%i18n:@favorite%',
|
||||
action: this.favorite
|
||||
});
|
||||
if (this.note.userId == this.$store.state.i.id) {
|
||||
items.push({
|
||||
content: '%i18n:@pin%',
|
||||
onClick: this.pin
|
||||
text: '%i18n:@pin%',
|
||||
action: this.pin
|
||||
});
|
||||
items.push({
|
||||
content: '%i18n:@delete%',
|
||||
onClick: this.del
|
||||
text: '%i18n:@delete%',
|
||||
action: this.del
|
||||
});
|
||||
}
|
||||
if (this.note.uri) {
|
||||
items.push({
|
||||
content: '%i18n:@remote%',
|
||||
onClick: () => {
|
||||
text: '%i18n:@remote%',
|
||||
action: () => {
|
||||
window.open(this.note.uri, '_blank');
|
||||
}
|
||||
});
|
||||
|
|
|
@ -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
|
||||
}]);
|
||||
},
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
@click="toggleActive"
|
||||
@dragstart="onDragstart"
|
||||
@dragend="onDragend"
|
||||
@contextmenu.prevent.stop="onContextmenu"
|
||||
>
|
||||
<slot name="header"></slot>
|
||||
<span class="count" v-if="count > 0">({{ count }})</span>
|
||||
|
@ -24,6 +25,7 @@
|
|||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import Menu from '../../../../common/views/components/menu.vue';
|
||||
import contextmenu from '../../../api/contextmenu';
|
||||
|
||||
export default Vue.extend({
|
||||
props: {
|
||||
|
@ -132,10 +134,11 @@ export default Vue.extend({
|
|||
}
|
||||
},
|
||||
|
||||
showMenu() {
|
||||
getMenu() {
|
||||
const items = [{
|
||||
content: '%fa:pencil-alt% %i18n:common.deck.rename%',
|
||||
onClick: () => {
|
||||
icon: '%fa:pencil-alt%',
|
||||
text: '%i18n:common.deck.rename%',
|
||||
action: () => {
|
||||
(this as any).apis.input({
|
||||
title: '%i18n:common.deck.rename%',
|
||||
default: this.name,
|
||||
|
@ -145,38 +148,45 @@ export default Vue.extend({
|
|||
});
|
||||
}
|
||||
}, null, {
|
||||
content: '%fa:arrow-left% %i18n:common.deck.swap-left%',
|
||||
onClick: () => {
|
||||
icon: '%fa:arrow-left%',
|
||||
text: '%i18n:common.deck.swap-left%',
|
||||
action: () => {
|
||||
this.$store.dispatch('settings/swapLeftDeckColumn', this.column.id);
|
||||
}
|
||||
}, {
|
||||
content: '%fa:arrow-right% %i18n:common.deck.swap-right%',
|
||||
onClick: () => {
|
||||
icon: '%fa:arrow-right%',
|
||||
text: '%i18n:common.deck.swap-right%',
|
||||
action: () => {
|
||||
this.$store.dispatch('settings/swapRightDeckColumn', this.column.id);
|
||||
}
|
||||
}, this.isStacked ? {
|
||||
content: '%fa:arrow-up% %i18n:common.deck.swap-up%',
|
||||
onClick: () => {
|
||||
icon: '%fa:arrow-up%',
|
||||
text: '%i18n:common.deck.swap-up%',
|
||||
action: () => {
|
||||
this.$store.dispatch('settings/swapUpDeckColumn', this.column.id);
|
||||
}
|
||||
} : undefined, this.isStacked ? {
|
||||
content: '%fa:arrow-down% %i18n:common.deck.swap-down%',
|
||||
onClick: () => {
|
||||
icon: '%fa:arrow-down%',
|
||||
text: '%i18n:common.deck.swap-down%',
|
||||
action: () => {
|
||||
this.$store.dispatch('settings/swapDownDeckColumn', this.column.id);
|
||||
}
|
||||
} : undefined, null, {
|
||||
content: '%fa:window-restore R% %i18n:common.deck.stack-left%',
|
||||
onClick: () => {
|
||||
icon: '%fa:window-restore R%',
|
||||
text: '%i18n:common.deck.stack-left%',
|
||||
action: () => {
|
||||
this.$store.dispatch('settings/stackLeftDeckColumn', this.column.id);
|
||||
}
|
||||
}, this.isStacked ? {
|
||||
content: '%fa:window-maximize R% %i18n:common.deck.pop-right%',
|
||||
onClick: () => {
|
||||
icon: '%fa:window-maximize R%',
|
||||
text: '%i18n:common.deck.pop-right%',
|
||||
action: () => {
|
||||
this.$store.dispatch('settings/popRightDeckColumn', this.column.id);
|
||||
}
|
||||
} : undefined, null, {
|
||||
content: '%fa:trash-alt R% %i18n:common.deck.remove%',
|
||||
onClick: () => {
|
||||
icon: '%fa:trash-alt R%',
|
||||
text: '%i18n:common.deck.remove%',
|
||||
action: () => {
|
||||
this.$store.dispatch('settings/removeDeckColumn', this.column.id);
|
||||
}
|
||||
}];
|
||||
|
@ -186,10 +196,18 @@ export default Vue.extend({
|
|||
this.menu.reverse().forEach(i => items.unshift(i));
|
||||
}
|
||||
|
||||
return items;
|
||||
},
|
||||
|
||||
onContextmenu(e) {
|
||||
contextmenu((this as any).os)(e, this.getMenu());
|
||||
},
|
||||
|
||||
showMenu() {
|
||||
this.os.new(Menu, {
|
||||
source: this.$refs.menu,
|
||||
compact: false,
|
||||
items
|
||||
items: this.getMenu()
|
||||
});
|
||||
},
|
||||
|
||||
|
|
|
@ -45,8 +45,9 @@ export default Vue.extend({
|
|||
return {
|
||||
edit: false,
|
||||
menu: [{
|
||||
content: '%fa:cog% %i18n:@edit%',
|
||||
onClick: () => {
|
||||
icon: '%fa:cog%',
|
||||
text: '%i18n:@edit%',
|
||||
action: () => {
|
||||
this.edit = !this.edit;
|
||||
}
|
||||
}]
|
||||
|
|
|
@ -102,32 +102,36 @@ export default Vue.extend({
|
|||
source: this.$refs.add,
|
||||
compact: true,
|
||||
items: [{
|
||||
content: '%i18n:common.deck.home%',
|
||||
onClick: () => {
|
||||
icon: '%fa:home%',
|
||||
text: '%i18n:common.deck.home%',
|
||||
action: () => {
|
||||
this.$store.dispatch('settings/addDeckColumn', {
|
||||
id: uuid(),
|
||||
type: 'home'
|
||||
});
|
||||
}
|
||||
}, {
|
||||
content: '%i18n:common.deck.local%',
|
||||
onClick: () => {
|
||||
icon: '%fa:comments R%',
|
||||
text: '%i18n:common.deck.local%',
|
||||
action: () => {
|
||||
this.$store.dispatch('settings/addDeckColumn', {
|
||||
id: uuid(),
|
||||
type: 'local'
|
||||
});
|
||||
}
|
||||
}, {
|
||||
content: '%i18n:common.deck.global%',
|
||||
onClick: () => {
|
||||
icon: '%fa:globe%',
|
||||
text: '%i18n:common.deck.global%',
|
||||
action: () => {
|
||||
this.$store.dispatch('settings/addDeckColumn', {
|
||||
id: uuid(),
|
||||
type: 'global'
|
||||
});
|
||||
}
|
||||
}, {
|
||||
content: '%i18n:common.deck.list%',
|
||||
onClick: () => {
|
||||
icon: '%fa:list%',
|
||||
text: '%i18n:common.deck.list%',
|
||||
action: () => {
|
||||
const w = (this as any).os.new(MkUserListsWindow);
|
||||
w.$once('choosen', list => {
|
||||
this.$store.dispatch('settings/addDeckColumn', {
|
||||
|
@ -139,16 +143,18 @@ export default Vue.extend({
|
|||
});
|
||||
}
|
||||
}, {
|
||||
content: '%i18n:common.deck.notifications%',
|
||||
onClick: () => {
|
||||
icon: '%fa:bell R%',
|
||||
text: '%i18n:common.deck.notifications%',
|
||||
action: () => {
|
||||
this.$store.dispatch('settings/addDeckColumn', {
|
||||
id: uuid(),
|
||||
type: 'notifications'
|
||||
});
|
||||
}
|
||||
}, {
|
||||
content: '%i18n:common.deck.widgets%',
|
||||
onClick: () => {
|
||||
icon: '%fa:calculator%',
|
||||
text: '%i18n:common.deck.widgets%',
|
||||
action: () => {
|
||||
this.$store.dispatch('settings/addDeckColumn', {
|
||||
id: uuid(),
|
||||
type: 'widgets',
|
||||
|
|
|
@ -92,8 +92,9 @@ export default Vue.extend({
|
|||
|
||||
created() {
|
||||
this.menu = [{
|
||||
content: '%fa:cog% %i18n:@edit%',
|
||||
onClick: () => {
|
||||
icon: '%fa:cog%',
|
||||
text: '%i18n:@edit%',
|
||||
action: () => {
|
||||
this.edit = !this.edit;
|
||||
}
|
||||
}];
|
||||
|
|
Loading…
Reference in a new issue