summaryrefslogtreecommitdiff
path: root/packages
diff options
context:
space:
mode:
authorMarie <github@yuugi.dev>2024-11-04 11:22:37 +0100
committerMarie <github@yuugi.dev>2024-12-09 05:33:19 +0100
commit1d3c8253981fba2d431df2f5cc12dd78b21d37bc (patch)
tree263d59f8f07b27d4d6192c2273eca3195e5e8bc1 /packages
parentchore: remove from note required type (diff)
downloadsharkey-1d3c8253981fba2d431df2f5cc12dd78b21d37bc.tar.gz
sharkey-1d3c8253981fba2d431df2f5cc12dd78b21d37bc.tar.bz2
sharkey-1d3c8253981fba2d431df2f5cc12dd78b21d37bc.zip
upd: add notification for when scheduled note gets posted
Diffstat (limited to 'packages')
-rw-r--r--packages/backend/src/core/entities/NotificationEntityService.ts2
-rw-r--r--packages/backend/src/models/Notification.ts5
-rw-r--r--packages/backend/src/models/json-schema/notification.ts25
-rw-r--r--packages/backend/src/queue/processors/ScheduleNotePostProcessorService.ts5
-rw-r--r--packages/backend/src/types.ts1
-rw-r--r--packages/frontend-shared/js/const.ts1
-rw-r--r--packages/frontend/src/components/MkNotification.vue11
-rw-r--r--packages/misskey-js/etc/misskey-js.api.md2
-rw-r--r--packages/misskey-js/src/autogen/types.ts19
-rw-r--r--packages/misskey-js/src/consts.ts2
-rw-r--r--packages/sw/src/scripts/create-notification.ts8
11 files changed, 72 insertions, 9 deletions
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
@@ -390,6 +390,31 @@ export const packedNotificationSchema = {
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: {
+ ...baseSchema.properties,
+ type: {
+ type: 'string',
+ optional: false, nullable: false,
enum: ['reaction:grouped'],
},
note: {
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
<template>
<div :class="$style.root">
<div :class="$style.head">
- <MkAvatar v-if="['pollEnded', 'note', 'edited'].includes(notification.type) && 'note' in notification" :class="$style.icon" :user="notification.note.user" link preview/>
+ <MkAvatar v-if="['pollEnded', 'note', 'edited', 'scheduledNotePosted'].includes(notification.type) && 'note' in notification" :class="$style.icon" :user="notification.note.user" link preview/>
<MkAvatar v-else-if="['roleAssigned', 'achievementEarned', 'scheduledNoteFailed'].includes(notification.type)" :class="$style.icon" :user="$i" link preview/>
<div v-else-if="notification.type === 'reaction:grouped' && notification.note.reactionAcceptance === 'likeOnly'" :class="[$style.icon, $style.icon_reactionGroup]"><i class="ph-smiley ph-bold ph-lg" style="line-height: 1;"></i></div>
<div v-else-if="notification.type === 'reaction:grouped'" :class="[$style.icon, $style.icon_reactionGroup]"><i class="ph-smiley ph-bold ph-lg" style="line-height: 1;"></i></div>
@@ -30,6 +30,7 @@ SPDX-License-Identifier: AGPL-3.0-only
[$style.t_roleAssigned]: notification.type === 'roleAssigned' && notification.role.iconUrl == null,
[$style.t_pollEnded]: notification.type === 'edited',
[$style.t_roleAssigned]: notification.type === 'scheduledNoteFailed',
+ [$style.t_pollEnded]: notification.type === 'scheduledNotePosted',
}]"
> <!-- we re-use t_pollEnded for "edited" instead of making an identical style -->
<i v-if="notification.type === 'follow'" class="ti ti-plus"></i>
@@ -48,6 +49,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<i v-else-if="notification.type === 'edited'" class="ph-pencil ph-bold ph-lg"></i>
<i v-else-if="notification.type === 'scheduledNoteFailed'" class="ti ti-calendar-event"></i>
+ <i v-else-if="notification.type === 'scheduledNotePosted'" class="ti ti-calendar-event"></i>
<!-- notification.reaction が null になることはまずないが、ここでoptional chaining使うと一部ブラウザで刺さるので念の為 -->
<MkReactionIcon
v-else-if="notification.type === 'reaction'"
@@ -73,6 +75,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<span v-else-if="notification.type === 'app'">{{ notification.header }}</span>
<span v-else-if="notification.type === 'edited'">{{ i18n.ts._notification.edited }}</span>
<span v-else-if="notification.type === 'scheduledNoteFailed'">{{ i18n.ts._notification.scheduledNoteFailed }}</span>
+ <span v-else-if="notification.type === 'scheduledNotePosted'">{{ i18n.ts._notification.scheduledNotePosted }}</span>
<MkTime v-if="withTime" :time="notification.createdAt" :class="$style.headerTime"/>
</header>
<div>
@@ -162,6 +165,12 @@ SPDX-License-Identifier: AGPL-3.0-only
<Mfm :text="getNoteSummary(notification.note)" :isBlock="true" :plain="true" :nowrap="true" :author="notification.note.user"/>
<i class="ph-quotes ph-bold ph-lg" :class="$style.quote"></i>
</MkA>
+
+ <MkA v-else-if="notification.type === 'scheduledNotePosted'" :class="$style.text" :to="notePage(notification.note)" :title="getNoteSummary(notification.note)">
+ <i class="ph-quotes ph-bold ph-lg" :class="$style.quote"></i>
+ <Mfm :text="getNoteSummary(notification.note)" :isBlock="true" :plain="true" :nowrap="true" :author="notification.note.user"/>
+ <i class="ph-quotes ph-bold ph-lg" :class="$style.quote"></i>
+ </MkA>
</div>
</div>
</div>
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
@@ -4531,6 +4531,17 @@ export type components = {
/** 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;
+ /** Format: date-time */
+ createdAt: string;
+ /** @enum {string} */
type: 'reaction:grouped';
note: components['schemas']['Note'];
reactions: {
@@ -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;
}