mirror of
				https://codeberg.org/yeentown/barkey.git
				synced 2025-10-31 13:34:12 +00:00 
			
		
		
		
	
							parent
							
								
									d53d059480
								
							
						
					
					
						commit
						6909add1ec
					
				
					 12 changed files with 11 additions and 157 deletions
				
			
		|  | @ -10,6 +10,7 @@ unreleased | ||||||
| * ログイン時に二段階認証が分かりにくいのを改善 | * ログイン時に二段階認証が分かりにくいのを改善 | ||||||
| * 投稿のツールチップを出すのは時間の上だけに変更 | * 投稿のツールチップを出すのは時間の上だけに変更 | ||||||
| * ハッシュタグ判定の強化 | * ハッシュタグ判定の強化 | ||||||
|  | * ストーク機能の廃止 | ||||||
| * クライアントのAPIリクエストをストリーム経由で行うオプションを廃止 | * クライアントのAPIリクエストをストリーム経由で行うオプションを廃止 | ||||||
| * 一部箇所でカスタム絵文字が適用されていないのを修正 | * 一部箇所でカスタム絵文字が適用されていないのを修正 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1402,9 +1402,6 @@ desktop/views/pages/user/user.photos.vue: | ||||||
| 
 | 
 | ||||||
| desktop/views/pages/user/user.profile.vue: | desktop/views/pages/user/user.profile.vue: | ||||||
|   follows-you: "フォローされています" |   follows-you: "フォローされています" | ||||||
|   stalk: "ストークする" |  | ||||||
|   stalking: "ストーキングしています" |  | ||||||
|   unstalk: "ストーク解除" |  | ||||||
|   menu: "メニュー" |   menu: "メニュー" | ||||||
| 
 | 
 | ||||||
