-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* wip * Update read-announcement.ts * wip * wip * wip * Update index.d.ts * wip * Create 1691649257651-refine-announcement.js * wip * wip * wip * wip * wip * wip * Update announcements.vue * wip * wip * Update announcements.vue * wip * Update announcements.vue * wip * Update misskey-js.api.md * Update users.ts * Create MkAnnouncementDialog.stories.impl.ts * wip * wip * Create AnnouncementService.ts
- Loading branch information
Showing
38 changed files
with
1,229 additions
and
226 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
27 changes: 27 additions & 0 deletions
27
packages/backend/migration/1691649257651-refine-announcement.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
export class RefineAnnouncement1691649257651 { | ||
name = 'RefineAnnouncement1691649257651' | ||
|
||
async up(queryRunner) { | ||
await queryRunner.query(`ALTER TABLE "announcement" ADD "display" character varying(256) NOT NULL DEFAULT 'normal'`); | ||
await queryRunner.query(`ALTER TABLE "announcement" ADD "needConfirmationToRead" boolean NOT NULL DEFAULT false`); | ||
await queryRunner.query(`ALTER TABLE "announcement" ADD "isActive" boolean NOT NULL DEFAULT true`); | ||
await queryRunner.query(`ALTER TABLE "announcement" ADD "forExistingUsers" boolean NOT NULL DEFAULT false`); | ||
await queryRunner.query(`ALTER TABLE "announcement" ADD "userId" character varying(32)`); | ||
await queryRunner.query(`CREATE INDEX "IDX_bc1afcc8ef7e9400cdc3c0a87e" ON "announcement" ("isActive") `); | ||
await queryRunner.query(`CREATE INDEX "IDX_da795d3a83187e8832005ba19d" ON "announcement" ("forExistingUsers") `); | ||
await queryRunner.query(`CREATE INDEX "IDX_fd25dfe3da37df1715f11ba6ec" ON "announcement" ("userId") `); | ||
await queryRunner.query(`ALTER TABLE "announcement" ADD CONSTRAINT "FK_fd25dfe3da37df1715f11ba6ec8" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); | ||
} | ||
|
||
async down(queryRunner) { | ||
await queryRunner.query(`ALTER TABLE "announcement" DROP CONSTRAINT "FK_fd25dfe3da37df1715f11ba6ec8"`); | ||
await queryRunner.query(`DROP INDEX "public"."IDX_fd25dfe3da37df1715f11ba6ec"`); | ||
await queryRunner.query(`DROP INDEX "public"."IDX_da795d3a83187e8832005ba19d"`); | ||
await queryRunner.query(`DROP INDEX "public"."IDX_bc1afcc8ef7e9400cdc3c0a87e"`); | ||
await queryRunner.query(`ALTER TABLE "announcement" DROP COLUMN "userId"`); | ||
await queryRunner.query(`ALTER TABLE "announcement" DROP COLUMN "forExistingUsers"`); | ||
await queryRunner.query(`ALTER TABLE "announcement" DROP COLUMN "isActive"`); | ||
await queryRunner.query(`ALTER TABLE "announcement" DROP COLUMN "needConfirmationToRead"`); | ||
await queryRunner.query(`ALTER TABLE "announcement" DROP COLUMN "display"`); | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
packages/backend/migration/1691657412740-refine-announcement-2.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
export class RefineAnnouncement21691657412740 { | ||
name = 'RefineAnnouncement21691657412740' | ||
|
||
async up(queryRunner) { | ||
await queryRunner.query(`ALTER TABLE "announcement" ADD "icon" character varying(256) NOT NULL DEFAULT 'info'`); | ||
} | ||
|
||
async down(queryRunner) { | ||
await queryRunner.query(`ALTER TABLE "announcement" DROP COLUMN "icon"`); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
/* | ||
* SPDX-FileCopyrightText: syuilo and other misskey contributors | ||
* SPDX-License-Identifier: AGPL-3.0-only | ||
*/ | ||
|
||
import { Inject, Injectable } from '@nestjs/common'; | ||
import { Brackets } from 'typeorm'; | ||
import { DI } from '@/di-symbols.js'; | ||
import type { User } from '@/models/entities/User.js'; | ||
import type { AnnouncementReadsRepository, AnnouncementsRepository, Announcement, AnnouncementRead } from '@/models/index.js'; | ||
import { bindThis } from '@/decorators.js'; | ||
import { Packed } from '@/misc/json-schema.js'; | ||
import { IdService } from '@/core/IdService.js'; | ||
import { GlobalEventService } from '@/core/GlobalEventService.js'; | ||
|
||
@Injectable() | ||
export class AnnouncementService { | ||
constructor( | ||
@Inject(DI.announcementsRepository) | ||
private announcementsRepository: AnnouncementsRepository, | ||
|
||
@Inject(DI.announcementReadsRepository) | ||
private announcementReadsRepository: AnnouncementReadsRepository, | ||
|
||
private idService: IdService, | ||
private globalEventService: GlobalEventService, | ||
) { | ||
} | ||
|
||
@bindThis | ||
public async getReads(userId: User['id']): Promise<AnnouncementRead[]> { | ||
return this.announcementReadsRepository.findBy({ | ||
userId: userId, | ||
}); | ||
} | ||
|
||
@bindThis | ||
public async getUnreadAnnouncements(user: User): Promise<Announcement[]> { | ||
const readsQuery = this.announcementReadsRepository.createQueryBuilder('read') | ||
.select('read.announcementId') | ||
.where('read.userId = :userId', { userId: user.id }); | ||
|
||
const q = this.announcementsRepository.createQueryBuilder('announcement') | ||
.where('announcement.isActive = true') | ||
.andWhere(new Brackets(qb => { | ||
qb.orWhere('announcement.userId = :userId', { userId: user.id }); | ||
qb.orWhere('announcement.userId IS NULL'); | ||
})) | ||
.andWhere(new Brackets(qb => { | ||
qb.orWhere('announcement.forExistingUsers = false'); | ||
qb.orWhere('announcement.createdAt > :createdAt', { createdAt: user.createdAt }); | ||
})) | ||
.andWhere(`announcement.id NOT IN (${ readsQuery.getQuery() })`); | ||
|
||
q.setParameters(readsQuery.getParameters()); | ||
|
||
return q.getMany(); | ||
} | ||
|
||
@bindThis | ||
public async create(values: Partial<Announcement>): Promise<{ raw: Announcement; packed: Packed<'Announcement'> }> { | ||
const announcement = await this.announcementsRepository.insert({ | ||
id: this.idService.genId(), | ||
createdAt: new Date(), | ||
updatedAt: null, | ||
title: values.title, | ||
text: values.text, | ||
imageUrl: values.imageUrl, | ||
icon: values.icon, | ||
display: values.display, | ||
forExistingUsers: values.forExistingUsers, | ||
needConfirmationToRead: values.needConfirmationToRead, | ||
userId: values.userId, | ||
}).then(x => this.announcementsRepository.findOneByOrFail(x.identifiers[0])); | ||
|
||
const packed = (await this.packMany([announcement]))[0]; | ||
|
||
if (values.userId) { | ||
this.globalEventService.publishMainStream(values.userId, 'announcementCreated', { | ||
announcement: packed, | ||
}); | ||
} else { | ||
this.globalEventService.publishBroadcastStream('announcementCreated', { | ||
announcement: packed, | ||
}); | ||
} | ||
|
||
return { | ||
raw: announcement, | ||
packed: packed, | ||
}; | ||
} | ||
|
||
@bindThis | ||
public async read(user: User, announcementId: Announcement['id']): Promise<void> { | ||
try { | ||
await this.announcementReadsRepository.insert({ | ||
id: this.idService.genId(), | ||
createdAt: new Date(), | ||
announcementId: announcementId, | ||
userId: user.id, | ||
}); | ||
} catch (e) { | ||
return; | ||
} | ||
|
||
if ((await this.getUnreadAnnouncements(user)).length === 0) { | ||
this.globalEventService.publishMainStream(user.id, 'readAllAnnouncements'); | ||
} | ||
} | ||
|
||
@bindThis | ||
public async packMany( | ||
announcements: Announcement[], | ||
me?: { id: User['id'] } | null | undefined, | ||
options?: { | ||
reads?: AnnouncementRead[]; | ||
}, | ||
): Promise<Packed<'Announcement'>[]> { | ||
const reads = me ? (options?.reads ?? await this.getReads(me.id)) : []; | ||
return announcements.map(announcement => ({ | ||
id: announcement.id, | ||
createdAt: announcement.createdAt.toISOString(), | ||
updatedAt: announcement.updatedAt?.toISOString() ?? null, | ||
text: announcement.text, | ||
title: announcement.title, | ||
imageUrl: announcement.imageUrl, | ||
icon: announcement.icon, | ||
display: announcement.display, | ||
needConfirmationToRead: announcement.needConfirmationToRead, | ||
forYou: announcement.userId === me?.id, | ||
isRead: reads.some(read => read.announcementId === announcement.id), | ||
})); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
9487856
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Chromatic detects changes. Please review the changes on Chromatic.