From 2528508cff9d8c90abd33e46b15220a49a00e2e2 Mon Sep 17 00:00:00 2001 From: NoriDev Date: Thu, 31 Oct 2024 13:52:01 +0900 Subject: feat: 노트 게시를 예약할 수 있음 (yojo-art/cherrypick#483, [Type4ny-Project/Type4ny@271c872c](https://github.com/Type4ny-Project/Type4ny/commit/271c872c97f215ef5d8e0be62251dd422a52e5b1)) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/components/MkNoteHeader.vue | 5 +- packages/frontend/src/components/MkNoteSimple.vue | 55 ++++++++++++++++- packages/frontend/src/components/MkPostForm.vue | 59 +++++++++++++++++- .../frontend/src/components/MkScheduleEditor.vue | 69 ++++++++++++++++++++++ .../src/components/MkSchedulePostListDialog.vue | 60 +++++++++++++++++++ 5 files changed, 243 insertions(+), 5 deletions(-) create mode 100644 packages/frontend/src/components/MkScheduleEditor.vue create mode 100644 packages/frontend/src/components/MkSchedulePostListDialog.vue (limited to 'packages/frontend/src/components') diff --git a/packages/frontend/src/components/MkNoteHeader.vue b/packages/frontend/src/components/MkNoteHeader.vue index cd6fdf576c..2c69048ec5 100644 --- a/packages/frontend/src/components/MkNoteHeader.vue +++ b/packages/frontend/src/components/MkNoteHeader.vue @@ -50,7 +50,10 @@ import { popupMenu } from '@/os.js'; import { defaultStore } from '@/store.js'; const props = defineProps<{ - note: Misskey.entities.Note; + note: Misskey.entities.Note & { + isSchedule?: boolean + }; + scheduled?: boolean; }>(); const menuVersionsButton = shallowRef(); diff --git a/packages/frontend/src/components/MkNoteSimple.vue b/packages/frontend/src/components/MkNoteSimple.vue index 542e3e79ea..7d2bbb31d3 100644 --- a/packages/frontend/src/components/MkNoteSimple.vue +++ b/packages/frontend/src/components/MkNoteSimple.vue @@ -4,7 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only --> + {{ i18n.tsx._notification.renotedBySomeUsers({ n: notification.users.length }) }} {{ notification.header }} {{ i18n.ts._notification.edited }} + {{ i18n.ts._notification.scheduledNoteFailed }}
@@ -109,6 +112,9 @@ SPDX-License-Identifier: AGPL-3.0-only {{ i18n.ts.showFile }} +
+ {{ notification.reason }} +
diff --git a/packages/frontend/src/components/MkPostForm.vue b/packages/frontend/src/components/MkPostForm.vue index 443e9e7ee9..bbde7c65f9 100644 --- a/packages/frontend/src/components/MkPostForm.vue +++ b/packages/frontend/src/components/MkPostForm.vue @@ -1046,8 +1046,9 @@ function openAccountMenu(ev: MouseEvent) { } function toggleScheduleNote() { - if (scheduleNote.value) scheduleNote.value = null; - else { + if (scheduleNote.value) { + scheduleNote.value = null; + } else { scheduleNote.value = { scheduledAt: null, }; diff --git a/packages/frontend/src/components/MkSchedulePostListDialog.vue b/packages/frontend/src/components/MkSchedulePostListDialog.vue index cfae94951b..d0716ead79 100644 --- a/packages/frontend/src/components/MkSchedulePostListDialog.vue +++ b/packages/frontend/src/components/MkSchedulePostListDialog.vue @@ -48,6 +48,7 @@ const cancel = () => { emit('cancel'); dialogEl.value.close(); }; + const paginationEl = ref(); const pagination: Paging = { endpoint: 'notes/schedule/list', diff --git a/packages/misskey-js/etc/misskey-js.api.md b/packages/misskey-js/etc/misskey-js.api.md index ca7a374a67..880be518fa 100644 --- a/packages/misskey-js/etc/misskey-js.api.md +++ b/packages/misskey-js/etc/misskey-js.api.md @@ -2890,7 +2890,7 @@ type Notification_2 = components['schemas']['Notification']; type NotificationsCreateRequest = operations['notifications___create']['requestBody']['content']['application/json']; // @public (undocumented) -export const notificationTypes: readonly ["note", "follow", "mention", "reply", "renote", "quote", "reaction", "pollVote", "pollEnded", "receiveFollowRequest", "followRequestAccepted", "groupInvited", "app", "roleAssigned", "achievementEarned", "edited"]; +export const notificationTypes: readonly ["note", "follow", "mention", "reply", "renote", "quote", "reaction", "pollVote", "pollEnded", "receiveFollowRequest", "followRequestAccepted", "groupInvited", "app", "roleAssigned", "achievementEarned", "edited", "scheduledNoteFailed"]; // @public (undocumented) export function nyaize(text: string): string; diff --git a/packages/misskey-js/src/autogen/types.ts b/packages/misskey-js/src/autogen/types.ts index c8d7194405..6eb1819037 100644 --- a/packages/misskey-js/src/autogen/types.ts +++ b/packages/misskey-js/src/autogen/types.ts @@ -4517,6 +4517,14 @@ export type components = { /** Format: id */ userId: string; note: components['schemas']['Note']; + } | { + /** Format: id */ + id: string; + /** Format: date-time */ + createdAt: string; + /** @enum {string} */ + type: 'scheduledNoteFailed'; + reason: string; } | { /** Format: id */ id: string; @@ -19984,8 +19992,8 @@ export type operations = { untilId?: string; /** @default true */ markAsRead?: boolean; - includeTypes?: ('note' | 'follow' | 'mention' | 'reply' | 'renote' | 'quote' | 'reaction' | 'pollEnded' | 'edited' | 'receiveFollowRequest' | 'followRequestAccepted' | 'roleAssigned' | 'achievementEarned' | 'exportCompleted' | 'app' | 'test' | 'pollVote' | 'groupInvited')[]; - excludeTypes?: ('note' | 'follow' | 'mention' | 'reply' | 'renote' | 'quote' | 'reaction' | 'pollEnded' | 'edited' | 'receiveFollowRequest' | 'followRequestAccepted' | 'roleAssigned' | 'achievementEarned' | 'exportCompleted' | 'app' | 'test' | 'pollVote' | 'groupInvited')[]; + includeTypes?: ('note' | 'follow' | 'mention' | 'reply' | 'renote' | 'quote' | 'reaction' | 'pollEnded' | 'edited' | 'receiveFollowRequest' | 'followRequestAccepted' | 'roleAssigned' | 'achievementEarned' | 'exportCompleted' | 'scheduledNoteFailed' | 'app' | 'test' | 'pollVote' | 'groupInvited')[]; + excludeTypes?: ('note' | 'follow' | 'mention' | 'reply' | 'renote' | 'quote' | 'reaction' | 'pollEnded' | 'edited' | 'receiveFollowRequest' | 'followRequestAccepted' | 'roleAssigned' | 'achievementEarned' | 'exportCompleted' | 'scheduledNoteFailed' | 'app' | 'test' | 'pollVote' | 'groupInvited')[]; }; }; }; @@ -20052,8 +20060,8 @@ export type operations = { untilId?: string; /** @default true */ markAsRead?: boolean; - includeTypes?: ('note' | 'follow' | 'mention' | 'reply' | 'renote' | 'quote' | 'reaction' | 'pollEnded' | 'edited' | 'receiveFollowRequest' | 'followRequestAccepted' | 'roleAssigned' | 'achievementEarned' | 'exportCompleted' | 'app' | 'test' | 'reaction:grouped' | 'renote:grouped' | 'pollVote' | 'groupInvited')[]; - excludeTypes?: ('note' | 'follow' | 'mention' | 'reply' | 'renote' | 'quote' | 'reaction' | 'pollEnded' | 'edited' | 'receiveFollowRequest' | 'followRequestAccepted' | 'roleAssigned' | 'achievementEarned' | 'exportCompleted' | 'app' | 'test' | 'reaction:grouped' | 'renote:grouped' | 'pollVote' | 'groupInvited')[]; + includeTypes?: ('note' | 'follow' | 'mention' | 'reply' | 'renote' | 'quote' | 'reaction' | 'pollEnded' | 'edited' | 'receiveFollowRequest' | 'followRequestAccepted' | 'roleAssigned' | 'achievementEarned' | 'exportCompleted' | 'scheduledNoteFailed' | 'app' | 'test' | 'reaction:grouped' | 'renote:grouped' | 'pollVote' | 'groupInvited')[]; + excludeTypes?: ('note' | 'follow' | 'mention' | 'reply' | 'renote' | 'quote' | 'reaction' | 'pollEnded' | 'edited' | 'receiveFollowRequest' | 'followRequestAccepted' | 'roleAssigned' | 'achievementEarned' | 'exportCompleted' | 'scheduledNoteFailed' | 'app' | 'test' | 'reaction:grouped' | 'renote:grouped' | 'pollVote' | 'groupInvited')[]; }; }; }; diff --git a/packages/misskey-js/src/consts.ts b/packages/misskey-js/src/consts.ts index d090a6b46f..34fc7c1a03 100644 --- a/packages/misskey-js/src/consts.ts +++ b/packages/misskey-js/src/consts.ts @@ -16,7 +16,7 @@ import type { UserLite, } from './autogen/models.js'; -export const notificationTypes = ['note', 'follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollVote', 'pollEnded', 'receiveFollowRequest', 'followRequestAccepted', 'groupInvited', 'app', 'roleAssigned', 'achievementEarned', 'edited'] as const; +export const notificationTypes = ['note', 'follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollVote', 'pollEnded', 'receiveFollowRequest', 'followRequestAccepted', 'groupInvited', 'app', 'roleAssigned', 'achievementEarned', 'edited', 'scheduledNoteFailed'] as const; export const noteVisibilities = ['public', 'home', 'followers', 'specified'] as const; diff --git a/packages/sw/src/scripts/create-notification.ts b/packages/sw/src/scripts/create-notification.ts index 9c56e338c7..8442552e3b 100644 --- a/packages/sw/src/scripts/create-notification.ts +++ b/packages/sw/src/scripts/create-notification.ts @@ -258,6 +258,13 @@ async function composeNotification(data: PushNotificationDataMap[keyof PushNotif data, }]; + case 'scheduledNoteFailed': + return [i18n.ts._notification.scheduledNoteFailed, { + body: data.body.reason, + badge: iconUrl('bell'), + data, + }]; + default: return null; } diff --git a/sharkey-locales/en-US.yml b/sharkey-locales/en-US.yml index 79c362cfd8..582f4eda0a 100644 --- a/sharkey-locales/en-US.yml +++ b/sharkey-locales/en-US.yml @@ -277,6 +277,7 @@ _notification: youRenoted: "Boost from {name}" renotedBySomeUsers: "Boosted by {n} users" edited: "Note got edited" + scheduledNoteFailed: "Posting scheduled note failed" _types: renote: "Boosts" edited: "Edits" -- cgit v1.2.3-freya From 1d3c8253981fba2d431df2f5cc12dd78b21d37bc Mon Sep 17 00:00:00 2001 From: Marie Date: Mon, 4 Nov 2024 11:22:37 +0100 Subject: upd: add notification for when scheduled note gets posted --- locales/index.d.ts | 4 ++++ .../src/core/entities/NotificationEntityService.ts | 2 +- packages/backend/src/models/Notification.ts | 5 +++++ .../backend/src/models/json-schema/notification.ts | 25 ++++++++++++++++++++++ .../processors/ScheduleNotePostProcessorService.ts | 5 ++++- packages/backend/src/types.ts | 1 + packages/frontend-shared/js/const.ts | 1 + .../frontend/src/components/MkNotification.vue | 11 +++++++++- packages/misskey-js/etc/misskey-js.api.md | 2 +- packages/misskey-js/src/autogen/types.ts | 19 ++++++++++++---- packages/misskey-js/src/consts.ts | 2 +- packages/sw/src/scripts/create-notification.ts | 8 +++++++ sharkey-locales/en-US.yml | 1 + 13 files changed, 77 insertions(+), 9 deletions(-) (limited to 'packages/frontend/src/components') diff --git a/locales/index.d.ts b/locales/index.d.ts index 4cfc220731..89541e6414 100644 --- a/locales/index.d.ts +++ b/locales/index.d.ts @@ -9562,6 +9562,10 @@ export interface Locale extends ILocale { * Posting scheduled note failed */ "scheduledNoteFailed": string; + /** + * Scheduled Note was posted + */ + "scheduledNotePosted": string; }; "_deck": { /** diff --git a/packages/backend/src/core/entities/NotificationEntityService.ts b/packages/backend/src/core/entities/NotificationEntityService.ts index 447d95cc68..31a9809323 100644 --- a/packages/backend/src/core/entities/NotificationEntityService.ts +++ b/packages/backend/src/core/entities/NotificationEntityService.ts @@ -20,7 +20,7 @@ import type { OnModuleInit } from '@nestjs/common'; import type { UserEntityService } from './UserEntityService.js'; import type { NoteEntityService } from './NoteEntityService.js'; -const NOTE_REQUIRED_NOTIFICATION_TYPES = new Set(['note', 'mention', 'reply', 'renote', 'renote:grouped', 'quote', 'reaction', 'reaction:grouped', 'pollEnded', 'edited'] as (typeof groupedNotificationTypes[number])[]); +const NOTE_REQUIRED_NOTIFICATION_TYPES = new Set(['note', 'mention', 'reply', 'renote', 'renote:grouped', 'quote', 'reaction', 'reaction:grouped', 'pollEnded', 'edited', 'scheduledNotePosted'] as (typeof groupedNotificationTypes[number])[]); @Injectable() export class NotificationEntityService implements OnModuleInit { diff --git a/packages/backend/src/models/Notification.ts b/packages/backend/src/models/Notification.ts index 5003e02d96..53003a0a5a 100644 --- a/packages/backend/src/models/Notification.ts +++ b/packages/backend/src/models/Notification.ts @@ -127,6 +127,11 @@ export type MiNotification = { id: string; createdAt: string; reason: string; +} | { + type: 'scheduledNotePosted'; + id: string; + createdAt: string; + noteId: MiNote['id']; }; export type MiGroupedNotification = MiNotification | { diff --git a/packages/backend/src/models/json-schema/notification.ts b/packages/backend/src/models/json-schema/notification.ts index 69bd9531ec..26498e3e9d 100644 --- a/packages/backend/src/models/json-schema/notification.ts +++ b/packages/backend/src/models/json-schema/notification.ts @@ -383,6 +383,31 @@ export const packedNotificationSchema = { optional: false, nullable: false, }, }, + }, { + type: 'object', + properties: { + ...baseSchema.properties, + type: { + type: 'string', + optional: false, nullable: false, + enum: ['scheduledNotePosted'], + }, + user: { + type: 'object', + ref: 'UserLite', + optional: false, nullable: false, + }, + userId: { + type: 'string', + optional: false, nullable: false, + format: 'id', + }, + note: { + type: 'object', + ref: 'Note', + optional: false, nullable: false, + }, + }, }, { type: 'object', properties: { diff --git a/packages/backend/src/queue/processors/ScheduleNotePostProcessorService.ts b/packages/backend/src/queue/processors/ScheduleNotePostProcessorService.ts index 59e23b865e..f281b0ed7b 100644 --- a/packages/backend/src/queue/processors/ScheduleNotePostProcessorService.ts +++ b/packages/backend/src/queue/processors/ScheduleNotePostProcessorService.ts @@ -107,7 +107,7 @@ export class ScheduleNotePostProcessorService { return; } - await this.noteCreateService.create(me, { + const createdNote = await this.noteCreateService.create(me, { ...note, createdAt: new Date(), files, @@ -121,6 +121,9 @@ export class ScheduleNotePostProcessorService { channel, }); await this.noteScheduleRepository.remove(data); + this.notificationService.createNotification(me.id, 'scheduledNotePosted', { + noteId: createdNote.id, + }); } }); } diff --git a/packages/backend/src/types.ts b/packages/backend/src/types.ts index 7930129002..95f049f768 100644 --- a/packages/backend/src/types.ts +++ b/packages/backend/src/types.ts @@ -36,6 +36,7 @@ export const notificationTypes = [ 'achievementEarned', 'exportCompleted', 'scheduledNoteFailed', + 'scheduledNotePosted', 'app', 'test', ] as const; diff --git a/packages/frontend-shared/js/const.ts b/packages/frontend-shared/js/const.ts index 5bc75db908..a6eebe8e15 100644 --- a/packages/frontend-shared/js/const.ts +++ b/packages/frontend-shared/js/const.ts @@ -132,6 +132,7 @@ export const notificationTypes = [ 'app', 'edited', 'scheduledNoteFailed', + 'scheduledNotePosted', ] as const; export const obsoleteNotificationTypes = ['pollVote', 'groupInvited'] as const; diff --git a/packages/frontend/src/components/MkNotification.vue b/packages/frontend/src/components/MkNotification.vue index 3c4f56b537..f713d46137 100644 --- a/packages/frontend/src/components/MkNotification.vue +++ b/packages/frontend/src/components/MkNotification.vue @@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only + {{ notification.header }} {{ i18n.ts._notification.edited }} {{ i18n.ts._notification.scheduledNoteFailed }} + {{ i18n.ts._notification.scheduledNotePosted }}
@@ -162,6 +165,12 @@ SPDX-License-Identifier: AGPL-3.0-only + + + + + +
diff --git a/packages/misskey-js/etc/misskey-js.api.md b/packages/misskey-js/etc/misskey-js.api.md index 880be518fa..4a261028ed 100644 --- a/packages/misskey-js/etc/misskey-js.api.md +++ b/packages/misskey-js/etc/misskey-js.api.md @@ -2890,7 +2890,7 @@ type Notification_2 = components['schemas']['Notification']; type NotificationsCreateRequest = operations['notifications___create']['requestBody']['content']['application/json']; // @public (undocumented) -export const notificationTypes: readonly ["note", "follow", "mention", "reply", "renote", "quote", "reaction", "pollVote", "pollEnded", "receiveFollowRequest", "followRequestAccepted", "groupInvited", "app", "roleAssigned", "achievementEarned", "edited", "scheduledNoteFailed"]; +export const notificationTypes: readonly ["note", "follow", "mention", "reply", "renote", "quote", "reaction", "pollVote", "pollEnded", "receiveFollowRequest", "followRequestAccepted", "groupInvited", "app", "roleAssigned", "achievementEarned", "edited", "scheduledNoteFailed", "scheduledNotePosted"]; // @public (undocumented) export function nyaize(text: string): string; diff --git a/packages/misskey-js/src/autogen/types.ts b/packages/misskey-js/src/autogen/types.ts index 6eb1819037..29c2e814d2 100644 --- a/packages/misskey-js/src/autogen/types.ts +++ b/packages/misskey-js/src/autogen/types.ts @@ -4525,6 +4525,17 @@ export type components = { /** @enum {string} */ type: 'scheduledNoteFailed'; reason: string; + } | { + /** Format: id */ + id: string; + /** Format: date-time */ + createdAt: string; + /** @enum {string} */ + type: 'scheduledNotePosted'; + user: components['schemas']['UserLite']; + /** Format: id */ + userId: string; + note: components['schemas']['Note']; } | { /** Format: id */ id: string; @@ -19992,8 +20003,8 @@ export type operations = { untilId?: string; /** @default true */ markAsRead?: boolean; - includeTypes?: ('note' | 'follow' | 'mention' | 'reply' | 'renote' | 'quote' | 'reaction' | 'pollEnded' | 'edited' | 'receiveFollowRequest' | 'followRequestAccepted' | 'roleAssigned' | 'achievementEarned' | 'exportCompleted' | 'scheduledNoteFailed' | 'app' | 'test' | 'pollVote' | 'groupInvited')[]; - excludeTypes?: ('note' | 'follow' | 'mention' | 'reply' | 'renote' | 'quote' | 'reaction' | 'pollEnded' | 'edited' | 'receiveFollowRequest' | 'followRequestAccepted' | 'roleAssigned' | 'achievementEarned' | 'exportCompleted' | 'scheduledNoteFailed' | 'app' | 'test' | 'pollVote' | 'groupInvited')[]; + includeTypes?: ('note' | 'follow' | 'mention' | 'reply' | 'renote' | 'quote' | 'reaction' | 'pollEnded' | 'edited' | 'receiveFollowRequest' | 'followRequestAccepted' | 'roleAssigned' | 'achievementEarned' | 'exportCompleted' | 'scheduledNoteFailed' | 'scheduledNotePosted' | 'app' | 'test' | 'pollVote' | 'groupInvited')[]; + excludeTypes?: ('note' | 'follow' | 'mention' | 'reply' | 'renote' | 'quote' | 'reaction' | 'pollEnded' | 'edited' | 'receiveFollowRequest' | 'followRequestAccepted' | 'roleAssigned' | 'achievementEarned' | 'exportCompleted' | 'scheduledNoteFailed' | 'scheduledNotePosted' | 'app' | 'test' | 'pollVote' | 'groupInvited')[]; }; }; }; @@ -20060,8 +20071,8 @@ export type operations = { untilId?: string; /** @default true */ markAsRead?: boolean; - includeTypes?: ('note' | 'follow' | 'mention' | 'reply' | 'renote' | 'quote' | 'reaction' | 'pollEnded' | 'edited' | 'receiveFollowRequest' | 'followRequestAccepted' | 'roleAssigned' | 'achievementEarned' | 'exportCompleted' | 'scheduledNoteFailed' | 'app' | 'test' | 'reaction:grouped' | 'renote:grouped' | 'pollVote' | 'groupInvited')[]; - excludeTypes?: ('note' | 'follow' | 'mention' | 'reply' | 'renote' | 'quote' | 'reaction' | 'pollEnded' | 'edited' | 'receiveFollowRequest' | 'followRequestAccepted' | 'roleAssigned' | 'achievementEarned' | 'exportCompleted' | 'scheduledNoteFailed' | 'app' | 'test' | 'reaction:grouped' | 'renote:grouped' | 'pollVote' | 'groupInvited')[]; + includeTypes?: ('note' | 'follow' | 'mention' | 'reply' | 'renote' | 'quote' | 'reaction' | 'pollEnded' | 'edited' | 'receiveFollowRequest' | 'followRequestAccepted' | 'roleAssigned' | 'achievementEarned' | 'exportCompleted' | 'scheduledNoteFailed' | 'scheduledNotePosted' | 'app' | 'test' | 'reaction:grouped' | 'renote:grouped' | 'pollVote' | 'groupInvited')[]; + excludeTypes?: ('note' | 'follow' | 'mention' | 'reply' | 'renote' | 'quote' | 'reaction' | 'pollEnded' | 'edited' | 'receiveFollowRequest' | 'followRequestAccepted' | 'roleAssigned' | 'achievementEarned' | 'exportCompleted' | 'scheduledNoteFailed' | 'scheduledNotePosted' | 'app' | 'test' | 'reaction:grouped' | 'renote:grouped' | 'pollVote' | 'groupInvited')[]; }; }; }; diff --git a/packages/misskey-js/src/consts.ts b/packages/misskey-js/src/consts.ts index 34fc7c1a03..6e32060fb7 100644 --- a/packages/misskey-js/src/consts.ts +++ b/packages/misskey-js/src/consts.ts @@ -16,7 +16,7 @@ import type { UserLite, } from './autogen/models.js'; -export const notificationTypes = ['note', 'follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollVote', 'pollEnded', 'receiveFollowRequest', 'followRequestAccepted', 'groupInvited', 'app', 'roleAssigned', 'achievementEarned', 'edited', 'scheduledNoteFailed'] as const; +export const notificationTypes = ['note', 'follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollVote', 'pollEnded', 'receiveFollowRequest', 'followRequestAccepted', 'groupInvited', 'app', 'roleAssigned', 'achievementEarned', 'edited', 'scheduledNoteFailed', 'scheduledNotePosted'] as const; export const noteVisibilities = ['public', 'home', 'followers', 'specified'] as const; diff --git a/packages/sw/src/scripts/create-notification.ts b/packages/sw/src/scripts/create-notification.ts index 8442552e3b..4fda784dba 100644 --- a/packages/sw/src/scripts/create-notification.ts +++ b/packages/sw/src/scripts/create-notification.ts @@ -265,6 +265,14 @@ async function composeNotification(data: PushNotificationDataMap[keyof PushNotif data, }]; + case 'scheduledNotePosted': + return [i18n.ts._notification.scheduledNotePosted, { + body: data.body.note.text ?? '', + icon: data.body.user.avatarUrl ?? undefined, + badge: iconUrl('bell'), + data, + }]; + default: return null; } diff --git a/sharkey-locales/en-US.yml b/sharkey-locales/en-US.yml index 582f4eda0a..f15646a156 100644 --- a/sharkey-locales/en-US.yml +++ b/sharkey-locales/en-US.yml @@ -278,6 +278,7 @@ _notification: renotedBySomeUsers: "Boosted by {n} users" edited: "Note got edited" scheduledNoteFailed: "Posting scheduled note failed" + scheduledNotePosted: "Scheduled Note was posted" _types: renote: "Boosts" edited: "Edits" -- cgit v1.2.3-freya From 3efb99dd576a2e3492fea7bd15a77c0414289fff Mon Sep 17 00:00:00 2001 From: Marie Date: Mon, 4 Nov 2024 18:05:29 +0100 Subject: fix: missing MKButton import --- packages/frontend/src/components/MkNoteSimple.vue | 1 + 1 file changed, 1 insertion(+) (limited to 'packages/frontend/src/components') diff --git a/packages/frontend/src/components/MkNoteSimple.vue b/packages/frontend/src/components/MkNoteSimple.vue index 48bf53fab5..6db95f1987 100644 --- a/packages/frontend/src/components/MkNoteSimple.vue +++ b/packages/frontend/src/components/MkNoteSimple.vue @@ -32,6 +32,7 @@ import * as os from '@/os.js'; import MkNoteHeader from '@/components/MkNoteHeader.vue'; import MkSubNoteContent from '@/components/MkSubNoteContent.vue'; import MkCwButton from '@/components/MkCwButton.vue'; +import MkButton from '@/components/MkButton.vue'; import { defaultStore } from '@/store.js'; import { misskeyApi } from '@/scripts/misskey-api.js'; import { i18n } from '@/i18n.js'; -- cgit v1.2.3-freya From 7eb0996b60943cf4aeb7e753fec9cfac5d2322ed Mon Sep 17 00:00:00 2001 From: Marie Date: Mon, 4 Nov 2024 18:06:38 +0100 Subject: upd: use apiWithDialog instead of misskeyApi --- packages/frontend/src/components/MkNoteSimple.vue | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) (limited to 'packages/frontend/src/components') diff --git a/packages/frontend/src/components/MkNoteSimple.vue b/packages/frontend/src/components/MkNoteSimple.vue index 6db95f1987..e7a357d1b6 100644 --- a/packages/frontend/src/components/MkNoteSimple.vue +++ b/packages/frontend/src/components/MkNoteSimple.vue @@ -34,7 +34,6 @@ import MkSubNoteContent from '@/components/MkSubNoteContent.vue'; import MkCwButton from '@/components/MkCwButton.vue'; import MkButton from '@/components/MkButton.vue'; import { defaultStore } from '@/store.js'; -import { misskeyApi } from '@/scripts/misskey-api.js'; import { i18n } from '@/i18n.js'; const props = defineProps<{ @@ -68,14 +67,10 @@ async function deleteScheduleNote() { } async function editScheduleNote() { - try { - await misskeyApi('notes/schedule/delete', { noteId: props.note.id }) - .then(() => { - isDeleted.value = true; - }); - } catch (err) { - console.error(err); - } + await os.apiWithDialog('notes/schedule/delete', { noteId: props.note.id }) + .then(() => { + isDeleted.value = true; + }); await os.post({ initialNote: props.note, -- cgit v1.2.3-freya From b10eb7ada9072190767cdb4ea4a016e2ee95eda8 Mon Sep 17 00:00:00 2001 From: Marie Date: Mon, 9 Dec 2024 05:10:52 +0100 Subject: fix missing imports --- packages/frontend/src/components/MkMediaList.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/frontend/src/components') diff --git a/packages/frontend/src/components/MkMediaList.vue b/packages/frontend/src/components/MkMediaList.vue index 4ef929e81f..9952f511f3 100644 --- a/packages/frontend/src/components/MkMediaList.vue +++ b/packages/frontend/src/components/MkMediaList.vue @@ -35,7 +35,7 @@ import * as Misskey from 'misskey-js'; import PhotoSwipeLightbox from 'photoswipe/lightbox'; import PhotoSwipe from 'photoswipe'; import 'photoswipe/style.css'; -import { FILE_TYPE_BROWSERSAFE, FILE_EXT_TRACKER_MODULES, FILE_TYPE_TRACKER_MODULES } from '@@/js/const.js'; +import { FILE_TYPE_BROWSERSAFE, FILE_EXT_TRACKER_MODULES, FILE_TYPE_TRACKER_MODULES, FILE_TYPE_FLASH_CONTENT, FILE_EXT_FLASH_CONTENT } from '@@/js/const.js'; import XBanner from '@/components/MkMediaBanner.vue'; import XImage from '@/components/MkMediaImage.vue'; import XVideo from '@/components/MkMediaVideo.vue'; -- cgit v1.2.3-freya From 152cc074831b784bb1e12267587184cea293a186 Mon Sep 17 00:00:00 2001 From: Marie Date: Mon, 9 Dec 2024 05:58:25 +0100 Subject: Apply suggestions --- .../src/queue/processors/ScheduleNotePostProcessorService.ts | 7 +++++++ packages/backend/src/server/api/endpoints/notes/schedule/create.ts | 2 +- packages/frontend/src/components/MkPostForm.vue | 4 +--- 3 files changed, 9 insertions(+), 4 deletions(-) (limited to 'packages/frontend/src/components') diff --git a/packages/backend/src/queue/processors/ScheduleNotePostProcessorService.ts b/packages/backend/src/queue/processors/ScheduleNotePostProcessorService.ts index f281b0ed7b..ea43448ed0 100644 --- a/packages/backend/src/queue/processors/ScheduleNotePostProcessorService.ts +++ b/packages/backend/src/queue/processors/ScheduleNotePostProcessorService.ts @@ -10,6 +10,7 @@ import { NoteCreateService } from '@/core/NoteCreateService.js'; import type { ChannelsRepository, DriveFilesRepository, MiDriveFile, NoteScheduleRepository, NotesRepository, UsersRepository } from '@/models/_.js'; import { DI } from '@/di-symbols.js'; import { NotificationService } from '@/core/NotificationService.js'; +import { IdentifiableError } from '@/misc/identifiable-error.js'; import { QueueLoggerService } from '../QueueLoggerService.js'; import type * as Bull from 'bullmq'; import type { ScheduleNotePostJobData } from '../types.js'; @@ -119,6 +120,12 @@ export class ScheduleNotePostProcessorService { reply, renote, channel, + }).catch(async (err: IdentifiableError) => { + this.notificationService.createNotification(me.id, 'scheduledNoteFailed', { + reason: err.message, + }); + await this.noteScheduleRepository.remove(data); + throw this.logger.error(`Schedule Note Failed Reason: ${err.message}`); }); await this.noteScheduleRepository.remove(data); this.notificationService.createNotification(me.id, 'scheduledNotePosted', { diff --git a/packages/backend/src/server/api/endpoints/notes/schedule/create.ts b/packages/backend/src/server/api/endpoints/notes/schedule/create.ts index b8ae3f44a3..7d20b6b82a 100644 --- a/packages/backend/src/server/api/endpoints/notes/schedule/create.ts +++ b/packages/backend/src/server/api/endpoints/notes/schedule/create.ts @@ -360,7 +360,7 @@ export default class extends Endpoint { // eslint- }, { delay, removeOnComplete: true, - jobId: noteId, + jobId: `schedNote:${noteId}`, }); } diff --git a/packages/frontend/src/components/MkPostForm.vue b/packages/frontend/src/components/MkPostForm.vue index bbde7c65f9..c7d5611847 100644 --- a/packages/frontend/src/components/MkPostForm.vue +++ b/packages/frontend/src/components/MkPostForm.vue @@ -821,7 +821,7 @@ async function post(ev?: MouseEvent) { const filesData = toRaw(files.value); const isMissingAltText = filesData.filter( - file => file.type.startsWith('image/') || file.type.startsWith('video/') || file.type.startsWith('audio/') + file => file.type.startsWith('image/') || file.type.startsWith('video/') || file.type.startsWith('audio/'), ).some(file => !file.comment); if (isMissingAltText) { @@ -914,8 +914,6 @@ async function post(ev?: MouseEvent) { claimAchievement('notes1'); } - poll.value = null; - const text = postData.text ?? ''; const lowerCase = text.toLowerCase(); if ((lowerCase.includes('love') || lowerCase.includes('❤')) && lowerCase.includes('sharkey')) { -- cgit v1.2.3-freya From 116a14720285707f2b884ccf6d39e224b04ec390 Mon Sep 17 00:00:00 2001 From: Marie Date: Mon, 9 Dec 2024 05:00:20 +0000 Subject: remove comma added by vscode prettifer --- packages/frontend/src/components/MkPostForm.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/frontend/src/components') diff --git a/packages/frontend/src/components/MkPostForm.vue b/packages/frontend/src/components/MkPostForm.vue index c7d5611847..93328fe52f 100644 --- a/packages/frontend/src/components/MkPostForm.vue +++ b/packages/frontend/src/components/MkPostForm.vue @@ -821,7 +821,7 @@ async function post(ev?: MouseEvent) { const filesData = toRaw(files.value); const isMissingAltText = filesData.filter( - file => file.type.startsWith('image/') || file.type.startsWith('video/') || file.type.startsWith('audio/'), + file => file.type.startsWith('image/') || file.type.startsWith('video/') || file.type.startsWith('audio/') ).some(file => !file.comment); if (isMissingAltText) { -- cgit v1.2.3-freya From dda922a030cdbd80f35aef38f2a67114a067c5c4 Mon Sep 17 00:00:00 2001 From: Marie Date: Mon, 9 Dec 2024 06:13:46 +0100 Subject: remove splatting --- packages/frontend/src/components/MkScheduleEditor.vue | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'packages/frontend/src/components') diff --git a/packages/frontend/src/components/MkScheduleEditor.vue b/packages/frontend/src/components/MkScheduleEditor.vue index 8f18f620ae..60a60bed28 100644 --- a/packages/frontend/src/components/MkScheduleEditor.vue +++ b/packages/frontend/src/components/MkScheduleEditor.vue @@ -49,11 +49,7 @@ function get() { return new Date(`${ atDate.value } ${ atTime.value }`).getTime(); }; - return { - ...( - { scheduledAt: calcAt() } - ), - }; + return { scheduledAt: calcAt() }; } watch([ -- cgit v1.2.3-freya From 234d14a892153f8249ced4e81d569418879f5f8c Mon Sep 17 00:00:00 2001 From: Marie Date: Mon, 9 Dec 2024 05:21:53 +0000 Subject: Revert import order update caused by saving --- packages/frontend/src/components/MkMediaList.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/frontend/src/components') diff --git a/packages/frontend/src/components/MkMediaList.vue b/packages/frontend/src/components/MkMediaList.vue index 9952f511f3..5209489046 100644 --- a/packages/frontend/src/components/MkMediaList.vue +++ b/packages/frontend/src/components/MkMediaList.vue @@ -35,13 +35,13 @@ import * as Misskey from 'misskey-js'; import PhotoSwipeLightbox from 'photoswipe/lightbox'; import PhotoSwipe from 'photoswipe'; import 'photoswipe/style.css'; -import { FILE_TYPE_BROWSERSAFE, FILE_EXT_TRACKER_MODULES, FILE_TYPE_TRACKER_MODULES, FILE_TYPE_FLASH_CONTENT, FILE_EXT_FLASH_CONTENT } from '@@/js/const.js'; import XBanner from '@/components/MkMediaBanner.vue'; import XImage from '@/components/MkMediaImage.vue'; import XVideo from '@/components/MkMediaVideo.vue'; import XModPlayer from '@/components/SkModPlayer.vue'; import XFlashPlayer from '@/components/SkFlashPlayer.vue'; import * as os from '@/os.js'; +import { FILE_TYPE_BROWSERSAFE, FILE_EXT_TRACKER_MODULES, FILE_TYPE_TRACKER_MODULES, FILE_TYPE_FLASH_CONTENT, FILE_EXT_FLASH_CONTENT } from '@@/js/const.js'; import { defaultStore } from '@/store.js'; import { focusParent } from '@/scripts/focus.js'; -- cgit v1.2.3-freya From bb12109bc43792666b8e3a2904a911c7576173dd Mon Sep 17 00:00:00 2001 From: Caramel Date: Mon, 9 Dec 2024 11:41:42 +0100 Subject: Make collapsed notes subscribe to stream Previously, when the note was collapsed, it didn't get updates such as reactions from streaming server. This was a problem, as any change made to the post before it got uncollapsed would end up being ignored. --- packages/frontend/src/components/MkNote.vue | 2 +- packages/frontend/src/components/SkNote.vue | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'packages/frontend/src/components') diff --git a/packages/frontend/src/components/MkNote.vue b/packages/frontend/src/components/MkNote.vue index 7ba4f0b9d9..323f6e994e 100644 --- a/packages/frontend/src/components/MkNote.vue +++ b/packages/frontend/src/components/MkNote.vue @@ -19,7 +19,7 @@ SPDX-License-Identifier: AGPL-3.0-only : - +
{{ i18n.ts.pinnedNote }}
diff --git a/packages/frontend/src/components/SkNote.vue b/packages/frontend/src/components/SkNote.vue index bda5282144..dc8c32a7d9 100644 --- a/packages/frontend/src/components/SkNote.vue +++ b/packages/frontend/src/components/SkNote.vue @@ -12,7 +12,7 @@ SPDX-License-Identifier: AGPL-3.0-only :class="[$style.root, { [$style.showActionsOnlyHover]: defaultStore.state.showNoteActionsOnlyHover }]" :tabindex="isDeleted ? '-1' : '0'" > - +
-- cgit v1.2.3-freya From bf01dcd8fb770d88f8509bbcb63bdaef1aa97fa5 Mon Sep 17 00:00:00 2001 From: Marie Date: Mon, 9 Dec 2024 18:58:57 +0100 Subject: Apply suggestions --- .../processors/ScheduleNotePostProcessorService.ts | 65 ++++++++++++---------- packages/frontend/src/components/MkNoteSimple.vue | 2 +- 2 files changed, 37 insertions(+), 30 deletions(-) (limited to 'packages/frontend/src/components') diff --git a/packages/backend/src/queue/processors/ScheduleNotePostProcessorService.ts b/packages/backend/src/queue/processors/ScheduleNotePostProcessorService.ts index ea43448ed0..62e3d1072f 100644 --- a/packages/backend/src/queue/processors/ScheduleNotePostProcessorService.ts +++ b/packages/backend/src/queue/processors/ScheduleNotePostProcessorService.ts @@ -11,6 +11,7 @@ import type { ChannelsRepository, DriveFilesRepository, MiDriveFile, NoteSchedul import { DI } from '@/di-symbols.js'; import { NotificationService } from '@/core/NotificationService.js'; import { IdentifiableError } from '@/misc/identifiable-error.js'; +import type { MiScheduleNoteType } from '@/models/NoteSchedule.js'; import { QueueLoggerService } from '../QueueLoggerService.js'; import type * as Bull from 'bullmq'; import type { ScheduleNotePostJobData } from '../types.js'; @@ -39,7 +40,36 @@ export class ScheduleNotePostProcessorService { this.logger = this.queueLoggerService.logger.createSubLogger('schedule-note-post'); } - @bindThis + @bindThis + private async isValidNoteSchedule(note: MiScheduleNoteType, id: string): Promise { + const reply = note.reply ? await this.notesRepository.findOneBy({ id: note.reply }) : undefined; + const renote = note.reply ? await this.notesRepository.findOneBy({ id: note.renote }) : undefined; + const channel = note.channel ? await this.channelsRepository.findOneBy({ id: note.channel, isArchived: false }) : undefined; + if (note.reply && !reply) { + this.logger.warn('Schedule Note Failed Reason: parent note to reply does not exist'); + this.notificationService.createNotification(id, 'scheduledNoteFailed', { + reason: 'Replied to note on your scheduled note no longer exists', + }); + return false; + } + if (note.renote && !renote) { + this.logger.warn('Schedule Note Failed Reason: attached quote note no longer exists'); + this.notificationService.createNotification(id, 'scheduledNoteFailed', { + reason: 'A quoted note from one of your scheduled notes no longer exists', + }); + return false; + } + if (note.channel && !channel) { + this.logger.warn('Schedule Note Failed Reason: Channel does not exist'); + this.notificationService.createNotification(id, 'scheduledNoteFailed', { + reason: 'An attached channel on your scheduled note no longer exists', + }); + return false; + } + return true; + } + + @bindThis public async process(job: Bull.Job): Promise { this.noteScheduleRepository.findOneBy({ id: job.data.scheduleNoteId }).then(async (data) => { if (!data) { @@ -47,11 +77,10 @@ export class ScheduleNotePostProcessorService { } else { const me = await this.usersRepository.findOneBy({ id: data.userId }); const note = data.note; - - //idの形式でキューに積んであったのをDBから取り寄せる const reply = note.reply ? await this.notesRepository.findOneBy({ id: note.reply }) : undefined; const renote = note.reply ? await this.notesRepository.findOneBy({ id: note.renote }) : undefined; const channel = note.channel ? await this.channelsRepository.findOneBy({ id: note.channel, isArchived: false }) : undefined; + let files: MiDriveFile[] = []; const fileIds = note.files; @@ -72,37 +101,15 @@ export class ScheduleNotePostProcessorService { return; } - if (note.files.length !== files.length) { - this.logger.warn('Schedule Note Failed Reason: files are missing in the user\'s drive'); - this.notificationService.createNotification(me.id, 'scheduledNoteFailed', { - reason: 'Some attached files on your scheduled note no longer exist', - }); - await this.noteScheduleRepository.remove(data); - return; - } - - if (note.reply && !reply) { - this.logger.warn('Schedule Note Failed Reason: parent note to reply does not exist'); - this.notificationService.createNotification(me.id, 'scheduledNoteFailed', { - reason: 'Replied to note on your scheduled note no longer exists', - }); - await this.noteScheduleRepository.remove(data); - return; - } - - if (note.renote && !renote) { - this.logger.warn('Schedule Note Failed Reason: attached quote note no longer exists'); - this.notificationService.createNotification(me.id, 'scheduledNoteFailed', { - reason: 'A quoted note from one of your scheduled notes no longer exists', - }); + if (!await this.isValidNoteSchedule(note, me.id)) { await this.noteScheduleRepository.remove(data); return; } - if (note.channel && !channel) { - this.logger.warn('Schedule Note Failed Reason: Channel does not exist'); + if (note.files.length !== files.length) { + this.logger.warn('Schedule Note Failed Reason: files are missing in the user\'s drive'); this.notificationService.createNotification(me.id, 'scheduledNoteFailed', { - reason: 'An attached channel on your scheduled note no longer exists', + reason: 'Some attached files on your scheduled note no longer exist', }); await this.noteScheduleRepository.remove(data); return; diff --git a/packages/frontend/src/components/MkNoteSimple.vue b/packages/frontend/src/components/MkNoteSimple.vue index e7a357d1b6..924262d62e 100644 --- a/packages/frontend/src/components/MkNoteSimple.vue +++ b/packages/frontend/src/components/MkNoteSimple.vue @@ -4,7 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only -->