| desktop/views/pages/user/user.header.vue: | desktop/views/pages/user/user.header.vue: | ||||||
|  |  | ||||||
|  | @ -3,10 +3,6 @@ | ||||||
| 	<div class="friend-form" v-if="$store.state.i.id != user.id"> | 	<div class="friend-form" v-if="$store.state.i.id != user.id"> | ||||||
| 		<mk-follow-button :user="user" block/> | 		<mk-follow-button :user="user" block/> | ||||||
| 		<p class="followed" v-if="user.isFollowed">{{ $t('follows-you') }}</p> | 		<p class="followed" v-if="user.isFollowed">{{ $t('follows-you') }}</p> | ||||||
| 		<p class="stalk" v-if="user.isFollowing"> |  | ||||||
| 			<span v-if="user.isStalking">{{ $t('stalking') }} <a @click="unstalk"><fa icon="meh"/> {{ $t('unstalk') }}</a></span> |  | ||||||
| 			<span v-if="!user.isStalking"><a @click="stalk"><fa icon="user-secret"/> {{ $t('stalk') }}</a></span> |  | ||||||
| 		</p> |  | ||||||
| 	</div> | 	</div> | ||||||
| 	<div class="action-form"> | 	<div class="action-form"> | ||||||
| 		<ui-button @click="menu" ref="menu">{{ $t('menu') }}</ui-button> | 		<ui-button @click="menu" ref="menu">{{ $t('menu') }}</ui-button> | ||||||
|  | @ -24,26 +20,6 @@ export default Vue.extend({ | ||||||
| 	props: ['user'], | 	props: ['user'], | ||||||
| 
 | 
 | ||||||
| 	methods: { | 	methods: { | ||||||
| 		stalk() { |  | ||||||
| 			this.$root.api('following/stalk', { |  | ||||||
| 				userId: this.user.id |  | ||||||
| 			}).then(() => { |  | ||||||
| 				this.user.isStalking = true; |  | ||||||
| 			}, () => { |  | ||||||
| 				alert('error'); |  | ||||||
| 			}); |  | ||||||
| 		}, |  | ||||||
| 
 |  | ||||||
| 		unstalk() { |  | ||||||
| 			this.$root.api('following/unstalk', { |  | ||||||
| 				userId: this.user.id |  | ||||||
| 			}).then(() => { |  | ||||||
| 				this.user.isStalking = false; |  | ||||||
| 			}, () => { |  | ||||||
| 				alert('error'); |  | ||||||
| 			}); |  | ||||||
| 		}, |  | ||||||
| 
 |  | ||||||
| 		menu() { | 		menu() { | ||||||
| 			this.$root.new(XUserMenu, { | 			this.$root.new(XUserMenu, { | ||||||
| 				source: this.$refs.menu.$el, | 				source: this.$refs.menu.$el, | ||||||
|  | @ -78,9 +54,6 @@ export default Vue.extend({ | ||||||
| 			background #eefaff | 			background #eefaff | ||||||
| 			border-radius 4px | 			border-radius 4px | ||||||
| 
 | 
 | ||||||
| 		> .stalk |  | ||||||
| 			margin 12px 0 0 0 |  | ||||||
| 
 |  | ||||||
| 	> .action-form | 	> .action-form | ||||||
| 		padding 16px | 		padding 16px | ||||||
| 		text-align center | 		text-align center | ||||||
|  |  | ||||||
|  | @ -1,8 +1,3 @@ | ||||||
| # フォロー | # フォロー | ||||||
| ユーザーをフォローすると、タイムラインにそのユーザーの投稿が表示されるようになります。ただし、他のユーザーに対する返信は含まれません。 | ユーザーをフォローすると、タイムラインにそのユーザーの投稿が表示されるようになります。ただし、他のユーザーに対する返信は含まれません。 | ||||||
| ユーザーをフォローするには、ユーザーページの「フォロー」ボタンをクリックします。フォローを解除するには、もう一度クリックします。 | ユーザーをフォローするには、ユーザーページの「フォロー」ボタンをクリックします。フォローを解除するには、もう一度クリックします。 | ||||||
| 
 |  | ||||||
| ## ストーキング |  | ||||||
| ユーザーをフォローしている状態では、さらに「ストーキング」モードをオンにすることができます。ストーキングを行うと、タイムラインにそのユーザーの全ての投稿が表示されるようになります。つまり、他のユーザーに対する返信も含まれることになります。 |  | ||||||
| ストーキングするには、ユーザーページの「ストークする」をクリックします。ストーキングをやめるには、もう一度クリックします。 |  | ||||||
| ストーキングしていることは相手に通知されません。 |  | ||||||
|  |  | ||||||
|  | @ -12,7 +12,6 @@ export type IFollowing = { | ||||||
| 	createdAt: Date; | 	createdAt: Date; | ||||||
| 	followeeId: mongo.ObjectID; | 	followeeId: mongo.ObjectID; | ||||||
| 	followerId: mongo.ObjectID; | 	followerId: mongo.ObjectID; | ||||||
| 	stalk: boolean; |  | ||||||
| 
 | 
 | ||||||
| 	// 非正規化
 | 	// 非正規化
 | ||||||
| 	_followee: { | 	_followee: { | ||||||
|  |  | ||||||
|  | @ -219,7 +219,6 @@ export async function getRelation(me: mongo.ObjectId, target: mongo.ObjectId) { | ||||||
| 	return { | 	return { | ||||||
| 		id: target, | 		id: target, | ||||||
| 		isFollowing: following1 !== null, | 		isFollowing: following1 !== null, | ||||||
| 		isStalking: following1 ? following1.stalk : false, |  | ||||||
| 		hasPendingFollowRequestFromYou: followReq1 !== null, | 		hasPendingFollowRequestFromYou: followReq1 !== null, | ||||||
| 		hasPendingFollowRequestToYou: followReq2 !== null, | 		hasPendingFollowRequestToYou: followReq2 !== null, | ||||||
| 		isFollowed: following2 !== null, | 		isFollowed: following2 !== null, | ||||||
|  | @ -352,7 +351,6 @@ export const pack = ( | ||||||
| 
 | 
 | ||||||
| 		_user.isFollowing = relation.isFollowing; | 		_user.isFollowing = relation.isFollowing; | ||||||
| 		_user.isFollowed = relation.isFollowed; | 		_user.isFollowed = relation.isFollowed; | ||||||
| 		_user.isStalking = relation.isStalking; |  | ||||||
| 		_user.hasPendingFollowRequestFromYou = relation.hasPendingFollowRequestFromYou; | 		_user.hasPendingFollowRequestFromYou = relation.hasPendingFollowRequestFromYou; | ||||||
| 		_user.hasPendingFollowRequestToYou = relation.hasPendingFollowRequestToYou; | 		_user.hasPendingFollowRequestToYou = relation.hasPendingFollowRequestToYou; | ||||||
| 		_user.isBlocking = relation.isBlocking; | 		_user.isBlocking = relation.isBlocking; | ||||||
|  |  | ||||||
|  | @ -36,14 +36,12 @@ export const getFriends = async (me: mongodb.ObjectID, includeMe = true, remoteO | ||||||
| 
 | 
 | ||||||
| 	// ID list of other users who the I follows
 | 	// ID list of other users who the I follows
 | ||||||
| 	const myfollowings = followings.map(following => ({ | 	const myfollowings = followings.map(following => ({ | ||||||
| 		id: following.followeeId, | 		id: following.followeeId | ||||||
| 		stalk: following.stalk |  | ||||||
| 	})); | 	})); | ||||||
| 
 | 
 | ||||||
| 	if (includeMe) { | 	if (includeMe) { | ||||||
| 		myfollowings.push({ | 		myfollowings.push({ | ||||||
| 			id: me, | 			id: me | ||||||
| 			stalk: true |  | ||||||
| 		}); | 		}); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,50 +0,0 @@ | ||||||
| import $ from 'cafy'; import ID, { transform } from '../../../../misc/cafy-id'; |  | ||||||
| import Following from '../../../../models/following'; |  | ||||||
| import define from '../../define'; |  | ||||||
| 
 |  | ||||||
| export const meta = { |  | ||||||
| 	desc: { |  | ||||||
| 		'ja-JP': '指定したユーザーをストーキングします。', |  | ||||||
| 		'en-US': 'Stalk a user.' |  | ||||||
| 	}, |  | ||||||
| 
 |  | ||||||
| 	requireCredential: true, |  | ||||||
| 
 |  | ||||||
| 	kind: 'following-write', |  | ||||||
| 
 |  | ||||||
| 	params: { |  | ||||||
| 		userId: { |  | ||||||
| 			validator: $.type(ID), |  | ||||||
| 			transform: transform, |  | ||||||
| 			desc: { |  | ||||||
| 				'ja-JP': '対象のユーザーのID', |  | ||||||
| 				'en-US': 'Target user ID' |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| export default define(meta, (ps, user) => new Promise(async (res, rej) => { |  | ||||||
| 	const follower = user; |  | ||||||
| 
 |  | ||||||
| 	// Fetch following
 |  | ||||||
| 	const following = await Following.findOne({ |  | ||||||
| 		followerId: follower._id, |  | ||||||
| 		followeeId: ps.userId |  | ||||||
| 	}); |  | ||||||
| 
 |  | ||||||
| 	if (following === null) { |  | ||||||
| 		return rej('following not found'); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	// Stalk
 |  | ||||||
| 	await Following.update({ _id: following._id }, { |  | ||||||
| 		$set: { |  | ||||||
| 			stalk: true |  | ||||||
| 		} |  | ||||||
| 	}); |  | ||||||
| 
 |  | ||||||
| 	res(); |  | ||||||
| 
 |  | ||||||
| 	// TODO: イベント
 |  | ||||||
| })); |  | ||||||
|  | @ -1,50 +0,0 @@ | ||||||
| import $ from 'cafy'; import ID, { transform } from '../../../../misc/cafy-id'; |  | ||||||
| import Following from '../../../../models/following'; |  | ||||||
| import define from '../../define'; |  | ||||||
| 
 |  | ||||||
| export const meta = { |  | ||||||
| 	desc: { |  | ||||||
| 		'ja-JP': '指定したユーザーのストーキングをやめます。', |  | ||||||
| 		'en-US': 'Unstalk a user.' |  | ||||||
| 	}, |  | ||||||
| 
 |  | ||||||
| 	requireCredential: true, |  | ||||||
| 
 |  | ||||||
| 	kind: 'following-write', |  | ||||||
| 
 |  | ||||||
| 	params: { |  | ||||||
| 		userId: { |  | ||||||
| 			validator: $.type(ID), |  | ||||||
| 			transform: transform, |  | ||||||
| 			desc: { |  | ||||||
| 				'ja-JP': '対象のユーザーのID', |  | ||||||
| 				'en-US': 'Target user ID' |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| export default define(meta, (ps, user) => new Promise(async (res, rej) => { |  | ||||||
| 	const follower = user; |  | ||||||
| 
 |  | ||||||
| 	// Fetch following
 |  | ||||||
| 	const following = await Following.findOne({ |  | ||||||
| 		followerId: follower._id, |  | ||||||
| 		followeeId: ps.userId |  | ||||||
| 	}); |  | ||||||
| 
 |  | ||||||
| 	if (following === null) { |  | ||||||
| 		return rej('following not found'); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	// Stalk
 |  | ||||||
| 	await Following.update({ _id: following._id }, { |  | ||||||
| 		$set: { |  | ||||||
| 			stalk: false |  | ||||||
| 		} |  | ||||||
| 	}); |  | ||||||
| 
 |  | ||||||
| 	res(); |  | ||||||
| 
 |  | ||||||
| 	// TODO: イベント
 |  | ||||||
| })); |  | ||||||
|  | @ -119,12 +119,10 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => { | ||||||
| 		_id: -1 | 		_id: -1 | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 	const followQuery = followings.map(f => f.stalk ? { | 	const followQuery = followings.map(f => ({ | ||||||
| 		userId: f.id |  | ||||||
| 	} : { |  | ||||||
| 		userId: f.id, | 		userId: f.id, | ||||||
| 
 | 
 | ||||||
| 		// ストーキングしてないならリプライは含めない(ただし投稿者自身の投稿へのリプライ、自分の投稿へのリプライ、自分のリプライは含める)
 | 		// リプライは含めない(ただし投稿者自身の投稿へのリプライ、自分の投稿へのリプライ、自分のリプライは含める)
 | ||||||
| 		$or: [{ | 		$or: [{ | ||||||
| 			// リプライでない
 | 			// リプライでない
 | ||||||
| 			replyId: null | 			replyId: null | ||||||
|  | @ -140,7 +138,7 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => { | ||||||
| 			// 自分(フォロワー)が送信したリプライ
 | 			// 自分(フォロワー)が送信したリプライ
 | ||||||
| 			userId: user._id | 			userId: user._id | ||||||
| 		}] | 		}] | ||||||
| 	}); | 	})); | ||||||
| 
 | 
 | ||||||
| 	const visibleQuery = user == null ? [{ | 	const visibleQuery = user == null ? [{ | ||||||
| 		visibility: { $in: [ 'public', 'home' ] } | 		visibility: { $in: [ 'public', 'home' ] } | ||||||
|  |  | ||||||
|  | @ -117,9 +117,7 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => { | ||||||
| 		_id: -1 | 		_id: -1 | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 	const followQuery = followings.map(f => f.stalk ? { | 	const followQuery = followings.map(f => ({ | ||||||
| 		userId: f.id |  | ||||||
| 	} : { |  | ||||||
| 		userId: f.id, | 		userId: f.id, | ||||||
| 
 | 
 | ||||||
| 		// ストーキングしてないならリプライは含めない(ただし投稿者自身の投稿へのリプライ、自分の投稿へのリプライ、自分のリプライは含める)
 | 		// ストーキングしてないならリプライは含めない(ただし投稿者自身の投稿へのリプライ、自分の投稿へのリプライ、自分のリプライは含める)
 | ||||||
|  | @ -138,7 +136,7 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => { | ||||||
| 			// 自分(フォロワー)が送信したリプライ
 | 			// 自分(フォロワー)が送信したリプライ
 | ||||||
| 			userId: user._id | 			userId: user._id | ||||||
| 		}] | 		}] | ||||||
| 	}); | 	})); | ||||||
| 
 | 
 | ||||||
| 	const visibleQuery = user == null ? [{ | 	const visibleQuery = user == null ? [{ | ||||||
| 		visibility: { $in: [ 'public', 'home' ] } | 		visibility: { $in: [ 'public', 'home' ] } | ||||||
|  |  | ||||||
|  | @ -540,12 +540,9 @@ async function publishToFollowers(note: INote, user: IUser, noteActivity: any) { | ||||||
| 		const follower = following._follower; | 		const follower = following._follower; | ||||||
| 
 | 
 | ||||||
| 		if (isLocalUser(follower)) { | 		if (isLocalUser(follower)) { | ||||||
| 			// ストーキングしていない場合
 | 			// この投稿が返信ならスキップ
 | ||||||
| 			if (!following.stalk) { | 			if (note.replyId && !note._reply.userId.equals(following.followerId) && !note._reply.userId.equals(note.userId)) | ||||||
| 				// この投稿が返信ならスキップ
 | 				continue; | ||||||
| 				if (note.replyId && !note._reply.userId.equals(following.followerId) && !note._reply.userId.equals(note.userId)) |  | ||||||
| 					continue; |  | ||||||
| 			} |  | ||||||
| 
 | 
 | ||||||
| 			// Publish event to followers stream
 | 			// Publish event to followers stream
 | ||||||
| 			publishHomeTimelineStream(following.followerId, detailPackedNote); | 			publishHomeTimelineStream(following.followerId, detailPackedNote); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue