ported $[small ] and $[center ] from firefish #60
19 changed files with 80 additions and 5 deletions
|
@ -175,6 +175,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."
|
||||
flagAsCat: "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. If this isn't working, then please check that you dont have 'Disable cat speak' on under General/Note Display"
|
||||
flagShowTimelineReplies: "Show replies in timeline"
|
||||
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"
|
||||
|
@ -762,6 +764,7 @@ noCrawleDescription: "Ask search engines to not index your profile page, notes,
|
|||
lockedAccountInfo: "Unless you set your note visiblity to \"Followers only\", your notes will be visible to anyone, even if you require followers to be manually approved."
|
||||
alwaysMarkSensitive: "Mark as sensitive by default"
|
||||
loadRawImages: "Load original images instead of showing thumbnails"
|
||||
disableCatSpeak: "Disable cat speak"
|
||||
disableShowingAnimatedImages: "Don't play animated images"
|
||||
highlightSensitiveMedia: "Highlight sensitive media"
|
||||
verificationEmailSent: "A verification email has been sent. Please follow the included link to complete verification."
|
||||
|
|
12
locales/index.d.ts
vendored
12
locales/index.d.ts
vendored
|
@ -724,6 +724,14 @@ export interface Locale extends ILocale {
|
|||
* にゃにゃにゃ??
|
||||
*/
|
||||
"flagAsCatDescription": string;
|
||||
/**
|
||||
* 猫語で話す
|
||||
*/
|
||||
"flagSpeakAsCat": string;
|
||||
/**
|
||||
* 有効にすると、あなたの投稿の 「な」を「にゃ」にします。
|
||||
*/
|
||||
"flagSpeakAsCatDescription": string;
|
||||
/**
|
||||
* タイムラインにノートへの返信を表示する
|
||||
*/
|
||||
|
@ -3064,6 +3072,10 @@ export interface Locale extends ILocale {
|
|||
* 添付画像のサムネイルをオリジナル画質にする
|
||||
*/
|
||||
"loadRawImages": string;
|
||||
/**
|
||||
* 猫の話し方を無効にする
|
||||
*/
|
||||
"disableCatSpeak": string;
|
||||
/**
|
||||
* アニメーション画像を再生しない
|
||||
*/
|
||||
|
|
|
@ -177,6 +177,8 @@ flagAsBot: "Botとして設定"
|
|||
flagAsBotDescription: "このアカウントがプログラムによって運用される場合は、このフラグをオンにします。オンにすると、反応の連鎖を防ぐためのフラグとして他の開発者に役立ったり、Misskeyのシステム上での扱いがBotに合ったものになります。"
|
||||
flagAsCat: "にゃああああああああああああああ!!!!!!!!!!!!"
|
||||
flagAsCatDescription: "にゃにゃにゃ??"
|
||||
flagSpeakAsCat: "猫語で話す"
|
||||
flagSpeakAsCatDescription: "有効にすると、あなたの投稿の 「な」を「にゃ」にします。"
|
||||
flagShowTimelineReplies: "タイムラインにノートへの返信を表示する"
|
||||
flagShowTimelineRepliesDescription: "オンにすると、タイムラインにユーザーのノート以外にもそのユーザーの他のノートへの返信を表示します。"
|
||||
autoAcceptFollowed: "フォロー中ユーザーからのフォロリクを自動承認"
|
||||
|
@ -762,6 +764,7 @@ noCrawleDescription: "外部の検索エンジンにあなたのユーザーペ
|
|||
lockedAccountInfo: "フォローを承認制にしても、ノートの公開範囲を「フォロワー」にしない限り、誰でもあなたのノートを見ることができます。"
|
||||
alwaysMarkSensitive: "デフォルトでメディアをセンシティブ設定にする"
|
||||
loadRawImages: "添付画像のサムネイルをオリジナル画質にする"
|
||||
disableCatSpeak: "猫の話し方を無効にする"
|
||||
disableShowingAnimatedImages: "アニメーション画像を再生しない"
|
||||
highlightSensitiveMedia: "メディアがセンシティブであることを分かりやすく表示"
|
||||
verificationEmailSent: "確認のメールを送信しました。メールに記載されたリンクにアクセスして、設定を完了してください。"
|
||||
|
|
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"`);
|
||||
}
|
||||
}
|
|
@ -518,6 +518,7 @@ export class ApRendererService {
|
|||
discoverable: user.isExplorable,
|
||||
publicKey: this.renderKey(user, keypair, '#main-key'),
|
||||
isCat: user.isCat,
|
||||
speakAsCat: user.speakAsCat,
|
||||
attachment: attachment.length ? attachment : undefined,
|
||||
};
|
||||
|
||||
|
|
|
@ -553,6 +553,9 @@ export const CONTEXTS: (string | Context)[] = [
|
|||
'_misskey_votes': 'misskey:_misskey_votes',
|
||||
'_misskey_summary': 'misskey:_misskey_summary',
|
||||
'isCat': 'misskey:isCat',
|
||||
// Firefish
|
||||
firefish: "https://joinfirefish.org/ns#",
|
||||
speakAsCat: "firefish:speakAsCat",
|
||||
// vcard
|
||||
vcard: 'http://www.w3.org/2006/vcard/ns#',
|
||||
} satisfies Context,
|
||||
|
|
|
@ -389,6 +389,7 @@ export class ApPersonService implements OnModuleInit {
|
|||
tags,
|
||||
isBot,
|
||||
isCat: (person as any).isCat === true,
|
||||
speakAsCat: (person as any).speakAsCat != null ? (person as any).speakAsCat === true : (person as any).isCat === true,
|
||||
emojis,
|
||||
})) as MiRemoteUser;
|
||||
|
||||
|
@ -562,12 +563,13 @@ export class ApPersonService implements OnModuleInit {
|
|||
tags,
|
||||
isBot: getApType(object) === 'Service' || getApType(object) === 'Application',
|
||||
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,
|
||||
movedToUri: person.movedTo ?? null,
|
||||
alsoKnownAs: person.alsoKnownAs ?? null,
|
||||
isExplorable: person.discoverable,
|
||||
...((policy.canUpdateAvatar || policy.canUpdateBanner) ? await this.resolveAvatarAndBanner(exist, policy.canUpdateAvatar ? person.icon : exist.avatarUrl, policy.canUpdateBanner ? person.image : exist.bannerUrl).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 => {
|
||||
// 移行先がない→ある
|
||||
|
|
|
@ -489,6 +489,7 @@ export class UserEntityService implements OnModuleInit {
|
|||
}))) : [],
|
||||
isBot: user.isBot,
|
||||
isCat: user.isCat,
|
||||
speakAsCat: user.speakAsCat,
|
||||
instance: user.host ? this.federatedInstanceService.federatedInstanceCache.fetch(user.host).then(instance => instance ? {
|
||||
name: instance.name,
|
||||
softwareName: instance.softwareName,
|
||||
|
|
|
@ -186,6 +186,12 @@ export class MiUser {
|
|||
})
|
||||
public isCat: boolean;
|
||||
|
||||
@Column('boolean', {
|
||||
default: false,
|
||||
comment: 'Whether the User speaks in nya.',
|
||||
})
|
||||
public speakAsCat: boolean;
|
||||
|
||||
@Column('boolean', {
|
||||
default: false,
|
||||
comment: 'Whether the User is the root.',
|
||||
|
|
|
@ -115,6 +115,10 @@ export const packedUserLiteSchema = {
|
|||
type: 'boolean',
|
||||
nullable: false, optional: true,
|
||||
},
|
||||
speakAsCat: {
|
||||
type: 'boolean',
|
||||
nullable: false, optional: true,
|
||||
},
|
||||
instance: {
|
||||
type: 'object',
|
||||
nullable: false, optional: true,
|
||||
|
|
|
@ -187,6 +187,7 @@ export const paramDef = {
|
|||
preventAiLearning: { type: 'boolean' },
|
||||
isBot: { type: 'boolean' },
|
||||
isCat: { type: 'boolean' },
|
||||
speakAsCat: { type: 'boolean' },
|
||||
injectFeaturedNote: { type: 'boolean' },
|
||||
receiveAnnouncementEmail: { type: 'boolean' },
|
||||
alwaysMarkNsfw: { type: 'boolean' },
|
||||
|
@ -341,6 +342,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
if (typeof ps.noCrawle === 'boolean') profileUpdates.noCrawle = ps.noCrawle;
|
||||
if (typeof ps.preventAiLearning === 'boolean') profileUpdates.preventAiLearning = ps.preventAiLearning;
|
||||
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.receiveAnnouncementEmail === 'boolean') profileUpdates.receiveAnnouncementEmail = ps.receiveAnnouncementEmail;
|
||||
if (typeof ps.alwaysMarkNsfw === 'boolean') {
|
||||
|
|
|
@ -40,6 +40,7 @@ describe('ユーザー', () => {
|
|||
avatarDecorations: user.avatarDecorations,
|
||||
isBot: user.isBot,
|
||||
isCat: user.isCat,
|
||||
speakAsCat: user.speakAsCat,
|
||||
instance: user.instance,
|
||||
emojis: user.emojis,
|
||||
onlineStatus: user.onlineStatus,
|
||||
|
@ -311,6 +312,7 @@ describe('ユーザー', () => {
|
|||
assert.deepStrictEqual(response.avatarDecorations, []);
|
||||
assert.strictEqual(response.isBot, false);
|
||||
assert.strictEqual(response.isCat, false);
|
||||
assert.strictEqual(response.speakAsCat, false);
|
||||
assert.strictEqual(response.instance, undefined);
|
||||
assert.deepStrictEqual(response.emojis, {});
|
||||
assert.strictEqual(response.onlineStatus, 'unknown');
|
||||
|
@ -446,6 +448,8 @@ describe('ユーザー', () => {
|
|||
{ parameters: () => ({ isBot: false }) },
|
||||
{ parameters: () => ({ isCat: true }) },
|
||||
{ parameters: () => ({ isCat: false }) },
|
||||
{ parameters: () => ({ speakAsCat: true }) },
|
||||
{ parameters: () => ({ speakAsCat: false }) },
|
||||
{ parameters: () => ({ injectFeaturedNote: true }) },
|
||||
{ parameters: () => ({ injectFeaturedNote: false }) },
|
||||
{ parameters: () => ({ receiveAnnouncementEmail: true }) },
|
||||
|
|
|
@ -100,6 +100,7 @@ export function userDetailed(id = 'someuserid', username = 'miskist', host = 'mi
|
|||
isBlocking: false,
|
||||
isBot: false,
|
||||
isCat: false,
|
||||
speakAsCat: false,
|
||||
isFollowed: false,
|
||||
isFollowing: false,
|
||||
isLocked: false,
|
||||
|
|
|
@ -55,7 +55,7 @@ export default function (props: MfmProps, { emit }: { emit: SetupContext<MfmEven
|
|||
provide('linkNavigationBehavior', props.linkNavigationBehavior);
|
||||
|
||||
const isNote = props.isNote ?? true;
|
||||
const shouldNyaize = props.nyaize ? props.nyaize === 'respect' ? props.author?.isCat : false : false;
|
||||
const shouldNyaize = props.nyaize === 'respect' && props.author?.isCat && props.author?.speakAsCat && !defaultStore.state.disableCatSpeak;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||
if (props.text == null || props.text === '') return;
|
||||
|
|
|
@ -63,6 +63,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<MkSwitch v-model="showReactionsCount">{{ i18n.ts.showReactionsCount }}</MkSwitch>
|
||||
<MkSwitch v-model="showGapBetweenNotesInTimeline">{{ i18n.ts.showGapBetweenNotesInTimeline }}</MkSwitch>
|
||||
<MkSwitch v-model="loadRawImages">{{ i18n.ts.loadRawImages }}</MkSwitch>
|
||||
<MkSwitch v-model="disableCatSpeak">{{ i18n.ts.disableCatSpeak }}</MkSwitch>
|
||||
<MkRadios v-model="reactionsDisplaySize">
|
||||
<template #label>{{ i18n.ts.reactionsDisplaySize }}</template>
|
||||
<option value="small">{{ i18n.ts.small }}</option>
|
||||
|
@ -299,6 +300,7 @@ const disableDrawer = computed(defaultStore.makeGetterSetter('disableDrawer'));
|
|||
const disableShowingAnimatedImages = computed(defaultStore.makeGetterSetter('disableShowingAnimatedImages'));
|
||||
const forceShowAds = computed(defaultStore.makeGetterSetter('forceShowAds'));
|
||||
const loadRawImages = computed(defaultStore.makeGetterSetter('loadRawImages'));
|
||||
const disableCatSpeak = computed(defaultStore.makeGetterSetter('disableCatSpeak'));
|
||||
const highlightSensitiveMedia = computed(defaultStore.makeGetterSetter('highlightSensitiveMedia'));
|
||||
const imageNewTab = computed(defaultStore.makeGetterSetter('imageNewTab'));
|
||||
const warnMissingAltText = computed(defaultStore.makeGetterSetter('warnMissingAltText'));
|
||||
|
|
|
@ -78,6 +78,7 @@ const defaultStoreSaveKeys: (keyof typeof defaultStore['state'])[] = [
|
|||
'warnMissingAltText',
|
||||
'imageNewTab',
|
||||
'dataSaver',
|
||||
'disableCatSpeak',
|
||||
'disableShowingAnimatedImages',
|
||||
'emojiStyle',
|
||||
'disableDrawer',
|
||||
|
|
|
@ -171,6 +171,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
|
||||
<div class="_gaps_m">
|
||||
<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>
|
||||
</div>
|
||||
</MkFolder>
|
||||
|
@ -220,6 +221,7 @@ const profile = reactive({
|
|||
lang: $i.lang,
|
||||
isBot: $i.isBot ?? false,
|
||||
isCat: $i.isCat ?? false,
|
||||
speakAsCat: $i.speakAsCat ?? false,
|
||||
});
|
||||
|
||||
watch(() => profile, () => {
|
||||
|
@ -304,6 +306,7 @@ function save() {
|
|||
lang: profile.lang || null,
|
||||
isBot: !!profile.isBot,
|
||||
isCat: !!profile.isCat,
|
||||
speakAsCat: !!profile.speakAsCat,
|
||||
});
|
||||
globalEvents.emit('requestClearPageCache');
|
||||
claimAchievement('profileFilled');
|
||||
|
|
|
@ -259,6 +259,10 @@ export const defaultStore = markRaw(new Storage('base', {
|
|||
where: 'device',
|
||||
default: window.matchMedia('(prefers-reduced-motion)').matches,
|
||||
},
|
||||
disableCatSpeak: {
|
||||
where: 'account',
|
||||
default: false,
|
||||
},
|
||||
emojiStyle: {
|
||||
where: 'device',
|
||||
default: 'twemoji', // twemoji / fluentEmoji / native
|
||||
|
|
|
@ -3853,6 +3853,7 @@ export type components = {
|
|||
}[];
|
||||
isBot?: boolean;
|
||||
isCat?: boolean;
|
||||
speakAsCat?: boolean;
|
||||
instance?: {
|
||||
name: string | null;
|
||||
softwareName: string | null;
|
||||
|
@ -4702,7 +4703,7 @@ export type components = {
|
|||
blockee: components['schemas']['UserDetailedNotMe'];
|
||||
};
|
||||
Hashtag: {
|
||||
/** @example misskey */
|
||||
/** @example forkey */
|
||||
tag: string;
|
||||
mentionedUsersCount: number;
|
||||
mentionedLocalUsersCount: number;
|
||||
|
@ -4885,7 +4886,7 @@ export type components = {
|
|||
isNotResponding: boolean;
|
||||
isSuspended: boolean;
|
||||
isBlocked: boolean;
|
||||
/** @example misskey */
|
||||
/** @example forkey */
|
||||
softwareName: string | null;
|
||||
softwareVersion: string | null;
|
||||
/** @example true */
|
||||
|
@ -5239,6 +5240,8 @@ export type components = {
|
|||
enableTurnstile: boolean;
|
||||
turnstileSiteKey: string | null;
|
||||
googleAnalyticsId: string | null;
|
||||
enableFC: boolean;
|
||||
fcSiteKey: string | null;
|
||||
swPublickey: string | null;
|
||||
/** @default /assets/ai.png */
|
||||
mascotImageUrl: string;
|
||||
|
@ -5388,6 +5391,8 @@ export type operations = {
|
|||
enableTurnstile: boolean;
|
||||
turnstileSiteKey: string | null;
|
||||
googleAnalyticsId: string | null;
|
||||
enableFC: boolean;
|
||||
fcSiteKey: string | null;
|
||||
swPublickey: string | null;
|
||||
/** @default /assets/ai.png */
|
||||
mascotImageUrl: string | null;
|
||||
|
@ -5414,6 +5419,7 @@ export type operations = {
|
|||
mcaptchaSecretKey: string | null;
|
||||
recaptchaSecretKey: string | null;
|
||||
turnstileSecretKey: string | null;
|
||||
fcSecretKey: string | null;
|
||||
sensitiveMediaDetection: string;
|
||||
sensitiveMediaDetectionSensitivity: string;
|
||||
setSensitiveFlagAutomatically: boolean;
|
||||
|
@ -10319,6 +10325,9 @@ export type operations = {
|
|||
enableTurnstile?: boolean;
|
||||
turnstileSiteKey?: string | null;
|
||||
turnstileSecretKey?: string | null;
|
||||
enableFC?: boolean;
|
||||
fcSiteKey?: string | null;
|
||||
fcSecretKey?: string | null;
|
||||
googleAnalyticsId?: string | null;
|
||||
/** @enum {string} */
|
||||
sensitiveMediaDetection?: 'none' | 'all' | 'local' | 'remote';
|
||||
|
@ -21747,6 +21756,7 @@ export type operations = {
|
|||
preventAiLearning?: boolean;
|
||||
isBot?: boolean;
|
||||
isCat?: boolean;
|
||||
speakAsCat?: boolean;
|
||||
injectFeaturedNote?: boolean;
|
||||
receiveAnnouncementEmail?: boolean;
|
||||
alwaysMarkNsfw?: boolean;
|
||||
|
@ -30841,3 +30851,4 @@ export type operations = {
|
|||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue