Feat:ゴリラモード
This commit is contained in:
parent
10d38335f2
commit
5335e68bde
2
locales/index.d.ts
vendored
2
locales/index.d.ts
vendored
|
@ -175,7 +175,9 @@ export interface Locale {
|
||||||
"flagAsBot": string;
|
"flagAsBot": string;
|
||||||
"flagAsBotDescription": string;
|
"flagAsBotDescription": string;
|
||||||
"flagAsCat": string;
|
"flagAsCat": string;
|
||||||
|
"flagAsGorilla": string;
|
||||||
"flagAsCatDescription": string;
|
"flagAsCatDescription": string;
|
||||||
|
"flagAsGorillaDescription": string;
|
||||||
"flagShowTimelineReplies": string;
|
"flagShowTimelineReplies": string;
|
||||||
"showMediaTimeline": string;
|
"showMediaTimeline": string;
|
||||||
"showMediaTimelineInfo": string;
|
"showMediaTimelineInfo": string;
|
||||||
|
|
|
@ -172,7 +172,9 @@ cacheRemoteSensitiveFilesDescription: "この設定を無効にすると、リ
|
||||||
flagAsBot: "Botとして設定"
|
flagAsBot: "Botとして設定"
|
||||||
flagAsBotDescription: "このアカウントがプログラムによって運用される場合は、このフラグをオンにします。オンにすると、反応の連鎖を防ぐためのフラグとして他の開発者に役立ったり、Misskeyのシステム上での扱いがBotに合ったものになります。"
|
flagAsBotDescription: "このアカウントがプログラムによって運用される場合は、このフラグをオンにします。オンにすると、反応の連鎖を防ぐためのフラグとして他の開発者に役立ったり、Misskeyのシステム上での扱いがBotに合ったものになります。"
|
||||||
flagAsCat: "にゃああああああああああああああ!!!!!!!!!!!!"
|
flagAsCat: "にゃああああああああああああああ!!!!!!!!!!!!"
|
||||||
|
flagAsGorilla: "ウホウホウホホウホウホウホウホホホ!!!!!!!!!!!"
|
||||||
flagAsCatDescription: "にゃにゃにゃ??"
|
flagAsCatDescription: "にゃにゃにゃ??"
|
||||||
|
flagAsGorillaDescription: "ウホウホウホ??"
|
||||||
flagShowTimelineReplies: "タイムラインにノートへの返信を表示する"
|
flagShowTimelineReplies: "タイムラインにノートへの返信を表示する"
|
||||||
showMediaTimeline: "メディアタイムラインを表示する"
|
showMediaTimeline: "メディアタイムラインを表示する"
|
||||||
showMediaTimelineInfo: "オンにするとメディアタイムラインを上のバーに表示します。 オフにすると表示しなくなります。"
|
showMediaTimelineInfo: "オンにするとメディアタイムラインを上のバーに表示します。 オフにすると表示しなくなります。"
|
||||||
|
|
|
@ -224,6 +224,7 @@ export class NoteCreateService implements OnApplicationShutdown {
|
||||||
host: MiUser['host'];
|
host: MiUser['host'];
|
||||||
isBot: MiUser['isBot'];
|
isBot: MiUser['isBot'];
|
||||||
isCat: MiUser['isCat'];
|
isCat: MiUser['isCat'];
|
||||||
|
isGorilla: MiUser['isGorilla'];
|
||||||
}, data: Option, silent = false): Promise<MiNote> {
|
}, data: Option, silent = false): Promise<MiNote> {
|
||||||
// チャンネル外にリプライしたら対象のスコープに合わせる
|
// チャンネル外にリプライしたら対象のスコープに合わせる
|
||||||
// (クライアントサイドでやっても良い処理だと思うけどとりあえずサーバーサイドで)
|
// (クライアントサイドでやっても良い処理だと思うけどとりあえずサーバーサイドで)
|
||||||
|
|
|
@ -366,6 +366,7 @@ export class UserEntityService implements OnModuleInit {
|
||||||
}))) : [],
|
}))) : [],
|
||||||
isBot: user.isBot,
|
isBot: user.isBot,
|
||||||
isCat: user.isCat,
|
isCat: user.isCat,
|
||||||
|
isGorilla: user.isGorilla,
|
||||||
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,
|
||||||
|
|
|
@ -177,6 +177,12 @@ export class MiUser {
|
||||||
})
|
})
|
||||||
public isCat: boolean;
|
public isCat: boolean;
|
||||||
|
|
||||||
|
@Column('boolean', {
|
||||||
|
default: false,
|
||||||
|
comment: 'Whether the User is a gorilla.',
|
||||||
|
})
|
||||||
|
public isGorilla: boolean;
|
||||||
|
|
||||||
@Column('boolean', {
|
@Column('boolean', {
|
||||||
default: false,
|
default: false,
|
||||||
comment: 'Whether the User is the root.',
|
comment: 'Whether the User is the root.',
|
||||||
|
|
|
@ -83,6 +83,10 @@ export const packedUserLiteSchema = {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
nullable: false, optional: true,
|
nullable: false, optional: true,
|
||||||
},
|
},
|
||||||
|
isGorilla: {
|
||||||
|
type: 'boolean',
|
||||||
|
nullable: false, optional: true,
|
||||||
|
},
|
||||||
onlineStatus: {
|
onlineStatus: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
format: 'url',
|
format: 'url',
|
||||||
|
|
|
@ -165,6 +165,7 @@ export const paramDef = {
|
||||||
preventAiLearning: { type: 'boolean' },
|
preventAiLearning: { type: 'boolean' },
|
||||||
isBot: { type: 'boolean' },
|
isBot: { type: 'boolean' },
|
||||||
isCat: { type: 'boolean' },
|
isCat: { type: 'boolean' },
|
||||||
|
isGorilla: { type: 'boolean' },
|
||||||
injectFeaturedNote: { type: 'boolean' },
|
injectFeaturedNote: { type: 'boolean' },
|
||||||
receiveAnnouncementEmail: { type: 'boolean' },
|
receiveAnnouncementEmail: { type: 'boolean' },
|
||||||
alwaysMarkNsfw: { type: 'boolean' },
|
alwaysMarkNsfw: { type: 'boolean' },
|
||||||
|
@ -267,7 +268,12 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||||
if (typeof ps.autoAcceptFollowed === 'boolean') profileUpdates.autoAcceptFollowed = ps.autoAcceptFollowed;
|
if (typeof ps.autoAcceptFollowed === 'boolean') profileUpdates.autoAcceptFollowed = ps.autoAcceptFollowed;
|
||||||
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' && !ps.isGorilla) {
|
||||||
|
updates.isCat = ps.isCat;
|
||||||
|
};
|
||||||
|
if (typeof ps.isGorilla === 'boolean' && !ps.isCat) {
|
||||||
|
updates.isGorilla = ps.isGorilla
|
||||||
|
};
|
||||||
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') {
|
||||||
|
|
|
@ -16,6 +16,8 @@ import { defaultStore } from '@/store';
|
||||||
import { mixEmoji } from '@/scripts/emojiKitchen/emojiMixer';
|
import { mixEmoji } from '@/scripts/emojiKitchen/emojiMixer';
|
||||||
import MkRuby from "@/components/global/MkRuby.vue";
|
import MkRuby from "@/components/global/MkRuby.vue";
|
||||||
import { nyaize as doNyaize } from '@/scripts/nyaize.js';
|
import { nyaize as doNyaize } from '@/scripts/nyaize.js';
|
||||||
|
import { uhoize as doUhoize } from '@/scripts/uhoize.js';
|
||||||
|
import {ID, Instance} from "misskey-js/built/entities.js";
|
||||||
|
|
||||||
const QUOTE_STYLE = `
|
const QUOTE_STYLE = `
|
||||||
display: block;
|
display: block;
|
||||||
|
@ -62,12 +64,41 @@ type MfmProps = {
|
||||||
text: string;
|
text: string;
|
||||||
plain?: boolean;
|
plain?: boolean;
|
||||||
nowrap?: boolean;
|
nowrap?: boolean;
|
||||||
author?: Misskey.entities.UserLite;
|
author?: {
|
||||||
|
id: ID;
|
||||||
|
username: string;
|
||||||
|
host: string | null;
|
||||||
|
name: string | null;
|
||||||
|
onlineStatus: 'online' | 'active' | 'offline' | 'unknown';
|
||||||
|
avatarUrl: string;
|
||||||
|
avatarBlurhash: string;
|
||||||
|
avatarDecorations: {
|
||||||
|
id: ID;
|
||||||
|
url: string;
|
||||||
|
angle?: number;
|
||||||
|
flipH?: boolean;
|
||||||
|
}[];
|
||||||
|
emojis: {
|
||||||
|
name: string;
|
||||||
|
url: string;
|
||||||
|
}[];
|
||||||
|
instance?: {
|
||||||
|
name: Instance['name'];
|
||||||
|
softwareName: Instance['softwareName'];
|
||||||
|
softwareVersion: Instance['softwareVersion'];
|
||||||
|
iconUrl: Instance['iconUrl'];
|
||||||
|
faviconUrl: Instance['faviconUrl'];
|
||||||
|
themeColor: Instance['themeColor'];
|
||||||
|
};
|
||||||
|
isGorilla?: boolean;
|
||||||
|
isCat?: boolean;
|
||||||
|
isBot?: boolean;};
|
||||||
i?: Misskey.entities.UserLite | null;
|
i?: Misskey.entities.UserLite | null;
|
||||||
isNote?: boolean;
|
isNote?: boolean;
|
||||||
emojiUrls?: string[];
|
emojiUrls?: string[];
|
||||||
rootScale?: number;
|
rootScale?: number;
|
||||||
nyaize: boolean | 'account';
|
nyaize: boolean | 'account';
|
||||||
|
uhoize: boolean | 'account';
|
||||||
parsedNodes?: mfm.MfmNode[] | null;
|
parsedNodes?: mfm.MfmNode[] | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -75,7 +106,8 @@ type MfmProps = {
|
||||||
export default function(props: MfmProps) {
|
export default function(props: MfmProps) {
|
||||||
const isNote = props.isNote ?? true;
|
const isNote = props.isNote ?? true;
|
||||||
const shouldNyaize = props.nyaize ? props.nyaize === 'account' ? props.author?.isCat : false : false;
|
const shouldNyaize = props.nyaize ? props.nyaize === 'account' ? props.author?.isCat : false : false;
|
||||||
|
const shouldUhoize = props.nyaize ? props.nyaize === 'account' ? props.author?.isGorilla : false : false;
|
||||||
|
console.log(shouldUhoize, props.nyaize,props.author?.isGorilla)
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||||
if (props.text == null || props.text === '') return;
|
if (props.text == null || props.text === '') return;
|
||||||
|
|
||||||
|
@ -93,15 +125,18 @@ export default function(props: MfmProps) {
|
||||||
* @param ast MFM AST
|
* @param ast MFM AST
|
||||||
* @param scale How times large the text is
|
* @param scale How times large the text is
|
||||||
* @param disableNyaize Whether nyaize is disabled or not
|
* @param disableNyaize Whether nyaize is disabled or not
|
||||||
|
* @param disableUhoize
|
||||||
*/
|
*/
|
||||||
const genEl = (ast: mfm.MfmNode[], scale: number, disableNyaize = false) => ast.map((token): VNode | string | (VNode | string)[] => {
|
const genEl = (ast: mfm.MfmNode[], scale: number, disableNyaize = false, disableUhoize = false) => ast.map((token): VNode | string | (VNode | string)[] => {
|
||||||
switch (token.type) {
|
switch (token.type) {
|
||||||
case 'text': {
|
case 'text': {
|
||||||
let text = token.props.text.replace(/(\r\n|\n|\r)/g, '\n');
|
let text = token.props.text.replace(/(\r\n|\n|\r)/g, '\n');
|
||||||
if (!disableNyaize && shouldNyaize) {
|
if (!disableNyaize && shouldNyaize) {
|
||||||
text = doNyaize(text);
|
text = doNyaize(text);
|
||||||
}
|
}
|
||||||
|
if (!disableUhoize && shouldUhoize) {
|
||||||
|
text = doUhoize(text);
|
||||||
|
}
|
||||||
if (!props.plain) {
|
if (!props.plain) {
|
||||||
const res: (VNode | string)[] = [];
|
const res: (VNode | string)[] = [];
|
||||||
for (const t of text.split('\n')) {
|
for (const t of text.split('\n')) {
|
||||||
|
|
|
@ -105,7 +105,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<template #label>{{ i18n.ts.advancedSettings }}</template>
|
<template #label>{{ i18n.ts.advancedSettings }}</template>
|
||||||
|
|
||||||
<div class="_gaps_m">
|
<div class="_gaps_m">
|
||||||
<MkSwitch v-model="profile.isCat">{{ i18n.ts.flagAsCat }}<template #caption>{{ i18n.ts.flagAsCatDescription }}</template></MkSwitch>
|
<MkSwitch :disabled="profile.isGorilla" v-model="profile.isCat">{{ i18n.ts.flagAsCat }}<template #caption>{{ i18n.ts.flagAsCatDescription }}</template></MkSwitch>
|
||||||
|
<MkSwitch :disabled="profile.isCat" v-model="profile.isGorilla">{{ i18n.ts.flagAsGorilla }}<template #caption>{{ i18n.ts.flagAsGorillaDescription }}</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>
|
||||||
|
@ -154,6 +155,7 @@ const profile = reactive({
|
||||||
lang: $i.lang,
|
lang: $i.lang,
|
||||||
isBot: $i.isBot,
|
isBot: $i.isBot,
|
||||||
isCat: $i.isCat,
|
isCat: $i.isCat,
|
||||||
|
isGorilla: $i.isGorilla,
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(() => profile, () => {
|
watch(() => profile, () => {
|
||||||
|
@ -206,6 +208,7 @@ function save() {
|
||||||
lang: profile.lang || null,
|
lang: profile.lang || null,
|
||||||
isBot: !!profile.isBot,
|
isBot: !!profile.isBot,
|
||||||
isCat: !!profile.isCat,
|
isCat: !!profile.isCat,
|
||||||
|
isGorilla: !!profile.isGorilla,
|
||||||
});
|
});
|
||||||
claimAchievement('profileFilled');
|
claimAchievement('profileFilled');
|
||||||
if (profile.name === 'syuilo' || profile.name === 'しゅいろ') {
|
if (profile.name === 'syuilo' || profile.name === 'しゅいろ') {
|
||||||
|
@ -214,6 +217,9 @@ function save() {
|
||||||
if (profile.isCat) {
|
if (profile.isCat) {
|
||||||
claimAchievement('markedAsCat');
|
claimAchievement('markedAsCat');
|
||||||
}
|
}
|
||||||
|
if (profile.isGorilla) {
|
||||||
|
claimAchievement('markedAsCat');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeAvatar(ev) {
|
function changeAvatar(ev) {
|
||||||
|
|
|
@ -265,6 +265,11 @@ export const ACHIEVEMENT_BADGES = {
|
||||||
bg: 'linear-gradient(0deg, rgb(187 183 59), rgb(255 143 77))',
|
bg: 'linear-gradient(0deg, rgb(187 183 59), rgb(255 143 77))',
|
||||||
frame: 'bronze',
|
frame: 'bronze',
|
||||||
},
|
},
|
||||||
|
'markedAsGorilla': {
|
||||||
|
img: '/fluent-emoji/1f98D.png',
|
||||||
|
bg: 'linear-gradient(0deg, rgba(55,0,0,1) 0%, rgba(107,5,5,1) 59%, rgba(158,6,6,1) 100%)',
|
||||||
|
frame: 'bronze',
|
||||||
|
},
|
||||||
'following1': {
|
'following1': {
|
||||||
img: '/fluent-emoji/2618.png',
|
img: '/fluent-emoji/2618.png',
|
||||||
bg: 'linear-gradient(0deg, rgb(59 187 116), rgb(199 211 102))',
|
bg: 'linear-gradient(0deg, rgb(59 187 116), rgb(199 211 102))',
|
||||||
|
|
28
packages/frontend/src/scripts/uhoize.ts
Normal file
28
packages/frontend/src/scripts/uhoize.ts
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: syuilo and other misskey contributors
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
export function uhoize(text) {
|
||||||
|
const gorillaNoises = ['ウホ', 'ウホホ', 'ウホッ'];
|
||||||
|
let result = '';
|
||||||
|
let noiseIndex = 0;
|
||||||
|
for (let i = 0; i < text.length; i++) {
|
||||||
|
if (!(/[、。.,\/#!$%\^&\*;:{}=\-_`~()]/.test(text[i]))) {
|
||||||
|
if (/[^\x00-\x7F]/.test(text[i])) {
|
||||||
|
noiseIndex = Math.floor(Math.random() * 3);
|
||||||
|
const japaneseNoises = ['ウホ', 'ウホホ', 'ウホッ'];
|
||||||
|
result += japaneseNoises[noiseIndex];
|
||||||
|
} else {
|
||||||
|
noiseIndex = Math.floor(Math.random() * 2);
|
||||||
|
const englishNoises = ['uho', 'uhoho'];
|
||||||
|
result += englishNoises[noiseIndex];
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
result += text[i];
|
||||||
|
}
|
||||||
|
if (text.length*1.3 < result.length) return result
|
||||||
|
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
|
@ -2951,6 +2951,7 @@ type UserDetailed = UserLite & {
|
||||||
isBlocking: boolean;
|
isBlocking: boolean;
|
||||||
isBot: boolean;
|
isBot: boolean;
|
||||||
isCat: boolean;
|
isCat: boolean;
|
||||||
|
isGorilla: boolean;
|
||||||
isFollowed: boolean;
|
isFollowed: boolean;
|
||||||
isFollowing: boolean;
|
isFollowing: boolean;
|
||||||
isLocked: boolean;
|
isLocked: boolean;
|
||||||
|
@ -3014,6 +3015,7 @@ type UserLite = {
|
||||||
faviconUrl: Instance['faviconUrl'];
|
faviconUrl: Instance['faviconUrl'];
|
||||||
themeColor: Instance['themeColor'];
|
themeColor: Instance['themeColor'];
|
||||||
};
|
};
|
||||||
|
isGorilla?: boolean;
|
||||||
isCat?: boolean;
|
isCat?: boolean;
|
||||||
isBot?: boolean;
|
isBot?: boolean;
|
||||||
};
|
};
|
||||||
|
@ -3026,8 +3028,8 @@ type UserSorting = '+follower' | '-follower' | '+createdAt' | '-createdAt' | '+u
|
||||||
// src/api.types.ts:16:32 - (ae-forgotten-export) The symbol "TODO" needs to be exported by the entry point index.d.ts
|
// src/api.types.ts:16:32 - (ae-forgotten-export) The symbol "TODO" needs to be exported by the entry point index.d.ts
|
||||||
// src/api.types.ts:18:25 - (ae-forgotten-export) The symbol "NoParams" needs to be exported by the entry point index.d.ts
|
// src/api.types.ts:18:25 - (ae-forgotten-export) The symbol "NoParams" needs to be exported by the entry point index.d.ts
|
||||||
// src/api.types.ts:633:18 - (ae-forgotten-export) The symbol "ShowUserReq" needs to be exported by the entry point index.d.ts
|
// src/api.types.ts:633:18 - (ae-forgotten-export) The symbol "ShowUserReq" needs to be exported by the entry point index.d.ts
|
||||||
// src/entities.ts:116:2 - (ae-forgotten-export) The symbol "notificationTypes_2" needs to be exported by the entry point index.d.ts
|
// src/entities.ts:118:2 - (ae-forgotten-export) The symbol "notificationTypes_2" needs to be exported by the entry point index.d.ts
|
||||||
// src/entities.ts:614:2 - (ae-forgotten-export) The symbol "ModerationLogPayloads" needs to be exported by the entry point index.d.ts
|
// src/entities.ts:616:2 - (ae-forgotten-export) The symbol "ModerationLogPayloads" needs to be exported by the entry point index.d.ts
|
||||||
// src/streaming.types.ts:33:4 - (ae-forgotten-export) The symbol "FIXME" needs to be exported by the entry point index.d.ts
|
// src/streaming.types.ts:33:4 - (ae-forgotten-export) The symbol "FIXME" needs to be exported by the entry point index.d.ts
|
||||||
|
|
||||||
// (No @packageDocumentation comment for this package)
|
// (No @packageDocumentation comment for this package)
|
||||||
|
|
|
@ -34,6 +34,7 @@ export type UserLite = {
|
||||||
faviconUrl: Instance['faviconUrl'];
|
faviconUrl: Instance['faviconUrl'];
|
||||||
themeColor: Instance['themeColor'];
|
themeColor: Instance['themeColor'];
|
||||||
};
|
};
|
||||||
|
isGorilla?: boolean;
|
||||||
isCat?: boolean;
|
isCat?: boolean;
|
||||||
isBot?: boolean;
|
isBot?: boolean;
|
||||||
};
|
};
|
||||||
|
@ -58,6 +59,7 @@ export type UserDetailed = UserLite & {
|
||||||
isBlocking: boolean;
|
isBlocking: boolean;
|
||||||
isBot: boolean;
|
isBot: boolean;
|
||||||
isCat: boolean;
|
isCat: boolean;
|
||||||
|
isGorilla: boolean;
|
||||||
isFollowed: boolean;
|
isFollowed: boolean;
|
||||||
isFollowing: boolean;
|
isFollowing: boolean;
|
||||||
isLocked: boolean;
|
isLocked: boolean;
|
||||||
|
|
Loading…
Reference in a new issue