From 45bf8262aa533ebfe33d7425a942926f98a3b568 Mon Sep 17 00:00:00 2001 From: bunnybeam Date: Mon, 7 Jul 2025 20:03:28 +0100 Subject: [PATCH] implement optional confetti on announcements --- locales/en-US.yml | 2 ++ locales/index.d.ts | 4 ++++ .../1751912435779-announcement-confetti.js | 16 ++++++++++++++++ .../backend/src/core/AnnouncementService.ts | 2 ++ .../core/entities/AnnouncementEntityService.ts | 1 + packages/backend/src/models/Announcement.ts | 6 ++++++ .../src/models/json-schema/announcement.ts | 4 ++++ .../api/endpoints/admin/announcements/create.ts | 2 ++ .../api/endpoints/admin/announcements/list.ts | 1 + .../api/endpoints/admin/announcements/update.ts | 2 ++ .../frontend/src/pages/admin/announcements.vue | 4 ++++ packages/frontend/src/pages/announcement.vue | 17 ++++++++++++++++- 12 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 packages/backend/migration/1751912435779-announcement-confetti.js diff --git a/locales/en-US.yml b/locales/en-US.yml index 4901dcd8e5..06f2dfcba5 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -1501,6 +1501,8 @@ _announcement: dialogAnnouncementUxWarn: "Having two or more dialog-style notifications simultaneously can significantly impact the user experience, so please use them carefully." silence: "No notification" silenceDescription: "Turning this on will skip the notification of this announcement and the user won't need to read it." + confetti: "Throw confetti" + confettiDescription: "If enabled, the announcement will display a confetti effect when viewed." _initialAccountSetting: accountCreated: "Your account was successfully created!" letsStartAccountSetup: "For starters, let's set up your profile." diff --git a/locales/index.d.ts b/locales/index.d.ts index d126174ebb..f1626a3212 100644 --- a/locales/index.d.ts +++ b/locales/index.d.ts @@ -13346,6 +13346,10 @@ export interface Locale extends ILocale { * Don't delete files used as avatars&c */ "keepFilesInUse": string; + /** + * this option requires more complicated database queries, you may need to increase the value of db.extra.statement_timeout in the configuration file + */ + "keepFilesInUseDescription": string; }; } declare const locales: { diff --git a/packages/backend/migration/1751912435779-announcement-confetti.js b/packages/backend/migration/1751912435779-announcement-confetti.js new file mode 100644 index 0000000000..0968ff44f6 --- /dev/null +++ b/packages/backend/migration/1751912435779-announcement-confetti.js @@ -0,0 +1,16 @@ +/* + * SPDX-FileCopyrightText: bunnybeam and other Sharkey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +export class AnnouncementConfetti1751912435779 { + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "announcement" ADD "confetti" boolean NOT NULL DEFAULT false`); + await queryRunner.query(`CREATE INDEX "IDX_94aabe9f742bc9808264a1c97c" ON "announcement" ("confetti") `); + } + + async down(queryRunner) { + await queryRunner.query(`DROP INDEX "public"."IDX_94aabe9f742bc9808264a1c97c"`); + await queryRunner.query(`ALTER TABLE "announcement" DROP COLUMN "confetti"`); + } +} diff --git a/packages/backend/src/core/AnnouncementService.ts b/packages/backend/src/core/AnnouncementService.ts index a9f6731977..95899c2ccc 100644 --- a/packages/backend/src/core/AnnouncementService.ts +++ b/packages/backend/src/core/AnnouncementService.ts @@ -78,6 +78,7 @@ export class AnnouncementService { forExistingUsers: values.forExistingUsers, silence: values.silence, needConfirmationToRead: values.needConfirmationToRead, + confetti: values.confetti, userId: values.userId, }); @@ -130,6 +131,7 @@ export class AnnouncementService { forExistingUsers: values.forExistingUsers, silence: values.silence, needConfirmationToRead: values.needConfirmationToRead, + confetti: values.confetti, isActive: values.isActive, }); diff --git a/packages/backend/src/core/entities/AnnouncementEntityService.ts b/packages/backend/src/core/entities/AnnouncementEntityService.ts index 90b04d0229..6cf2df4211 100644 --- a/packages/backend/src/core/entities/AnnouncementEntityService.ts +++ b/packages/backend/src/core/entities/AnnouncementEntityService.ts @@ -55,6 +55,7 @@ export class AnnouncementEntityService { forYou: announcement.userId === me?.id, needConfirmationToRead: announcement.needConfirmationToRead, silence: announcement.silence, + confetti: announcement.confetti, isRead: announcement.isRead !== null ? announcement.isRead : undefined, }; } diff --git a/packages/backend/src/models/Announcement.ts b/packages/backend/src/models/Announcement.ts index d0c59fff50..8b1389e4a2 100644 --- a/packages/backend/src/models/Announcement.ts +++ b/packages/backend/src/models/Announcement.ts @@ -72,6 +72,12 @@ export class MiAnnouncement { }) public silence: boolean; + @Index() + @Column('boolean', { + default: false, + }) + public confetti: boolean; + @Index() @Column({ ...id(), diff --git a/packages/backend/src/models/json-schema/announcement.ts b/packages/backend/src/models/json-schema/announcement.ts index b9352bd31e..3ac4a886bc 100644 --- a/packages/backend/src/models/json-schema/announcement.ts +++ b/packages/backend/src/models/json-schema/announcement.ts @@ -52,6 +52,10 @@ export const packedAnnouncementSchema = { type: 'boolean', optional: false, nullable: false, }, + confetti: { + type: 'boolean', + optional: false, nullable: false, + }, forYou: { type: 'boolean', optional: false, nullable: false, diff --git a/packages/backend/src/server/api/endpoints/admin/announcements/create.ts b/packages/backend/src/server/api/endpoints/admin/announcements/create.ts index b8bfda73a4..8da39810e9 100644 --- a/packages/backend/src/server/api/endpoints/admin/announcements/create.ts +++ b/packages/backend/src/server/api/endpoints/admin/announcements/create.ts @@ -61,6 +61,7 @@ export const paramDef = { forExistingUsers: { type: 'boolean', default: false }, silence: { type: 'boolean', default: false }, needConfirmationToRead: { type: 'boolean', default: false }, + confetti: { type: 'boolean', default: false }, userId: { type: 'string', format: 'misskey:id', nullable: true, default: null }, }, required: ['title', 'text', 'imageUrl'], @@ -83,6 +84,7 @@ export default class extends Endpoint { // eslint- forExistingUsers: ps.forExistingUsers, silence: ps.silence, needConfirmationToRead: ps.needConfirmationToRead, + confetti: ps.confetti, userId: ps.userId, }, me); diff --git a/packages/backend/src/server/api/endpoints/admin/announcements/list.ts b/packages/backend/src/server/api/endpoints/admin/announcements/list.ts index 7596bf44e3..2423807518 100644 --- a/packages/backend/src/server/api/endpoints/admin/announcements/list.ts +++ b/packages/backend/src/server/api/endpoints/admin/announcements/list.ts @@ -124,6 +124,7 @@ export default class extends Endpoint { // eslint- forExistingUsers: announcement.forExistingUsers, silence: announcement.silence, needConfirmationToRead: announcement.needConfirmationToRead, + confetti: announcement.confetti, userId: announcement.userId, reads: reads.get(announcement)!, })); diff --git a/packages/backend/src/server/api/endpoints/admin/announcements/update.ts b/packages/backend/src/server/api/endpoints/admin/announcements/update.ts index 6fce6e4e0a..e68a0439c1 100644 --- a/packages/backend/src/server/api/endpoints/admin/announcements/update.ts +++ b/packages/backend/src/server/api/endpoints/admin/announcements/update.ts @@ -38,6 +38,7 @@ export const paramDef = { forExistingUsers: { type: 'boolean' }, silence: { type: 'boolean' }, needConfirmationToRead: { type: 'boolean' }, + confetti: { type: 'boolean' }, isActive: { type: 'boolean' }, }, required: ['id'], @@ -67,6 +68,7 @@ export default class extends Endpoint { // eslint- forExistingUsers: ps.forExistingUsers, silence: ps.silence, needConfirmationToRead: ps.needConfirmationToRead, + confetti: ps.confetti, isActive: ps.isActive, }, me); }); diff --git a/packages/frontend/src/pages/admin/announcements.vue b/packages/frontend/src/pages/admin/announcements.vue index b2d7b4889a..025cb08b7b 100644 --- a/packages/frontend/src/pages/admin/announcements.vue +++ b/packages/frontend/src/pages/admin/announcements.vue @@ -70,6 +70,9 @@ SPDX-License-Identifier: AGPL-3.0-only {{ i18n.ts._announcement.needConfirmationToRead }} + + {{ i18n.ts._announcement.confetti }} +

{{ i18n.tsx.nUsersRead({ n: announcement.reads }) }}

@@ -127,6 +130,7 @@ function add() { forExistingUsers: false, silence: false, needConfirmationToRead: false, + confetti: false, }); } diff --git a/packages/frontend/src/pages/announcement.vue b/packages/frontend/src/pages/announcement.vue index 9fa06dfd9a..6839d9c65d 100644 --- a/packages/frontend/src/pages/announcement.vue +++ b/packages/frontend/src/pages/announcement.vue @@ -47,7 +47,7 @@ SPDX-License-Identifier: AGPL-3.0-only