parent
							
								
									488e6feed9
								
							
						
					
					
						commit
						69c3c4e3dc
					
				
					 13 changed files with 52 additions and 4 deletions
				
			
		|  | @ -655,6 +655,8 @@ useSystemFont: "システムのデフォルトのフォントを使う" | ||||||
| clips: "クリップ" | clips: "クリップ" | ||||||
| experimentalFeatures: "実験的機能" | experimentalFeatures: "実験的機能" | ||||||
| developer: "開発者" | developer: "開発者" | ||||||
|  | makeExplorable: "アカウントを見つけやすくする" | ||||||
|  | makeExplorableDescription: "オフにすると、「みつける」にアカウントが載らなくなります。" | ||||||
| 
 | 
 | ||||||
| _aboutMisskey: | _aboutMisskey: | ||||||
|   about: "Misskeyはsyuiloによって2014年から開発されている、オープンソースのソフトウェアです。" |   about: "Misskeyはsyuiloによって2014年から開発されている、オープンソースのソフトウェアです。" | ||||||
|  |  | ||||||
							
								
								
									
										18
									
								
								migration/1607353487793-isExplorable.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								migration/1607353487793-isExplorable.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,18 @@ | ||||||
|  | import {MigrationInterface, QueryRunner} from "typeorm"; | ||||||
|  | 
 | ||||||
