wip: refactor(client): migrate components to composition api
This commit is contained in:
parent
bf51450647
commit
ed5c918d70
3 changed files with 86 additions and 123 deletions
|
@ -36,7 +36,8 @@ const active = $computed(() => {
|
||||||
});
|
});
|
||||||
|
|
||||||
function onContextmenu(ev) {
|
function onContextmenu(ev) {
|
||||||
if (window.getSelection().toString() !== '') return;
|
const selection = window.getSelection();
|
||||||
|
if (selection && selection.toString() !== '') return;
|
||||||
os.contextMenu([{
|
os.contextMenu([{
|
||||||
type: 'label',
|
type: 'label',
|
||||||
text: props.to,
|
text: props.to,
|
||||||
|
@ -73,7 +74,7 @@ function onContextmenu(ev) {
|
||||||
}], ev);
|
}], ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
function window() {
|
function openWindow() {
|
||||||
os.pageWindow(props.to);
|
os.pageWindow(props.to);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,7 +94,7 @@ function nav() {
|
||||||
|
|
||||||
if (props.behavior) {
|
if (props.behavior) {
|
||||||
if (props.behavior === 'window') {
|
if (props.behavior === 'window') {
|
||||||
return window();
|
return openWindow();
|
||||||
} else if (props.behavior === 'modalWindow') {
|
} else if (props.behavior === 'modalWindow') {
|
||||||
return modalWindow();
|
return modalWindow();
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<span>{{ $ts.clickToShow }}</span>
|
<span>{{ $ts.clickToShow }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="media.type.startsWith('audio') && media.type !== 'audio/midi'" class="audio">
|
<div v-else-if="media.type.startsWith('audio') && media.type !== 'audio/midi'" class="audio">
|
||||||
<audio ref="audio"
|
<audio ref="audioEl"
|
||||||
class="audio"
|
class="audio"
|
||||||
:src="media.url"
|
:src="media.url"
|
||||||
:title="media.name"
|
:title="media.name"
|
||||||
|
@ -25,34 +25,26 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts" setup>
|
||||||
import { defineComponent } from 'vue';
|
import { onMounted } from 'vue';
|
||||||
import * as os from '@/os';
|
import * as misskey from 'misskey-js';
|
||||||
import { ColdDeviceStorage } from '@/store';
|
import { ColdDeviceStorage } from '@/store';
|
||||||
|
|
||||||
export default defineComponent({
|
const props = withDefaults(defineProps<{
|
||||||
props: {
|
media: misskey.entities.DriveFile;
|
||||||
media: {
|
}>(), {
|
||||||
type: Object,
|
});
|
||||||
required: true
|
|
||||||
}
|
const audioEl = $ref<HTMLAudioElement | null>();
|
||||||
},
|
let hide = $ref(true);
|
||||||
data() {
|
|
||||||
return {
|
function volumechange() {
|
||||||
hide: true,
|
if (audioEl) ColdDeviceStorage.set('mediaVolume', audioEl.volume);
|
||||||
};
|
}
|
||||||
},
|
|
||||||
mounted() {
|
onMounted(() => {
|
||||||
const audioTag = this.$refs.audio as HTMLAudioElement;
|
if (audioEl) audioEl.volume = ColdDeviceStorage.get('mediaVolume');
|
||||||
if (audioTag) audioTag.volume = ColdDeviceStorage.get('mediaVolume');
|
});
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
volumechange() {
|
|
||||||
const audioTag = this.$refs.audio as HTMLAudioElement;
|
|
||||||
ColdDeviceStorage.set('mediaVolume', audioTag.volume);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<iframe :src="player.url + (player.url.match(/\?/) ? '&autoplay=1&auto_play=1' : '?autoplay=1&auto_play=1')" :width="player.width || '100%'" :heigth="player.height || 250" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen />
|
<iframe :src="player.url + (player.url.match(/\?/) ? '&autoplay=1&auto_play=1' : '?autoplay=1&auto_play=1')" :width="player.width || '100%'" :heigth="player.height || 250" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen />
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="tweetId && tweetExpanded" ref="twitter" class="twitter">
|
<div v-else-if="tweetId && tweetExpanded" ref="twitter" class="twitter">
|
||||||
<iframe ref="tweet" scrolling="no" frameborder="no" :style="{ position: 'relative', left: `${tweetLeft}px`, width: `${tweetLeft < 0 ? 'auto' : '100%'}`, height: `${tweetHeight}px` }" :src="`https://platform.twitter.com/embed/index.html?embedId=${embedId}&hideCard=false&hideThread=false&lang=en&theme=${$store.state.darkMode ? 'dark' : 'light'}&id=${tweetId}`"></iframe>
|
<iframe ref="tweet" scrolling="no" frameborder="no" :style="{ position: 'relative', width: '100%', height: `${tweetHeight}px` }" :src="`https://platform.twitter.com/embed/index.html?embedId=${embedId}&hideCard=false&hideThread=false&lang=en&theme=${$store.state.darkMode ? 'dark' : 'light'}&id=${tweetId}`"></iframe>
|
||||||
</div>
|
</div>
|
||||||
<div v-else v-size="{ max: [400, 350] }" class="mk-url-preview">
|
<div v-else v-size="{ max: [400, 350] }" class="mk-url-preview">
|
||||||
<transition name="zoom" mode="out-in">
|
<transition name="zoom" mode="out-in">
|
||||||
|
@ -32,110 +32,80 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts" setup>
|
||||||
import { defineComponent } from 'vue';
|
import { onMounted, onUnmounted } from 'vue';
|
||||||
import { url as local, lang } from '@/config';
|
import { url as local, lang } from '@/config';
|
||||||
import * as os from '@/os';
|
|
||||||
|
|
||||||
export default defineComponent({
|
const props = withDefaults(defineProps<{
|
||||||
props: {
|
url: string;
|
||||||
url: {
|
detail?: boolean;
|
||||||
type: String,
|
compact?: boolean;
|
||||||
require: true
|
}>(), {
|
||||||
},
|
detail: false,
|
||||||
|
compact: false,
|
||||||
|
});
|
||||||
|
|
||||||
detail: {
|
const self = props.url.startsWith(local);
|
||||||
type: Boolean,
|
const attr = self ? 'to' : 'href';
|
||||||
required: false,
|
const target = self ? null : '_blank';
|
||||||
default: false
|
let fetching = $ref(true);
|
||||||
},
|
let title = $ref<string | null>(null);
|
||||||
|
let description = $ref<string | null>(null);
|
||||||
|
let thumbnail = $ref<string | null>(null);
|
||||||
|
let icon = $ref<string | null>(null);
|
||||||
|
let sitename = $ref<string | null>(null);
|
||||||
|
let player = $ref({
|
||||||
|
url: null,
|
||||||
|
width: null,
|
||||||
|
height: null
|
||||||
|
});
|
||||||
|
let playerEnabled = $ref(false);
|
||||||
|
let tweetId = $ref<string | null>(null);
|
||||||
|
let tweetExpanded = $ref(props.detail);
|
||||||
|
const embedId = `embed${Math.random().toString().replace(/\D/,'')}`;
|
||||||
|
let tweetHeight = $ref(150);
|
||||||
|
|
||||||
compact: {
|
const requestUrl = new URL(props.url);
|
||||||
type: Boolean,
|
|
||||||
required: false,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
data() {
|
if (requestUrl.hostname == 'twitter.com') {
|
||||||
const self = this.url.startsWith(local);
|
const m = requestUrl.pathname.match(/^\/.+\/status(?:es)?\/(\d+)/);
|
||||||
return {
|
if (m) tweetId = m[1];
|
||||||
local,
|
}
|
||||||
fetching: true,
|
|
||||||
title: null,
|
|
||||||
description: null,
|
|
||||||
thumbnail: null,
|
|
||||||
icon: null,
|
|
||||||
sitename: null,
|
|
||||||
player: {
|
|
||||||
url: null,
|
|
||||||
width: null,
|
|
||||||
height: null
|
|
||||||
},
|
|
||||||
tweetId: null,
|
|
||||||
tweetExpanded: this.detail,
|
|
||||||
embedId: `embed${Math.random().toString().replace(/\D/,'')}`,
|
|
||||||
tweetHeight: 150,
|
|
||||||
tweetLeft: 0,
|
|
||||||
playerEnabled: false,
|
|
||||||
self: self,
|
|
||||||
attr: self ? 'to' : 'href',
|
|
||||||
target: self ? null : '_blank',
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
created() {
|
if (requestUrl.hostname === 'music.youtube.com' && requestUrl.pathname.match('^/(?:watch|channel)')) {
|
||||||
const requestUrl = new URL(this.url);
|
requestUrl.hostname = 'www.youtube.com';
|
||||||
|
}
|
||||||
|
|
||||||
if (requestUrl.hostname == 'twitter.com') {
|
const requestLang = (lang || 'ja-JP').replace('ja-KS', 'ja-JP');
|
||||||
const m = requestUrl.pathname.match(/^\/.+\/status(?:es)?\/(\d+)/);
|
|
||||||
if (m) this.tweetId = m[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (requestUrl.hostname === 'music.youtube.com' && requestUrl.pathname.match('^/(?:watch|channel)')) {
|
requestUrl.hash = '';
|
||||||
requestUrl.hostname = 'www.youtube.com';
|
|
||||||
}
|
|
||||||
|
|
||||||
const requestLang = (lang || 'ja-JP').replace('ja-KS', 'ja-JP');
|
fetch(`/url?url=${encodeURIComponent(requestUrl.href)}&lang=${requestLang}`).then(res => {
|
||||||
|
res.json().then(info => {
|
||||||
|
if (info.url == null) return;
|
||||||
|
title = info.title;
|
||||||
|
description = info.description;
|
||||||
|
thumbnail = info.thumbnail;
|
||||||
|
icon = info.icon;
|
||||||
|
sitename = info.sitename;
|
||||||
|
fetching = false;
|
||||||
|
player = info.player;
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
requestUrl.hash = '';
|
function adjustTweetHeight(message: any) {
|
||||||
|
if (message.origin !== 'https://platform.twitter.com') return;
|
||||||
|
const embed = message.data?.['twttr.embed'];
|
||||||
|
if (embed?.method !== 'twttr.private.resize') return;
|
||||||
|
if (embed?.id !== embedId) return;
|
||||||
|
const height = embed?.params[0]?.height;
|
||||||
|
if (height) tweetHeight = height;
|
||||||
|
}
|
||||||
|
|
||||||
fetch(`/url?url=${encodeURIComponent(requestUrl.href)}&lang=${requestLang}`).then(res => {
|
(window as any).addEventListener('message', adjustTweetHeight);
|
||||||
res.json().then(info => {
|
|
||||||
if (info.url == null) return;
|
|
||||||
this.title = info.title;
|
|
||||||
this.description = info.description;
|
|
||||||
this.thumbnail = info.thumbnail;
|
|
||||||
this.icon = info.icon;
|
|
||||||
this.sitename = info.sitename;
|
|
||||||
this.fetching = false;
|
|
||||||
this.player = info.player;
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
(window as any).addEventListener('message', this.adjustTweetHeight);
|
onUnmounted(() => {
|
||||||
},
|
(window as any).removeEventListener('message', adjustTweetHeight);
|
||||||
|
|
||||||
mounted() {
|
|
||||||
// 300pxないと絶対右にはみ出るので左に移動してしまう
|
|
||||||
const areaWidth = (this.$el as any)?.clientWidth;
|
|
||||||
if (areaWidth && areaWidth < 300) this.tweetLeft = areaWidth - 241;
|
|
||||||
},
|
|
||||||
|
|
||||||
beforeUnmount() {
|
|
||||||
(window as any).removeEventListener('message', this.adjustTweetHeight);
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
|
||||||
adjustTweetHeight(message: any) {
|
|
||||||
if (message.origin !== 'https://platform.twitter.com') return;
|
|
||||||
const embed = message.data?.['twttr.embed'];
|
|
||||||
if (embed?.method !== 'twttr.private.resize') return;
|
|
||||||
if (embed?.id !== this.embedId) return;
|
|
||||||
const height = embed?.params[0]?.height;
|
|
||||||
if (height) this.tweetHeight = height;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue