enhance(frontend): X (formally known as Twitter) (MisskeyIO#208)
* enhance(frontend): TwitterアイコンをXに変更 (misskey-dev#11436) cheery-picked from007ed5c929Co-authored-by: Ebise Lutica <7106976+EbiseLutica@users.noreply.github.com> * fix(frontend/MkUrlPreview): allow fullscreen from tweets (misskey-dev#11712) cheery-picked from2896fc6cb4Co-authored-by: Kagami Sascha Rosylight <saschanaz@outlook.com> * enhance(frontend): x.comでも展開ができるように (misskey-dev#11757) cheery-picked fromcb80dff7dfCo-authored-by: maguroshouta <54607611+maguroshouta@users.noreply.github.com>
This commit is contained in:
		| @@ -23,7 +23,7 @@ | |||||||
| 		"@rollup/plugin-typescript": "^11.1.2", | 		"@rollup/plugin-typescript": "^11.1.2", | ||||||
| 		"@rollup/pluginutils": "5.0.2", | 		"@rollup/pluginutils": "5.0.2", | ||||||
| 		"@syuilo/aiscript": "0.15.0", | 		"@syuilo/aiscript": "0.15.0", | ||||||
| 		"@tabler/icons-webfont": "2.25.0", | 		"@tabler/icons-webfont": "2.30.0", | ||||||
| 		"@vitejs/plugin-vue": "4.2.3", | 		"@vitejs/plugin-vue": "4.2.3", | ||||||
| 		"@vue-macros/reactivity-transform": "0.3.15", | 		"@vue-macros/reactivity-transform": "0.3.15", | ||||||
| 		"@vue/compiler-sfc": "3.3.4", | 		"@vue/compiler-sfc": "3.3.4", | ||||||
|   | |||||||
| @@ -28,7 +28,14 @@ SPDX-License-Identifier: AGPL-3.0-only | |||||||
| </template> | </template> | ||||||
| <template v-else-if="tweetId && tweetExpanded"> | <template v-else-if="tweetId && tweetExpanded"> | ||||||
| 	<div ref="twitter"> | 	<div ref="twitter"> | ||||||
| 		<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=${defaultStore.state.darkMode ? 'dark' : 'light'}&id=${tweetId}`"></iframe> | 		<iframe | ||||||
|  | 			ref="tweet" | ||||||
|  | 			allow="fullscreen;web-share" | ||||||
|  | 			sandbox="allow-popups allow-scripts allow-same-origin" | ||||||
|  | 			scrolling="no" | ||||||
|  | 			:style="{ position: 'relative', width: '100%', height: `${tweetHeight}px`, border: 0 }" | ||||||
|  | 			:src="`https://platform.twitter.com/embed/index.html?embedId=${embedId}&hideCard=false&hideThread=false&lang=en&theme=${defaultStore.state.darkMode ? 'dark' : 'light'}&id=${tweetId}`" | ||||||
|  | 		></iframe> | ||||||
| 	</div> | 	</div> | ||||||
| 	<div :class="$style.action"> | 	<div :class="$style.action"> | ||||||
| 		<MkButton :small="true" inline @click="tweetExpanded = false"> | 		<MkButton :small="true" inline @click="tweetExpanded = false"> | ||||||
| @@ -60,7 +67,7 @@ SPDX-License-Identifier: AGPL-3.0-only | |||||||
| 	<template v-if="showActions"> | 	<template v-if="showActions"> | ||||||
| 		<div v-if="tweetId" :class="$style.action"> | 		<div v-if="tweetId" :class="$style.action"> | ||||||
| 			<MkButton :small="true" inline @click="tweetExpanded = true"> | 			<MkButton :small="true" inline @click="tweetExpanded = true"> | ||||||
| 				<i class="ti ti-brand-twitter"></i> {{ i18n.ts.expandTweet }} | 				<i class="ti ti-brand-x"></i> {{ i18n.ts.expandTweet }} | ||||||
| 			</MkButton> | 			</MkButton> | ||||||
| 		</div> | 		</div> | ||||||
| 		<div v-if="!playerEnabled && player.url" :class="$style.action"> | 		<div v-if="!playerEnabled && player.url" :class="$style.action"> | ||||||
| @@ -126,7 +133,7 @@ let unknownUrl = $ref(false); | |||||||
| const requestUrl = new URL(props.url); | const requestUrl = new URL(props.url); | ||||||
| if (!['http:', 'https:'].includes(requestUrl.protocol)) throw new Error('invalid url'); | if (!['http:', 'https:'].includes(requestUrl.protocol)) throw new Error('invalid url'); | ||||||
|  |  | ||||||
| if (requestUrl.hostname === 'twitter.com' || requestUrl.hostname === 'mobile.twitter.com') { | if (requestUrl.hostname === 'twitter.com' || requestUrl.hostname === 'mobile.twitter.com' || requestUrl.hostname === 'x.com' || requestUrl.hostname === 'mobile.x.com') { | ||||||
| 	const m = requestUrl.pathname.match(/^\/.+\/status(?:es)?\/(\d+)/); | 	const m = requestUrl.pathname.match(/^\/.+\/status(?:es)?\/(\d+)/); | ||||||
| 	if (m) tweetId = m[1]; | 	if (m) tweetId = m[1]; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -13,7 +13,7 @@ import MkUrlPreview from '@/components/MkUrlPreview.vue'; | |||||||
|  |  | ||||||
| type SummalyResult = Awaited<ReturnType<typeof summaly>>; | type SummalyResult = Awaited<ReturnType<typeof summaly>>; | ||||||
|  |  | ||||||
| describe('MkMediaImage', () => { | describe('MkUrlPreview', () => { | ||||||
| 	const renderPreviewBy = async (summary: Partial<SummalyResult>): Promise<RenderResult> => { | 	const renderPreviewBy = async (summary: Partial<SummalyResult>): Promise<RenderResult> => { | ||||||
| 		if (!summary.player) { | 		if (!summary.player) { | ||||||
| 			summary.player = { | 			summary.player = { | ||||||
| @@ -143,4 +143,22 @@ describe('MkMediaImage', () => { | |||||||
| 		assert.exists(iframe, 'iframe should exist'); | 		assert.exists(iframe, 'iframe should exist'); | ||||||
| 		assert.strictEqual(iframe?.parentElement?.style.paddingTop, '200px'); | 		assert.strictEqual(iframe?.parentElement?.style.paddingTop, '200px'); | ||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
|  | 	test('Loading a tweet in iframe', async () => { | ||||||
|  | 		const iframe = await renderAndOpenPreview({ | ||||||
|  | 			url: 'https://twitter.com/i/web/status/1685072521782325249', | ||||||
|  | 		}); | ||||||
|  | 		assert.exists(iframe, 'iframe should exist'); | ||||||
|  | 		assert.strictEqual(iframe?.getAttribute('allow'), 'fullscreen;web-share'); | ||||||
|  | 		assert.strictEqual(iframe?.getAttribute('sandbox'), 'allow-popups allow-scripts allow-same-origin'); | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  | 	test('Loading a post in iframe', async () => { | ||||||
|  | 		const iframe = await renderAndOpenPreview({ | ||||||
|  | 			url: 'https://x.com/i/web/status/1685072521782325249', | ||||||
|  | 		}); | ||||||
|  | 		assert.exists(iframe, 'iframe should exist'); | ||||||
|  | 		assert.strictEqual(iframe?.getAttribute('allow'), 'fullscreen;web-share'); | ||||||
|  | 		assert.strictEqual(iframe?.getAttribute('sandbox'), 'allow-popups allow-scripts allow-same-origin'); | ||||||
|  | 	}); | ||||||
| }); | }); | ||||||
|   | |||||||
							
								
								
									
										14
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										14
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							| @@ -638,8 +638,8 @@ importers: | |||||||
|         specifier: 0.15.0 |         specifier: 0.15.0 | ||||||
|         version: 0.15.0 |         version: 0.15.0 | ||||||
|       '@tabler/icons-webfont': |       '@tabler/icons-webfont': | ||||||
|         specifier: 2.25.0 |         specifier: 2.30.0 | ||||||
|         version: 2.25.0 |         version: 2.30.0 | ||||||
|       '@vitejs/plugin-vue': |       '@vitejs/plugin-vue': | ||||||
|         specifier: 4.2.3 |         specifier: 4.2.3 | ||||||
|         version: 4.2.3(vite@4.4.4)(vue@3.3.4) |         version: 4.2.3(vite@4.4.4)(vue@3.3.4) | ||||||
| @@ -8394,14 +8394,14 @@ packages: | |||||||
|     dependencies: |     dependencies: | ||||||
|       defer-to-connect: 2.0.1 |       defer-to-connect: 2.0.1 | ||||||
|  |  | ||||||
|   /@tabler/icons-webfont@2.25.0: |   /@tabler/icons-webfont@2.30.0: | ||||||
|     resolution: {integrity: sha512-IWYVnYlCwlGC95kvpY5Hdiyn1/amXOUwsfRthtmgEtHCQly4JSLRuaD90xD0O+pQ+wZBXIVNsO3pKdg74zEaBg==} |     resolution: {integrity: sha512-tGGKxeATvyHJBHl5FzY4oAShbAiR4ovstG62lqb2HGlOJwz4Io9TSk4eoB88nqxg3sT5no2YsAKXcr1UnlpnNQ==} | ||||||
|     dependencies: |     dependencies: | ||||||
|       '@tabler/icons': 2.25.0 |       '@tabler/icons': 2.30.0 | ||||||
|     dev: false |     dev: false | ||||||
|  |  | ||||||
|   /@tabler/icons@2.25.0: |   /@tabler/icons@2.30.0: | ||||||
|     resolution: {integrity: sha512-Z+FtSZoG/CM1TMCgg7elUew2m0+qMdh5gutMhvxiIY77KIIsE6L/6fUBy+rPXWE9v7MV296fsnCvbpfgwpXupQ==} |     resolution: {integrity: sha512-tvtmkI4ALjKThVVORh++sB9JnkFY7eGInKxNy+Df7WVQiF7T85tlvGADzlgX4Ic+CK5MIUzZ0jhOlQ/RRlgXpg==} | ||||||
|     dev: false |     dev: false | ||||||
|  |  | ||||||
|   /@tensorflow/tfjs-backend-cpu@4.4.0(@tensorflow/tfjs-core@4.4.0): |   /@tensorflow/tfjs-backend-cpu@4.4.0(@tensorflow/tfjs-core@4.4.0): | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 まっちゃとーにゅ
					まっちゃとーにゅ