|  | export class isExplorable1607353487793 implements MigrationInterface { | ||||||
|  |     name = 'isExplorable1607353487793' | ||||||
|  | 
 | ||||||
|  |     public async up(queryRunner: QueryRunner): Promise<void> { | ||||||
|  |         await queryRunner.query(`ALTER TABLE "user" ADD "isExplorable" boolean NOT NULL DEFAULT true`); | ||||||
|  |         await queryRunner.query(`COMMENT ON COLUMN "user"."isExplorable" IS 'Whether the User is explorable.'`); | ||||||
|  |         await queryRunner.query(`CREATE INDEX "IDX_d5a1b83c7cab66f167e6888188" ON "user" ("isExplorable") `); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public async down(queryRunner: QueryRunner): Promise<void> { | ||||||
|  |         await queryRunner.query(`DROP INDEX "IDX_d5a1b83c7cab66f167e6888188"`); | ||||||
|  |         await queryRunner.query(`COMMENT ON COLUMN "user"."isExplorable" IS 'Whether the User is explorable.'`); | ||||||
|  |         await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "isExplorable"`); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | @ -9,6 +9,10 @@ | ||||||
| 		{{ $t('noCrawle') }} | 		{{ $t('noCrawle') }} | ||||||
| 		<template #desc>{{ $t('noCrawleDescription') }}</template> | 		<template #desc>{{ $t('noCrawleDescription') }}</template> | ||||||
| 	</FormSwitch> | 	</FormSwitch> | ||||||
|  | 	<FormSwitch v-model:value="isExplorable" @update:value="save()"> | ||||||
|  | 		{{ $t('makeExplorable') }} | ||||||
|  | 		<template #desc>{{ $t('makeExplorableDescription') }}</template> | ||||||
|  | 	</FormSwitch> | ||||||
| 	<FormSwitch v-model:value="rememberNoteVisibility" @update:value="save()">{{ $t('rememberNoteVisibility') }}</FormSwitch> | 	<FormSwitch v-model:value="rememberNoteVisibility" @update:value="save()">{{ $t('rememberNoteVisibility') }}</FormSwitch> | ||||||
| 	<FormGroup v-if="!rememberNoteVisibility"> | 	<FormGroup v-if="!rememberNoteVisibility"> | ||||||
| 		<template #label>{{ $t('defaultNoteVisibility') }}</template> | 		<template #label>{{ $t('defaultNoteVisibility') }}</template> | ||||||
|  | @ -51,6 +55,7 @@ export default defineComponent({ | ||||||
| 			isLocked: false, | 			isLocked: false, | ||||||
| 			autoAcceptFollowed: false, | 			autoAcceptFollowed: false, | ||||||
| 			noCrawle: false, | 			noCrawle: false, | ||||||
|  | 			isExplorable: false, | ||||||
| 		} | 		} | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
|  | @ -75,6 +80,7 @@ export default defineComponent({ | ||||||
| 		this.isLocked = this.$store.state.i.isLocked; | 		this.isLocked = this.$store.state.i.isLocked; | ||||||
| 		this.autoAcceptFollowed = this.$store.state.i.autoAcceptFollowed; | 		this.autoAcceptFollowed = this.$store.state.i.autoAcceptFollowed; | ||||||
| 		this.noCrawle = this.$store.state.i.noCrawle; | 		this.noCrawle = this.$store.state.i.noCrawle; | ||||||
|  | 		this.isExplorable = this.$store.state.i.isExplorable; | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
| 	mounted() { | 	mounted() { | ||||||
|  | @ -87,6 +93,7 @@ export default defineComponent({ | ||||||
| 				isLocked: !!this.isLocked, | 				isLocked: !!this.isLocked, | ||||||
| 				autoAcceptFollowed: !!this.autoAcceptFollowed, | 				autoAcceptFollowed: !!this.autoAcceptFollowed, | ||||||
| 				noCrawle: !!this.noCrawle, | 				noCrawle: !!this.noCrawle, | ||||||
|  | 				isExplorable: !!this.isExplorable, | ||||||
| 			}); | 			}); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -157,6 +157,13 @@ export class User { | ||||||
| 	}) | 	}) | ||||||
| 	public isModerator: boolean; | 	public isModerator: boolean; | ||||||
| 
 | 
 | ||||||
|  | 	@Index() | ||||||
|  | 	@Column('boolean', { | ||||||
|  | 		default: true, | ||||||
|  | 		comment: 'Whether the User is explorable.' | ||||||
|  | 	}) | ||||||
|  | 	public isExplorable: boolean; | ||||||
|  | 
 | ||||||
| 	@Column('varchar', { | 	@Column('varchar', { | ||||||
| 		length: 128, array: true, default: '{}' | 		length: 128, array: true, default: '{}' | ||||||
| 	}) | 	}) | ||||||
|  |  | ||||||
|  | @ -240,6 +240,7 @@ export class UserRepository extends Repository<User> { | ||||||
| 				carefulBot: profile!.carefulBot, | 				carefulBot: profile!.carefulBot, | ||||||
| 				autoAcceptFollowed: profile!.autoAcceptFollowed, | 				autoAcceptFollowed: profile!.autoAcceptFollowed, | ||||||
| 				noCrawle: profile!.noCrawle, | 				noCrawle: profile!.noCrawle, | ||||||
|  | 				isExplorable: user.isExplorable, | ||||||
| 				hasUnreadSpecifiedNotes: NoteUnreads.count({ | 				hasUnreadSpecifiedNotes: NoteUnreads.count({ | ||||||
| 					where: { userId: user.id, isSpecified: true }, | 					where: { userId: user.id, isSpecified: true }, | ||||||
| 					take: 1 | 					take: 1 | ||||||
|  |  | ||||||
|  | @ -153,6 +153,7 @@ export async function createPerson(uri: string, resolver?: Resolver): Promise<Us | ||||||
| 				lastFetchedAt: new Date(), | 				lastFetchedAt: new Date(), | ||||||
| 				name: person.name, | 				name: person.name, | ||||||
| 				isLocked: !!person.manuallyApprovesFollowers, | 				isLocked: !!person.manuallyApprovesFollowers, | ||||||
|  | 				isExplorable: !!person.discoverable, | ||||||
| 				username: person.preferredUsername, | 				username: person.preferredUsername, | ||||||
| 				usernameLower: person.preferredUsername!.toLowerCase(), | 				usernameLower: person.preferredUsername!.toLowerCase(), | ||||||
| 				host, | 				host, | ||||||
|  | @ -336,6 +337,7 @@ export async function updatePerson(uri: string, resolver?: Resolver | null, hint | ||||||
| 		isBot: object.type === 'Service', | 		isBot: object.type === 'Service', | ||||||
| 		isCat: (person as any).isCat === true, | 		isCat: (person as any).isCat === true, | ||||||
| 		isLocked: !!person.manuallyApprovesFollowers, | 		isLocked: !!person.manuallyApprovesFollowers, | ||||||
|  | 		isExplorable: !!person.discoverable, | ||||||
| 	} as Partial<User>; | 	} as Partial<User>; | ||||||
| 
 | 
 | ||||||
| 	if (avatar) { | 	if (avatar) { | ||||||
|  |  | ||||||
|  | @ -38,6 +38,7 @@ export const attachLdSignature = async (activity: any, user: ILocalUser): Promis | ||||||
| 		toot: 'http://joinmastodon.org/ns#', | 		toot: 'http://joinmastodon.org/ns#', | ||||||
| 		Emoji: 'toot:Emoji', | 		Emoji: 'toot:Emoji', | ||||||
| 		featured: 'toot:featured', | 		featured: 'toot:featured', | ||||||
|  | 		discoverable: 'toot:discoverable', | ||||||
| 		// schema
 | 		// schema
 | ||||||
| 		schema: 'http://schema.org#', | 		schema: 'http://schema.org#', | ||||||
| 		PropertyValue: 'schema:PropertyValue', | 		PropertyValue: 'schema:PropertyValue', | ||||||
|  |  | ||||||
|  | @ -70,6 +70,7 @@ export async function renderPerson(user: ILocalUser) { | ||||||
| 		image: banner ? renderImage(banner) : null, | 		image: banner ? renderImage(banner) : null, | ||||||
| 		tag, | 		tag, | ||||||
| 		manuallyApprovesFollowers: user.isLocked, | 		manuallyApprovesFollowers: user.isLocked, | ||||||
|  | 		discoverable: !!user.isExplorable, | ||||||
| 		publicKey: renderKey(user, keypair, `#main-key`), | 		publicKey: renderKey(user, keypair, `#main-key`), | ||||||
| 		isCat: user.isCat, | 		isCat: user.isCat, | ||||||
| 		attachment: attachment.length ? attachment : undefined | 		attachment: attachment.length ? attachment : undefined | ||||||
|  |  | ||||||
|  | @ -135,6 +135,7 @@ export interface IPerson extends IObject { | ||||||
| 	name?: string; | 	name?: string; | ||||||
| 	preferredUsername?: string; | 	preferredUsername?: string; | ||||||
| 	manuallyApprovesFollowers?: boolean; | 	manuallyApprovesFollowers?: boolean; | ||||||
|  | 	discoverable?: boolean; | ||||||
| 	inbox?: string; | 	inbox?: string; | ||||||
| 	sharedInbox?: string;	// 後方互換性のため
 | 	sharedInbox?: string;	// 後方互換性のため
 | ||||||
| 	publicKey: { | 	publicKey: { | ||||||
|  |  | ||||||
|  | @ -92,6 +92,10 @@ export const meta = { | ||||||
| 			} | 			} | ||||||
| 		}, | 		}, | ||||||
| 
 | 
 | ||||||
|  | 		isExplorable: { | ||||||
|  | 			validator: $.optional.bool, | ||||||
|  | 		}, | ||||||
|  | 
 | ||||||
| 		carefulBot: { | 		carefulBot: { | ||||||
| 			validator: $.optional.bool, | 			validator: $.optional.bool, | ||||||
| 			desc: { | 			desc: { | ||||||
|  | @ -208,6 +212,7 @@ export default define(meta, async (ps, user, token) => { | ||||||
| 	} | 	} | ||||||
| 	if (ps.mutingNotificationTypes !== undefined) profileUpdates.mutingNotificationTypes = ps.mutingNotificationTypes as typeof notificationTypes[number][]; | 	if (ps.mutingNotificationTypes !== undefined) profileUpdates.mutingNotificationTypes = ps.mutingNotificationTypes as typeof notificationTypes[number][]; | ||||||
| 	if (typeof ps.isLocked === 'boolean') updates.isLocked = ps.isLocked; | 	if (typeof ps.isLocked === 'boolean') updates.isLocked = ps.isLocked; | ||||||
|  | 	if (typeof ps.isExplorable === 'boolean') updates.isExplorable = ps.isExplorable; | ||||||
| 	if (typeof ps.isBot === 'boolean') updates.isBot = ps.isBot; | 	if (typeof ps.isBot === 'boolean') updates.isBot = ps.isBot; | ||||||
| 	if (typeof ps.carefulBot === 'boolean') profileUpdates.carefulBot = ps.carefulBot; | 	if (typeof ps.carefulBot === 'boolean') profileUpdates.carefulBot = ps.carefulBot; | ||||||
| 	if (typeof ps.autoAcceptFollowed === 'boolean') profileUpdates.autoAcceptFollowed = ps.autoAcceptFollowed; | 	if (typeof ps.autoAcceptFollowed === 'boolean') profileUpdates.autoAcceptFollowed = ps.autoAcceptFollowed; | ||||||
|  |  | ||||||
|  | @ -64,12 +64,13 @@ export const meta = { | ||||||
| 
 | 
 | ||||||
| export default define(meta, async (ps, me) => { | export default define(meta, async (ps, me) => { | ||||||
| 	const query = Users.createQueryBuilder('user'); | 	const query = Users.createQueryBuilder('user'); | ||||||
|  | 	query.where('user.isExplorable = TRUE'); | ||||||
| 
 | 
 | ||||||
| 	switch (ps.state) { | 	switch (ps.state) { | ||||||
| 		case 'admin': query.where('user.isAdmin = TRUE'); break; | 		case 'admin': query.andWhere('user.isAdmin = TRUE'); break; | ||||||
| 		case 'moderator': query.where('user.isModerator = TRUE'); break; | 		case 'moderator': query.andWhere('user.isModerator = TRUE'); break; | ||||||
| 		case 'adminOrModerator': query.where('user.isAdmin = TRUE OR isModerator = TRUE'); break; | 		case 'adminOrModerator': query.andWhere('user.isAdmin = TRUE OR isModerator = TRUE'); break; | ||||||
| 		case 'alive': query.where('user.updatedAt > :date', { date: new Date(Date.now() - 1000 * 60 * 60 * 24 * 5) }); break; | 		case 'alive': query.andWhere('user.updatedAt > :date', { date: new Date(Date.now() - 1000 * 60 * 60 * 24 * 5) }); break; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	switch (ps.origin) { | 	switch (ps.origin) { | ||||||
|  |  | ||||||
|  | @ -42,6 +42,7 @@ export const meta = { | ||||||
| export default define(meta, async (ps, me) => { | export default define(meta, async (ps, me) => { | ||||||
| 	const query = Users.createQueryBuilder('user') | 	const query = Users.createQueryBuilder('user') | ||||||
| 		.where('user.isLocked = FALSE') | 		.where('user.isLocked = FALSE') | ||||||
|  | 		.andWhere('user.isExplorable = TRUE') | ||||||
| 		.andWhere('user.host IS NULL') | 		.andWhere('user.host IS NULL') | ||||||
| 		.andWhere('user.updatedAt >= :date', { date: new Date(Date.now() - ms('7days')) }) | 		.andWhere('user.updatedAt >= :date', { date: new Date(Date.now() - ms('7days')) }) | ||||||
| 		.andWhere('user.id != :meId', { meId: me.id }) | 		.andWhere('user.id != :meId', { meId: me.id }) | ||||||
|  |  | ||||||
|  | @ -34,6 +34,7 @@ export async function createSystemUser(username: string) { | ||||||
| 			token: secret, | 			token: secret, | ||||||
| 			isAdmin: false, | 			isAdmin: false, | ||||||
| 			isLocked: true, | 			isLocked: true, | ||||||
|  | 			isExplorable: false, | ||||||
| 			isBot: true, | 			isBot: true, | ||||||
| 		})); | 		})); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue