diff --git a/packages/client/src/components/global/a.vue b/packages/client/src/components/global/a.vue index d3bc2235b..cf7385ca2 100644 --- a/packages/client/src/components/global/a.vue +++ b/packages/client/src/components/global/a.vue @@ -36,7 +36,8 @@ const active = $computed(() => { }); function onContextmenu(ev) { - if (window.getSelection().toString() !== '') return; + const selection = window.getSelection(); + if (selection && selection.toString() !== '') return; os.contextMenu([{ type: 'label', text: props.to, @@ -73,7 +74,7 @@ function onContextmenu(ev) { }], ev); } -function window() { +function openWindow() { os.pageWindow(props.to); } @@ -93,7 +94,7 @@ function nav() { if (props.behavior) { if (props.behavior === 'window') { - return window(); + return openWindow(); } else if (props.behavior === 'modalWindow') { return modalWindow(); } diff --git a/packages/client/src/components/media-banner.vue b/packages/client/src/components/media-banner.vue index 9dbfe3d0c..5093f11e9 100644 --- a/packages/client/src/components/media-banner.vue +++ b/packages/client/src/components/media-banner.vue @@ -6,7 +6,7 @@ <span>{{ $ts.clickToShow }}</span> </div> <div v-else-if="media.type.startsWith('audio') && media.type !== 'audio/midi'" class="audio"> - <audio ref="audio" + <audio ref="audioEl" class="audio" :src="media.url" :title="media.name" @@ -25,34 +25,26 @@ </div> </template> -<script lang="ts"> -import { defineComponent } from 'vue'; -import * as os from '@/os'; +<script lang="ts" setup> +import { onMounted } from 'vue'; +import * as misskey from 'misskey-js'; import { ColdDeviceStorage } from '@/store'; -export default defineComponent({ - props: { - media: { - type: Object, - required: true - } - }, - data() { - return { - hide: true, - }; - }, - mounted() { - const audioTag = this.$refs.audio as HTMLAudioElement; - if (audioTag) audioTag.volume = ColdDeviceStorage.get('mediaVolume'); - }, - methods: { - volumechange() { - const audioTag = this.$refs.audio as HTMLAudioElement; - ColdDeviceStorage.set('mediaVolume', audioTag.volume); - }, - }, -}) +const props = withDefaults(defineProps<{ + media: misskey.entities.DriveFile; +}>(), { +}); + +const audioEl = $ref<HTMLAudioElement | null>(); +let hide = $ref(true); + +function volumechange() { + if (audioEl) ColdDeviceStorage.set('mediaVolume', audioEl.volume); +} + +onMounted(() => { + if (audioEl) audioEl.volume = ColdDeviceStorage.get('mediaVolume'); +}); </script> <style lang="scss" scoped> diff --git a/packages/client/src/components/url-preview.vue b/packages/client/src/components/url-preview.vue index dff74800e..bf3b35879 100644 --- a/packages/client/src/components/url-preview.vue +++ b/packages/client/src/components/url-preview.vue @@ -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 /> </div> <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 v-else v-size="{ max: [400, 350] }" class="mk-url-preview"> <transition name="zoom" mode="out-in"> @@ -32,110 +32,80 @@ </div> </template> -<script lang="ts"> -import { defineComponent } from 'vue'; +<script lang="ts" setup> +import { onMounted, onUnmounted } from 'vue'; import { url as local, lang } from '@/config'; -import * as os from '@/os'; -export default defineComponent({ - props: { - url: { - type: String, - require: true - }, +const props = withDefaults(defineProps<{ + url: string; + detail?: boolean; + compact?: boolean; +}>(), { + detail: false, + compact: false, +}); - detail: { - type: Boolean, - required: false, - default: false - }, +const self = props.url.startsWith(local); +const attr = self ? 'to' : 'href'; +const target = self ? null : '_blank'; +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: { - type: Boolean, - required: false, - default: false - }, - }, +const requestUrl = new URL(props.url); - data() { - const self = this.url.startsWith(local); - return { - 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', - }; - }, +if (requestUrl.hostname == 'twitter.com') { + const m = requestUrl.pathname.match(/^\/.+\/status(?:es)?\/(\d+)/); + if (m) tweetId = m[1]; +} - created() { - const requestUrl = new URL(this.url); +if (requestUrl.hostname === 'music.youtube.com' && requestUrl.pathname.match('^/(?:watch|channel)')) { + requestUrl.hostname = 'www.youtube.com'; +} - if (requestUrl.hostname == 'twitter.com') { - const m = requestUrl.pathname.match(/^\/.+\/status(?:es)?\/(\d+)/); - if (m) this.tweetId = m[1]; - } +const requestLang = (lang || 'ja-JP').replace('ja-KS', 'ja-JP'); - if (requestUrl.hostname === 'music.youtube.com' && requestUrl.pathname.match('^/(?:watch|channel)')) { - requestUrl.hostname = 'www.youtube.com'; - } +requestUrl.hash = ''; - 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 => { - 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', adjustTweetHeight); - (window as any).addEventListener('message', this.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; - }, - }, +onUnmounted(() => { + (window as any).removeEventListener('message', adjustTweetHeight); }); </script>