mirror of
https://activitypub.software/TransFem-org/Sharkey
synced 2024-11-22 05:55:12 +00:00
Merge branch 'develop' into hazelnoot/following-timeline
This commit is contained in:
commit
4ca27692ac
28 changed files with 129 additions and 36 deletions
|
@ -144,8 +144,10 @@ markAsSensitive: "Mark as sensitive"
|
||||||
unmarkAsSensitive: "Unmark as sensitive"
|
unmarkAsSensitive: "Unmark as sensitive"
|
||||||
enterFileName: "Enter filename"
|
enterFileName: "Enter filename"
|
||||||
mute: "Mute"
|
mute: "Mute"
|
||||||
|
muted: "Muted"
|
||||||
unmute: "Unmute"
|
unmute: "Unmute"
|
||||||
renoteMute: "Mute Boosts"
|
renoteMute: "Mute Boosts"
|
||||||
|
renoteMuted: "Boosts muted"
|
||||||
renoteUnmute: "Unmute Boosts"
|
renoteUnmute: "Unmute Boosts"
|
||||||
block: "Block"
|
block: "Block"
|
||||||
unblock: "Unblock"
|
unblock: "Unblock"
|
||||||
|
@ -185,7 +187,7 @@ flagAsBotDescription: "Enable this option if this account is controlled by a pro
|
||||||
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"
|
flagSpeakAsCat: "Speak as a cat"
|
||||||
flagSpeakAsCatDescription: "Your posts will get nyanified when in cat mode."
|
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"
|
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"
|
||||||
|
@ -780,6 +782,7 @@ lockedAccountInfo: "Unless you set your note visiblity to \"Followers only\", yo
|
||||||
alwaysMarkSensitive: "Mark as sensitive by default"
|
alwaysMarkSensitive: "Mark as sensitive by default"
|
||||||
loadRawImages: "Load original images instead of showing thumbnails"
|
loadRawImages: "Load original images instead of showing thumbnails"
|
||||||
showTickerOnReplies: "Show instance ticker on replies"
|
showTickerOnReplies: "Show instance ticker on replies"
|
||||||
|
disableCatSpeak: "Disable cat speak"
|
||||||
searchEngine: "Search Engine For Search MFM"
|
searchEngine: "Search Engine For Search MFM"
|
||||||
searchEngineOther: "Other"
|
searchEngineOther: "Other"
|
||||||
searchEngineCustomURIDescription: "The custom URI must be input in the format like \"https://www.google.com/search?q=\\{query}\" or \"https://www.google.com/search?q=%s\"."
|
searchEngineCustomURIDescription: "The custom URI must be input in the format like \"https://www.google.com/search?q=\\{query}\" or \"https://www.google.com/search?q=%s\"."
|
||||||
|
@ -1280,6 +1283,7 @@ detach: "Remove"
|
||||||
detachAll: "Remove All"
|
detachAll: "Remove All"
|
||||||
angle: "Angle"
|
angle: "Angle"
|
||||||
flip: "Flip"
|
flip: "Flip"
|
||||||
|
showBelowAvatar: "Show Below Avatar"
|
||||||
showAvatarDecorations: "Show avatar decorations"
|
showAvatarDecorations: "Show avatar decorations"
|
||||||
releaseToRefresh: "Release to refresh"
|
releaseToRefresh: "Release to refresh"
|
||||||
refreshing: "Refreshing..."
|
refreshing: "Refreshing..."
|
||||||
|
|
20
locales/index.d.ts
vendored
20
locales/index.d.ts
vendored
|
@ -592,6 +592,10 @@ export interface Locale extends ILocale {
|
||||||
* ミュート
|
* ミュート
|
||||||
*/
|
*/
|
||||||
"mute": string;
|
"mute": string;
|
||||||
|
/**
|
||||||
|
* Muted
|
||||||
|
*/
|
||||||
|
"muted": string;
|
||||||
/**
|
/**
|
||||||
* ミュート解除
|
* ミュート解除
|
||||||
*/
|
*/
|
||||||
|
@ -600,6 +604,10 @@ export interface Locale extends ILocale {
|
||||||
* ブーストをミュート
|
* ブーストをミュート
|
||||||
*/
|
*/
|
||||||
"renoteMute": string;
|
"renoteMute": string;
|
||||||
|
/**
|
||||||
|
* Boosts muted
|
||||||
|
*/
|
||||||
|
"renoteMuted": string;
|
||||||
/**
|
/**
|
||||||
* ブーストのミュートを解除
|
* ブーストのミュートを解除
|
||||||
*/
|
*/
|
||||||
|
@ -3136,6 +3144,10 @@ export interface Locale extends ILocale {
|
||||||
* 返信にサーバー情報を表示する
|
* 返信にサーバー情報を表示する
|
||||||
*/
|
*/
|
||||||
"showTickerOnReplies": string;
|
"showTickerOnReplies": string;
|
||||||
|
/**
|
||||||
|
* 猫の話し方を無効にする
|
||||||
|
*/
|
||||||
|
"disableCatSpeak": string;
|
||||||
/**
|
/**
|
||||||
* 検索MFMの検索エンジン
|
* 検索MFMの検索エンジン
|
||||||
*/
|
*/
|
||||||
|
@ -5137,6 +5149,10 @@ export interface Locale extends ILocale {
|
||||||
* 反転
|
* 反転
|
||||||
*/
|
*/
|
||||||
"flip": string;
|
"flip": string;
|
||||||
|
/**
|
||||||
|
* アイコンの後ろに表示
|
||||||
|
*/
|
||||||
|
"showBelowAvatar": string;
|
||||||
/**
|
/**
|
||||||
* アイコンのデコレーションを表示
|
* アイコンのデコレーションを表示
|
||||||
*/
|
*/
|
||||||
|
@ -5777,7 +5793,7 @@ export interface Locale extends ILocale {
|
||||||
*/
|
*/
|
||||||
"social": string;
|
"social": string;
|
||||||
/**
|
/**
|
||||||
* バッッブルタイムラインでは、管理者が選択した接続サーバーからのメモを表示できます。
|
* バブルタイムラインでは、管理者が選択した接続サーバーからの投稿を表示できます。
|
||||||
*/
|
*/
|
||||||
"bubble": string;
|
"bubble": string;
|
||||||
/**
|
/**
|
||||||
|
@ -9139,7 +9155,7 @@ export interface Locale extends ILocale {
|
||||||
*/
|
*/
|
||||||
"global": string;
|
"global": string;
|
||||||
/**
|
/**
|
||||||
* バッッブル
|
* バブル
|
||||||
*/
|
*/
|
||||||
"bubble": string;
|
"bubble": string;
|
||||||
};
|
};
|
||||||
|
|
|
@ -144,8 +144,10 @@ markAsSensitive: "センシティブとして設定"
|
||||||
unmarkAsSensitive: "センシティブを解除する"
|
unmarkAsSensitive: "センシティブを解除する"
|
||||||
enterFileName: "ファイル名を入力"
|
enterFileName: "ファイル名を入力"
|
||||||
mute: "ミュート"
|
mute: "ミュート"
|
||||||
|
muted: "Muted"
|
||||||
unmute: "ミュート解除"
|
unmute: "ミュート解除"
|
||||||
renoteMute: "ブーストをミュート"
|
renoteMute: "ブーストをミュート"
|
||||||
|
renoteMuted: "Boosts muted"
|
||||||
renoteUnmute: "ブーストのミュートを解除"
|
renoteUnmute: "ブーストのミュートを解除"
|
||||||
block: "ブロック"
|
block: "ブロック"
|
||||||
unblock: "ブロック解除"
|
unblock: "ブロック解除"
|
||||||
|
@ -780,6 +782,7 @@ lockedAccountInfo: "フォローを承認制にしても、ノートの公開範
|
||||||
alwaysMarkSensitive: "デフォルトでメディアをセンシティブ設定にする"
|
alwaysMarkSensitive: "デフォルトでメディアをセンシティブ設定にする"
|
||||||
loadRawImages: "添付画像のサムネイルをオリジナル画質にする"
|
loadRawImages: "添付画像のサムネイルをオリジナル画質にする"
|
||||||
showTickerOnReplies: "返信にサーバー情報を表示する"
|
showTickerOnReplies: "返信にサーバー情報を表示する"
|
||||||
|
disableCatSpeak: "猫の話し方を無効にする"
|
||||||
searchEngine: "検索MFMの検索エンジン"
|
searchEngine: "検索MFMの検索エンジン"
|
||||||
searchEngineOther: "カスタム"
|
searchEngineOther: "カスタム"
|
||||||
searchEngineCustomURIDescription: "カスタム検索エンジンのURIは、\"https://www.google.com/search?q=\\{query}\" や \"https://www.google.com/search?q=%s\" のような形式で入力する必要があります。"
|
searchEngineCustomURIDescription: "カスタム検索エンジンのURIは、\"https://www.google.com/search?q=\\{query}\" や \"https://www.google.com/search?q=%s\" のような形式で入力する必要があります。"
|
||||||
|
@ -1280,6 +1283,7 @@ detach: "外す"
|
||||||
detachAll: "全て外す"
|
detachAll: "全て外す"
|
||||||
angle: "角度"
|
angle: "角度"
|
||||||
flip: "反転"
|
flip: "反転"
|
||||||
|
showBelowAvatar: "アイコンの後ろに表示"
|
||||||
showAvatarDecorations: "アイコンのデコレーションを表示"
|
showAvatarDecorations: "アイコンのデコレーションを表示"
|
||||||
releaseToRefresh: "離してリロード"
|
releaseToRefresh: "離してリロード"
|
||||||
refreshing: "リロード中"
|
refreshing: "リロード中"
|
||||||
|
|
|
@ -526,6 +526,7 @@ export class ApRendererService {
|
||||||
publicKey: this.renderKey(user, keypair, '#main-key'),
|
publicKey: this.renderKey(user, keypair, '#main-key'),
|
||||||
isCat: user.isCat,
|
isCat: user.isCat,
|
||||||
noindex: user.noindex,
|
noindex: user.noindex,
|
||||||
|
indexable: !user.noindex,
|
||||||
speakAsCat: user.speakAsCat,
|
speakAsCat: user.speakAsCat,
|
||||||
attachment: attachment.length ? attachment : undefined,
|
attachment: attachment.length ? attachment : undefined,
|
||||||
};
|
};
|
||||||
|
|
|
@ -545,6 +545,7 @@ const extension_context_definition = {
|
||||||
Emoji: 'toot:Emoji',
|
Emoji: 'toot:Emoji',
|
||||||
featured: 'toot:featured',
|
featured: 'toot:featured',
|
||||||
discoverable: 'toot:discoverable',
|
discoverable: 'toot:discoverable',
|
||||||
|
indexable: 'toot:indexable',
|
||||||
// schema
|
// schema
|
||||||
schema: 'http://schema.org#',
|
schema: 'http://schema.org#',
|
||||||
PropertyValue: 'schema:PropertyValue',
|
PropertyValue: 'schema:PropertyValue',
|
||||||
|
|
|
@ -587,7 +587,7 @@ export class ApNoteService {
|
||||||
// ここでuriの代わりに添付されてきたNote Objectが指定されていると、サーバーフェッチを経ずにノートが生成されるが
|
// ここでuriの代わりに添付されてきたNote Objectが指定されていると、サーバーフェッチを経ずにノートが生成されるが
|
||||||
// 添付されてきたNote Objectは偽装されている可能性があるため、常にuriを指定してサーバーフェッチを行う。
|
// 添付されてきたNote Objectは偽装されている可能性があるため、常にuriを指定してサーバーフェッチを行う。
|
||||||
const createFrom = options.sentFrom?.origin === new URL(uri).origin ? value : uri;
|
const createFrom = options.sentFrom?.origin === new URL(uri).origin ? value : uri;
|
||||||
return await this.createNote(createFrom, options.resolver, true);
|
return await this.createNote(createFrom, options.resolver, false);
|
||||||
} finally {
|
} finally {
|
||||||
unlock();
|
unlock();
|
||||||
}
|
}
|
||||||
|
|
|
@ -525,6 +525,7 @@ export class UserEntityService implements OnModuleInit {
|
||||||
flipH: ud.flipH || undefined,
|
flipH: ud.flipH || undefined,
|
||||||
offsetX: ud.offsetX || undefined,
|
offsetX: ud.offsetX || undefined,
|
||||||
offsetY: ud.offsetY || undefined,
|
offsetY: ud.offsetY || undefined,
|
||||||
|
showBelow: ud.showBelow || undefined,
|
||||||
url: decorations.find(d => d.id === ud.id)!.url,
|
url: decorations.find(d => d.id === ud.id)!.url,
|
||||||
}))) : [],
|
}))) : [],
|
||||||
isBot: user.isBot,
|
isBot: user.isBot,
|
||||||
|
|
|
@ -170,6 +170,7 @@ export class MiUser {
|
||||||
flipH?: boolean;
|
flipH?: boolean;
|
||||||
offsetX?: number;
|
offsetX?: number;
|
||||||
offsetY?: number;
|
offsetY?: number;
|
||||||
|
showBelow?: boolean;
|
||||||
}[];
|
}[];
|
||||||
|
|
||||||
@Index()
|
@Index()
|
||||||
|
|
|
@ -104,6 +104,10 @@ export const packedUserLiteSchema = {
|
||||||
type: 'number',
|
type: 'number',
|
||||||
nullable: false, optional: true,
|
nullable: false, optional: true,
|
||||||
},
|
},
|
||||||
|
showBelow: {
|
||||||
|
type: 'boolean',
|
||||||
|
nullable: false, optional: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -159,6 +159,7 @@ export const paramDef = {
|
||||||
flipH: { type: 'boolean', nullable: true },
|
flipH: { type: 'boolean', nullable: true },
|
||||||
offsetX: { type: 'number', nullable: true, maximum: 0.25, minimum: -0.25 },
|
offsetX: { type: 'number', nullable: true, maximum: 0.25, minimum: -0.25 },
|
||||||
offsetY: { type: 'number', nullable: true, maximum: 0.25, minimum: -0.25 },
|
offsetY: { type: 'number', nullable: true, maximum: 0.25, minimum: -0.25 },
|
||||||
|
showBelow: { type: 'boolean', nullable: true },
|
||||||
},
|
},
|
||||||
required: ['id'],
|
required: ['id'],
|
||||||
} },
|
} },
|
||||||
|
@ -417,6 +418,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||||
flipH: d.flipH ?? false,
|
flipH: d.flipH ?? false,
|
||||||
offsetX: d.offsetX ?? 0,
|
offsetX: d.offsetX ?? 0,
|
||||||
offsetY: d.offsetY ?? 0,
|
offsetY: d.offsetY ?? 0,
|
||||||
|
showBelow: d.showBelow ?? false,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -193,9 +193,9 @@ export class ClientServerService {
|
||||||
icon: meta.iconUrl,
|
icon: meta.iconUrl,
|
||||||
appleTouchIcon: meta.app512IconUrl,
|
appleTouchIcon: meta.app512IconUrl,
|
||||||
themeColor: meta.themeColor,
|
themeColor: meta.themeColor,
|
||||||
serverErrorImageUrl: meta.serverErrorImageUrl ?? 'https://launcher.moe/error.png',
|
serverErrorImageUrl: meta.serverErrorImageUrl ?? '/status/error.png',
|
||||||
infoImageUrl: meta.infoImageUrl ?? 'https://launcher.moe/nothinghere.png',
|
infoImageUrl: meta.infoImageUrl ?? '/status/nothinghere.png',
|
||||||
notFoundImageUrl: meta.notFoundImageUrl ?? 'https://launcher.moe/missingpage.webp',
|
notFoundImageUrl: meta.notFoundImageUrl ?? '/status/missingpage.webp',
|
||||||
instanceUrl: this.config.url,
|
instanceUrl: this.config.url,
|
||||||
randomMOTD: this.config.customMOTD ? this.config.customMOTD[Math.floor(Math.random() * this.config.customMOTD.length)] : undefined,
|
randomMOTD: this.config.customMOTD ? this.config.customMOTD[Math.floor(Math.random() * this.config.customMOTD.length)] : undefined,
|
||||||
metaJson: htmlSafeJsonStringify(await this.metaEntityService.packDetailed(meta)),
|
metaJson: htmlSafeJsonStringify(await this.metaEntityService.packDetailed(meta)),
|
||||||
|
|
BIN
packages/frontend/assets/status/error.png
Normal file
BIN
packages/frontend/assets/status/error.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 26 KiB |
BIN
packages/frontend/assets/status/missingpage.webp
Normal file
BIN
packages/frontend/assets/status/missingpage.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.4 KiB |
BIN
packages/frontend/assets/status/nothinghere.png
Normal file
BIN
packages/frontend/assets/status/nothinghere.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 36 KiB |
|
@ -216,19 +216,25 @@ export async function mainBoot() {
|
||||||
claimAchievement('collectAchievements30');
|
claimAchievement('collectAchievements30');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!claimedAchievements.includes('justPlainLucky')) {
|
||||||
window.setInterval(() => {
|
window.setInterval(() => {
|
||||||
if (Math.floor(Math.random() * 20000) === 0) {
|
if (Math.floor(Math.random() * 20000) === 0) {
|
||||||
claimAchievement('justPlainLucky');
|
claimAchievement('justPlainLucky');
|
||||||
}
|
}
|
||||||
}, 1000 * 10);
|
}, 1000 * 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!claimedAchievements.includes('client30min')) {
|
||||||
window.setTimeout(() => {
|
window.setTimeout(() => {
|
||||||
claimAchievement('client30min');
|
claimAchievement('client30min');
|
||||||
}, 1000 * 60 * 30);
|
}, 1000 * 60 * 30);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!claimedAchievements.includes('client60min')) {
|
||||||
window.setTimeout(() => {
|
window.setTimeout(() => {
|
||||||
claimAchievement('client60min');
|
claimAchievement('client60min');
|
||||||
}, 1000 * 60 * 60);
|
}, 1000 * 60 * 60);
|
||||||
|
}
|
||||||
|
|
||||||
// 邪魔
|
// 邪魔
|
||||||
//const lastUsed = miLocalStorage.getItem('lastUsed');
|
//const lastUsed = miLocalStorage.getItem('lastUsed');
|
||||||
|
|
|
@ -630,11 +630,22 @@ async function onPaste(ev: ClipboardEvent) {
|
||||||
|
|
||||||
if (paste.length > 1000) {
|
if (paste.length > 1000) {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
os.confirm({
|
os.actions({
|
||||||
type: 'info',
|
type: 'question',
|
||||||
text: i18n.ts.attachAsFileQuestion,
|
text: i18n.ts.attachAsFileQuestion,
|
||||||
}).then(({ canceled }) => {
|
actions: [
|
||||||
if (canceled) {
|
{
|
||||||
|
value: 'yes',
|
||||||
|
text: i18n.ts.yes,
|
||||||
|
primary: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'no',
|
||||||
|
text: i18n.ts.no,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}).then(({ result }) => {
|
||||||
|
if (result !== 'yes') {
|
||||||
insertTextAtCursor(textareaEl.value, paste);
|
insertTextAtCursor(textareaEl.value, paste);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
rotate: getDecorationAngle(decoration),
|
rotate: getDecorationAngle(decoration),
|
||||||
scale: getDecorationScale(decoration),
|
scale: getDecorationScale(decoration),
|
||||||
translate: getDecorationOffset(decoration),
|
translate: getDecorationOffset(decoration),
|
||||||
|
zIndex: getDecorationZIndex(decoration),
|
||||||
}"
|
}"
|
||||||
alt=""
|
alt=""
|
||||||
>
|
>
|
||||||
|
@ -113,6 +114,10 @@ function getDecorationOffset(decoration: Omit<Misskey.entities.UserDetailed['ava
|
||||||
return offsetX === 0 && offsetY === 0 ? undefined : `${offsetX * 100}% ${offsetY * 100}%`;
|
return offsetX === 0 && offsetY === 0 ? undefined : `${offsetX * 100}% ${offsetY * 100}%`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getDecorationZIndex(decoration: Omit<Misskey.entities.UserDetailed['avatarDecorations'][number], 'id'>) {
|
||||||
|
return decoration.showBelow ? '-1' : undefined;
|
||||||
|
}
|
||||||
|
|
||||||
const color = ref<string | undefined>();
|
const color = ref<string | undefined>();
|
||||||
|
|
||||||
watch(() => props.user.avatarBlurhash, () => {
|
watch(() => props.user.avatarBlurhash, () => {
|
||||||
|
@ -159,6 +164,7 @@ watch(() => props.user.avatarBlurhash, () => {
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
border-radius: 100%; // sharkey: controlled by square avatars setting!
|
border-radius: 100%; // sharkey: controlled by square avatars setting!
|
||||||
line-height: 16px;
|
line-height: 16px;
|
||||||
|
z-index: 0; // sharkey: starts stacking context to help with showing decorations behind the avatar
|
||||||
}
|
}
|
||||||
|
|
||||||
.inner {
|
.inner {
|
||||||
|
|
|
@ -58,8 +58,7 @@ export default function (props: MfmProps, { emit }: { emit: SetupContext<MfmEven
|
||||||
provide('linkNavigationBehavior', props.linkNavigationBehavior);
|
provide('linkNavigationBehavior', props.linkNavigationBehavior);
|
||||||
|
|
||||||
const isNote = props.isNote ?? true;
|
const isNote = props.isNote ?? true;
|
||||||
const shouldNyaize = props.nyaize ? props.nyaize === 'respect' ? props.author?.isCat ? props.author.speakAsCat : false : 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
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||||
if (props.text == null || props.text === '') return;
|
if (props.text == null || props.text === '') return;
|
||||||
|
|
||||||
|
|
|
@ -160,9 +160,9 @@ export const ROLE_POLICIES = [
|
||||||
export const CURRENT_STICKY_TOP = 'CURRENT_STICKY_TOP';
|
export const CURRENT_STICKY_TOP = 'CURRENT_STICKY_TOP';
|
||||||
export const CURRENT_STICKY_BOTTOM = 'CURRENT_STICKY_BOTTOM';
|
export const CURRENT_STICKY_BOTTOM = 'CURRENT_STICKY_BOTTOM';
|
||||||
|
|
||||||
export const DEFAULT_SERVER_ERROR_IMAGE_URL = 'https://launcher.moe/error.png';
|
export const DEFAULT_SERVER_ERROR_IMAGE_URL = '/status/error.png';
|
||||||
export const DEFAULT_NOT_FOUND_IMAGE_URL = 'https://launcher.moe/missingpage.webp';
|
export const DEFAULT_NOT_FOUND_IMAGE_URL = '/status/missingpage.webp';
|
||||||
export const DEFAULT_INFO_IMAGE_URL = 'https://launcher.moe/nothinghere.png';
|
export const DEFAULT_INFO_IMAGE_URL = '/status/nothinghere.png';
|
||||||
|
|
||||||
export const MFM_TAGS = ['tada', 'jelly', 'twitch', 'shake', 'spin', 'jump', 'bounce', 'flip', 'x2', 'x3', 'x4', 'scale', 'position', 'fg', 'bg', 'border', 'font', 'blur', 'rainbow', 'sparkle', 'rotate', 'ruby', 'unixtime', 'crop', 'fade', 'followmouse'];
|
export const MFM_TAGS = ['tada', 'jelly', 'twitch', 'shake', 'spin', 'jump', 'bounce', 'flip', 'x2', 'x3', 'x4', 'scale', 'position', 'fg', 'bg', 'border', 'font', 'blur', 'rainbow', 'sparkle', 'rotate', 'ruby', 'unixtime', 'crop', 'fade', 'followmouse'];
|
||||||
export const MFM_PARAMS: Record<typeof MFM_TAGS[number], string[]> = {
|
export const MFM_PARAMS: Record<typeof MFM_TAGS[number], string[]> = {
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
worker-src 'self';
|
worker-src 'self';
|
||||||
script-src 'self' 'unsafe-eval' https://*.hcaptcha.com https://challenges.cloudflare.com https://esm.sh;
|
script-src 'self' 'unsafe-eval' https://*.hcaptcha.com https://challenges.cloudflare.com https://esm.sh;
|
||||||
style-src 'self' 'unsafe-inline';
|
style-src 'self' 'unsafe-inline';
|
||||||
img-src 'self' data: blob: www.google.com xn--931a.moe launcher.moe localhost:3000 localhost:5173 127.0.0.1:5173 127.0.0.1:3000 activitypub.software secure.gravatar.com avatars.githubusercontent.com;
|
img-src 'self' data: blob: www.google.com xn--931a.moe localhost:3000 localhost:5173 127.0.0.1:5173 127.0.0.1:3000 activitypub.software secure.gravatar.com avatars.githubusercontent.com;
|
||||||
media-src 'self' localhost:3000 localhost:5173 127.0.0.1:5173 127.0.0.1:3000;
|
media-src 'self' localhost:3000 localhost:5173 127.0.0.1:5173 127.0.0.1:3000;
|
||||||
connect-src 'self' localhost:3000 localhost:5173 127.0.0.1:5173 127.0.0.1:3000 https://newassets.hcaptcha.com https://api.listenbrainz.org;
|
connect-src 'self' localhost:3000 localhost:5173 127.0.0.1:5173 127.0.0.1:3000 https://newassets.hcaptcha.com https://api.listenbrainz.org;
|
||||||
frame-src *;"
|
frame-src *;"
|
||||||
|
|
|
@ -9,7 +9,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
@click="emit('click')"
|
@click="emit('click')"
|
||||||
>
|
>
|
||||||
<div :class="$style.name"><MkCondensedLine :minScale="0.5">{{ decoration.name }}</MkCondensedLine></div>
|
<div :class="$style.name"><MkCondensedLine :minScale="0.5">{{ decoration.name }}</MkCondensedLine></div>
|
||||||
<MkAvatar style="width: 60px; height: 60px;" :user="$i" :decorations="[{ url: decoration.url, angle, flipH, offsetX, offsetY }]" forceShowDecoration/>
|
<MkAvatar style="width: 60px; height: 60px;" :user="$i" :decorations="[{ url: decoration.url, angle, flipH, offsetX, offsetY, showBelow }]" forceShowDecoration/>
|
||||||
<i v-if="decoration.roleIdsThatCanBeUsedThisDecoration.length > 0 && !$i.roles.some(r => decoration.roleIdsThatCanBeUsedThisDecoration.includes(r.id))" :class="$style.lock" class="ti ti-lock"></i>
|
<i v-if="decoration.roleIdsThatCanBeUsedThisDecoration.length > 0 && !$i.roles.some(r => decoration.roleIdsThatCanBeUsedThisDecoration.includes(r.id))" :class="$style.lock" class="ti ti-lock"></i>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -32,6 +32,7 @@ const props = defineProps<{
|
||||||
flipH?: boolean;
|
flipH?: boolean;
|
||||||
offsetX?: number;
|
offsetX?: number;
|
||||||
offsetY?: number;
|
offsetY?: number;
|
||||||
|
showBelow?: boolean;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
|
|
|
@ -29,6 +29,9 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<MkRange v-model="offsetY" continuousUpdate :min="-0.25" :max="0.25" :step="0.025" :textConverter="(v) => `${Math.floor(v * 100)}%`">
|
<MkRange v-model="offsetY" continuousUpdate :min="-0.25" :max="0.25" :step="0.025" :textConverter="(v) => `${Math.floor(v * 100)}%`">
|
||||||
<template #label>Y {{ i18n.ts.position }}</template>
|
<template #label>Y {{ i18n.ts.position }}</template>
|
||||||
</MkRange>
|
</MkRange>
|
||||||
|
<MkSwitch v-model="showBelow">
|
||||||
|
<template #label>{{ i18n.ts.showBelowAvatar }}</template>
|
||||||
|
</MkSwitch>
|
||||||
<MkSwitch v-model="flipH">
|
<MkSwitch v-model="flipH">
|
||||||
<template #label>{{ i18n.ts.flip }}</template>
|
<template #label>{{ i18n.ts.flip }}</template>
|
||||||
</MkSwitch>
|
</MkSwitch>
|
||||||
|
@ -71,12 +74,14 @@ const emit = defineEmits<{
|
||||||
flipH: boolean;
|
flipH: boolean;
|
||||||
offsetX: number;
|
offsetX: number;
|
||||||
offsetY: number;
|
offsetY: number;
|
||||||
|
showBelow: boolean;
|
||||||
}): void;
|
}): void;
|
||||||
(ev: 'update', payload: {
|
(ev: 'update', payload: {
|
||||||
angle: number;
|
angle: number;
|
||||||
flipH: boolean;
|
flipH: boolean;
|
||||||
offsetX: number;
|
offsetX: number;
|
||||||
offsetY: number;
|
offsetY: number;
|
||||||
|
showBelow: boolean;
|
||||||
}): void;
|
}): void;
|
||||||
(ev: 'detach'): void;
|
(ev: 'detach'): void;
|
||||||
}>();
|
}>();
|
||||||
|
@ -87,6 +92,7 @@ const angle = ref((props.usingIndex != null ? $i.avatarDecorations[props.usingIn
|
||||||
const flipH = ref((props.usingIndex != null ? $i.avatarDecorations[props.usingIndex].flipH : null) ?? false);
|
const flipH = ref((props.usingIndex != null ? $i.avatarDecorations[props.usingIndex].flipH : null) ?? false);
|
||||||
const offsetX = ref((props.usingIndex != null ? $i.avatarDecorations[props.usingIndex].offsetX : null) ?? 0);
|
const offsetX = ref((props.usingIndex != null ? $i.avatarDecorations[props.usingIndex].offsetX : null) ?? 0);
|
||||||
const offsetY = ref((props.usingIndex != null ? $i.avatarDecorations[props.usingIndex].offsetY : null) ?? 0);
|
const offsetY = ref((props.usingIndex != null ? $i.avatarDecorations[props.usingIndex].offsetY : null) ?? 0);
|
||||||
|
const showBelow = ref((props.usingIndex != null ? $i.avatarDecorations[props.usingIndex].showBelow : null) ?? false);
|
||||||
|
|
||||||
const decorationsForPreview = computed(() => {
|
const decorationsForPreview = computed(() => {
|
||||||
const decoration = {
|
const decoration = {
|
||||||
|
@ -96,6 +102,7 @@ const decorationsForPreview = computed(() => {
|
||||||
flipH: flipH.value,
|
flipH: flipH.value,
|
||||||
offsetX: offsetX.value,
|
offsetX: offsetX.value,
|
||||||
offsetY: offsetY.value,
|
offsetY: offsetY.value,
|
||||||
|
showBelow: showBelow.value,
|
||||||
};
|
};
|
||||||
const decorations = [...$i.avatarDecorations];
|
const decorations = [...$i.avatarDecorations];
|
||||||
if (props.usingIndex != null) {
|
if (props.usingIndex != null) {
|
||||||
|
@ -116,6 +123,7 @@ async function update() {
|
||||||
flipH: flipH.value,
|
flipH: flipH.value,
|
||||||
offsetX: offsetX.value,
|
offsetX: offsetX.value,
|
||||||
offsetY: offsetY.value,
|
offsetY: offsetY.value,
|
||||||
|
showBelow: showBelow.value,
|
||||||
});
|
});
|
||||||
dialog.value.close();
|
dialog.value.close();
|
||||||
}
|
}
|
||||||
|
@ -126,6 +134,7 @@ async function attach() {
|
||||||
flipH: flipH.value,
|
flipH: flipH.value,
|
||||||
offsetX: offsetX.value,
|
offsetX: offsetX.value,
|
||||||
offsetY: offsetY.value,
|
offsetY: offsetY.value,
|
||||||
|
showBelow: showBelow.value,
|
||||||
});
|
});
|
||||||
dialog.value.close();
|
dialog.value.close();
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
:flipH="avatarDecoration.flipH"
|
:flipH="avatarDecoration.flipH"
|
||||||
:offsetX="avatarDecoration.offsetX"
|
:offsetX="avatarDecoration.offsetX"
|
||||||
:offsetY="avatarDecoration.offsetY"
|
:offsetY="avatarDecoration.offsetY"
|
||||||
|
:showBelow="avatarDecoration.showBelow"
|
||||||
:active="true"
|
:active="true"
|
||||||
@click="openDecoration(avatarDecoration, i)"
|
@click="openDecoration(avatarDecoration, i)"
|
||||||
/>
|
/>
|
||||||
|
@ -78,6 +79,7 @@ function openDecoration(avatarDecoration, index?: number) {
|
||||||
flipH: payload.flipH,
|
flipH: payload.flipH,
|
||||||
offsetX: payload.offsetX,
|
offsetX: payload.offsetX,
|
||||||
offsetY: payload.offsetY,
|
offsetY: payload.offsetY,
|
||||||
|
showBelow: payload.showBelow,
|
||||||
};
|
};
|
||||||
const update = [...$i.avatarDecorations, decoration];
|
const update = [...$i.avatarDecorations, decoration];
|
||||||
await os.apiWithDialog('i/update', {
|
await os.apiWithDialog('i/update', {
|
||||||
|
@ -92,6 +94,7 @@ function openDecoration(avatarDecoration, index?: number) {
|
||||||
flipH: payload.flipH,
|
flipH: payload.flipH,
|
||||||
offsetX: payload.offsetX,
|
offsetX: payload.offsetX,
|
||||||
offsetY: payload.offsetY,
|
offsetY: payload.offsetY,
|
||||||
|
showBelow: payload.showBelow,
|
||||||
};
|
};
|
||||||
const update = [...$i.avatarDecorations];
|
const update = [...$i.avatarDecorations];
|
||||||
update[index] = decoration;
|
update[index] = decoration;
|
||||||
|
|
|
@ -68,6 +68,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<MkSwitch v-model="showGapBetweenNotesInTimeline">{{ i18n.ts.showGapBetweenNotesInTimeline }}</MkSwitch>
|
<MkSwitch v-model="showGapBetweenNotesInTimeline">{{ i18n.ts.showGapBetweenNotesInTimeline }}</MkSwitch>
|
||||||
<MkSwitch v-model="loadRawImages">{{ i18n.ts.loadRawImages }}</MkSwitch>
|
<MkSwitch v-model="loadRawImages">{{ i18n.ts.loadRawImages }}</MkSwitch>
|
||||||
<MkSwitch v-model="showTickerOnReplies">{{ i18n.ts.showTickerOnReplies }}</MkSwitch>
|
<MkSwitch v-model="showTickerOnReplies">{{ i18n.ts.showTickerOnReplies }}</MkSwitch>
|
||||||
|
<MkSwitch v-model="disableCatSpeak">{{ i18n.ts.disableCatSpeak }}</MkSwitch>
|
||||||
<MkSelect v-model="searchEngine" placeholder="Other">
|
<MkSelect v-model="searchEngine" placeholder="Other">
|
||||||
<template #label>{{ i18n.ts.searchEngine }}</template>
|
<template #label>{{ i18n.ts.searchEngine }}</template>
|
||||||
<option
|
<option
|
||||||
|
@ -400,6 +401,7 @@ const disableShowingAnimatedImages = computed(defaultStore.makeGetterSetter('dis
|
||||||
const forceShowAds = computed(defaultStore.makeGetterSetter('forceShowAds'));
|
const forceShowAds = computed(defaultStore.makeGetterSetter('forceShowAds'));
|
||||||
const oneko = computed(defaultStore.makeGetterSetter('oneko'));
|
const oneko = computed(defaultStore.makeGetterSetter('oneko'));
|
||||||
const loadRawImages = computed(defaultStore.makeGetterSetter('loadRawImages'));
|
const loadRawImages = computed(defaultStore.makeGetterSetter('loadRawImages'));
|
||||||
|
const disableCatSpeak = computed(defaultStore.makeGetterSetter('disableCatSpeak'));
|
||||||
const highlightSensitiveMedia = computed(defaultStore.makeGetterSetter('highlightSensitiveMedia'));
|
const highlightSensitiveMedia = computed(defaultStore.makeGetterSetter('highlightSensitiveMedia'));
|
||||||
const imageNewTab = computed(defaultStore.makeGetterSetter('imageNewTab'));
|
const imageNewTab = computed(defaultStore.makeGetterSetter('imageNewTab'));
|
||||||
const enableFaviconNotificationDot = computed(defaultStore.makeGetterSetter('enableFaviconNotificationDot'));
|
const enableFaviconNotificationDot = computed(defaultStore.makeGetterSetter('enableFaviconNotificationDot'));
|
||||||
|
|
|
@ -77,6 +77,7 @@ const defaultStoreSaveKeys: (keyof typeof defaultStore['state'])[] = [
|
||||||
'enableFaviconNotificationDot',
|
'enableFaviconNotificationDot',
|
||||||
'imageNewTab',
|
'imageNewTab',
|
||||||
'dataSaver',
|
'dataSaver',
|
||||||
|
'disableCatSpeak',
|
||||||
'disableShowingAnimatedImages',
|
'disableShowingAnimatedImages',
|
||||||
'emojiStyle',
|
'emojiStyle',
|
||||||
'disableDrawer',
|
'disableDrawer',
|
||||||
|
|
|
@ -30,7 +30,12 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<span v-if="$i && $i.id != user.id && user.isFollowed" class="followed">{{ i18n.ts.followsYou }}</span>
|
<div v-if="$i && $i.id != user.id" class="info-badges">
|
||||||
|
<span v-if="user.isFollowed">{{ i18n.ts.followsYou }}</span>
|
||||||
|
<span v-if="user.isMuted">{{ i18n.ts.muted }}</span>
|
||||||
|
<span v-if="user.isRenoteMuted">{{ i18n.ts.renoteMuted }}</span>
|
||||||
|
<span v-if="user.isBlocking">{{ i18n.ts.blocked }}</span>
|
||||||
|
</div>
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
<button class="menu _button" @click="menu"><i class="ti ti-dots"></i></button>
|
<button class="menu _button" @click="menu"><i class="ti ti-dots"></i></button>
|
||||||
<MkFollowButton v-if="$i?.id != user.id" v-model:user="user" :inline="true" :transparent="false" :full="true" class="koudoku"/>
|
<MkFollowButton v-if="$i?.id != user.id" v-model:user="user" :inline="true" :transparent="false" :full="true" class="koudoku"/>
|
||||||
|
@ -445,10 +450,15 @@ onUnmounted(() => {
|
||||||
background: linear-gradient(transparent, rgba(#000, 0.7));
|
background: linear-gradient(transparent, rgba(#000, 0.7));
|
||||||
}
|
}
|
||||||
|
|
||||||
> .followed {
|
> .info-badges {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 12px;
|
top: 12px;
|
||||||
left: 12px;
|
left: 12px;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
|
||||||
|
> * {
|
||||||
padding: 4px 8px;
|
padding: 4px 8px;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
background: rgba(0, 0, 0, 0.7);
|
background: rgba(0, 0, 0, 0.7);
|
||||||
|
@ -456,6 +466,11 @@ onUnmounted(() => {
|
||||||
border-radius: var(--radius-sm);
|
border-radius: var(--radius-sm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
> :not(:first-child) {
|
||||||
|
margin-left: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
> .actions {
|
> .actions {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 12px;
|
top: 12px;
|
||||||
|
|
|
@ -288,6 +288,10 @@ export const defaultStore = markRaw(new Storage('base', {
|
||||||
where: 'device',
|
where: 'device',
|
||||||
default: window.matchMedia('(prefers-reduced-motion)').matches,
|
default: window.matchMedia('(prefers-reduced-motion)').matches,
|
||||||
},
|
},
|
||||||
|
disableCatSpeak: {
|
||||||
|
where: 'account',
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
emojiStyle: {
|
emojiStyle: {
|
||||||
where: 'device',
|
where: 'device',
|
||||||
default: 'twemoji', // twemoji / fluentEmoji / native
|
default: 'twemoji', // twemoji / fluentEmoji / native
|
||||||
|
|
|
@ -3830,6 +3830,7 @@ export type components = {
|
||||||
url: string;
|
url: string;
|
||||||
offsetX?: number;
|
offsetX?: number;
|
||||||
offsetY?: number;
|
offsetY?: number;
|
||||||
|
showBelow?: boolean;
|
||||||
}[];
|
}[];
|
||||||
/** @default false */
|
/** @default false */
|
||||||
isAdmin?: boolean;
|
isAdmin?: boolean;
|
||||||
|
@ -20243,6 +20244,7 @@ export type operations = {
|
||||||
flipH?: boolean | null;
|
flipH?: boolean | null;
|
||||||
offsetX?: number | null;
|
offsetX?: number | null;
|
||||||
offsetY?: number | null;
|
offsetY?: number | null;
|
||||||
|
showBelow?: boolean | null;
|
||||||
})[];
|
})[];
|
||||||
/** Format: misskey:id */
|
/** Format: misskey:id */
|
||||||
bannerId?: string | null;
|
bannerId?: string | null;
|
||||||
|
|
Loading…
Reference in a new issue