mirror of
https://github.com/misskey-dev/misskey.git
synced 2024-12-28 12:20:21 +01:00
tweak of 7ce569424
This commit is contained in:
parent
db1098a180
commit
231506772a
6 changed files with 73 additions and 50 deletions
|
@ -1052,6 +1052,7 @@ failedToPreviewUrl: "プレビューできません"
|
||||||
update: "更新"
|
update: "更新"
|
||||||
rolesThatCanBeUsedThisEmojiAsReaction: "リアクションとして使えるロール"
|
rolesThatCanBeUsedThisEmojiAsReaction: "リアクションとして使えるロール"
|
||||||
rolesThatCanBeUsedThisEmojiAsReactionEmptyDescription: "ロールの指定が一つもない場合、誰でもリアクションとして使えます。"
|
rolesThatCanBeUsedThisEmojiAsReactionEmptyDescription: "ロールの指定が一つもない場合、誰でもリアクションとして使えます。"
|
||||||
|
rolesThatCanBeUsedThisEmojiAsReactionPublicRoleWarn: "ロールは公開ロールである必要があります。"
|
||||||
|
|
||||||
_initialAccountSetting:
|
_initialAccountSetting:
|
||||||
accountCreated: "アカウントの作成が完了しました!"
|
accountCreated: "アカウントの作成が完了しました!"
|
||||||
|
|
|
@ -26,7 +26,8 @@ export class EmojiEntityService {
|
||||||
category: emoji.category,
|
category: emoji.category,
|
||||||
// || emoji.originalUrl してるのは後方互換性のため(publicUrlはstringなので??はだめ)
|
// || emoji.originalUrl してるのは後方互換性のため(publicUrlはstringなので??はだめ)
|
||||||
url: emoji.publicUrl || emoji.originalUrl,
|
url: emoji.publicUrl || emoji.originalUrl,
|
||||||
isSensitive: emoji.isSensitive,
|
isSensitive: emoji.isSensitive ? true : undefined,
|
||||||
|
roleIdsThatCanBeUsedThisEmojiAsReaction: emoji.roleIdsThatCanBeUsedThisEmojiAsReaction.length > 0 ? emoji.roleIdsThatCanBeUsedThisEmojiAsReaction : undefined,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,16 @@ export const packedEmojiSimpleSchema = {
|
||||||
},
|
},
|
||||||
isSensitive: {
|
isSensitive: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
optional: false, nullable: false,
|
optional: true, nullable: false,
|
||||||
|
},
|
||||||
|
roleIdsThatCanBeUsedThisEmojiAsReaction: {
|
||||||
|
type: 'array',
|
||||||
|
optional: true, nullable: false,
|
||||||
|
items: {
|
||||||
|
type: 'string',
|
||||||
|
optional: false, nullable: false,
|
||||||
|
format: 'id',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
} as const;
|
} as const;
|
||||||
|
|
|
@ -3,11 +3,11 @@ import * as misskey from 'misskey-js';
|
||||||
import { showSuspendedDialog } from './scripts/show-suspended-dialog';
|
import { showSuspendedDialog } from './scripts/show-suspended-dialog';
|
||||||
import { i18n } from './i18n';
|
import { i18n } from './i18n';
|
||||||
import { miLocalStorage } from './local-storage';
|
import { miLocalStorage } from './local-storage';
|
||||||
|
import { MenuButton } from './types/menu';
|
||||||
import { del, get, set } from '@/scripts/idb-proxy';
|
import { del, get, set } from '@/scripts/idb-proxy';
|
||||||
import { apiUrl } from '@/config';
|
import { apiUrl } from '@/config';
|
||||||
import { waiting, api, popup, popupMenu, success, alert } from '@/os';
|
import { waiting, api, popup, popupMenu, success, alert } from '@/os';
|
||||||
import { unisonReload, reloadChannel } from '@/scripts/unison-reload';
|
import { unisonReload, reloadChannel } from '@/scripts/unison-reload';
|
||||||
import { MenuButton } from './types/menu';
|
|
||||||
|
|
||||||
// TODO: 他のタブと永続化されたstateを同期
|
// TODO: 他のタブと永続化されたstateを同期
|
||||||
|
|
||||||
|
@ -101,57 +101,57 @@ function fetchAccount(token: string, id?: string, forceShowDialog?: boolean): Pr
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.then(res => new Promise<Account | { error: Record<string, any> }>((done2, fail2) => {
|
.then(res => new Promise<Account | { error: Record<string, any> }>((done2, fail2) => {
|
||||||
if (res.status >= 500 && res.status < 600) {
|
if (res.status >= 500 && res.status < 600) {
|
||||||
// サーバーエラー(5xx)の場合をrejectとする
|
// サーバーエラー(5xx)の場合をrejectとする
|
||||||
// (認証エラーなど4xxはresolve)
|
// (認証エラーなど4xxはresolve)
|
||||||
return fail2(res);
|
return fail2(res);
|
||||||
}
|
}
|
||||||
res.json().then(done2, fail2);
|
res.json().then(done2, fail2);
|
||||||
}))
|
}))
|
||||||
.then(async res => {
|
.then(async res => {
|
||||||
if (res.error) {
|
if (res.error) {
|
||||||
if (res.error.id === 'a8c724b3-6e9c-4b46-b1a8-bc3ed6258370') {
|
if (res.error.id === 'a8c724b3-6e9c-4b46-b1a8-bc3ed6258370') {
|
||||||
// SUSPENDED
|
// SUSPENDED
|
||||||
if (forceShowDialog || $i && (token === $i.token || id === $i.id)) {
|
if (forceShowDialog || $i && (token === $i.token || id === $i.id)) {
|
||||||
await showSuspendedDialog();
|
await showSuspendedDialog();
|
||||||
}
|
}
|
||||||
} else if (res.error.id === 'e5b3b9f0-2b8f-4b9f-9c1f-8c5c1b2e1b1a') {
|
} else if (res.error.id === 'e5b3b9f0-2b8f-4b9f-9c1f-8c5c1b2e1b1a') {
|
||||||
// USER_IS_DELETED
|
// USER_IS_DELETED
|
||||||
// アカウントが削除されている
|
// アカウントが削除されている
|
||||||
if (forceShowDialog || $i && (token === $i.token || id === $i.id)) {
|
if (forceShowDialog || $i && (token === $i.token || id === $i.id)) {
|
||||||
await alert({
|
await alert({
|
||||||
type: 'error',
|
type: 'error',
|
||||||
title: i18n.ts.accountDeleted,
|
title: i18n.ts.accountDeleted,
|
||||||
text: i18n.ts.accountDeletedDescription,
|
text: i18n.ts.accountDeletedDescription,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else if (res.error.id === 'b0a7f5f8-dc2f-4171-b91f-de88ad238e14') {
|
} else if (res.error.id === 'b0a7f5f8-dc2f-4171-b91f-de88ad238e14') {
|
||||||
// AUTHENTICATION_FAILED
|
// AUTHENTICATION_FAILED
|
||||||
// トークンが無効化されていたりアカウントが削除されたりしている
|
// トークンが無効化されていたりアカウントが削除されたりしている
|
||||||
if (forceShowDialog || $i && (token === $i.token || id === $i.id)) {
|
if (forceShowDialog || $i && (token === $i.token || id === $i.id)) {
|
||||||
|
await alert({
|
||||||
|
type: 'error',
|
||||||
|
title: i18n.ts.tokenRevoked,
|
||||||
|
text: i18n.ts.tokenRevokedDescription,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
await alert({
|
await alert({
|
||||||
type: 'error',
|
type: 'error',
|
||||||
title: i18n.ts.tokenRevoked,
|
title: i18n.ts.failedToFetchAccountInformation,
|
||||||
text: i18n.ts.tokenRevokedDescription,
|
text: JSON.stringify(res.error),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
await alert({
|
|
||||||
type: 'error',
|
|
||||||
title: i18n.ts.failedToFetchAccountInformation,
|
|
||||||
text: JSON.stringify(res.error),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// rejectかつ理由がtrueの場合、削除対象であることを示す
|
// rejectかつ理由がtrueの場合、削除対象であることを示す
|
||||||
fail(true);
|
fail(true);
|
||||||
} else {
|
} else {
|
||||||
(res as Account).token = token;
|
(res as Account).token = token;
|
||||||
done(res as Account);
|
done(res as Account);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(fail);
|
.catch(fail);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -305,3 +305,7 @@ export async function openAccountMenu(opts: {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_DEV_) {
|
||||||
|
(window as any).$i = $i;
|
||||||
|
}
|
||||||
|
|
|
@ -69,8 +69,8 @@
|
||||||
<XSection
|
<XSection
|
||||||
v-for="category in customEmojiCategories"
|
v-for="category in customEmojiCategories"
|
||||||
:key="`custom:${category}`"
|
:key="`custom:${category}`"
|
||||||
:initial-shown="false"
|
:initialShown="false"
|
||||||
:emojis="computed(() => customEmojis.filter(e => category === null ? (e.category === 'null' || !e.category) : e.category === category).map(e => `:${e.name}:`))"
|
:emojis="computed(() => customEmojis.filter(e => category === null ? (e.category === 'null' || !e.category) : e.category === category).filter(filterAvailable).map(e => `:${e.name}:`))"
|
||||||
@chosen="chosen"
|
@chosen="chosen"
|
||||||
>
|
>
|
||||||
{{ category || i18n.ts.other }}
|
{{ category || i18n.ts.other }}
|
||||||
|
@ -102,6 +102,7 @@ import { deviceKind } from '@/scripts/device-kind';
|
||||||
import { i18n } from '@/i18n';
|
import { i18n } from '@/i18n';
|
||||||
import { defaultStore } from '@/store';
|
import { defaultStore } from '@/store';
|
||||||
import { customEmojiCategories, customEmojis } from '@/custom-emojis';
|
import { customEmojiCategories, customEmojis } from '@/custom-emojis';
|
||||||
|
import { $i } from '@/account';
|
||||||
|
|
||||||
const props = withDefaults(defineProps<{
|
const props = withDefaults(defineProps<{
|
||||||
showPinned?: boolean;
|
showPinned?: boolean;
|
||||||
|
@ -274,10 +275,14 @@ watch(q, () => {
|
||||||
return matches;
|
return matches;
|
||||||
};
|
};
|
||||||
|
|
||||||
searchResultCustom.value = Array.from(searchCustom());
|
searchResultCustom.value = Array.from(searchCustom()).filter(filterAvailable);
|
||||||
searchResultUnicode.value = Array.from(searchUnicode());
|
searchResultUnicode.value = Array.from(searchUnicode());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function filterAvailable(emoji: Misskey.entities.CustomEmoji): boolean {
|
||||||
|
return (emoji.roleIdsThatCanBeUsedThisEmojiAsReaction == null || emoji.roleIdsThatCanBeUsedThisEmojiAsReaction.length === 0) || ($i && $i.roles.some(r => emoji.roleIdsThatCanBeUsedThisEmojiAsReaction.includes(r.id)));
|
||||||
|
}
|
||||||
|
|
||||||
function focus() {
|
function focus() {
|
||||||
if (!['smartphone', 'tablet'].includes(deviceKind) && !isTouchUsing) {
|
if (!['smartphone', 'tablet'].includes(deviceKind) && !isTouchUsing) {
|
||||||
searchEl.value?.focus({
|
searchEl.value?.focus({
|
||||||
|
|
|
@ -41,16 +41,19 @@
|
||||||
</MkInput>
|
</MkInput>
|
||||||
<MkFolder>
|
<MkFolder>
|
||||||
<template #label>{{ i18n.ts.rolesThatCanBeUsedThisEmojiAsReaction }}</template>
|
<template #label>{{ i18n.ts.rolesThatCanBeUsedThisEmojiAsReaction }}</template>
|
||||||
<div class="_gaps">
|
<template #suffix>{{ rolesThatCanBeUsedThisEmojiAsReaction.length === 0 ? i18n.ts.all : rolesThatCanBeUsedThisEmojiAsReaction.length }}</template>
|
||||||
<MkInfo>{{ i18n.ts.rolesThatCanBeUsedThisEmojiAsReactionEmptyDescription }}</MkInfo>
|
|
||||||
|
|
||||||
|
<div class="_gaps">
|
||||||
<MkButton rounded @click="addRole"><i class="ti ti-plus"></i> {{ i18n.ts.add }}</MkButton>
|
<MkButton rounded @click="addRole"><i class="ti ti-plus"></i> {{ i18n.ts.add }}</MkButton>
|
||||||
|
|
||||||
<div v-for="role in rolesThatCanBeUsedThisEmojiAsReaction" :key="role.id" :class="$style.roleItem">
|
<div v-for="role in rolesThatCanBeUsedThisEmojiAsReaction" :key="role.id" :class="$style.roleItem">
|
||||||
<MkRolePreview :class="$style.role" :role="role" :forModeration="true" :detailed="false"/>
|
<MkRolePreview :class="$style.role" :role="role" :forModeration="true" :detailed="false" style="pointer-events: none;"/>
|
||||||
<button v-if="role.target === 'manual'" class="_button" :class="$style.roleUnassign" @click="removeRole(role, $event)"><i class="ti ti-x"></i></button>
|
<button v-if="role.target === 'manual'" class="_button" :class="$style.roleUnassign" @click="removeRole(role, $event)"><i class="ti ti-x"></i></button>
|
||||||
<button v-else class="_button" :class="$style.roleUnassign" disabled><i class="ti ti-ban"></i></button>
|
<button v-else class="_button" :class="$style.roleUnassign" disabled><i class="ti ti-ban"></i></button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<MkInfo>{{ i18n.ts.rolesThatCanBeUsedThisEmojiAsReactionEmptyDescription }}</MkInfo>
|
||||||
|
<MkInfo warn>{{ i18n.ts.rolesThatCanBeUsedThisEmojiAsReactionPublicRoleWarn }}</MkInfo>
|
||||||
</div>
|
</div>
|
||||||
</MkFolder>
|
</MkFolder>
|
||||||
<MkSwitch v-model="isSensitive">isSensitive</MkSwitch>
|
<MkSwitch v-model="isSensitive">isSensitive</MkSwitch>
|
||||||
|
@ -128,8 +131,8 @@ async function removeRole(role, ev) {
|
||||||
async function done() {
|
async function done() {
|
||||||
const params = {
|
const params = {
|
||||||
name,
|
name,
|
||||||
category,
|
category: category === '' ? null : category,
|
||||||
aliases: aliases.split(' '),
|
aliases: aliases.split(' ').filter(x => x !== ''),
|
||||||
license: license === '' ? null : license,
|
license: license === '' ? null : license,
|
||||||
isSensitive,
|
isSensitive,
|
||||||
localOnly,
|
localOnly,
|
||||||
|
|
Loading…
Reference in a new issue