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…
Reference in a new issue