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