実績を凍結する
This commit is contained in:
parent
2f3c2af619
commit
23670ff0fe
|
@ -1034,12 +1034,12 @@ _accountMigration:
|
||||||
moveTo: "このアカウントを新しいアカウントへ移行"
|
moveTo: "このアカウントを新しいアカウントへ移行"
|
||||||
moveToLabel: "移行先のアカウント:"
|
moveToLabel: "移行先のアカウント:"
|
||||||
moveCannotBeUndone: "アカウントを移行すると、取り消すことはできません。"
|
moveCannotBeUndone: "アカウントを移行すると、取り消すことはできません。"
|
||||||
moveAccountDescription: "新しいアカウントへ移行します。\n ・フォロワーが新しいアカウントを自動でフォローします(フォロワーのサーバーが対応している場合)。\n ・このアカウントからのフォローは全て解除されます。\n ・このアカウントではノートの作成などができなくなります。\n\nフォロワーの移行は自動ですが、フォローの移行は手動で行う必要があります。移行前にこのアカウントでフォローエクスポートし、移行後すぐに移行先アカウントでインポートを行なってください。"
|
moveAccountDescription: "新しいアカウントへ移行します。\n ・フォロワーが新しいアカウントを自動でフォローします(フォロワーのサーバーが対応している場合)。\n ・このアカウントからのフォローは全て解除されます。\n ・このアカウントではノートの作成などができなくなります。\n\nフォロワーの移行は自動ですが、フォローの移行は手動で行う必要があります。移行前にこのアカウントでフォローエクスポートし、移行後すぐに移行先アカウントでインポートを行なってください。\nリスト・ミュート・ブロックについても同様ですので、手動で移行する必要があります。\n\n(ここに記載されている仕様は同一サーバーもしくは13.12.0以降のMisskeyサーバーのものであり、他のActivityPub実装では挙動が異なる場合があります。)"
|
||||||
moveAccountHowTo: "アカウントの移行には、まずは移行先のアカウントでこのアカウントに対しエイリアスを作成します。\nエイリアス作成後、移行先のアカウントを次のように入力してください: @username@server.example.com"
|
moveAccountHowTo: "アカウントの移行には、まずは移行先のアカウントでこのアカウントに対しエイリアスを作成します。\nエイリアス作成後、移行先のアカウントを次のように入力してください: @username@server.example.com"
|
||||||
startMigration: "移行する"
|
startMigration: "移行する"
|
||||||
migrationConfirm: "本当にこのアカウントを {account} に移行しますか?一度移行すると取り消せず、二度とこのアカウントを元の状態で使用できなくなります。"
|
migrationConfirm: "本当にこのアカウントを {account} に移行しますか?一度移行すると取り消せず、二度とこのアカウントを元の状態で使用できなくなります。"
|
||||||
postMigrationNote: "フォロー解除は、移行操作をしてから1日後に行われます。"
|
|
||||||
movedAndCannotBeUndone: "\nアカウントは移行されています。\n移行を取り消すことはできません。"
|
movedAndCannotBeUndone: "\nアカウントは移行されています。\n移行を取り消すことはできません。"
|
||||||
|
postMigrationNote: "このアカウントからのフォロー解除は移行操作から24時間後に実行されます。\nこのアカウントのフォロー・フォロワー数は0になっています。フォロワーの解除はされないため、あなたのフォロワーはこのアカウントのフォロワー向け投稿を引き続き閲覧できます。"
|
||||||
movedTo: "移行先のアカウント:"
|
movedTo: "移行先のアカウント:"
|
||||||
|
|
||||||
_achievements:
|
_achievements:
|
||||||
|
|
|
@ -4,6 +4,7 @@ import { AchievementService, ACHIEVEMENT_TYPES } from '@/core/AchievementService
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
|
prohibitMoved: true,
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
|
|
@ -388,6 +388,7 @@ describe('Account Move', () => {
|
||||||
'/gallery/posts/like',
|
'/gallery/posts/like',
|
||||||
'/gallery/posts/unlike',
|
'/gallery/posts/unlike',
|
||||||
'/gallery/posts/update',
|
'/gallery/posts/update',
|
||||||
|
'/i/claim-achievement',
|
||||||
'/i/move',
|
'/i/move',
|
||||||
'/i/import-blocking',
|
'/i/import-blocking',
|
||||||
'/i/import-following',
|
'/i/import-following',
|
||||||
|
|
|
@ -162,6 +162,7 @@ import { claimAchievement } from '@/scripts/achievements';
|
||||||
import { getNoteSummary } from '@/scripts/get-note-summary';
|
import { getNoteSummary } from '@/scripts/get-note-summary';
|
||||||
import { MenuItem } from '@/types/menu';
|
import { MenuItem } from '@/types/menu';
|
||||||
import MkRippleEffect from '@/components/MkRippleEffect.vue';
|
import MkRippleEffect from '@/components/MkRippleEffect.vue';
|
||||||
|
import { showMovedDialog } from '@/scripts/show-moved-dialog';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
note: misskey.entities.Note;
|
note: misskey.entities.Note;
|
||||||
|
@ -255,6 +256,7 @@ useTooltip(renoteButton, async (showing) => {
|
||||||
|
|
||||||
function renote(viaKeyboard = false) {
|
function renote(viaKeyboard = false) {
|
||||||
pleaseLogin();
|
pleaseLogin();
|
||||||
|
showMovedDialog();
|
||||||
|
|
||||||
let items = [] as MenuItem[];
|
let items = [] as MenuItem[];
|
||||||
|
|
||||||
|
@ -335,6 +337,7 @@ function reply(viaKeyboard = false): void {
|
||||||
|
|
||||||
function react(viaKeyboard = false): void {
|
function react(viaKeyboard = false): void {
|
||||||
pleaseLogin();
|
pleaseLogin();
|
||||||
|
showMovedDialog();
|
||||||
if (appearNote.reactionAcceptance === 'likeOnly') {
|
if (appearNote.reactionAcceptance === 'likeOnly') {
|
||||||
os.api('notes/reactions/create', {
|
os.api('notes/reactions/create', {
|
||||||
noteId: appearNote.id,
|
noteId: appearNote.id,
|
||||||
|
@ -401,6 +404,7 @@ async function clip() {
|
||||||
|
|
||||||
function showRenoteMenu(viaKeyboard = false): void {
|
function showRenoteMenu(viaKeyboard = false): void {
|
||||||
if (!isMyRenote) return;
|
if (!isMyRenote) return;
|
||||||
|
pleaseLogin();
|
||||||
os.popupMenu([{
|
os.popupMenu([{
|
||||||
text: i18n.ts.unrenote,
|
text: i18n.ts.unrenote,
|
||||||
icon: 'ti ti-trash',
|
icon: 'ti ti-trash',
|
||||||
|
|
|
@ -166,6 +166,7 @@ import { useTooltip } from '@/scripts/use-tooltip';
|
||||||
import { claimAchievement } from '@/scripts/achievements';
|
import { claimAchievement } from '@/scripts/achievements';
|
||||||
import { MenuItem } from '@/types/menu';
|
import { MenuItem } from '@/types/menu';
|
||||||
import MkRippleEffect from '@/components/MkRippleEffect.vue';
|
import MkRippleEffect from '@/components/MkRippleEffect.vue';
|
||||||
|
import { showMovedDialog } from '@/scripts/show-moved-dialog';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
note: misskey.entities.Note;
|
note: misskey.entities.Note;
|
||||||
|
@ -248,6 +249,7 @@ useTooltip(renoteButton, async (showing) => {
|
||||||
|
|
||||||
function renote(viaKeyboard = false) {
|
function renote(viaKeyboard = false) {
|
||||||
pleaseLogin();
|
pleaseLogin();
|
||||||
|
showMovedDialog();
|
||||||
|
|
||||||
let items = [] as MenuItem[];
|
let items = [] as MenuItem[];
|
||||||
|
|
||||||
|
@ -318,6 +320,7 @@ function renote(viaKeyboard = false) {
|
||||||
|
|
||||||
function reply(viaKeyboard = false): void {
|
function reply(viaKeyboard = false): void {
|
||||||
pleaseLogin();
|
pleaseLogin();
|
||||||
|
showMovedDialog();
|
||||||
os.post({
|
os.post({
|
||||||
reply: appearNote,
|
reply: appearNote,
|
||||||
animation: !viaKeyboard,
|
animation: !viaKeyboard,
|
||||||
|
@ -328,6 +331,7 @@ function reply(viaKeyboard = false): void {
|
||||||
|
|
||||||
function react(viaKeyboard = false): void {
|
function react(viaKeyboard = false): void {
|
||||||
pleaseLogin();
|
pleaseLogin();
|
||||||
|
showMovedDialog();
|
||||||
if (appearNote.reactionAcceptance === 'likeOnly') {
|
if (appearNote.reactionAcceptance === 'likeOnly') {
|
||||||
os.api('notes/reactions/create', {
|
os.api('notes/reactions/create', {
|
||||||
noteId: appearNote.id,
|
noteId: appearNote.id,
|
||||||
|
@ -394,6 +398,7 @@ async function clip() {
|
||||||
|
|
||||||
function showRenoteMenu(viaKeyboard = false): void {
|
function showRenoteMenu(viaKeyboard = false): void {
|
||||||
if (!isMyRenote) return;
|
if (!isMyRenote) return;
|
||||||
|
pleaseLogin();
|
||||||
os.popupMenu([{
|
os.popupMenu([{
|
||||||
text: i18n.ts.unrenote,
|
text: i18n.ts.unrenote,
|
||||||
icon: 'ti ti-trash',
|
icon: 'ti ti-trash',
|
||||||
|
|
|
@ -18,7 +18,7 @@ import MkPopupMenu from '@/components/MkPopupMenu.vue';
|
||||||
import MkContextMenu from '@/components/MkContextMenu.vue';
|
import MkContextMenu from '@/components/MkContextMenu.vue';
|
||||||
import { MenuItem } from '@/types/menu';
|
import { MenuItem } from '@/types/menu';
|
||||||
import copyToClipboard from './scripts/copy-to-clipboard';
|
import copyToClipboard from './scripts/copy-to-clipboard';
|
||||||
import { $i } from './account';
|
import { showMovedDialog } from './scripts/show-moved-dialog';
|
||||||
|
|
||||||
export const openingWindowsCount = ref(0);
|
export const openingWindowsCount = ref(0);
|
||||||
|
|
||||||
|
@ -579,13 +579,7 @@ export function contextMenu(items: MenuItem[] | Ref<MenuItem[]>, ev: MouseEvent)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function post(props: Record<string, any> = {}): Promise<void> {
|
export function post(props: Record<string, any> = {}): Promise<void> {
|
||||||
if ($i && $i.movedTo) {
|
showMovedDialog();
|
||||||
return alert({
|
|
||||||
type: 'error',
|
|
||||||
title: i18n.ts.accountMovedShort,
|
|
||||||
text: i18n.ts.operationForbidden,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
// NOTE: MkPostFormDialogをdynamic importするとiOSでテキストエリアに自動フォーカスできない
|
// NOTE: MkPostFormDialogをdynamic importするとiOSでテキストエリアに自動フォーカスできない
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
<MkButton primary :class="$style.button" inline @click="exportFollowing()"><i class="ti ti-download"></i> {{ i18n.ts.export }}</MkButton>
|
<MkButton primary :class="$style.button" inline @click="exportFollowing()"><i class="ti ti-download"></i> {{ i18n.ts.export }}</MkButton>
|
||||||
</div>
|
</div>
|
||||||
</MkFolder>
|
</MkFolder>
|
||||||
<MkFolder>
|
<MkFolder v-if="$i && !$i.movedTo">
|
||||||
<template #label>{{ i18n.ts.import }}</template>
|
<template #label>{{ i18n.ts.import }}</template>
|
||||||
<template #icon><i class="ti ti-upload"></i></template>
|
<template #icon><i class="ti ti-upload"></i></template>
|
||||||
<MkButton primary :class="$style.button" inline @click="importFollowing($event)"><i class="ti ti-upload"></i> {{ i18n.ts.import }}</MkButton>
|
<MkButton primary :class="$style.button" inline @click="importFollowing($event)"><i class="ti ti-upload"></i> {{ i18n.ts.import }}</MkButton>
|
||||||
|
@ -47,7 +47,7 @@
|
||||||
<template #icon><i class="ti ti-download"></i></template>
|
<template #icon><i class="ti ti-download"></i></template>
|
||||||
<MkButton primary :class="$style.button" inline @click="exportUserLists()"><i class="ti ti-download"></i> {{ i18n.ts.export }}</MkButton>
|
<MkButton primary :class="$style.button" inline @click="exportUserLists()"><i class="ti ti-download"></i> {{ i18n.ts.export }}</MkButton>
|
||||||
</MkFolder>
|
</MkFolder>
|
||||||
<MkFolder>
|
<MkFolder v-if="$i && !$i.movedTo">
|
||||||
<template #label>{{ i18n.ts.import }}</template>
|
<template #label>{{ i18n.ts.import }}</template>
|
||||||
<template #icon><i class="ti ti-upload"></i></template>
|
<template #icon><i class="ti ti-upload"></i></template>
|
||||||
<MkButton primary :class="$style.button" inline @click="importUserLists($event)"><i class="ti ti-upload"></i> {{ i18n.ts.import }}</MkButton>
|
<MkButton primary :class="$style.button" inline @click="importUserLists($event)"><i class="ti ti-upload"></i> {{ i18n.ts.import }}</MkButton>
|
||||||
|
@ -62,7 +62,7 @@
|
||||||
<template #icon><i class="ti ti-download"></i></template>
|
<template #icon><i class="ti ti-download"></i></template>
|
||||||
<MkButton primary :class="$style.button" inline @click="exportMuting()"><i class="ti ti-download"></i> {{ i18n.ts.export }}</MkButton>
|
<MkButton primary :class="$style.button" inline @click="exportMuting()"><i class="ti ti-download"></i> {{ i18n.ts.export }}</MkButton>
|
||||||
</MkFolder>
|
</MkFolder>
|
||||||
<MkFolder>
|
<MkFolder v-if="$i && !$i.movedTo">
|
||||||
<template #label>{{ i18n.ts.import }}</template>
|
<template #label>{{ i18n.ts.import }}</template>
|
||||||
<template #icon><i class="ti ti-upload"></i></template>
|
<template #icon><i class="ti ti-upload"></i></template>
|
||||||
<MkButton primary :class="$style.button" inline @click="importMuting($event)"><i class="ti ti-upload"></i> {{ i18n.ts.import }}</MkButton>
|
<MkButton primary :class="$style.button" inline @click="importMuting($event)"><i class="ti ti-upload"></i> {{ i18n.ts.import }}</MkButton>
|
||||||
|
@ -77,7 +77,7 @@
|
||||||
<template #icon><i class="ti ti-download"></i></template>
|
<template #icon><i class="ti ti-download"></i></template>
|
||||||
<MkButton primary :class="$style.button" inline @click="exportBlocking()"><i class="ti ti-download"></i> {{ i18n.ts.export }}</MkButton>
|
<MkButton primary :class="$style.button" inline @click="exportBlocking()"><i class="ti ti-download"></i> {{ i18n.ts.export }}</MkButton>
|
||||||
</MkFolder>
|
</MkFolder>
|
||||||
<MkFolder>
|
<MkFolder v-if="$i && !$i.movedTo">
|
||||||
<template #label>{{ i18n.ts.import }}</template>
|
<template #label>{{ i18n.ts.import }}</template>
|
||||||
<template #icon><i class="ti ti-upload"></i></template>
|
<template #icon><i class="ti ti-upload"></i></template>
|
||||||
<MkButton primary :class="$style.button" inline @click="importBlocking($event)"><i class="ti ti-upload"></i> {{ i18n.ts.import }}</MkButton>
|
<MkButton primary :class="$style.button" inline @click="importBlocking($event)"><i class="ti ti-upload"></i> {{ i18n.ts.import }}</MkButton>
|
||||||
|
@ -97,6 +97,7 @@ import * as os from '@/os';
|
||||||
import { selectFile } from '@/scripts/select-file';
|
import { selectFile } from '@/scripts/select-file';
|
||||||
import { i18n } from '@/i18n';
|
import { i18n } from '@/i18n';
|
||||||
import { definePageMetadata } from '@/scripts/page-metadata';
|
import { definePageMetadata } from '@/scripts/page-metadata';
|
||||||
|
import { $i } from '@/account';
|
||||||
|
|
||||||
const excludeMutingUsers = ref(false);
|
const excludeMutingUsers = ref(false);
|
||||||
const excludeInactiveUsers = ref(false);
|
const excludeInactiveUsers = ref(false);
|
||||||
|
|
|
@ -464,6 +464,7 @@ const claimingQueue = new Set<string>();
|
||||||
|
|
||||||
export async function claimAchievement(type: typeof ACHIEVEMENT_TYPES[number]) {
|
export async function claimAchievement(type: typeof ACHIEVEMENT_TYPES[number]) {
|
||||||
if ($i == null) return;
|
if ($i == null) return;
|
||||||
|
if ($i.movedTo) return;
|
||||||
if (claimedAchievements.includes(type)) return;
|
if (claimedAchievements.includes(type)) return;
|
||||||
claimingQueue.add(type);
|
claimingQueue.add(type);
|
||||||
claimedAchievements.push(type);
|
claimedAchievements.push(type);
|
||||||
|
|
|
@ -17,5 +17,5 @@ export function pleaseLogin(path?: string) {
|
||||||
},
|
},
|
||||||
}, 'closed');
|
}, 'closed');
|
||||||
|
|
||||||
if (!path) throw new Error('signin required');
|
throw new Error('signin required');
|
||||||
}
|
}
|
||||||
|
|
16
packages/frontend/src/scripts/show-moved-dialog.ts
Normal file
16
packages/frontend/src/scripts/show-moved-dialog.ts
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
import * as os from '@/os';
|
||||||
|
import { $i } from '@/account';
|
||||||
|
import { i18n } from '@/i18n';
|
||||||
|
|
||||||
|
export function showMovedDialog() {
|
||||||
|
if (!$i) return;
|
||||||
|
if (!$i.movedTo) return;
|
||||||
|
|
||||||
|
os.alert({
|
||||||
|
type: 'error',
|
||||||
|
title: i18n.ts.accountMovedShort,
|
||||||
|
text: i18n.ts.operationForbidden,
|
||||||
|
});
|
||||||
|
|
||||||
|
throw new Error('account moved');
|
||||||
|
}
|
Loading…
Reference in a new issue