mirror of
https://iceshrimp.dev/limepotato/jormungandr-bite.git
synced 2024-11-22 09:57:29 -07:00
refactor(client): refactor
This commit is contained in:
parent
da7c0635d4
commit
1a86751ef3
3 changed files with 28 additions and 65 deletions
|
@ -1,7 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<component :is="self ? 'MkA' : 'a'" class="ieqqeuvs _link" :[attr]="self ? url.substr(local.length) : url" :rel="rel" :target="target"
|
<component :is="self ? 'MkA' : 'a'" ref="el" class="ieqqeuvs _link" :[attr]="self ? url.substr(local.length) : url" :rel="rel" :target="target"
|
||||||
@mouseover="onMouseover"
|
|
||||||
@mouseleave="onMouseleave"
|
|
||||||
@contextmenu.stop="() => {}"
|
@contextmenu.stop="() => {}"
|
||||||
>
|
>
|
||||||
<template v-if="!self">
|
<template v-if="!self">
|
||||||
|
@ -20,11 +18,11 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent, ref } from 'vue';
|
||||||
import { toUnicode as decodePunycode } from 'punycode/';
|
import { toUnicode as decodePunycode } from 'punycode/';
|
||||||
import { url as local } from '@/config';
|
import { url as local } from '@/config';
|
||||||
import { isTouchUsing } from '@/scripts/touch';
|
|
||||||
import * as os from '@/os';
|
import * as os from '@/os';
|
||||||
|
import { useTooltip } from '@/scripts/use-tooltip';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
props: {
|
props: {
|
||||||
|
@ -35,74 +33,36 @@ export default defineComponent({
|
||||||
rel: {
|
rel: {
|
||||||
type: String,
|
type: String,
|
||||||
required: false,
|
required: false,
|
||||||
|
default: null,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
setup(props) {
|
||||||
const self = this.url.startsWith(local);
|
const self = props.url.startsWith(local);
|
||||||
|
const url = new URL(props.url);
|
||||||
|
const el = ref();
|
||||||
|
|
||||||
|
useTooltip(el, (showing) => {
|
||||||
|
os.popup(import('@/components/url-preview-popup.vue'), {
|
||||||
|
showing,
|
||||||
|
url: props.url,
|
||||||
|
source: el.value,
|
||||||
|
}, {}, 'closed');
|
||||||
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
local,
|
local,
|
||||||
schema: null as string | null,
|
schema: url.protocol,
|
||||||
hostname: null as string | null,
|
hostname: decodePunycode(url.hostname),
|
||||||
port: null as string | null,
|
port: url.port,
|
||||||
pathname: null as string | null,
|
pathname: decodeURIComponent(url.pathname),
|
||||||
query: null as string | null,
|
query: decodeURIComponent(url.search),
|
||||||
hash: null as string | null,
|
hash: decodeURIComponent(url.hash),
|
||||||
self: self,
|
self: self,
|
||||||
attr: self ? 'to' : 'href',
|
attr: self ? 'to' : 'href',
|
||||||
target: self ? null : '_blank',
|
target: self ? null : '_blank',
|
||||||
showTimer: null,
|
el,
|
||||||
hideTimer: null,
|
|
||||||
checkTimer: null,
|
|
||||||
close: null,
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
created() {
|
|
||||||
const url = new URL(this.url);
|
|
||||||
this.schema = url.protocol;
|
|
||||||
this.hostname = decodePunycode(url.hostname);
|
|
||||||
this.port = url.port;
|
|
||||||
this.pathname = decodeURIComponent(url.pathname);
|
|
||||||
this.query = decodeURIComponent(url.search);
|
|
||||||
this.hash = decodeURIComponent(url.hash);
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
async showPreview() {
|
|
||||||
if (!document.body.contains(this.$el)) return;
|
|
||||||
if (this.close) return;
|
|
||||||
|
|
||||||
const { dispose } = await os.popup(import('@/components/url-preview-popup.vue'), {
|
|
||||||
url: this.url,
|
|
||||||
source: this.$el
|
|
||||||
});
|
|
||||||
|
|
||||||
this.close = () => {
|
|
||||||
dispose();
|
|
||||||
};
|
|
||||||
|
|
||||||
this.checkTimer = setInterval(() => {
|
|
||||||
if (!document.body.contains(this.$el)) this.closePreview();
|
|
||||||
}, 1000);
|
|
||||||
},
|
|
||||||
closePreview() {
|
|
||||||
if (this.close) {
|
|
||||||
clearInterval(this.checkTimer);
|
|
||||||
this.close();
|
|
||||||
this.close = null;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onMouseover() {
|
|
||||||
if (isTouchUsing) return;
|
|
||||||
clearTimeout(this.showTimer);
|
|
||||||
clearTimeout(this.hideTimer);
|
|
||||||
this.showTimer = setTimeout(this.showPreview, 500);
|
|
||||||
},
|
|
||||||
onMouseleave() {
|
|
||||||
if (isTouchUsing) return;
|
|
||||||
clearTimeout(this.showTimer);
|
|
||||||
clearTimeout(this.hideTimer);
|
|
||||||
this.hideTimer = setTimeout(this.closePreview, 500);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ export default defineComponent({
|
||||||
actions: [{
|
actions: [{
|
||||||
icon: 'fas fa-plus',
|
icon: 'fas fa-plus',
|
||||||
text: this.$ts.create,
|
text: this.$ts.create,
|
||||||
handler: this.create
|
handler: this.create,
|
||||||
}],
|
}],
|
||||||
tabs: [{
|
tabs: [{
|
||||||
active: this.tab === 'featured',
|
active: this.tab === 'featured',
|
||||||
|
|
|
@ -18,6 +18,9 @@ export function useTooltip(
|
||||||
const open = () => {
|
const open = () => {
|
||||||
close();
|
close();
|
||||||
if (!isHovering) return;
|
if (!isHovering) return;
|
||||||
|
if (elRef.value == null) return;
|
||||||
|
const el = elRef.value instanceof Element ? elRef.value : elRef.value.$el;
|
||||||
|
if (!document.body.contains(el)) return; // openしようとしたときに既に元要素がDOMから消えている場合があるため
|
||||||
|
|
||||||
const showing = ref(true);
|
const showing = ref(true);
|
||||||
onShow(showing);
|
onShow(showing);
|
||||||
|
|
Loading…
Reference in a new issue