タイムライン上でTwitterウィジットを展開できるようになど (#6496)
* TL上でTwitterウィジットを展開できるようになど * use iframe * Twitterウィジットがはみ出すのを修正
This commit is contained in:
		
							parent
							
								
									5f8fb43cc9
								
							
						
					
					
						commit
						5b28d7bf90
					
				
					 2 changed files with 50 additions and 31 deletions
				
			
		|  | @ -516,6 +516,9 @@ visibility: "公開範囲" | |||
| poll: "アンケート" | ||||
| useCw: "内容を隠す" | ||||
| fixedWidgetsPosition: "ウィジェットの位置を固定する" | ||||
| enablePlayer: "プレイヤーを開く" | ||||
| disablePlayer: "プレイヤーを閉じる" | ||||
| expandTweet: "ツイートを展開する" | ||||
| 
 | ||||
| _theme: | ||||
|   explore: "テーマを探す" | ||||
|  |  | |||
|  | @ -1,18 +1,16 @@ | |||
| <template> | ||||
| <div v-if="playerEnabled" class="player" :style="`padding: ${(player.height || 0) / (player.width || 1) * 100}% 0 0`"> | ||||
| 	<button class="disablePlayer" @click="playerEnabled = false" :title="$t('disable-player')"><fa icon="times"/></button> | ||||
| 	<button class="disablePlayer" @click="playerEnabled = false" :title="$t('disablePlayer')"><fa icon="times"/></button> | ||||
| 	<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="tweetUrl && detail" class="twitter"> | ||||
| 	<blockquote ref="tweet" class="twitter-tweet" :data-theme="$store.state.device.darkMode ? 'dark' : null"> | ||||
| 		<a :href="url"></a> | ||||
| 	</blockquote> | ||||
| <div v-else-if="tweetId && tweetExpanded" class="twitter" ref="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.device.darkMode ? 'dark' : 'light'}&id=${tweetId}`"></iframe> | ||||
| </div> | ||||
| <div v-else class="mk-url-preview" v-size="[{ max: 400 }, { max: 350 }]"> | ||||
| 	<transition name="zoom" mode="out-in"> | ||||
| 		<component :is="self ? 'router-link' : 'a'" :class="{ compact }" :[attr]="self ? url.substr(local.length) : url" rel="nofollow noopener" :target="target" :title="url" v-if="!fetching"> | ||||
| 			<div class="thumbnail" v-if="thumbnail" :style="`background-image: url('${thumbnail}')`"> | ||||
| 				<button class="_button" v-if="!playerEnabled && player.url" @click.prevent="playerEnabled = true" :title="$t('enable-player')"><fa :icon="faPlayCircle"/></button> | ||||
| 				<button class="_button" v-if="!playerEnabled && player.url" @click.prevent="playerEnabled = true" :title="$t('enablePlayer')"><fa :icon="faPlayCircle"/></button> | ||||
| 			</div> | ||||
| 			<article> | ||||
| 				<header> | ||||
|  | @ -26,12 +24,18 @@ | |||
| 			</article> | ||||
| 		</component> | ||||
| 	</transition> | ||||
| 	<div class="expandTweet" v-if="tweetId"> | ||||
| 		<a @click="tweetExpanded = true"> | ||||
| 			<fa :icon="faTwitter"/> {{ $t('expandTweet') }} | ||||
| 		</a> | ||||
| 	</div> | ||||
| </div> | ||||
| </template> | ||||
| 
 | ||||
| <script lang="ts"> | ||||
| import Vue from 'vue'; | ||||
| import { faPlayCircle } from '@fortawesome/free-regular-svg-icons'; | ||||
| import { faTwitter } from '@fortawesome/free-brands-svg-icons';  | ||||
| import { url as local, lang } from '../config'; | ||||
| 
 | ||||
| export default Vue.extend({ | ||||
|  | @ -69,42 +73,29 @@ export default Vue.extend({ | |||
| 				width: null, | ||||
| 				height: null | ||||
| 			}, | ||||
| 			tweetUrl: 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', | ||||
| 			faPlayCircle | ||||
| 			faPlayCircle, faTwitter | ||||
| 		}; | ||||
| 	}, | ||||
| 
 | ||||
| 	created() { | ||||
| 		const requestUrl = new URL(this.url); | ||||
| 
 | ||||
| 		if (this.detail && requestUrl.hostname == 'twitter.com' && /^\/.+\/status(es)?\/\d+/.test(requestUrl.pathname)) { | ||||
| 			this.tweetUrl = requestUrl; | ||||
| 			const twttr = (window as any).twttr || {}; | ||||
| 			const loadTweet = () => twttr.widgets.load(this.$refs.tweet); | ||||
| 
 | ||||
| 			if (twttr.widgets) { | ||||
| 				Vue.nextTick(loadTweet); | ||||
| 			} else { | ||||
| 				const wjsId = 'twitter-wjs'; | ||||
| 				if (!document.getElementById(wjsId)) { | ||||
| 					const head = document.getElementsByTagName('head')[0]; | ||||
| 					const script = document.createElement('script'); | ||||
| 					script.setAttribute('id', wjsId); | ||||
| 					script.setAttribute('src', 'https://platform.twitter.com/widgets.js'); | ||||
| 					head.appendChild(script); | ||||
| 				} | ||||
| 				twttr.ready = loadTweet; | ||||
| 				(window as any).twttr = twttr; | ||||
| 			} | ||||
| 			return; | ||||
| 		if (requestUrl.hostname == 'twitter.com') { | ||||
| 			const m = requestUrl.pathname.match(/^\/.+\/status(?:es)?\/(\d+)/); | ||||
| 			if (m) this.tweetId = m[1]; | ||||
| 		} | ||||
| 
 | ||||
| 		if (requestUrl.hostname === 'music.youtube.com') { | ||||
| 			requestUrl.hostname = 'youtube.com'; | ||||
| 		if (requestUrl.hostname === 'music.youtube.com' && requestUrl.pathname.match('^/(?:watch|channel)')) { | ||||
| 			requestUrl.hostname = 'www.youtube.com'; | ||||
| 		} | ||||
| 
 | ||||
| 		const requestLang = (lang || 'ja-JP').replace('ja-KS', 'ja-JP'); | ||||
|  | @ -123,7 +114,32 @@ export default Vue.extend({ | |||
| 				this.player = info.player; | ||||
| 			}) | ||||
| 		}); | ||||
| 	} | ||||
| 
 | ||||
| 		(window as any).addEventListener('message', this.adjustTweetHeight); | ||||
| 	}, | ||||
| 
 | ||||
| 	mounted() { | ||||
| 		// 300pxないと絶対右にはみ出るので左に移動してしまう | ||||
| 		const areaWidth = (this.$el as any)?.clientWidth; | ||||
| 		if (areaWidth && areaWidth < 300) this.tweetLeft = areaWidth - 241; | ||||
| 		console.log(`areaWidth: ${areaWidth}`); | ||||
| 		console.log(`this.tweetLeft: ${this.tweetLeft}`); | ||||
| 	}, | ||||
| 
 | ||||
| 	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; | ||||
|  		}, | ||||
| 	}, | ||||
| 
 | ||||
| 	beforeDestroy() { | ||||
| 		(window as any).removeEventListener('message', this.adjustTweetHeight); | ||||
| 	}, | ||||
| }); | ||||
| </script> | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue