fix(frontend): Twitchの埋め込みが開けない問題を修正 (#14247)
* fix(frontend): twitchの埋め込みが開けない問題を修正 * Update Changelog * fix test
This commit is contained in:
parent
ee3b132f05
commit
4f85b6aa91
|
@ -40,6 +40,7 @@
|
||||||
- Fix: MkSignin.vueのcredentialRequestからReactivityを削除(ProxyがPasskey認証処理に渡ることを避けるため)
|
- Fix: MkSignin.vueのcredentialRequestからReactivityを削除(ProxyがPasskey認証処理に渡ることを避けるため)
|
||||||
- Fix: 「アニメーション画像を再生しない」がオンのときでもサーバーのバナー画像・背景画像がアニメーションしてしまう問題を修正
|
- Fix: 「アニメーション画像を再生しない」がオンのときでもサーバーのバナー画像・背景画像がアニメーションしてしまう問題を修正
|
||||||
(Cherry-picked from https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/574)
|
(Cherry-picked from https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/574)
|
||||||
|
- Fix: Twitchの埋め込みが開けない問題を修正
|
||||||
|
|
||||||
### Server
|
### Server
|
||||||
- Feat: レートリミット制限に引っかかったときに`Retry-After`ヘッダーを返すように (#13949)
|
- Feat: レートリミット制限に引っかかったときに`Retry-After`ヘッダーを返すように (#13949)
|
||||||
|
|
|
@ -15,7 +15,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
scrolling="no"
|
scrolling="no"
|
||||||
:allow="player.allow == null ? 'autoplay;encrypted-media;fullscreen' : player.allow.filter(x => ['autoplay', 'clipboard-write', 'fullscreen', 'encrypted-media', 'picture-in-picture', 'web-share'].includes(x)).join(';')"
|
:allow="player.allow == null ? 'autoplay;encrypted-media;fullscreen' : player.allow.filter(x => ['autoplay', 'clipboard-write', 'fullscreen', 'encrypted-media', 'picture-in-picture', 'web-share'].includes(x)).join(';')"
|
||||||
:class="$style.playerIframe"
|
:class="$style.playerIframe"
|
||||||
:src="player.url + (player.url.match(/\?/) ? '&autoplay=1&auto_play=1' : '?autoplay=1&auto_play=1')"
|
:src="transformPlayerUrl(player.url)"
|
||||||
:style="{ border: 0 }"
|
:style="{ border: 0 }"
|
||||||
></iframe>
|
></iframe>
|
||||||
<span v-else>invalid url</span>
|
<span v-else>invalid url</span>
|
||||||
|
@ -91,6 +91,7 @@ import * as os from '@/os.js';
|
||||||
import { deviceKind } from '@/scripts/device-kind.js';
|
import { deviceKind } from '@/scripts/device-kind.js';
|
||||||
import MkButton from '@/components/MkButton.vue';
|
import MkButton from '@/components/MkButton.vue';
|
||||||
import { versatileLang } from '@/scripts/intl-const.js';
|
import { versatileLang } from '@/scripts/intl-const.js';
|
||||||
|
import { transformPlayerUrl } from '@/scripts/player-url-transform.js';
|
||||||
import { defaultStore } from '@/store.js';
|
import { defaultStore } from '@/store.js';
|
||||||
|
|
||||||
type SummalyResult = Awaited<ReturnType<typeof summaly>>;
|
type SummalyResult = Awaited<ReturnType<typeof summaly>>;
|
||||||
|
|
|
@ -13,7 +13,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<div class="poamfof">
|
<div class="poamfof">
|
||||||
<Transition :name="defaultStore.state.animation ? 'fade' : ''" mode="out-in">
|
<Transition :name="defaultStore.state.animation ? 'fade' : ''" mode="out-in">
|
||||||
<div v-if="player.url && (player.url.startsWith('http://') || player.url.startsWith('https://'))" class="player">
|
<div v-if="player.url && (player.url.startsWith('http://') || player.url.startsWith('https://'))" class="player">
|
||||||
<iframe v-if="!fetching" :src="player.url + (player.url.match(/\?/) ? '&autoplay=1&auto_play=1' : '?autoplay=1&auto_play=1')" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen/>
|
<iframe v-if="!fetching" :src="transformPlayerUrl(player.url)" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>
|
||||||
</div>
|
</div>
|
||||||
<span v-else>invalid url</span>
|
<span v-else>invalid url</span>
|
||||||
</Transition>
|
</Transition>
|
||||||
|
@ -27,6 +27,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import MkWindow from '@/components/MkWindow.vue';
|
import MkWindow from '@/components/MkWindow.vue';
|
||||||
import { versatileLang } from '@/scripts/intl-const.js';
|
import { versatileLang } from '@/scripts/intl-const.js';
|
||||||
|
import { transformPlayerUrl } from '@/scripts/player-url-transform.js';
|
||||||
import { defaultStore } from '@/store.js';
|
import { defaultStore } from '@/store.js';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
import { hostname } from '@/config.js';
|
||||||
|
|
||||||
|
export function transformPlayerUrl(url: string): string {
|
||||||
|
const urlObj = new URL(url);
|
||||||
|
if (!['https:', 'http:'].includes(urlObj.protocol)) throw new Error('Invalid protocol');
|
||||||
|
|
||||||
|
const urlParams = new URLSearchParams(urlObj.search);
|
||||||
|
|
||||||
|
if (urlObj.hostname === 'player.twitch.tv') {
|
||||||
|
// TwitchはCSPの制約あり
|
||||||
|
// https://dev.twitch.tv/docs/embed/video-and-clips/
|
||||||
|
urlParams.set('parent', hostname);
|
||||||
|
urlParams.set('allowfullscreen', '');
|
||||||
|
urlParams.set('autoplay', 'true');
|
||||||
|
} else {
|
||||||
|
urlParams.set('autoplay', '1');
|
||||||
|
urlParams.set('auto_play', '1');
|
||||||
|
}
|
||||||
|
urlObj.search = urlParams.toString();
|
||||||
|
|
||||||
|
return urlObj.toString();
|
||||||
|
}
|
Loading…
Reference in New Issue