This commit is contained in:
		
							parent
							
								
									4bf85a0e6b
								
							
						
					
					
						commit
						a9a7a89b8b
					
				
					 5 changed files with 142 additions and 34 deletions
				
			
		| 
						 | 
					@ -21,7 +21,9 @@ const defaultSettings = {
 | 
				
			||||||
	showMaps: true,
 | 
						showMaps: true,
 | 
				
			||||||
	showPostFormOnTopOfTl: false,
 | 
						showPostFormOnTopOfTl: false,
 | 
				
			||||||
	gradientWindowHeader: false,
 | 
						gradientWindowHeader: false,
 | 
				
			||||||
	showReplyTarget: true
 | 
						showReplyTarget: true,
 | 
				
			||||||
 | 
						showMyRenotes: true,
 | 
				
			||||||
 | 
						showRenotedMyNotes: true
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//#region api requests
 | 
					//#region api requests
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -45,6 +45,8 @@
 | 
				
			||||||
			</div>
 | 
								</div>
 | 
				
			||||||
			<mk-switch v-model="os.i.clientSettings.showPostFormOnTopOfTl" @change="onChangeShowPostFormOnTopOfTl" text="タイムライン上部に投稿フォームを表示する"/>
 | 
								<mk-switch v-model="os.i.clientSettings.showPostFormOnTopOfTl" @change="onChangeShowPostFormOnTopOfTl" text="タイムライン上部に投稿フォームを表示する"/>
 | 
				
			||||||
			<mk-switch v-model="os.i.clientSettings.showReplyTarget" @change="onChangeShowReplyTarget" text="リプライ先を表示する"/>
 | 
								<mk-switch v-model="os.i.clientSettings.showReplyTarget" @change="onChangeShowReplyTarget" text="リプライ先を表示する"/>
 | 
				
			||||||
 | 
								<mk-switch v-model="os.i.clientSettings.showMyRenotes" @change="onChangeShowMyRenotes" text="自分の行ったRenoteをタイムラインに表示する"/>
 | 
				
			||||||
 | 
								<mk-switch v-model="os.i.clientSettings.showRenotedMyNotes" @change="onChangeShowRenotedMyNotes" text="Renoteされた自分の投稿をタイムラインに表示する"/>
 | 
				
			||||||
			<mk-switch v-model="os.i.clientSettings.showMaps" @change="onChangeShowMaps" text="マップの自動展開">
 | 
								<mk-switch v-model="os.i.clientSettings.showMaps" @change="onChangeShowMaps" text="マップの自動展開">
 | 
				
			||||||
				<span>位置情報が添付された投稿のマップを自動的に展開します。</span>
 | 
									<span>位置情報が添付された投稿のマップを自動的に展開します。</span>
 | 
				
			||||||
			</mk-switch>
 | 
								</mk-switch>
 | 
				
			||||||
| 
						 | 
					@ -319,6 +321,18 @@ export default Vue.extend({
 | 
				
			||||||
				value: v
 | 
									value: v
 | 
				
			||||||
			});
 | 
								});
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
							onChangeShowMyRenotes(v) {
 | 
				
			||||||
 | 
								(this as any).api('i/update_client_setting', {
 | 
				
			||||||
 | 
									name: 'showMyRenotes',
 | 
				
			||||||
 | 
									value: v
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							onChangeShowRenotedMyNotes(v) {
 | 
				
			||||||
 | 
								(this as any).api('i/update_client_setting', {
 | 
				
			||||||
 | 
									name: 'showRenotedMyNotes',
 | 
				
			||||||
 | 
									value: v
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
		onChangeShowMaps(v) {
 | 
							onChangeShowMaps(v) {
 | 
				
			||||||
			(this as any).api('i/update_client_setting', {
 | 
								(this as any).api('i/update_client_setting', {
 | 
				
			||||||
				name: 'showMaps',
 | 
									name: 'showMaps',
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -90,7 +90,9 @@ export default Vue.extend({
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			(this as any).api(this.endpoint, {
 | 
								(this as any).api(this.endpoint, {
 | 
				
			||||||
				limit: 11,
 | 
									limit: 11,
 | 
				
			||||||
				untilDate: this.date ? this.date.getTime() : undefined
 | 
									untilDate: this.date ? this.date.getTime() : undefined,
 | 
				
			||||||
 | 
									includeMyRenotes: (this as any).os.i.clientSettings.showMyRenotes,
 | 
				
			||||||
 | 
									includeRenotedMyNotes: (this as any).os.i.clientSettings.showRenotedMyNotes
 | 
				
			||||||
			}).then(notes => {
 | 
								}).then(notes => {
 | 
				
			||||||
				if (notes.length == 11) {
 | 
									if (notes.length == 11) {
 | 
				
			||||||
					notes.pop();
 | 
										notes.pop();
 | 
				
			||||||
| 
						 | 
					@ -108,7 +110,9 @@ export default Vue.extend({
 | 
				
			||||||
			this.moreFetching = true;
 | 
								this.moreFetching = true;
 | 
				
			||||||
			(this as any).api(this.endpoint, {
 | 
								(this as any).api(this.endpoint, {
 | 
				
			||||||
				limit: 11,
 | 
									limit: 11,
 | 
				
			||||||
				untilId: this.notes[this.notes.length - 1].id
 | 
									untilId: this.notes[this.notes.length - 1].id,
 | 
				
			||||||
 | 
									includeMyRenotes: (this as any).os.i.clientSettings.showMyRenotes,
 | 
				
			||||||
 | 
									includeRenotedMyNotes: (this as any).os.i.clientSettings.showRenotedMyNotes
 | 
				
			||||||
			}).then(notes => {
 | 
								}).then(notes => {
 | 
				
			||||||
				if (notes.length == 11) {
 | 
									if (notes.length == 11) {
 | 
				
			||||||
					notes.pop();
 | 
										notes.pop();
 | 
				
			||||||
| 
						 | 
					@ -121,6 +125,21 @@ export default Vue.extend({
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		onNote(note) {
 | 
							onNote(note) {
 | 
				
			||||||
 | 
								const isMyNote = note.userId == (this as any).os.i.id;
 | 
				
			||||||
 | 
								const isPureRenote = note.renoteId != null && note.text == null && note.mediaIds.length == 0 && note.poll == null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if ((this as any).os.i.clientSettings.showMyRenotes === false) {
 | 
				
			||||||
 | 
									if (isMyNote && isPureRenote) {
 | 
				
			||||||
 | 
										return;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if ((this as any).os.i.clientSettings.showRenotedMyNotes === false) {
 | 
				
			||||||
 | 
									if (isPureRenote && (note.renote.userId == (this as any).os.i.id)) {
 | 
				
			||||||
 | 
										return;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// サウンドを再生する
 | 
								// サウンドを再生する
 | 
				
			||||||
			if ((this as any).os.isEnableSounds) {
 | 
								if ((this as any).os.isEnableSounds) {
 | 
				
			||||||
				const sound = new Audio(`${url}/assets/post.mp3`);
 | 
									const sound = new Audio(`${url}/assets/post.mp3`);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -30,6 +30,7 @@ export default Vue.extend({
 | 
				
			||||||
			default: null
 | 
								default: null
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	data() {
 | 
						data() {
 | 
				
			||||||
		return {
 | 
							return {
 | 
				
			||||||
			fetching: true,
 | 
								fetching: true,
 | 
				
			||||||
| 
						 | 
					@ -40,11 +41,13 @@ export default Vue.extend({
 | 
				
			||||||
			connectionId: null
 | 
								connectionId: null
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	computed: {
 | 
						computed: {
 | 
				
			||||||
		alone(): boolean {
 | 
							alone(): boolean {
 | 
				
			||||||
			return (this as any).os.i.followingCount == 0;
 | 
								return (this as any).os.i.followingCount == 0;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mounted() {
 | 
						mounted() {
 | 
				
			||||||
		this.connection = (this as any).os.stream.getConnection();
 | 
							this.connection = (this as any).os.stream.getConnection();
 | 
				
			||||||
		this.connectionId = (this as any).os.stream.use();
 | 
							this.connectionId = (this as any).os.stream.use();
 | 
				
			||||||
| 
						 | 
					@ -53,20 +56,24 @@ export default Vue.extend({
 | 
				
			||||||
		this.connection.on('follow', this.onChangeFollowing);
 | 
							this.connection.on('follow', this.onChangeFollowing);
 | 
				
			||||||
		this.connection.on('unfollow', this.onChangeFollowing);
 | 
							this.connection.on('unfollow', this.onChangeFollowing);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
this.fetch();
 | 
							this.fetch();
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	beforeDestroy() {
 | 
						beforeDestroy() {
 | 
				
			||||||
		this.connection.off('note', this.onNote);
 | 
							this.connection.off('note', this.onNote);
 | 
				
			||||||
		this.connection.off('follow', this.onChangeFollowing);
 | 
							this.connection.off('follow', this.onChangeFollowing);
 | 
				
			||||||
		this.connection.off('unfollow', this.onChangeFollowing);
 | 
							this.connection.off('unfollow', this.onChangeFollowing);
 | 
				
			||||||
		(this as any).os.stream.dispose(this.connectionId);
 | 
							(this as any).os.stream.dispose(this.connectionId);
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	methods: {
 | 
						methods: {
 | 
				
			||||||
		fetch(cb?) {
 | 
							fetch(cb?) {
 | 
				
			||||||
			this.fetching = true;
 | 
								this.fetching = true;
 | 
				
			||||||
			(this as any).api('notes/timeline', {
 | 
								(this as any).api('notes/timeline', {
 | 
				
			||||||
				limit: limit + 1,
 | 
									limit: limit + 1,
 | 
				
			||||||
				untilDate: this.date ? (this.date as any).getTime() : undefined
 | 
									untilDate: this.date ? (this.date as any).getTime() : undefined,
 | 
				
			||||||
 | 
									includeMyRenotes: (this as any).os.i.clientSettings.showMyRenotes,
 | 
				
			||||||
 | 
									includeRenotedMyNotes: (this as any).os.i.clientSettings.showRenotedMyNotes
 | 
				
			||||||
			}).then(notes => {
 | 
								}).then(notes => {
 | 
				
			||||||
				if (notes.length == limit + 1) {
 | 
									if (notes.length == limit + 1) {
 | 
				
			||||||
					notes.pop();
 | 
										notes.pop();
 | 
				
			||||||
| 
						 | 
					@ -78,11 +85,14 @@ this.fetch();
 | 
				
			||||||
				if (cb) cb();
 | 
									if (cb) cb();
 | 
				
			||||||
			});
 | 
								});
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		more() {
 | 
							more() {
 | 
				
			||||||
			this.moreFetching = true;
 | 
								this.moreFetching = true;
 | 
				
			||||||
			(this as any).api('notes/timeline', {
 | 
								(this as any).api('notes/timeline', {
 | 
				
			||||||
				limit: limit + 1,
 | 
									limit: limit + 1,
 | 
				
			||||||
				untilId: this.notes[this.notes.length - 1].id
 | 
									untilId: this.notes[this.notes.length - 1].id,
 | 
				
			||||||
 | 
									includeMyRenotes: (this as any).os.i.clientSettings.showMyRenotes,
 | 
				
			||||||
 | 
									includeRenotedMyNotes: (this as any).os.i.clientSettings.showRenotedMyNotes
 | 
				
			||||||
			}).then(notes => {
 | 
								}).then(notes => {
 | 
				
			||||||
				if (notes.length == limit + 1) {
 | 
									if (notes.length == limit + 1) {
 | 
				
			||||||
					notes.pop();
 | 
										notes.pop();
 | 
				
			||||||
| 
						 | 
					@ -94,12 +104,29 @@ this.fetch();
 | 
				
			||||||
				this.moreFetching = false;
 | 
									this.moreFetching = false;
 | 
				
			||||||
			});
 | 
								});
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		onNote(note) {
 | 
							onNote(note) {
 | 
				
			||||||
 | 
								const isMyNote = note.userId == (this as any).os.i.id;
 | 
				
			||||||
 | 
								const isPureRenote = note.renoteId != null && note.text == null && note.mediaIds.length == 0 && note.poll == null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if ((this as any).os.i.clientSettings.showMyRenotes === false) {
 | 
				
			||||||
 | 
									if (isMyNote && isPureRenote) {
 | 
				
			||||||
 | 
										return;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if ((this as any).os.i.clientSettings.showRenotedMyNotes === false) {
 | 
				
			||||||
 | 
									if (isPureRenote && (note.renote.userId == (this as any).os.i.id)) {
 | 
				
			||||||
 | 
										return;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			this.notes.unshift(note);
 | 
								this.notes.unshift(note);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			const isTop = window.scrollY > 8;
 | 
								const isTop = window.scrollY > 8;
 | 
				
			||||||
			if (isTop) this.notes.pop();
 | 
								if (isTop) this.notes.pop();
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		onChangeFollowing() {
 | 
							onChangeFollowing() {
 | 
				
			||||||
			this.fetch();
 | 
								this.fetch();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -37,6 +37,14 @@ module.exports = async (params, user, app) => {
 | 
				
			||||||
		throw 'only one of sinceId, untilId, sinceDate, untilDate can be specified';
 | 
							throw 'only one of sinceId, untilId, sinceDate, untilDate can be specified';
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Get 'includeMyRenotes' parameter
 | 
				
			||||||
 | 
						const [includeMyRenotes = true, includeMyRenotesErr] = $(params.includeMyRenotes).optional.boolean().$;
 | 
				
			||||||
 | 
						if (includeMyRenotesErr) throw 'invalid includeMyRenotes param';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Get 'includeRenotedMyNotes' parameter
 | 
				
			||||||
 | 
						const [includeRenotedMyNotes = true, includeRenotedMyNotesErr] = $(params.includeRenotedMyNotes).optional.boolean().$;
 | 
				
			||||||
 | 
						if (includeRenotedMyNotesErr) throw 'invalid includeRenotedMyNotes param';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const [followings, watchingChannelIds, mutedUserIds] = await Promise.all([
 | 
						const [followings, watchingChannelIds, mutedUserIds] = await Promise.all([
 | 
				
			||||||
		// フォローを取得
 | 
							// フォローを取得
 | 
				
			||||||
		// Fetch following
 | 
							// Fetch following
 | 
				
			||||||
| 
						 | 
					@ -84,6 +92,7 @@ module.exports = async (params, user, app) => {
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const query = {
 | 
						const query = {
 | 
				
			||||||
 | 
							$and: [{
 | 
				
			||||||
			$or: [{
 | 
								$or: [{
 | 
				
			||||||
				$and: [{
 | 
									$and: [{
 | 
				
			||||||
					// フォローしている人のタイムラインへの投稿
 | 
										// フォローしている人のタイムラインへの投稿
 | 
				
			||||||
| 
						 | 
					@ -114,8 +123,45 @@ module.exports = async (params, user, app) => {
 | 
				
			||||||
			'_renote.userId': {
 | 
								'_renote.userId': {
 | 
				
			||||||
				$nin: mutedUserIds
 | 
									$nin: mutedUserIds
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
 | 
							}]
 | 
				
			||||||
	} as any;
 | 
						} as any;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// MongoDBではトップレベルで否定ができないため、De Morganの法則を利用してクエリします。
 | 
				
			||||||
 | 
						// つまり、「『自分の投稿かつRenote』ではない」を「『自分の投稿ではない』または『Renoteではない』」と表現します。
 | 
				
			||||||
 | 
						// for details: https://en.wikipedia.org/wiki/De_Morgan%27s_laws
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (includeMyRenotes === false) {
 | 
				
			||||||
 | 
							query.$and.push({
 | 
				
			||||||
 | 
								$or: [{
 | 
				
			||||||
 | 
									userId: { $ne: user._id }
 | 
				
			||||||
 | 
								}, {
 | 
				
			||||||
 | 
									renoteId: null
 | 
				
			||||||
 | 
								}, {
 | 
				
			||||||
 | 
									text: { $ne: null }
 | 
				
			||||||
 | 
								}, {
 | 
				
			||||||
 | 
									mediaIds: { $ne: [] }
 | 
				
			||||||
 | 
								}, {
 | 
				
			||||||
 | 
									poll: { $ne: null }
 | 
				
			||||||
 | 
								}]
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (includeRenotedMyNotes === false) {
 | 
				
			||||||
 | 
							query.$and.push({
 | 
				
			||||||
 | 
								$or: [{
 | 
				
			||||||
 | 
									'_renote.userId': { $ne: user._id }
 | 
				
			||||||
 | 
								}, {
 | 
				
			||||||
 | 
									renoteId: null
 | 
				
			||||||
 | 
								}, {
 | 
				
			||||||
 | 
									text: { $ne: null }
 | 
				
			||||||
 | 
								}, {
 | 
				
			||||||
 | 
									mediaIds: { $ne: [] }
 | 
				
			||||||
 | 
								}, {
 | 
				
			||||||
 | 
									poll: { $ne: null }
 | 
				
			||||||
 | 
								}]
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (sinceId) {
 | 
						if (sinceId) {
 | 
				
			||||||
		sort._id = 1;
 | 
							sort._id = 1;
 | 
				
			||||||
		query._id = {
 | 
							query._id = {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue