merge: add speakAsCat extension and non-nya speech option
This commit is contained in:
commit
6dd0b88050
16 changed files with 48 additions and 2 deletions
|
@ -164,6 +164,8 @@ flagAsBot: "Mark this account as a bot"
|
||||||
flagAsBotDescription: "Enable this option if this account is controlled by a program. If enabled, it will act as a flag for other developers to prevent endless interaction chains with other bots and adjust Misskey's internal systems to treat this account as a bot."
|
flagAsBotDescription: "Enable this option if this account is controlled by a program. If enabled, it will act as a flag for other developers to prevent endless interaction chains with other bots and adjust Misskey's internal systems to treat this account as a bot."
|
||||||
flagAsCat: "Mark this account as a cat"
|
flagAsCat: "Mark this account as a cat"
|
||||||
flagAsCatDescription: "Enable this option to mark this account as a cat."
|
flagAsCatDescription: "Enable this option to mark this account as a cat."
|
||||||
|
flagSpeakAsCat: "Speak as a cat"
|
||||||
|
flagSpeakAsCatDescription: "Your posts will get nyanified when in cat mode."
|
||||||
flagShowTimelineReplies: "Show replies in timeline"
|
flagShowTimelineReplies: "Show replies in timeline"
|
||||||
flagShowTimelineRepliesDescription: "Shows replies of users to notes of other users in the timeline if turned on."
|
flagShowTimelineRepliesDescription: "Shows replies of users to notes of other users in the timeline if turned on."
|
||||||
autoAcceptFollowed: "Automatically approve follow requests from users you're following"
|
autoAcceptFollowed: "Automatically approve follow requests from users you're following"
|
||||||
|
|
12
packages/backend/migration/1696386694000-speakAsCat.js
Normal file
12
packages/backend/migration/1696386694000-speakAsCat.js
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
export class SpeakAsCat1696386694000 {
|
||||||
|
name = "SpeakAsCat1696386694000";
|
||||||
|
|
||||||
|
async up(queryRunner) {
|
||||||
|
await queryRunner.query(`ALTER TABLE "user" ADD "speakAsCat" boolean NOT NULL DEFAULT true`);
|
||||||
|
await queryRunner.query(`COMMENT ON COLUMN "user"."speakAsCat" IS 'Whether to speak as a cat if chosen.'`);
|
||||||
|
}
|
||||||
|
|
||||||
|
async down(queryRunner) {
|
||||||
|
await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "speakAsCat"`);
|
||||||
|
}
|
||||||
|
}
|
|
@ -501,6 +501,7 @@ export class ApRendererService {
|
||||||
discoverable: user.isExplorable,
|
discoverable: user.isExplorable,
|
||||||
publicKey: this.renderKey(user, keypair, '#main-key'),
|
publicKey: this.renderKey(user, keypair, '#main-key'),
|
||||||
isCat: user.isCat,
|
isCat: user.isCat,
|
||||||
|
speakAsCat: user.speakAsCat,
|
||||||
attachment: attachment.length ? attachment : undefined,
|
attachment: attachment.length ? attachment : undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -646,6 +647,9 @@ export class ApRendererService {
|
||||||
'_misskey_reaction': 'misskey:_misskey_reaction',
|
'_misskey_reaction': 'misskey:_misskey_reaction',
|
||||||
'_misskey_votes': 'misskey:_misskey_votes',
|
'_misskey_votes': 'misskey:_misskey_votes',
|
||||||
'isCat': 'misskey:isCat',
|
'isCat': 'misskey:isCat',
|
||||||
|
// Firefish
|
||||||
|
firefish: "https://joinfirefish.org/ns#",
|
||||||
|
speakAsCat: "firefish:speakAsCat",
|
||||||
// vcard
|
// vcard
|
||||||
vcard: 'http://www.w3.org/2006/vcard/ns#',
|
vcard: 'http://www.w3.org/2006/vcard/ns#',
|
||||||
},
|
},
|
||||||
|
|
|
@ -326,6 +326,7 @@ export class ApPersonService implements OnModuleInit {
|
||||||
tags,
|
tags,
|
||||||
isBot,
|
isBot,
|
||||||
isCat: (person as any).isCat === true,
|
isCat: (person as any).isCat === true,
|
||||||
|
speakAsCat: (person as any).speakAsCat != null ? (person as any).speakAsCat === true : (person as any).isCat === true,
|
||||||
emojis,
|
emojis,
|
||||||
})) as MiRemoteUser;
|
})) as MiRemoteUser;
|
||||||
|
|
||||||
|
@ -460,12 +461,13 @@ export class ApPersonService implements OnModuleInit {
|
||||||
tags,
|
tags,
|
||||||
isBot: getApType(object) === 'Service',
|
isBot: getApType(object) === 'Service',
|
||||||
isCat: (person as any).isCat === true,
|
isCat: (person as any).isCat === true,
|
||||||
|
speakAsCat: (person as any).speakAsCat != null ? (person as any).speakAsCat === true : (person as any).isCat === true,
|
||||||
isLocked: person.manuallyApprovesFollowers,
|
isLocked: person.manuallyApprovesFollowers,
|
||||||
movedToUri: person.movedTo ?? null,
|
movedToUri: person.movedTo ?? null,
|
||||||
alsoKnownAs: person.alsoKnownAs ?? null,
|
alsoKnownAs: person.alsoKnownAs ?? null,
|
||||||
isExplorable: person.discoverable,
|
isExplorable: person.discoverable,
|
||||||
...(await this.resolveAvatarAndBanner(exist, person.icon, person.image).catch(() => ({}))),
|
...(await this.resolveAvatarAndBanner(exist, person.icon, person.image).catch(() => ({}))),
|
||||||
} as Partial<MiRemoteUser> & Pick<MiRemoteUser, 'isBot' | 'isCat' | 'isLocked' | 'movedToUri' | 'alsoKnownAs' | 'isExplorable'>;
|
} as Partial<MiRemoteUser> & Pick<MiRemoteUser, 'isBot' | 'isCat' | 'speakAsCat' | 'isLocked' | 'movedToUri' | 'alsoKnownAs' | 'isExplorable'>;
|
||||||
|
|
||||||
const moving = ((): boolean => {
|
const moving = ((): boolean => {
|
||||||
// 移行先がない→ある
|
// 移行先がない→ある
|
||||||
|
|
|
@ -364,7 +364,7 @@ export class NoteEntityService implements OnModuleInit {
|
||||||
} : {}),
|
} : {}),
|
||||||
});
|
});
|
||||||
|
|
||||||
if (packed.user.isCat && packed.text) {
|
if (packed.user.isCat && packed.user.speakAsCat && packed.text) {
|
||||||
const tokens = packed.text ? mfm.parse(packed.text) : [];
|
const tokens = packed.text ? mfm.parse(packed.text) : [];
|
||||||
function nyaizeNode(node: mfm.MfmNode) {
|
function nyaizeNode(node: mfm.MfmNode) {
|
||||||
if (node.type === 'quote') return;
|
if (node.type === 'quote') return;
|
||||||
|
|
|
@ -352,6 +352,7 @@ export class UserEntityService implements OnModuleInit {
|
||||||
createdAt: user.createdAt.toISOString(),
|
createdAt: user.createdAt.toISOString(),
|
||||||
isBot: user.isBot ?? falsy,
|
isBot: user.isBot ?? falsy,
|
||||||
isCat: user.isCat ?? falsy,
|
isCat: user.isCat ?? falsy,
|
||||||
|
speakAsCat: user.speakAsCat ?? falsy,
|
||||||
instance: user.host ? this.federatedInstanceService.federatedInstanceCache.fetch(user.host).then(instance => instance ? {
|
instance: user.host ? this.federatedInstanceService.federatedInstanceCache.fetch(user.host).then(instance => instance ? {
|
||||||
name: instance.name,
|
name: instance.name,
|
||||||
softwareName: instance.softwareName,
|
softwareName: instance.softwareName,
|
||||||
|
|
|
@ -174,6 +174,12 @@ export class MiUser {
|
||||||
})
|
})
|
||||||
public isCat: boolean;
|
public isCat: boolean;
|
||||||
|
|
||||||
|
@Column('boolean', {
|
||||||
|
default: true,
|
||||||
|
comment: 'Whether the User speaks in nya.',
|
||||||
|
})
|
||||||
|
public speakAsCat: boolean;
|
||||||
|
|
||||||
@Column('boolean', {
|
@Column('boolean', {
|
||||||
default: false,
|
default: false,
|
||||||
comment: 'Whether the User is the root.',
|
comment: 'Whether the User is the root.',
|
||||||
|
|
|
@ -55,6 +55,10 @@ export const packedUserLiteSchema = {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
nullable: false, optional: true,
|
nullable: false, optional: true,
|
||||||
},
|
},
|
||||||
|
speakAsCat: {
|
||||||
|
type: 'boolean',
|
||||||
|
nullable: false, optional: true,
|
||||||
|
},
|
||||||
onlineStatus: {
|
onlineStatus: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
format: 'url',
|
format: 'url',
|
||||||
|
|
|
@ -156,6 +156,7 @@ export const paramDef = {
|
||||||
preventAiLearning: { type: 'boolean' },
|
preventAiLearning: { type: 'boolean' },
|
||||||
isBot: { type: 'boolean' },
|
isBot: { type: 'boolean' },
|
||||||
isCat: { type: 'boolean' },
|
isCat: { type: 'boolean' },
|
||||||
|
speakAsCat: { type: 'boolean' },
|
||||||
injectFeaturedNote: { type: 'boolean' },
|
injectFeaturedNote: { type: 'boolean' },
|
||||||
receiveAnnouncementEmail: { type: 'boolean' },
|
receiveAnnouncementEmail: { type: 'boolean' },
|
||||||
alwaysMarkNsfw: { type: 'boolean' },
|
alwaysMarkNsfw: { type: 'boolean' },
|
||||||
|
@ -259,6 +260,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||||
if (typeof ps.noCrawle === 'boolean') profileUpdates.noCrawle = ps.noCrawle;
|
if (typeof ps.noCrawle === 'boolean') profileUpdates.noCrawle = ps.noCrawle;
|
||||||
if (typeof ps.preventAiLearning === 'boolean') profileUpdates.preventAiLearning = ps.preventAiLearning;
|
if (typeof ps.preventAiLearning === 'boolean') profileUpdates.preventAiLearning = ps.preventAiLearning;
|
||||||
if (typeof ps.isCat === 'boolean') updates.isCat = ps.isCat;
|
if (typeof ps.isCat === 'boolean') updates.isCat = ps.isCat;
|
||||||
|
if (typeof ps.speakAsCat === 'boolean') updates.speakAsCat = ps.speakAsCat;
|
||||||
if (typeof ps.injectFeaturedNote === 'boolean') profileUpdates.injectFeaturedNote = ps.injectFeaturedNote;
|
if (typeof ps.injectFeaturedNote === 'boolean') profileUpdates.injectFeaturedNote = ps.injectFeaturedNote;
|
||||||
if (typeof ps.receiveAnnouncementEmail === 'boolean') profileUpdates.receiveAnnouncementEmail = ps.receiveAnnouncementEmail;
|
if (typeof ps.receiveAnnouncementEmail === 'boolean') profileUpdates.receiveAnnouncementEmail = ps.receiveAnnouncementEmail;
|
||||||
if (typeof ps.alwaysMarkNsfw === 'boolean') {
|
if (typeof ps.alwaysMarkNsfw === 'boolean') {
|
||||||
|
|
|
@ -70,6 +70,7 @@ describe('ユーザー', () => {
|
||||||
avatarBlurhash: user.avatarBlurhash,
|
avatarBlurhash: user.avatarBlurhash,
|
||||||
isBot: user.isBot,
|
isBot: user.isBot,
|
||||||
isCat: user.isCat,
|
isCat: user.isCat,
|
||||||
|
speakAsCat: user.speakAsCat,
|
||||||
instance: user.instance,
|
instance: user.instance,
|
||||||
emojis: user.emojis,
|
emojis: user.emojis,
|
||||||
onlineStatus: user.onlineStatus,
|
onlineStatus: user.onlineStatus,
|
||||||
|
@ -350,6 +351,7 @@ describe('ユーザー', () => {
|
||||||
assert.strictEqual(response.avatarBlurhash, null);
|
assert.strictEqual(response.avatarBlurhash, null);
|
||||||
assert.strictEqual(response.isBot, false);
|
assert.strictEqual(response.isBot, false);
|
||||||
assert.strictEqual(response.isCat, false);
|
assert.strictEqual(response.isCat, false);
|
||||||
|
assert.strictEqual(response.speakAsCat, false);
|
||||||
assert.strictEqual(response.instance, undefined);
|
assert.strictEqual(response.instance, undefined);
|
||||||
assert.deepStrictEqual(response.emojis, {});
|
assert.deepStrictEqual(response.emojis, {});
|
||||||
assert.strictEqual(response.onlineStatus, 'unknown');
|
assert.strictEqual(response.onlineStatus, 'unknown');
|
||||||
|
@ -481,6 +483,8 @@ describe('ユーザー', () => {
|
||||||
{ parameters: (): object => ({ isBot: false }) },
|
{ parameters: (): object => ({ isBot: false }) },
|
||||||
{ parameters: (): object => ({ isCat: true }) },
|
{ parameters: (): object => ({ isCat: true }) },
|
||||||
{ parameters: (): object => ({ isCat: false }) },
|
{ parameters: (): object => ({ isCat: false }) },
|
||||||
|
{ parameters: (): object => ({ speakAsCat: true }) },
|
||||||
|
{ parameters: (): object => ({ speakAsCat: false }) },
|
||||||
{ parameters: (): object => ({ injectFeaturedNote: true }) },
|
{ parameters: (): object => ({ injectFeaturedNote: true }) },
|
||||||
{ parameters: (): object => ({ injectFeaturedNote: false }) },
|
{ parameters: (): object => ({ injectFeaturedNote: false }) },
|
||||||
{ parameters: (): object => ({ receiveAnnouncementEmail: true }) },
|
{ parameters: (): object => ({ receiveAnnouncementEmail: true }) },
|
||||||
|
|
|
@ -99,6 +99,7 @@ export function userDetailed(id = 'someuserid', username = 'miskist', host = 'mi
|
||||||
isBlocking: false,
|
isBlocking: false,
|
||||||
isBot: false,
|
isBot: false,
|
||||||
isCat: false,
|
isCat: false,
|
||||||
|
speakAsCat: false,
|
||||||
isFollowed: false,
|
isFollowed: false,
|
||||||
isFollowing: false,
|
isFollowing: false,
|
||||||
isLocked: false,
|
isLocked: false,
|
||||||
|
|
|
@ -93,6 +93,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
<div class="_gaps_m">
|
<div class="_gaps_m">
|
||||||
<MkSwitch v-model="profile.isCat">{{ i18n.ts.flagAsCat }}<template #caption>{{ i18n.ts.flagAsCatDescription }}</template></MkSwitch>
|
<MkSwitch v-model="profile.isCat">{{ i18n.ts.flagAsCat }}<template #caption>{{ i18n.ts.flagAsCatDescription }}</template></MkSwitch>
|
||||||
|
<MkSwitch v-if="profile.isCat" v-model="profile.speakAsCat">{{ i18n.ts.flagSpeakAsCat }}<template #caption>{{ i18n.ts.flagSpeakAsCatDescription }}</template></MkSwitch>
|
||||||
<MkSwitch v-model="profile.isBot">{{ i18n.ts.flagAsBot }}<template #caption>{{ i18n.ts.flagAsBotDescription }}</template></MkSwitch>
|
<MkSwitch v-model="profile.isBot">{{ i18n.ts.flagAsBot }}<template #caption>{{ i18n.ts.flagAsBotDescription }}</template></MkSwitch>
|
||||||
</div>
|
</div>
|
||||||
</MkFolder>
|
</MkFolder>
|
||||||
|
@ -141,6 +142,7 @@ const profile = reactive({
|
||||||
lang: $i.lang,
|
lang: $i.lang,
|
||||||
isBot: $i.isBot,
|
isBot: $i.isBot,
|
||||||
isCat: $i.isCat,
|
isCat: $i.isCat,
|
||||||
|
speakAsCat: $i.speakAsCat,
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(() => profile, () => {
|
watch(() => profile, () => {
|
||||||
|
@ -190,6 +192,7 @@ function save() {
|
||||||
lang: profile.lang || null,
|
lang: profile.lang || null,
|
||||||
isBot: !!profile.isBot,
|
isBot: !!profile.isBot,
|
||||||
isCat: !!profile.isCat,
|
isCat: !!profile.isCat,
|
||||||
|
speakAsCat: !!profile.speakAsCat,
|
||||||
});
|
});
|
||||||
claimAchievement('profileFilled');
|
claimAchievement('profileFilled');
|
||||||
if (profile.name === 'syuilo' || profile.name === 'しゅいろ') {
|
if (profile.name === 'syuilo' || profile.name === 'しゅいろ') {
|
||||||
|
|
|
@ -13,6 +13,7 @@ namespace MisskeyEntity {
|
||||||
isModerator: boolean
|
isModerator: boolean
|
||||||
isBot: boolean
|
isBot: boolean
|
||||||
isCat: boolean
|
isCat: boolean
|
||||||
|
speakAsCat: boolean
|
||||||
emojis: Array<Emoji> | { [key: string]: string }
|
emojis: Array<Emoji> | { [key: string]: string }
|
||||||
createdAt: string
|
createdAt: string
|
||||||
bannerUrl: string
|
bannerUrl: string
|
||||||
|
|
|
@ -1541,6 +1541,7 @@ export type Endpoints = {
|
||||||
noCrawle?: boolean;
|
noCrawle?: boolean;
|
||||||
isBot?: boolean;
|
isBot?: boolean;
|
||||||
isCat?: boolean;
|
isCat?: boolean;
|
||||||
|
speakAsCat?: boolean;
|
||||||
injectFeaturedNote?: boolean;
|
injectFeaturedNote?: boolean;
|
||||||
receiveAnnouncementEmail?: boolean;
|
receiveAnnouncementEmail?: boolean;
|
||||||
alwaysMarkNsfw?: boolean;
|
alwaysMarkNsfw?: boolean;
|
||||||
|
@ -2915,6 +2916,7 @@ type UserDetailed = UserLite & {
|
||||||
isBlocking: boolean;
|
isBlocking: boolean;
|
||||||
isBot: boolean;
|
isBot: boolean;
|
||||||
isCat: boolean;
|
isCat: boolean;
|
||||||
|
speakAsCat: boolean;
|
||||||
isFollowed: boolean;
|
isFollowed: boolean;
|
||||||
isFollowing: boolean;
|
isFollowing: boolean;
|
||||||
isLocked: boolean;
|
isLocked: boolean;
|
||||||
|
|
|
@ -426,6 +426,7 @@ export type Endpoints = {
|
||||||
noCrawle?: boolean;
|
noCrawle?: boolean;
|
||||||
isBot?: boolean;
|
isBot?: boolean;
|
||||||
isCat?: boolean;
|
isCat?: boolean;
|
||||||
|
speakAsCat?: boolean;
|
||||||
injectFeaturedNote?: boolean;
|
injectFeaturedNote?: boolean;
|
||||||
receiveAnnouncementEmail?: boolean;
|
receiveAnnouncementEmail?: boolean;
|
||||||
alwaysMarkNsfw?: boolean;
|
alwaysMarkNsfw?: boolean;
|
||||||
|
|
|
@ -50,6 +50,7 @@ export type UserDetailed = UserLite & {
|
||||||
isBlocking: boolean;
|
isBlocking: boolean;
|
||||||
isBot: boolean;
|
isBot: boolean;
|
||||||
isCat: boolean;
|
isCat: boolean;
|
||||||
|
speakAsCat: boolean;
|
||||||
isFollowed: boolean;
|
isFollowed: boolean;
|
||||||
isFollowing: boolean;
|
isFollowing: boolean;
|
||||||
isLocked: boolean;
|
isLocked: boolean;
|
||||||
|
|
Loading…
Reference in a new issue