diff --git a/locales/index.d.ts b/locales/index.d.ts
index f1626a3212..387f92f456 100644
--- a/locales/index.d.ts
+++ b/locales/index.d.ts
@@ -10378,6 +10378,10 @@ export interface Locale extends ILocale {
* Scheduled Note was posted
*/
"scheduledNotePosted": string;
+ /**
+ * Import of {x} has been completed
+ */
+ "importOfXCompleted": ParameterizedString<"x">;
};
"_deck": {
/**
diff --git a/packages/backend/src/core/entities/NotificationEntityService.ts b/packages/backend/src/core/entities/NotificationEntityService.ts
index cc8edfc666..bb956b1097 100644
--- a/packages/backend/src/core/entities/NotificationEntityService.ts
+++ b/packages/backend/src/core/entities/NotificationEntityService.ts
@@ -187,6 +187,10 @@ export class NotificationEntityService implements OnModuleInit {
exportedEntity: notification.exportedEntity,
fileId: notification.fileId,
} : {}),
+ ...(notification.type === 'importCompleted' ? {
+ importedEntity: notification.importedEntity,
+ fileId: notification.fileId,
+ } : {}),
...(notification.type === 'scheduledNoteFailed' ? {
reason: notification.reason,
} : {}),
diff --git a/packages/backend/src/models/Notification.ts b/packages/backend/src/models/Notification.ts
index cff95cbf6e..1f87c1068d 100644
--- a/packages/backend/src/models/Notification.ts
+++ b/packages/backend/src/models/Notification.ts
@@ -3,7 +3,7 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
-import { userExportableEntities } from '@/types.js';
+import { userExportableEntities, userImportableEntities } from '@/types.js';
import { MiUser } from './User.js';
import { MiNote } from './Note.js';
import { MiAccessToken } from './AccessToken.js';
@@ -92,6 +92,12 @@ export type MiNotification = {
createdAt: string;
exportedEntity: typeof userExportableEntities[number];
fileId: MiDriveFile['id'];
+} | {
+ type: 'importCompleted';
+ id: string;
+ createdAt: string;
+ importedEntity: typeof userImportableEntities[number];
+ fileId?: MiDriveFile['id'];
} | {
type: 'login';
id: string;
diff --git a/packages/backend/src/models/json-schema/notification.ts b/packages/backend/src/models/json-schema/notification.ts
index 79c41e7e46..2663b2f5f8 100644
--- a/packages/backend/src/models/json-schema/notification.ts
+++ b/packages/backend/src/models/json-schema/notification.ts
@@ -3,7 +3,7 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
-import { notificationTypes, userExportableEntities } from '@/types.js';
+import { notificationTypes, userExportableEntities, userImportableEntities } from '@/types.js';
const baseSchema = {
type: 'object',
@@ -334,6 +334,26 @@ export const packedNotificationSchema = {
format: 'id',
},
},
+ }, {
+ type: 'object',
+ properties: {
+ ...baseSchema.properties,
+ type: {
+ type: 'string',
+ optional: false, nullable: false,
+ enum: ['importCompleted'],
+ },
+ importedEntity: {
+ type: 'string',
+ optional: false, nullable: false,
+ enum: userImportableEntities,
+ },
+ fileId: {
+ type: 'string',
+ optional: false, nullable: false,
+ format: 'id',
+ },
+ },
}, {
type: 'object',
properties: {
diff --git a/packages/backend/src/queue/processors/ImportAntennasProcessorService.ts b/packages/backend/src/queue/processors/ImportAntennasProcessorService.ts
index f29a19ce66..35e31b9533 100644
--- a/packages/backend/src/queue/processors/ImportAntennasProcessorService.ts
+++ b/packages/backend/src/queue/processors/ImportAntennasProcessorService.ts
@@ -12,6 +12,7 @@ import type { AntennasRepository, UsersRepository } from '@/models/_.js';
import { DI } from '@/di-symbols.js';
import { bindThis } from '@/decorators.js';
import { QueueLoggerService } from '../QueueLoggerService.js';
+import { NotificationService } from '@/core/NotificationService.js';
import { DBAntennaImportJobData } from '../types.js';
import type * as Bull from 'bullmq';
@@ -65,6 +66,7 @@ export class ImportAntennasProcessorService {
private queueLoggerService: QueueLoggerService,
private idService: IdService,
private globalEventService: GlobalEventService,
+ private notificationService: NotificationService,
) {
this.logger = this.queueLoggerService.logger.createSubLogger('import-antennas');
}
@@ -106,6 +108,10 @@ export class ImportAntennasProcessorService {
this.logger.debug('Antenna created: ' + result.id);
this.globalEventService.publishInternalEvent('antennaCreated', result);
}
+
+ this.notificationService.createNotification(job.data.user.id, 'importCompleted', {
+ importedEntity: 'antenna',
+ });
} catch (err: any) {
this.logger.error('Error importing antennas:', err);
}
diff --git a/packages/backend/src/queue/processors/ImportCustomEmojisProcessorService.ts b/packages/backend/src/queue/processors/ImportCustomEmojisProcessorService.ts
index 4b909328cd..3be5b8401b 100644
--- a/packages/backend/src/queue/processors/ImportCustomEmojisProcessorService.ts
+++ b/packages/backend/src/queue/processors/ImportCustomEmojisProcessorService.ts
@@ -18,6 +18,7 @@ import { bindThis } from '@/decorators.js';
import type { Config } from '@/config.js';
import { renderInlineError } from '@/misc/render-inline-error.js';
import { QueueLoggerService } from '../QueueLoggerService.js';
+import { NotificationService } from '@/core/NotificationService.js';
import type * as Bull from 'bullmq';
import type { DbUserImportJobData } from '../types.js';
@@ -40,6 +41,7 @@ export class ImportCustomEmojisProcessorService {
private driveService: DriveService,
private downloadService: DownloadService,
private queueLoggerService: QueueLoggerService,
+ private notificationService: NotificationService,
) {
this.logger = this.queueLoggerService.logger.createSubLogger('import-custom-emojis');
}
@@ -127,7 +129,12 @@ export class ImportCustomEmojisProcessorService {
cleanup();
- this.logger.debug('Imported');
+ this.notificationService.createNotification(job.data.user.id, 'importCompleted', {
+ importedEntity: 'customEmoji',
+ fileId: file.id,
+ });
+
+ this.logger.debug('Imported', file.name);
} catch (e) {
this.logger.error('Error importing custom emojis:', e as Error);
cleanup();
diff --git a/packages/backend/src/queue/processors/ImportMutingProcessorService.ts b/packages/backend/src/queue/processors/ImportMutingProcessorService.ts
index d3827b12fd..492f3785e8 100644
--- a/packages/backend/src/queue/processors/ImportMutingProcessorService.ts
+++ b/packages/backend/src/queue/processors/ImportMutingProcessorService.ts
@@ -16,6 +16,7 @@ import { UtilityService } from '@/core/UtilityService.js';
import { bindThis } from '@/decorators.js';
import { renderInlineError } from '@/misc/render-inline-error.js';
import { QueueLoggerService } from '../QueueLoggerService.js';
+import { NotificationService } from '@/core/NotificationService.js';
import type * as Bull from 'bullmq';
import type { DbUserImportJobData } from '../types.js';
@@ -35,6 +36,7 @@ export class ImportMutingProcessorService {
private remoteUserResolveService: RemoteUserResolveService,
private downloadService: DownloadService,
private queueLoggerService: QueueLoggerService,
+ private notificationService: NotificationService,
) {
this.logger = this.queueLoggerService.logger.createSubLogger('import-muting');
}
@@ -99,6 +101,11 @@ export class ImportMutingProcessorService {
}
}
+ this.notificationService.createNotification(job.data.user.id, 'importCompleted', {
+ importedEntity: 'muting',
+ fileId: file.id,
+ });
+
this.logger.debug('Imported');
}
}
diff --git a/packages/backend/src/queue/processors/ImportUserListsProcessorService.ts b/packages/backend/src/queue/processors/ImportUserListsProcessorService.ts
index 482054e52f..059a2a9773 100644
--- a/packages/backend/src/queue/processors/ImportUserListsProcessorService.ts
+++ b/packages/backend/src/queue/processors/ImportUserListsProcessorService.ts
@@ -17,6 +17,7 @@ import { UtilityService } from '@/core/UtilityService.js';
import { bindThis } from '@/decorators.js';
import { renderInlineError } from '@/misc/render-inline-error.js';
import { QueueLoggerService } from '../QueueLoggerService.js';
+import { NotificationService } from '@/core/NotificationService.js';
import type * as Bull from 'bullmq';
import type { DbUserImportJobData } from '../types.js';
@@ -43,6 +44,7 @@ export class ImportUserListsProcessorService {
private remoteUserResolveService: RemoteUserResolveService,
private downloadService: DownloadService,
private queueLoggerService: QueueLoggerService,
+ private notificationService: NotificationService,
) {
this.logger = this.queueLoggerService.logger.createSubLogger('import-user-lists');
}
@@ -109,6 +111,11 @@ export class ImportUserListsProcessorService {
}
}
+ this.notificationService.createNotification(job.data.user.id, 'importCompleted', {
+ importedEntity: 'userList',
+ fileId: file.id,
+ });
+
this.logger.debug('Imported');
}
}
diff --git a/packages/backend/src/types.ts b/packages/backend/src/types.ts
index 53eb4e6f3e..8aa047a3ab 100644
--- a/packages/backend/src/types.ts
+++ b/packages/backend/src/types.ts
@@ -39,6 +39,7 @@ export const notificationTypes = [
'chatRoomInvitationReceived',
'achievementEarned',
'exportCompleted',
+ 'importCompleted',
'login',
'createToken',
'scheduledNoteFailed',
diff --git a/packages/frontend-shared/js/const.ts b/packages/frontend-shared/js/const.ts
index bded34ea41..8e9bf86705 100644
--- a/packages/frontend-shared/js/const.ts
+++ b/packages/frontend-shared/js/const.ts
@@ -129,6 +129,7 @@ export const notificationTypes = [
'chatRoomInvitationReceived',
'achievementEarned',
'exportCompleted',
+ 'importCompleted',
'login',
'createToken',
'test',
diff --git a/packages/frontend/src/components/MkNotification.vue b/packages/frontend/src/components/MkNotification.vue
index d42905fd6b..bd15dab26d 100644
--- a/packages/frontend/src/components/MkNotification.vue
+++ b/packages/frontend/src/components/MkNotification.vue
@@ -7,7 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only
-
+
@@ -25,6 +25,7 @@ SPDX-License-Identifier: AGPL-3.0-only
[$style.t_pollEnded]: notification.type === 'pollEnded',
[$style.t_achievementEarned]: notification.type === 'achievementEarned',
[$style.t_exportCompleted]: notification.type === 'exportCompleted',
+ [$style.t_importCompleted]: notification.type === 'importCompleted',
[$style.t_login]: notification.type === 'login',
[$style.t_createToken]: notification.type === 'createToken',
[$style.t_chatRoomInvitationReceived]: notification.type === 'chatRoomInvitationReceived',
@@ -44,6 +45,7 @@ SPDX-License-Identifier: AGPL-3.0-only
+
@@ -75,6 +77,7 @@ SPDX-License-Identifier: AGPL-3.0-only
{{ i18n.ts._notification.createToken }}
{{ i18n.ts._notification.testNotification }}
{{ i18n.tsx._notification.exportOfXCompleted({ x: exportEntityName[notification.exportedEntity] }) }}
+
{{ i18n.tsx._notification.importOfXCompleted({ x: importEntityName[notification.importedEntity] }) }}
{{ i18n.tsx._notification.likedBySomeUsers({ n: getActualReactedUsersCount(notification) }) }}
{{ i18n.tsx._notification.reactedBySomeUsers({ n: getActualReactedUsersCount(notification) }) }}
@@ -122,7 +125,7 @@ SPDX-License-Identifier: AGPL-3.0-only
{{ i18n.ts._achievements._types['_' + notification.achievement].title }}
-
+
{{ i18n.ts.showFile }}
@@ -219,18 +222,10 @@ const props = withDefaults(defineProps<{
});
type ExportCompletedNotification = Misskey.entities.Notification & { type: 'exportCompleted' };
+type ImportCompletedNotification = Misskey.entities.Notification & { type: 'importCompleted' };
-const exportEntityName = {
- antenna: i18n.ts.antennas,
- blocking: i18n.ts.blockedUsers,
- clip: i18n.ts.clips,
- customEmoji: i18n.ts.customEmojis,
- favorite: i18n.ts.favorites,
- following: i18n.ts.following,
- muting: i18n.ts.mutedUsers,
- note: i18n.ts.notes,
- userList: i18n.ts.lists,
-} as const satisfies Record;
+const exportEntityName = Misskey.entities.exportEntityName(i18n);
+const importEntityName = Misskey.entities.importEntityName(i18n);
const followRequestDone = ref(true);
const userDetailed: Ref = ref(null);
@@ -398,7 +393,7 @@ function getActualReactedUsersCount(notification: Misskey.entities.Notification)
pointer-events: none;
}
-.t_exportCompleted {
+.t_exportCompleted, .t_importCompleted {
background: var(--eventOther);
pointer-events: none;
}
diff --git a/packages/frontend/src/pages/settings/notifications.vue b/packages/frontend/src/pages/settings/notifications.vue
index 168bff681d..e1cf4dac4d 100644
--- a/packages/frontend/src/pages/settings/notifications.vue
+++ b/packages/frontend/src/pages/settings/notifications.vue
@@ -85,7 +85,7 @@ import MkFeatureBanner from '@/components/MkFeatureBanner.vue';
const $i = ensureSignin();
-const nonConfigurableNotificationTypes = ['note', 'roleAssigned', 'followRequestAccepted', 'test', 'exportCompleted'] satisfies (typeof notificationTypes[number])[] as string[];
+const nonConfigurableNotificationTypes = ['note', 'roleAssigned', 'followRequestAccepted', 'test', 'exportCompleted', 'importCompleted'] satisfies (typeof notificationTypes[number])[] as string[];
const onlyOnOrOffNotificationTypes = ['app', 'achievementEarned', 'login', 'createToken', 'scheduledNoteFailed', 'scheduledNotePosted'] satisfies (typeof notificationTypes[number])[] as string[];
diff --git a/packages/misskey-js/etc/misskey-js.api.md b/packages/misskey-js/etc/misskey-js.api.md
index 2b0f4b1ba2..94accf852e 100644
--- a/packages/misskey-js/etc/misskey-js.api.md
+++ b/packages/misskey-js/etc/misskey-js.api.md
@@ -164,6 +164,9 @@ type AdminDeleteAccountRequest = operations['admin___delete-account']['requestBo
// @public (undocumented)
type AdminDeleteAllFilesOfAUserRequest = operations['admin___delete-all-files-of-a-user']['requestBody']['content']['application/json'];
+// @public (undocumented)
+type AdminDriveCleanRemoteFilesRequest = operations['admin___drive___clean-remote-files']['requestBody']['content']['application/json'];
+
// @public (undocumented)
type AdminDriveFilesRequest = operations['admin___drive___files']['requestBody']['content']['application/json'];
@@ -1498,6 +1501,8 @@ declare namespace entities {
SigninWithPasskeyInitResponse,
SigninWithPasskeyResponse,
PartialRolePolicyOverride,
+ exportEntityName,
+ importEntityName,
EmptyRequest,
EmptyResponse,
AdminAbuseReportNotificationRecipientCreateRequest,
@@ -1541,6 +1546,7 @@ declare namespace entities {
AdminDeclineUserRequest,
AdminDeleteAccountRequest,
AdminDeleteAllFilesOfAUserRequest,
+ AdminDriveCleanRemoteFilesRequest,
AdminDriveFilesRequest,
AdminDriveFilesResponse,
AdminDriveShowFileRequest,
@@ -2230,6 +2236,19 @@ export { entities }
// @public (undocumented)
type Error_2 = components['schemas']['Error'];
+// @public (undocumented)
+const exportEntityName: (i18n: any) => {
+ readonly antenna: any;
+ readonly blocking: any;
+ readonly clip: any;
+ readonly customEmoji: any;
+ readonly favorite: any;
+ readonly following: any;
+ readonly muting: any;
+ readonly note: any;
+ readonly userList: any;
+};
+
// @public (undocumented)
type FederationFollowersRequest = operations['federation___followers']['requestBody']['content']['application/json'];
@@ -2607,6 +2626,19 @@ type IMoveRequest = operations['i___move']['requestBody']['content']['applicatio
// @public (undocumented)
type IMoveResponse = operations['i___move']['responses']['200']['content']['application/json'];
+// @public (undocumented)
+const importEntityName: (i18n: any) => {
+ readonly antenna: any;
+ readonly blocking: any;
+ readonly clip: any;
+ readonly customEmoji: any;
+ readonly favorite: any;
+ readonly following: any;
+ readonly muting: any;
+ readonly note: any;
+ readonly userList: any;
+};
+
// @public (undocumented)
type INotificationsGroupedRequest = operations['i___notifications-grouped']['requestBody']['content']['application/json'];
@@ -3919,7 +3951,7 @@ type V2AdminEmojiListResponse = operations['v2___admin___emoji___list']['respons
// Warnings were encountered during analysis:
//
-// src/entities.ts:50:2 - (ae-forgotten-export) The symbol "ModerationLogPayloads" needs to be exported by the entry point index.d.ts
+// src/entities.ts:51:2 - (ae-forgotten-export) The symbol "ModerationLogPayloads" needs to be exported by the entry point index.d.ts
// src/streaming.ts:57:3 - (ae-forgotten-export) The symbol "ReconnectingWebSocket" needs to be exported by the entry point index.d.ts
// src/streaming.types.ts:234:4 - (ae-forgotten-export) The symbol "ReversiUpdateKey" needs to be exported by the entry point index.d.ts
// src/streaming.types.ts:244:4 - (ae-forgotten-export) The symbol "ReversiUpdateSettings" needs to be exported by the entry point index.d.ts
diff --git a/packages/misskey-js/src/autogen/endpoint.ts b/packages/misskey-js/src/autogen/endpoint.ts
index 4712c16265..5a40b74b8f 100644
--- a/packages/misskey-js/src/autogen/endpoint.ts
+++ b/packages/misskey-js/src/autogen/endpoint.ts
@@ -42,6 +42,7 @@ import type {
AdminDeclineUserRequest,
AdminDeleteAccountRequest,
AdminDeleteAllFilesOfAUserRequest,
+ AdminDriveCleanRemoteFilesRequest,
AdminDriveFilesRequest,
AdminDriveFilesResponse,
AdminDriveShowFileRequest,
@@ -691,7 +692,7 @@ export type Endpoints = {
'admin/decline-user': { req: AdminDeclineUserRequest; res: EmptyResponse };
'admin/delete-account': { req: AdminDeleteAccountRequest; res: EmptyResponse };
'admin/delete-all-files-of-a-user': { req: AdminDeleteAllFilesOfAUserRequest; res: EmptyResponse };
- 'admin/drive/clean-remote-files': { req: EmptyRequest; res: EmptyResponse };
+ 'admin/drive/clean-remote-files': { req: AdminDriveCleanRemoteFilesRequest; res: EmptyResponse };
'admin/drive/cleanup': { req: EmptyRequest; res: EmptyResponse };
'admin/drive/files': { req: AdminDriveFilesRequest; res: AdminDriveFilesResponse };
'admin/drive/show-file': { req: AdminDriveShowFileRequest; res: AdminDriveShowFileResponse };
diff --git a/packages/misskey-js/src/autogen/entities.ts b/packages/misskey-js/src/autogen/entities.ts
index e1ba4e9704..12f9b4c5ca 100644
--- a/packages/misskey-js/src/autogen/entities.ts
+++ b/packages/misskey-js/src/autogen/entities.ts
@@ -45,6 +45,7 @@ export type AdminCwUserRequest = operations['admin___cw-user']['requestBody']['c
export type AdminDeclineUserRequest = operations['admin___decline-user']['requestBody']['content']['application/json'];
export type AdminDeleteAccountRequest = operations['admin___delete-account']['requestBody']['content']['application/json'];
export type AdminDeleteAllFilesOfAUserRequest = operations['admin___delete-all-files-of-a-user']['requestBody']['content']['application/json'];
+export type AdminDriveCleanRemoteFilesRequest = operations['admin___drive___clean-remote-files']['requestBody']['content']['application/json'];
export type AdminDriveFilesRequest = operations['admin___drive___files']['requestBody']['content']['application/json'];
export type AdminDriveFilesResponse = operations['admin___drive___files']['responses']['200']['content']['application/json'];
export type AdminDriveShowFileRequest = operations['admin___drive___show-file']['requestBody']['content']['application/json'];
diff --git a/packages/misskey-js/src/autogen/types.ts b/packages/misskey-js/src/autogen/types.ts
index 4b02302f1d..4c6cb44a52 100644
--- a/packages/misskey-js/src/autogen/types.ts
+++ b/packages/misskey-js/src/autogen/types.ts
@@ -4912,6 +4912,17 @@ export type components = {
exportedEntity: 'antenna' | 'blocking' | 'clip' | 'customEmoji' | 'favorite' | 'following' | 'muting' | 'note' | 'userList';
/** Format: id */
fileId: string;
+ }) | ({
+ /** Format: id */
+ id: string;
+ /** Format: date-time */
+ createdAt: string;
+ /** @enum {string} */
+ type: 'importCompleted';
+ /** @enum {string} */
+ importedEntity: 'antenna' | 'blocking' | 'customEmoji' | 'following' | 'muting' | 'userList';
+ /** Format: id */
+ fileId: string;
}) | {
/** Format: id */
id: string;
@@ -7583,6 +7594,14 @@ export type operations = {
* **Credential required**: *Yes* / **Permission**: *write:admin:drive*
*/
'admin___drive___clean-remote-files': {
+ requestBody: {
+ content: {
+ 'application/json': {
+ olderThanSeconds?: number;
+ keepFilesInUse?: boolean;
+ };
+ };
+ };
responses: {
/** @description OK (without any results) */
204: {
@@ -23881,8 +23900,8 @@ export type operations = {
untilId?: string;
/** @default true */
markAsRead?: boolean;
- includeTypes?: ('note' | 'follow' | 'mention' | 'reply' | 'renote' | 'quote' | 'reaction' | 'pollEnded' | 'edited' | 'receiveFollowRequest' | 'followRequestAccepted' | 'roleAssigned' | 'chatRoomInvitationReceived' | 'achievementEarned' | 'exportCompleted' | 'login' | 'createToken' | 'scheduledNoteFailed' | 'scheduledNotePosted' | 'app' | 'test' | 'pollVote' | 'groupInvited')[];
- excludeTypes?: ('note' | 'follow' | 'mention' | 'reply' | 'renote' | 'quote' | 'reaction' | 'pollEnded' | 'edited' | 'receiveFollowRequest' | 'followRequestAccepted' | 'roleAssigned' | 'chatRoomInvitationReceived' | 'achievementEarned' | 'exportCompleted' | 'login' | 'createToken' | 'scheduledNoteFailed' | 'scheduledNotePosted' | 'app' | 'test' | 'pollVote' | 'groupInvited')[];
+ includeTypes?: ('note' | 'follow' | 'mention' | 'reply' | 'renote' | 'quote' | 'reaction' | 'pollEnded' | 'edited' | 'receiveFollowRequest' | 'followRequestAccepted' | 'roleAssigned' | 'chatRoomInvitationReceived' | 'achievementEarned' | 'exportCompleted' | 'importCompleted' | 'login' | 'createToken' | 'scheduledNoteFailed' | 'scheduledNotePosted' | 'app' | 'test' | 'pollVote' | 'groupInvited')[];
+ excludeTypes?: ('note' | 'follow' | 'mention' | 'reply' | 'renote' | 'quote' | 'reaction' | 'pollEnded' | 'edited' | 'receiveFollowRequest' | 'followRequestAccepted' | 'roleAssigned' | 'chatRoomInvitationReceived' | 'achievementEarned' | 'exportCompleted' | 'importCompleted' | 'login' | 'createToken' | 'scheduledNoteFailed' | 'scheduledNotePosted' | 'app' | 'test' | 'pollVote' | 'groupInvited')[];
};
};
};
@@ -23949,8 +23968,8 @@ export type operations = {
untilId?: string;
/** @default true */
markAsRead?: boolean;
- includeTypes?: ('note' | 'follow' | 'mention' | 'reply' | 'renote' | 'quote' | 'reaction' | 'pollEnded' | 'edited' | 'receiveFollowRequest' | 'followRequestAccepted' | 'roleAssigned' | 'chatRoomInvitationReceived' | 'achievementEarned' | 'exportCompleted' | 'login' | 'createToken' | 'scheduledNoteFailed' | 'scheduledNotePosted' | 'app' | 'test' | 'pollVote' | 'groupInvited')[];
- excludeTypes?: ('note' | 'follow' | 'mention' | 'reply' | 'renote' | 'quote' | 'reaction' | 'pollEnded' | 'edited' | 'receiveFollowRequest' | 'followRequestAccepted' | 'roleAssigned' | 'chatRoomInvitationReceived' | 'achievementEarned' | 'exportCompleted' | 'login' | 'createToken' | 'scheduledNoteFailed' | 'scheduledNotePosted' | 'app' | 'test' | 'pollVote' | 'groupInvited')[];
+ includeTypes?: ('note' | 'follow' | 'mention' | 'reply' | 'renote' | 'quote' | 'reaction' | 'pollEnded' | 'edited' | 'receiveFollowRequest' | 'followRequestAccepted' | 'roleAssigned' | 'chatRoomInvitationReceived' | 'achievementEarned' | 'exportCompleted' | 'importCompleted' | 'login' | 'createToken' | 'scheduledNoteFailed' | 'scheduledNotePosted' | 'app' | 'test' | 'pollVote' | 'groupInvited')[];
+ excludeTypes?: ('note' | 'follow' | 'mention' | 'reply' | 'renote' | 'quote' | 'reaction' | 'pollEnded' | 'edited' | 'receiveFollowRequest' | 'followRequestAccepted' | 'roleAssigned' | 'chatRoomInvitationReceived' | 'achievementEarned' | 'exportCompleted' | 'importCompleted' | 'login' | 'createToken' | 'scheduledNoteFailed' | 'scheduledNotePosted' | 'app' | 'test' | 'pollVote' | 'groupInvited')[];
};
};
};
diff --git a/packages/misskey-js/src/entities.ts b/packages/misskey-js/src/entities.ts
index 3ffa1d1a3a..29eb169ab8 100644
--- a/packages/misskey-js/src/entities.ts
+++ b/packages/misskey-js/src/entities.ts
@@ -4,6 +4,7 @@ import {
EmojiDetailed,
MeDetailed,
Note,
+ Notification,
Page,
Role,
RolePolicies,
@@ -395,3 +396,20 @@ export type SigninWithPasskeyResponse = {
type Values> = T[keyof T];
export type PartialRolePolicyOverride = Partial<{ [k in keyof RolePolicies]: Omit, 'value'> & { value: RolePolicies[k] } }>;
+
+type ExportCompletedNotification = Notification & { type: 'exportCompleted' };
+type ImportCompletedNotification = Notification & { type: 'importCompleted' };
+
+export const exportEntityName = (i18n: any) => ({
+ antenna: i18n.ts.antennas,
+ blocking: i18n.ts.blockedUsers,
+ clip: i18n.ts.clips,
+ customEmoji: i18n.ts.customEmojis,
+ favorite: i18n.ts.favorites,
+ following: i18n.ts.following,
+ muting: i18n.ts.mutedUsers,
+ note: i18n.ts.notes,
+ userList: i18n.ts.lists,
+} as const satisfies Record);
+
+export const importEntityName = (i18n: any) => (exportEntityName(i18n) satisfies Record);
diff --git a/packages/sw/src/scripts/create-notification.ts b/packages/sw/src/scripts/create-notification.ts
index 68b5db54b7..8b0c5d300d 100644
--- a/packages/sw/src/scripts/create-notification.ts
+++ b/packages/sw/src/scripts/create-notification.ts
@@ -6,6 +6,7 @@
/*
* Notification manager for SW
*/
+import * as Misskey from 'misskey-js';
import type { BadgeNames, PushNotificationDataMap } from '@/types.js';
import { char2fileName } from '@/scripts/twemoji-base.js';
import { cli } from '@/scripts/operations.js';
@@ -216,24 +217,17 @@ async function composeNotification(data: PushNotificationDataMap[keyof PushNotif
data,
}];
- case 'exportCompleted': {
- const entityName = {
- antenna: i18n.ts.antennas,
- blocking: i18n.ts.blockedUsers,
- clip: i18n.ts.clips,
- customEmoji: i18n.ts.customEmojis,
- favorite: i18n.ts.favorites,
- following: i18n.ts.following,
- muting: i18n.ts.mutedUsers,
- note: i18n.ts.notes,
- userList: i18n.ts.lists,
- } as const satisfies Record;
-
- return [i18n.tsx._notification.exportOfXCompleted({ x: entityName[data.body.exportedEntity] }), {
+ case 'exportCompleted':
+ return [i18n.tsx._notification.exportOfXCompleted({ x: Misskey.entities.exportEntityName(i18n)[data.body.exportedEntity] }), {
+ badge: iconUrl('circle-check'),
+ data,
+ }];
+
+ case 'importCompleted':
+ return [i18n.tsx._notification.importOfXCompleted({ x: Misskey.entities.importEntityName(i18n)[data.body.importedEntity] }), {
badge: iconUrl('circle-check'),
data,
}];
- }
case 'pollEnded':
return [i18n.ts._notification.pollEnded, {
diff --git a/sharkey-locales/en-US.yml b/sharkey-locales/en-US.yml
index f1eca19c00..c49b342f97 100644
--- a/sharkey-locales/en-US.yml
+++ b/sharkey-locales/en-US.yml
@@ -314,6 +314,7 @@ _notification:
edited: "Note got edited"
scheduledNoteFailed: "Posting scheduled note failed"
scheduledNotePosted: "Scheduled Note was posted"
+ importOfXCompleted: "Import of {x} has been completed"
_types:
renote: "Boosts"
edited: "Edits"