メッセージタイムラインを追加
This commit is contained in:
		| @@ -38,7 +38,14 @@ export default Vue.extend({ | ||||
| 			streamManager: null, | ||||
| 			connection: null, | ||||
| 			connectionId: null, | ||||
| 			date: null | ||||
| 			date: null, | ||||
| 			baseQuery: { | ||||
| 				includeMyRenotes: this.$store.state.settings.showMyRenotes, | ||||
| 				includeRenotedMyNotes: this.$store.state.settings.showRenotedMyNotes, | ||||
| 				includeLocalRenotes: this.$store.state.settings.showLocalRenotes | ||||
| 			}, | ||||
| 			query: {}, | ||||
| 			endpoint: null | ||||
| 		}; | ||||
| 	}, | ||||
|  | ||||
| @@ -47,53 +54,102 @@ export default Vue.extend({ | ||||
| 			return this.$store.state.i.followingCount == 0; | ||||
| 		}, | ||||
|  | ||||
| 		endpoint(): string { | ||||
| 			switch (this.src) { | ||||
| 				case 'home': return 'notes/timeline'; | ||||
| 				case 'local': return 'notes/local-timeline'; | ||||
| 				case 'hybrid': return 'notes/hybrid-timeline'; | ||||
| 				case 'global': return 'notes/global-timeline'; | ||||
| 				case 'mentions': return 'notes/mentions'; | ||||
| 				case 'tag': return 'notes/search_by_tag'; | ||||
| 			} | ||||
| 		}, | ||||
|  | ||||
| 		canFetchMore(): boolean { | ||||
| 			return !this.moreFetching && !this.fetching && this.existMore; | ||||
| 		} | ||||
| 	}, | ||||
|  | ||||
| 	mounted() { | ||||
| 		const prepend = note => { | ||||
| 			(this.$refs.timeline as any).prepend(note); | ||||
| 		}; | ||||
|  | ||||
| 		if (this.src == 'tag') { | ||||
| 			this.endpoint = 'notes/search_by_tag'; | ||||
| 			this.query = { | ||||
| 				query: this.tagTl.query | ||||
| 			}; | ||||
| 			this.connection = new HashtagStream((this as any).os, this.$store.state.i, this.tagTl.query); | ||||
| 			this.connection.on('note', this.onNote); | ||||
| 			this.connection.on('note', prepend); | ||||
| 			this.$once('beforeDestroy', () => { | ||||
| 				this.connection.off('note', prepend); | ||||
| 				this.connection.close(); | ||||
| 			}); | ||||
| 		} else if (this.src == 'home') { | ||||
| 			this.endpoint = 'notes/timeline'; | ||||
| 			const onChangeFollowing = () => { | ||||
| 				this.fetch(); | ||||
| 			}; | ||||
| 			this.streamManager = (this as any).os.stream; | ||||
| 			this.connection = this.streamManager.getConnection(); | ||||
| 			this.connectionId = this.streamManager.use(); | ||||
| 			this.connection.on('note', this.onNote); | ||||
| 			this.connection.on('follow', this.onChangeFollowing); | ||||
| 			this.connection.on('unfollow', this.onChangeFollowing); | ||||
| 			this.connection.on('note', prepend); | ||||
| 			this.connection.on('follow', onChangeFollowing); | ||||
| 			this.connection.on('unfollow', onChangeFollowing); | ||||
| 			this.$once('beforeDestroy', () => { | ||||
| 				this.connection.off('note', prepend); | ||||
| 				this.connection.off('follow', onChangeFollowing); | ||||
| 				this.connection.off('unfollow', onChangeFollowing); | ||||
| 				this.streamManager.dispose(this.connectionId); | ||||
| 			}); | ||||
| 		} else if (this.src == 'local') { | ||||
| 			this.endpoint = 'notes/local-timeline'; | ||||
| 			this.streamManager = (this as any).os.streams.localTimelineStream; | ||||
| 			this.connection = this.streamManager.getConnection(); | ||||
| 			this.connectionId = this.streamManager.use(); | ||||
| 			this.connection.on('note', this.onNote); | ||||
| 			this.connection.on('note', prepend); | ||||
| 			this.$once('beforeDestroy', () => { | ||||
| 				this.connection.off('note', prepend); | ||||
| 				this.streamManager.dispose(this.connectionId); | ||||
| 			}); | ||||
| 		} else if (this.src == 'hybrid') { | ||||
| 			this.endpoint = 'notes/hybrid-timeline'; | ||||
| 			this.streamManager = (this as any).os.streams.hybridTimelineStream; | ||||
| 			this.connection = this.streamManager.getConnection(); | ||||
| 			this.connectionId = this.streamManager.use(); | ||||
| 			this.connection.on('note', this.onNote); | ||||
| 			this.connection.on('note', prepend); | ||||
| 			this.$once('beforeDestroy', () => { | ||||
| 				this.connection.off('note', prepend); | ||||
| 				this.streamManager.dispose(this.connectionId); | ||||
| 			}); | ||||
| 		} else if (this.src == 'global') { | ||||
| 			this.endpoint = 'notes/global-timeline'; | ||||
| 			this.streamManager = (this as any).os.streams.globalTimelineStream; | ||||
| 			this.connection = this.streamManager.getConnection(); | ||||
| 			this.connectionId = this.streamManager.use(); | ||||
| 			this.connection.on('note', this.onNote); | ||||
| 			this.connection.on('note', prepend); | ||||
| 			this.$once('beforeDestroy', () => { | ||||
| 				this.connection.off('note', prepend); | ||||
| 				this.streamManager.dispose(this.connectionId); | ||||
| 			}); | ||||
| 		} else if (this.src == 'mentions') { | ||||
| 			this.endpoint = 'notes/mentions'; | ||||
| 			this.streamManager = (this as any).os.stream; | ||||
| 			this.connection = this.streamManager.getConnection(); | ||||
| 			this.connectionId = this.streamManager.use(); | ||||
| 			this.connection.on('mention', this.onNote); | ||||
| 			this.connection.on('mention', prepend); | ||||
| 			this.$once('beforeDestroy', () => { | ||||
| 				this.connection.off('mention', prepend); | ||||
| 				this.streamManager.dispose(this.connectionId); | ||||
| 			}); | ||||
| 		} else if (this.src == 'messages') { | ||||
| 			this.endpoint = 'notes/mentions'; | ||||
| 			this.query = { | ||||
| 				visibility: 'specified' | ||||
| 			}; | ||||
| 			const onNote = note => { | ||||
| 				if (note.visibility == 'specified') { | ||||
| 					prepend(note); | ||||
| 				} | ||||
| 			}; | ||||
| 			this.streamManager = (this as any).os.stream; | ||||
| 			this.connection = this.streamManager.getConnection(); | ||||
| 			this.connectionId = this.streamManager.use(); | ||||
| 			this.connection.on('mention', onNote); | ||||
| 			this.$once('beforeDestroy', () => { | ||||
| 				this.connection.off('mention', onNote); | ||||
| 				this.streamManager.dispose(this.connectionId); | ||||
| 			}); | ||||
| 		} | ||||
|  | ||||
| 		document.addEventListener('keydown', this.onKeydown); | ||||
| @@ -102,28 +158,7 @@ export default Vue.extend({ | ||||
| 	}, | ||||
|  | ||||
| 	beforeDestroy() { | ||||
| 		if (this.src == 'tag') { | ||||
| 			this.connection.off('note', this.onNote); | ||||
| 			this.connection.close(); | ||||
| 		} else if (this.src == 'home') { | ||||
| 			this.connection.off('note', this.onNote); | ||||
| 			this.connection.off('follow', this.onChangeFollowing); | ||||
| 			this.connection.off('unfollow', this.onChangeFollowing); | ||||
| 			this.streamManager.dispose(this.connectionId); | ||||
| 		} else if (this.src == 'local') { | ||||
| 			this.connection.off('note', this.onNote); | ||||
| 			this.streamManager.dispose(this.connectionId); | ||||
| 		} else if (this.src == 'hybrid') { | ||||
| 			this.connection.off('note', this.onNote); | ||||
| 			this.streamManager.dispose(this.connectionId); | ||||
| 		} else if (this.src == 'global') { | ||||
| 			this.connection.off('note', this.onNote); | ||||
| 			this.streamManager.dispose(this.connectionId); | ||||
| 		} else if (this.src == 'mentions') { | ||||
| 			this.connection.off('mention', this.onNote); | ||||
| 			this.streamManager.dispose(this.connectionId); | ||||
| 		} | ||||
|  | ||||
| 		this.$emit('beforeDestroy'); | ||||
| 		document.removeEventListener('keydown', this.onKeydown); | ||||
| 	}, | ||||
|  | ||||
| @@ -132,14 +167,10 @@ export default Vue.extend({ | ||||
| 			this.fetching = true; | ||||
|  | ||||
| 			(this.$refs.timeline as any).init(() => new Promise((res, rej) => { | ||||
| 				(this as any).api(this.endpoint, { | ||||
| 				(this as any).api(this.endpoint, Object.assign({ | ||||
| 					limit: fetchLimit + 1, | ||||
| 					untilDate: this.date ? this.date.getTime() : undefined, | ||||
| 					includeMyRenotes: this.$store.state.settings.showMyRenotes, | ||||
| 					includeRenotedMyNotes: this.$store.state.settings.showRenotedMyNotes, | ||||
| 					includeLocalRenotes: this.$store.state.settings.showLocalRenotes, | ||||
| 					query: this.tagTl ? this.tagTl.query : undefined | ||||
| 				}).then(notes => { | ||||
| 					untilDate: this.date ? this.date.getTime() : undefined | ||||
| 				}, this.baseQuery, this.query)).then(notes => { | ||||
| 					if (notes.length == fetchLimit + 1) { | ||||
| 						notes.pop(); | ||||
| 						this.existMore = true; | ||||
| @@ -156,14 +187,10 @@ export default Vue.extend({ | ||||
|  | ||||
| 			this.moreFetching = true; | ||||
|  | ||||
| 			const promise = (this as any).api(this.endpoint, { | ||||
| 			const promise = (this as any).api(this.endpoint, Object.assign({ | ||||
| 				limit: fetchLimit + 1, | ||||
| 				untilId: (this.$refs.timeline as any).tail().id, | ||||
| 				includeMyRenotes: this.$store.state.settings.showMyRenotes, | ||||
| 				includeRenotedMyNotes: this.$store.state.settings.showRenotedMyNotes, | ||||
| 				includeLocalRenotes: this.$store.state.settings.showLocalRenotes, | ||||
| 				query: this.tagTl ? this.tagTl.query : undefined | ||||
| 			}); | ||||
| 				untilId: (this.$refs.timeline as any).tail().id | ||||
| 			}, this.baseQuery, this.query)); | ||||
|  | ||||
| 			promise.then(notes => { | ||||
| 				if (notes.length == fetchLimit + 1) { | ||||
| @@ -178,15 +205,6 @@ export default Vue.extend({ | ||||
| 			return promise; | ||||
| 		}, | ||||
|  | ||||
| 		onNote(note) { | ||||
| 			// Prepend a note | ||||
| 			(this.$refs.timeline as any).prepend(note); | ||||
| 		}, | ||||
|  | ||||
| 		onChangeFollowing() { | ||||
| 			this.fetch(); | ||||
| 		}, | ||||
|  | ||||
| 		focus() { | ||||
| 			(this.$refs.timeline as any).focus(); | ||||
| 		}, | ||||
|   | ||||
| @@ -5,10 +5,11 @@ | ||||
| 		<span :data-active="src == 'local'" @click="src = 'local'" v-if="enableLocalTimeline">%fa:R comments% %i18n:@local%</span> | ||||
| 		<span :data-active="src == 'hybrid'" @click="src = 'hybrid'" v-if="enableLocalTimeline">%fa:share-alt% %i18n:@hybrid%</span> | ||||
| 		<span :data-active="src == 'global'" @click="src = 'global'">%fa:globe% %i18n:@global%</span> | ||||
| 		<span :data-active="src == 'mentions'" @click="src = 'mentions'">%fa:at% %i18n:@mentions%</span> | ||||
| 		<span :data-active="src == 'tag'" @click="src = 'tag'" v-if="tagTl">%fa:hashtag% {{ tagTl.title }}</span> | ||||
| 		<span :data-active="src == 'list'" @click="src = 'list'" v-if="list">%fa:list% {{ list.title }}</span> | ||||
| 		<div class="buttons"> | ||||
| 			<button :data-active="src == 'mentions'" @click="src = 'mentions'" title="%i18n:@mentions%">%fa:at%</button> | ||||
| 			<button :data-active="src == 'messages'" @click="src = 'messages'" title="%i18n:@messages%">%fa:envelope R%</button> | ||||
| 			<button @click="chooseTag" title="%i18n:@hashtag%" ref="tagButton">%fa:hashtag%</button> | ||||
| 			<button @click="chooseList" title="%i18n:@list%" ref="listButton">%fa:list%</button> | ||||
| 		</div> | ||||
| @@ -18,6 +19,7 @@ | ||||
| 	<x-core v-if="src == 'hybrid'" ref="tl" key="hybrid" src="hybrid"/> | ||||
| 	<x-core v-if="src == 'global'" ref="tl" key="global" src="global"/> | ||||
| 	<x-core v-if="src == 'mentions'" ref="tl" key="mentions" src="mentions"/> | ||||
| 	<x-core v-if="src == 'messages'" ref="tl" key="messages" src="messages"/> | ||||
| 	<x-core v-if="src == 'tag'" ref="tl" key="tag" src="tag" :tag-tl="tagTl"/> | ||||
| 	<mk-user-list-timeline v-if="src == 'list'" ref="tl" :key="list.id" :list="list"/> | ||||
| </div> | ||||
| @@ -202,6 +204,20 @@ root(isDark) | ||||
| 				&:active | ||||
| 					color isDark ? #b2c1d5 : #999 | ||||
|  | ||||
| 				&[data-active] | ||||
| 					color $theme-color | ||||
| 					cursor default | ||||
|  | ||||
| 					&:before | ||||
| 						content "" | ||||
| 						display block | ||||
| 						position absolute | ||||
| 						bottom 0 | ||||
| 						left 0 | ||||
| 						width 100% | ||||
| 						height 2px | ||||
| 						background $theme-color | ||||
|  | ||||
| 		> span | ||||
| 			display inline-block | ||||
| 			padding 0 10px | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 syuilo
					syuilo