enhance: 非通知なお知らせを作成できるように
This commit is contained in:
parent
bdbb3266ae
commit
c2ddb649f8
|
@ -29,6 +29,7 @@
|
|||
- ユーザーが誤ったメールアドレスを入力した場合に招待コードが失効してしまう問題が解消されます。
|
||||
- Enhance: すでにフォローしたすべての人の返信をTLに追加できるように
|
||||
- Enhance: 未読の通知数を表示できるように
|
||||
- Enhance: 通知されず、確認の必要もないお知らせ(silence)を作成可能になりました
|
||||
- Enhance: ローカリゼーションの更新
|
||||
- Enhance: 依存関係の更新
|
||||
- Change: CWを使用する場合、注釈を空にすることは許可されなくなりました
|
||||
|
|
|
@ -1172,6 +1172,8 @@ export interface Locale {
|
|||
"readConfirmText": string;
|
||||
"shouldNotBeUsedToPresentPermanentInfo": string;
|
||||
"dialogAnnouncementUxWarn": string;
|
||||
"silence": string;
|
||||
"silenceDescription": string;
|
||||
};
|
||||
"_initialAccountSetting": {
|
||||
"accountCreated": string;
|
||||
|
|
|
@ -1170,6 +1170,8 @@ _announcement:
|
|||
readConfirmText: "「{title}」の内容を読み、既読にします。"
|
||||
shouldNotBeUsedToPresentPermanentInfo: "特に新規ユーザーのUXを損ねる可能性が高いため、ストック情報ではなくフロー情報の掲示にお知らせを使用することを推奨します。"
|
||||
dialogAnnouncementUxWarn: "ダイアログ形式のお知らせが同時に2つ以上ある場合、UXに悪影響を及ぼす可能性が非常に高いため、使用は慎重に行うことを推奨します。"
|
||||
silence: "非通知"
|
||||
silenceDescription: "オンにすると、このお知らせは通知されず、既読にする必要もなくなります。"
|
||||
|
||||
_initialAccountSetting:
|
||||
accountCreated: "アカウントの作成が完了しました!"
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: syuilo and other misskey contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
export class AnnouncementSilence1699141698112 {
|
||||
name = 'AnnouncementSilence1699141698112'
|
||||
|
||||
async up(queryRunner) {
|
||||
await queryRunner.query(`ALTER TABLE "announcement" ADD "silence" boolean NOT NULL DEFAULT false`);
|
||||
await queryRunner.query(`CREATE INDEX "IDX_7b8d9225168e962f94ea517e00" ON "announcement" ("silence") `);
|
||||
}
|
||||
|
||||
async down(queryRunner) {
|
||||
await queryRunner.query(`DROP INDEX "public"."IDX_7b8d9225168e962f94ea517e00"`);
|
||||
await queryRunner.query(`ALTER TABLE "announcement" DROP COLUMN "silence"`);
|
||||
}
|
||||
}
|
|
@ -47,6 +47,7 @@ export class AnnouncementService {
|
|||
|
||||
const q = this.announcementsRepository.createQueryBuilder('announcement')
|
||||
.where('announcement.isActive = true')
|
||||
.andWhere('announcement.silence = false')
|
||||
.andWhere(new Brackets(qb => {
|
||||
qb.orWhere('announcement.userId = :userId', { userId: user.id });
|
||||
qb.orWhere('announcement.userId IS NULL');
|
||||
|
@ -73,6 +74,7 @@ export class AnnouncementService {
|
|||
icon: values.icon,
|
||||
display: values.display,
|
||||
forExistingUsers: values.forExistingUsers,
|
||||
silence: values.silence,
|
||||
needConfirmationToRead: values.needConfirmationToRead,
|
||||
userId: values.userId,
|
||||
}).then(x => this.announcementsRepository.findOneByOrFail(x.identifiers[0]));
|
||||
|
@ -124,6 +126,7 @@ export class AnnouncementService {
|
|||
display: values.display,
|
||||
icon: values.icon,
|
||||
forExistingUsers: values.forExistingUsers,
|
||||
silence: values.silence,
|
||||
needConfirmationToRead: values.needConfirmationToRead,
|
||||
isActive: values.isActive,
|
||||
});
|
||||
|
@ -210,6 +213,7 @@ export class AnnouncementService {
|
|||
icon: announcement.icon,
|
||||
display: announcement.display,
|
||||
needConfirmationToRead: announcement.needConfirmationToRead,
|
||||
silence: announcement.silence,
|
||||
forYou: announcement.userId === me?.id,
|
||||
isRead: reads.some(read => read.announcementId === announcement.id),
|
||||
}));
|
||||
|
|
|
@ -66,6 +66,12 @@ export class MiAnnouncement {
|
|||
})
|
||||
public forExistingUsers: boolean;
|
||||
|
||||
@Index()
|
||||
@Column('boolean', {
|
||||
default: false,
|
||||
})
|
||||
public silence: boolean;
|
||||
|
||||
@Index()
|
||||
@Column({
|
||||
...id(),
|
||||
|
|
|
@ -58,6 +58,7 @@ export const paramDef = {
|
|||
icon: { type: 'string', enum: ['info', 'warning', 'error', 'success'], default: 'info' },
|
||||
display: { type: 'string', enum: ['normal', 'banner', 'dialog'], default: 'normal' },
|
||||
forExistingUsers: { type: 'boolean', default: false },
|
||||
silence: { type: 'boolean', default: false },
|
||||
needConfirmationToRead: { type: 'boolean', default: false },
|
||||
userId: { type: 'string', format: 'misskey:id', nullable: true, default: null },
|
||||
},
|
||||
|
@ -78,6 +79,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
icon: ps.icon,
|
||||
display: ps.display,
|
||||
forExistingUsers: ps.forExistingUsers,
|
||||
silence: ps.silence,
|
||||
needConfirmationToRead: ps.needConfirmationToRead,
|
||||
userId: ps.userId,
|
||||
}, me);
|
||||
|
|
|
@ -114,6 +114,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
display: announcement.display,
|
||||
isActive: announcement.isActive,
|
||||
forExistingUsers: announcement.forExistingUsers,
|
||||
silence: announcement.silence,
|
||||
needConfirmationToRead: announcement.needConfirmationToRead,
|
||||
userId: announcement.userId,
|
||||
reads: reads.get(announcement)!,
|
||||
|
|
|
@ -35,6 +35,7 @@ export const paramDef = {
|
|||
icon: { type: 'string', enum: ['info', 'warning', 'error', 'success'] },
|
||||
display: { type: 'string', enum: ['normal', 'banner', 'dialog'] },
|
||||
forExistingUsers: { type: 'boolean' },
|
||||
silence: { type: 'boolean' },
|
||||
needConfirmationToRead: { type: 'boolean' },
|
||||
isActive: { type: 'boolean' },
|
||||
},
|
||||
|
@ -63,6 +64,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
display: ps.display,
|
||||
icon: ps.icon,
|
||||
forExistingUsers: ps.forExistingUsers,
|
||||
silence: ps.silence,
|
||||
needConfirmationToRead: ps.needConfirmationToRead,
|
||||
isActive: ps.isActive,
|
||||
}, me);
|
||||
|
|
|
@ -48,6 +48,9 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<MkSwitch v-model="announcement.forExistingUsers" :helpText="i18n.ts._announcement.forExistingUsersDescription">
|
||||
{{ i18n.ts._announcement.forExistingUsers }}
|
||||
</MkSwitch>
|
||||
<MkSwitch v-model="announcement.silence" :helpText="i18n.ts._announcement.silenceDescription">
|
||||
{{ i18n.ts._announcement.silence }}
|
||||
</MkSwitch>
|
||||
<MkSwitch v-model="announcement.needConfirmationToRead" :helpText="i18n.ts._announcement.needConfirmationToReadDescription">
|
||||
{{ i18n.ts._announcement.needConfirmationToRead }}
|
||||
</MkSwitch>
|
||||
|
@ -97,6 +100,7 @@ function add() {
|
|||
icon: 'info',
|
||||
display: 'normal',
|
||||
forExistingUsers: false,
|
||||
silence: false,
|
||||
needConfirmationToRead: false,
|
||||
});
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<section v-for="announcement in items" :key="announcement.id" class="_panel" :class="$style.announcement">
|
||||
<div v-if="announcement.forYou" :class="$style.forYou"><i class="ti ti-pin"></i> {{ i18n.ts.forYou }}</div>
|
||||
<div :class="$style.header">
|
||||
<span v-if="$i && !announcement.isRead" style="margin-right: 0.5em;">🆕</span>
|
||||
<span v-if="$i && !announcement.silence && !announcement.isRead" style="margin-right: 0.5em;">🆕</span>
|
||||
<span style="margin-right: 0.5em;">
|
||||
<i v-if="announcement.icon === 'info'" class="ti ti-info-circle"></i>
|
||||
<i v-else-if="announcement.icon === 'warning'" class="ti ti-alert-triangle" style="color: var(--warn);"></i>
|
||||
|
@ -29,7 +29,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<MkTime :time="announcement.updatedAt ?? announcement.createdAt" mode="detail"/>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="tab !== 'past' && $i && !announcement.isRead" :class="$style.footer">
|
||||
<div v-if="tab !== 'past' && $i && !announcement.silence && !announcement.isRead" :class="$style.footer">
|
||||
<MkButton primary @click="read(announcement)"><i class="ti ti-check"></i> {{ i18n.ts.gotIt }}</MkButton>
|
||||
</div>
|
||||
</section>
|
||||
|
|
Loading…
Reference in New Issue