diff options
Diffstat (limited to 'src/client/components/ui/a.vue')
| -rw-r--r-- | src/client/components/ui/a.vue | 104 |
1 files changed, 104 insertions, 0 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> |