summaryrefslogtreecommitdiff
path: root/src/client/components/ui
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/components/ui')
-rw-r--r--src/client/components/ui/a.vue104
-rw-r--r--src/client/components/ui/context-menu.vue2
-rw-r--r--src/client/components/ui/menu.vue4
-rw-r--r--src/client/components/ui/radio.vue2
-rw-r--r--src/client/components/ui/window.vue27
5 files changed, 130 insertions, 9 deletions
diff --git a/src/client/components/ui/a.vue b/src/client/components/ui/a.vue
new file mode 100644
index 0000000000..dce99ef676
--- /dev/null
+++ b/src/client/components/ui/a.vue
@@ -0,0 +1,104 @@
+<template>
+<a :href="to" :class="active ? activeClass : null" @click.prevent="nav" @contextmenu.prevent.stop="onContextmenu">
+ <slot></slot>
+</a>
+</template>
+
+<script lang="ts">
+import { defineComponent } from 'vue';
+import { faExpandAlt, faColumns, faExternalLinkAlt, faLink, faWindowMaximize } from '@fortawesome/free-solid-svg-icons';
+import * as os from '@/os';
+import copyToClipboard from '@/scripts/copy-to-clipboard';
+import { router } from '@/router';
+import { deckmode } from '@/config';
+
+export default defineComponent({
+ inject: {
+ navHook: {
+ default: null
+ },
+ sideViewHook: {
+ default: null
+ }
+ },
+
+ props: {
+ to: {
+ type: String,
+ required: true,
+ },
+ activeClass: {
+ type: String,
+ required: false,
+ },
+ },
+
+ computed: {
+ active() {
+ if (this.activeClass == null) return false;
+ const resolved = router.resolve(this.to);
+ if (resolved.path == this.$route.path) return true;
+ if (resolved.name == null) return false;
+ if (this.$route.name == null) return false;
+ return resolved.name == this.$route.name;
+ }
+ },
+
+ methods: {
+ onContextmenu(e) {
+ if (window.getSelection().toString() !== '') return;
+ os.contextMenu([{
+ type: 'label',
+ text: this.to,
+ }, {
+ icon: faWindowMaximize,
+ text: this.$t('openInWindow'),
+ action: () => {
+ os.pageWindow(this.to);
+ }
+ }, !this.navHook && this.sideViewHook ? {
+ icon: faColumns,
+ text: this.$t('openInSideView'),
+ action: () => {
+ this.sideViewHook(this.to);
+ }
+ } : undefined, {
+ icon: faExpandAlt,
+ text: this.$t('showInPage'),
+ action: () => {
+ this.$router.push(this.to);
+ }
+ }, null, {
+ icon: faExternalLinkAlt,
+ text: this.$t('openInNewTab'),
+ action: () => {
+ window.open(this.to, '_blank');
+ }
+ }, {
+ icon: faLink,
+ text: this.$t('copyLink'),
+ action: () => {
+ copyToClipboard(this.to);
+ }
+ }], e);
+ },
+
+ nav() {
+ if (this.navHook) {
+ this.navHook(this.to);
+ } else {
+ if (this.$store.state.device.defaultSideView && this.sideViewHook && this.to !== '/') {
+ this.sideViewHook(this.to);
+ return;
+ }
+ if (this.$store.state.device.deckNavWindow && deckmode && this.to !== '/') {
+ os.pageWindow(this.to);
+ return;
+ }
+
+ this.$router.push(this.to);
+ }
+ }
+ }
+});
+</script>
diff --git a/src/client/components/ui/context-menu.vue b/src/client/components/ui/context-menu.vue
index 98586cf3fe..3a11589e8a 100644
--- a/src/client/components/ui/context-menu.vue
+++ b/src/client/components/ui/context-menu.vue
@@ -1,5 +1,5 @@
<template>
-<div class="nvlagfpb">
+<div class="nvlagfpb" @contextmenu.prevent.stop="() => {}">
<MkMenu :items="items" @close="$emit('closed')" class="_popup _shadow" :align="'left'"/>
</div>
</template>
diff --git a/src/client/components/ui/menu.vue b/src/client/components/ui/menu.vue
index 5e74828c20..9e4e319c8a 100644
--- a/src/client/components/ui/menu.vue
+++ b/src/client/components/ui/menu.vue
@@ -12,12 +12,12 @@
<span v-else-if="item.type === 'pending'" :tabindex="i" class="pending item">
<span><MkEllipsis/></span>
</span>
- <router-link v-else-if="item.type === 'link'" :to="item.to" @click.passive="close()" :tabindex="i" class="_button item">
+ <MkA v-else-if="item.type === 'link'" :to="item.to" @click.passive="close()" :tabindex="i" class="_button item">
<Fa v-if="item.icon" :icon="item.icon" fixed-width/>
<MkAvatar v-if="item.avatar" :user="item.avatar" class="avatar"/>
<span>{{ item.text }}</span>
<i v-if="item.indicate"><Fa :icon="faCircle"/></i>
- </router-link>
+ </MkA>
<a v-else-if="item.type === 'a'" :href="item.href" :target="item.target" :download="item.download" @click="close()" :tabindex="i" class="_button item">
<Fa v-if="item.icon" :icon="item.icon" fixed-width/>
<span>{{ item.text }}</span>
diff --git a/src/client/components/ui/radio.vue b/src/client/components/ui/radio.vue
index 8f2b843ee6..890ff08751 100644
--- a/src/client/components/ui/radio.vue
+++ b/src/client/components/ui/radio.vue
@@ -51,7 +51,7 @@ export default defineComponent({
.novjtctn {
position: relative;
display: inline-block;
- margin: 0 32px 0 0;
+ margin: 16px 32px 0 0;
cursor: pointer;
transition: all 0.3s;
diff --git a/src/client/components/ui/window.vue b/src/client/components/ui/window.vue
index d545ac4827..4c90ab9c8d 100644
--- a/src/client/components/ui/window.vue
+++ b/src/client/components/ui/window.vue
@@ -2,14 +2,16 @@
<transition :name="$store.state.device.animation ? 'window' : ''" appear @after-leave="$emit('closed')">
<div class="ebkgocck" v-if="showing">
<div class="body _popup _shadow _narrow_" @mousedown="onBodyMousedown" @keydown="onKeydown">
- <div class="header">
- <button class="_button" @click="close()"><Fa :icon="faTimes"/></button>
+ <div class="header" @contextmenu.prevent.stop="onContextmenu">
+ <slot v-if="closeRight" name="buttons"><button class="_button" style="pointer-events: none;"></button></slot>
+ <button v-else class="_button" @click="close()"><Fa :icon="faTimes"/></button>
+
<span class="title" @mousedown.prevent="onHeaderMousedown" @touchstart.prevent="onHeaderMousedown">
<slot name="header"></slot>
</span>
- <slot name="buttons">
- <button class="_button" style="pointer-events: none;"></button>
- </slot>
+
+ <button v-if="closeRight" class="_button" @click="close()"><Fa :icon="faTimes"/></button>
+ <slot v-else name="buttons"><button class="_button" style="pointer-events: none;"></button></slot>
</div>
<div class="body" v-if="padding">
<div class="_section">
@@ -85,6 +87,15 @@ export default defineComponent({
required: false,
default: false,
},
+ closeRight: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ contextmenu: {
+ type: Array,
+ required: false,
+ }
},
emits: ['closed'],
@@ -129,6 +140,12 @@ export default defineComponent({
}
},
+ onContextmenu(e) {
+ if (this.contextmenu) {
+ os.contextMenu(this.contextmenu, e);
+ }
+ },
+
// 最前面へ移動
top() {
let z = 0;