1
0
mirror of https://github.com/MisskeyIO/misskey synced 2024-11-27 06:18:40 +09:00

feat(announcement): お知らせの既読処理にチュートリアル受講を要求できるように (MisskeyIO#753)

This commit is contained in:
あわわわとーにゅ 2024-10-19 03:22:05 +09:00 committed by GitHub
parent c47140eab7
commit d005daae84
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
30 changed files with 130 additions and 20 deletions

View File

@ -1234,7 +1234,7 @@ _announcement:
forExistingUsers: "Anunci per usuaris registrats"
forExistingUsersDescription: "Aquest avís només es mostrarà als usuaris existents fins al moment de la publicació. Si no també es mostrarà als usuaris que es registrin després de la publicació."
needConfirmationToRead: "Es necessita confirmació de lectura de la notificació "
needConfirmationToReadDescription: "Si s'activa es mostrarà un diàleg per confirmar la lectura d'aquesta notificació. A més aquesta notificació serà exclosa de qualsevol funcionalitat com \"Marcar tot com a llegit\"."
needConfirmationToReadDescription: "Si s'activa es mostrarà un diàleg per confirmar la lectura d'aquesta notificació."
end: "Final de la notificació "
tooManyActiveAnnouncementDescription: "Tenir massa notificacions actives pot empitjorar l'experiència de l'usuari. Considera finalitzar els anuncis que siguin antics."
readConfirmTitle: "Marcar com llegida?"

View File

@ -1189,7 +1189,7 @@ _announcement:
forExistingUsers: "Nur für existierende Nutzer"
forExistingUsersDescription: "Ist diese Option aktiviert, wird diese Ankündigung nur Nutzern angezeigt, die zum Zeitpunkt der Ankündigung bereits registriert sind. Ist sie deaktiviert, wird sie auch Nutzern, die sich nach dessen Veröffentlichung registrieren, angezeigt."
needConfirmationToRead: "Separate Lesebestätigung erfordern"
needConfirmationToReadDescription: "Ist dies aktiviert, so wird beim Markieren dieser Ankündigung als gelesen ein separates Bestätigungsfenster angezeigt. Auch wird sie von der \"Alle als gelesen markieren\"-Funktion ausgenommen."
needConfirmationToReadDescription: "Ist dies aktiviert, so wird beim Markieren dieser Ankündigung als gelesen ein separates Bestätigungsfenster angezeigt."
end: "Ankündigung archivieren"
tooManyActiveAnnouncementDescription: "Zu viele aktive Ankündigungen können die Benutzerfreundlichkeit verschlechtern. Es wird empfohlen, veraltete Ankündigungen zu archivieren."
readConfirmTitle: "Als gelesen markieren?"

View File

@ -1319,7 +1319,9 @@ _announcement:
forExistingUsers: "Existing users only"
forExistingUsersDescription: "This announcement will only be shown to users existing at the point of publishment if enabled. If disabled, those newly signing up after it has been posted will also see it."
needConfirmationToRead: "Require separate read confirmation"
needConfirmationToReadDescription: "A separate prompt to confirm marking this announcement as read will be displayed if enabled. This announcement will also be excluded from any \"Mark all as read\" functionality."
needConfirmationToReadDescription: "A separate prompt to confirm marking this announcement as read will be displayed if enabled."
needEnrollmentTutorialToRead: "Require tutorial completion to read"
needEnrollmentTutorialToReadDescription: "Users must complete the tutorial to read this announcement if enabled."
end: "Archive announcement"
tooManyActiveAnnouncementDescription: "Having too many active announcements may worsen the user experience. Please consider archiving announcements that have become obsolete."
readConfirmTitle: "Mark as read?"

View File

@ -1252,7 +1252,7 @@ _announcement:
forExistingUsers: "Solo para usuarios registrados"
forExistingUsersDescription: "Este anuncio solo se mostrará a aquellos usuarios registrados en el momento de su publicación. Si se deshabilita esta opción, aquellos usuarios que se registren tras su publicación también lo verán."
needConfirmationToRead: "Requerir confirmación de lectura aparte"
needConfirmationToReadDescription: "Si se habilita esta opción, se pedirá una confirmación de lectura aparte. Además, este anuncio será excluido de cualquier funcionalidad de \"Marcar todos como leídos\"."
needConfirmationToReadDescription: "Si se habilita esta opción, se pedirá una confirmación de lectura aparte."
end: "Anuncios archivados"
tooManyActiveAnnouncementDescription: "Tener demasiados anuncios activos empeora la experiencia de usuario. Por favor, considera archivar aquellos anuncios que hayan quedado obsoletos."
readConfirmTitle: "¿Marcar como leído?"

View File

@ -1237,7 +1237,7 @@ _bubbleGame:
_announcement:
forExistingUsers: "Pour les utilisateurs existants seulement"
needConfirmationToRead: "Exiger la confirmation de la lecture"
needConfirmationToReadDescription: "Si activé, afficher un dialogue de confirmation quand l'annonce est marquée comme lue. Aussi, elle sera exclue de « marquer tout comme lu » ."
needConfirmationToReadDescription: "Si activé, afficher un dialogue de confirmation quand l'annonce est marquée comme lue."
end: "Archiver l'annonce"
tooManyActiveAnnouncementDescription: "Un grand nombre d'annonces actives peut baisser l'expérience utilisateur. Considérez d'archiver les annonces obsolètes."
readConfirmTitle: "Marquer comme lu ?"

View File

@ -1254,7 +1254,7 @@ _announcement:
forExistingUsers: "Hanya pengguna yang telah ada"
forExistingUsersDescription: "Pengumuman ini akan dimunculkan ke pengguna yang sudah ada dari titik waktu publikasi jika dinyalakan. Apabila dimatikan, mereka yang baru mendaftar setelah publikasi ini akan juga melihatnya."
needConfirmationToRead: "Membutuhkan konfirmasi terpisah bahwa telah dibaca"
needConfirmationToReadDescription: "Permintaan terpisah untuk mengonfirmasi menandai pengumuman ini telah dibaca akan ditampilkan apabila fitur ini dinyalakan. Pengumuman ini juga akan dikecualikan dari fungsi \"Tandai semua telah dibaca\"."
needConfirmationToReadDescription: "Permintaan terpisah untuk mengonfirmasi menandai pengumuman ini telah dibaca akan ditampilkan apabila fitur ini dinyalakan."
end: "Arsipkan pengumuman"
tooManyActiveAnnouncementDescription: "Terlalu banyak pengumuman dapat memperburuk pengalaman pengguna. Mohon pertimbangkan untuk mengarsipkan pengumuman yang sudah usang/tidak relevan."
readConfirmTitle: "Tandai telah dibaca?"

10
locales/index.d.ts vendored
View File

@ -5305,9 +5305,17 @@ export interface Locale extends ILocale {
*/
"needConfirmationToRead": string;
/**
*
*
*/
"needConfirmationToReadDescription": string;
/**
*
*/
"needEnrollmentTutorialToRead": string;
/**
*
*/
"needEnrollmentTutorialToReadDescription": string;
/**
*
*/

View File

@ -1252,7 +1252,7 @@ _announcement:
forExistingUsers: "Solo ai profili attuali"
forExistingUsersDescription: "L'annuncio sarà visibile solo ai profili esistenti in questo momento. Se disabilitato, sarà visibile anche ai profili che verranno creati dopo la pubblicazione di questo annuncio."
needConfirmationToRead: "Richiede la conferma di lettura"
needConfirmationToReadDescription: "Sarà visualizzata una finestra di dialogo che richiede la conferma di lettura. Inoltre, non è soggetto a conferme di lettura massicce."
needConfirmationToReadDescription: "Sarà visualizzata una finestra di dialogo che richiede la conferma di lettura."
end: "Archivia l'annuncio"
tooManyActiveAnnouncementDescription: "L'esperienza delle persone può peggiorare se ci sono troppi annunci attivi. Considera anche l'archiviazione degli annunci conclusi."
readConfirmTitle: "Segnare come già letto?"

View File

@ -1326,7 +1326,9 @@ _announcement:
forExistingUsers: "既存ユーザーのみ"
forExistingUsersDescription: "有効にすると、このお知らせ作成時点で存在するユーザーにのみお知らせが表示されます。無効にすると、このお知らせ作成後にアカウントを作成したユーザーにもお知らせが表示されます。"
needConfirmationToRead: "既読にするのに確認が必要"
needConfirmationToReadDescription: "有効にすると、このお知らせを既読にする際に確認ダイアログが表示されます。また、一括既読操作の対象になりません。"
needConfirmationToReadDescription: "有効にすると、このお知らせを既読にする際に確認ダイアログが表示されます。"
needEnrollmentTutorialToRead: "チュートリアルの受講が必要"
needEnrollmentTutorialToReadDescription: "有効にすると、このお知らせを既読にするためにはチュートリアルの受講が必要です。"
end: "お知らせを終了"
tooManyActiveAnnouncementDescription: "アクティブなお知らせが多いため、UXが低下する可能性があります。終了したお知らせはアーカイブすることを検討してください。"
readConfirmTitle: "既読にしますか?"

View File

@ -1254,7 +1254,7 @@ _announcement:
forExistingUsers: "もうおるユーザーのみ"
forExistingUsersDescription: "オンにしたらこのお知らせができた時点でおる人らにだけお知らせが行くで。切ったらこの知らせが行ったあとにアカウント作った人にもちゃんとお知らせが行くで。"
needConfirmationToRead: "既読にするんやったら確認してや"
needConfirmationToReadDescription: "オンにしたら、このお知らせを既読にする時に確認するで。ついでに、一括既読しても既読扱いにならへんで。"
needConfirmationToReadDescription: "オンにしたら、このお知らせを既読にする時に確認するで。"
end: "お知らせやめる"
tooManyActiveAnnouncementDescription: "お知らせが多すぎてUXが落ちそうや。終わったお知らせはアーカイブに突っ込んだほうがええかも。"
readConfirmTitle: "既読にしてええんやな?"

View File

@ -1312,7 +1312,9 @@ _announcement:
forExistingUsers: "기존 유저에게만 알림"
forExistingUsersDescription: "활성화하면 이 공지사항을 게시한 시점에서 이미 가입한 유저에게만 표시합니다. 비활성화하면 게시 후에 가입한 유저에게도 표시합니다."
needConfirmationToRead: "읽음으로 표시하기 전에 확인하기"
needConfirmationToReadDescription: "활성화하면 이 공지사항을 읽음으로 표시하기 전에 확인 알림창을 띄웁니다. '모두 읽음'의 대상에서도 제외됩니다."
needConfirmationToReadDescription: "활성화하면 이 공지사항을 읽음으로 표시하기 전에 확인 알림창을 띄웁니다."
needEnrollmentTutorialToRead: "읽음으로 표시하기 전에 튜토리얼 진행하기"
needEnrollmentTutorialToReadDescription: "활성화하면 이 공지사항을 읽음으로 표시하기 전에 사용자에게 튜토리얼을 진행하도록 요구합니다."
end: "공지에서 내리기"
tooManyActiveAnnouncementDescription: "공지사항이 너무 많을 경우, 사용자 경험에 영향을 끼칠 가능성이 있습니다. 오래된 공지사항은 아카이브하시는 것을 권장드립니다."
readConfirmTitle: "읽음으로 표시합니까?"

View File

@ -1254,7 +1254,7 @@ _announcement:
forExistingUsers: "ผู้ใช้งานที่มีอยู่เท่านั้น"
forExistingUsersDescription: "การประกาศนี้จะแสดงต่อผู้ใช้ที่มีอยู่ ณ จุดที่เผยแพร่นั้นๆถ้าหากเปิดใช้งาน ถ้าหากปิดใช้งานผู้ที่กำลังสมัครใหม่หลังจากโพสต์แล้วนั้นก็จะเห็นเช่นกัน"
needConfirmationToRead: "จำเป็นต้องยืนยันว่าอ่านแล้ว"
needConfirmationToReadDescription: "กล่องโต้ตอบการยืนยันจะปรากฏขึ้นเมื่อจะทำเครื่องหมายว่าอ่านแล้ว นอกจากนี้ยังทำให้ประกาศนี้ยังไม่ถูกอ่านเมื่อใช้ฟังก์ชั่น “ทำเครื่องหมายฯ ทั้งหมดว่าอ่านแล้ว”"
needConfirmationToReadDescription: "กล่องโต้ตอบการยืนยันจะปรากฏขึ้นเมื่อจะทำเครื่องหมายว่าอ่านแล้ว"
end: "เก็บประกาศ"
tooManyActiveAnnouncementDescription: "การมีประกาศที่ใช้งานมากเกินไปนั้นอาจจะทำให้ประสบการณ์ของผู้ใช้งานนั้นดูแย่ลง โปรดกรุณาพิจารณาการเก็บประกาศที่ล้าสมัยด้วยนะค่ะ"
readConfirmTitle: "ทำเครื่องหมายว่าอ่านแล้วเลยไหม?"

View File

@ -1275,7 +1275,7 @@ _announcement:
forExistingUsers: "仅限现有用户"
forExistingUsersDescription: "若启用,该公告将仅对创建此公告时存在的用户可见。 如果禁用,则在创建此公告后注册的用户也可以看到该公告。"
needConfirmationToRead: "需要确认才能标记为已读"
needConfirmationToReadDescription: "若启用,则会在标记已读时会显示确认对话框。此外,它也会不受批量已读操作的影响。"
needConfirmationToReadDescription: "若启用,则会在标记已读时会显示确认对话框。"
end: "结束公告"
tooManyActiveAnnouncementDescription: "若有大量活动公告,可能会造成用户体验下降。请考虑归档已完成的公告。"
readConfirmTitle: "标记为已读?"

View File

@ -1254,7 +1254,7 @@ _announcement:
forExistingUsers: "僅限既有的使用者"
forExistingUsersDescription: "啟用代表僅向現存使用者顯示;停用代表張貼後註冊的新使用者也會看到。"
needConfirmationToRead: "必須確認才能標記為已讀"
needConfirmationToReadDescription: "啟用代表此公告將顯示對話方塊以確認是否標記為已讀,同時不會受「標記所有公告為已讀」功能影響。"
needConfirmationToReadDescription: "啟用代表此公告將顯示對話方塊以確認是否標記為已讀。"
end: "結束公告"
tooManyActiveAnnouncementDescription: "有過多公告可能會影響使用者體驗。請考慮歸檔已結束的公告。"
readConfirmTitle: "標記為已讀嗎?"

View File

@ -0,0 +1,11 @@
export class AnnouncementNeedEnrollmentTutorialToRead1729270181417 {
name = 'AnnouncementNeedEnrollmentTutorialToRead1729270181417'
async up(queryRunner) {
await queryRunner.query(`ALTER TABLE "announcement" ADD "needEnrollmentTutorialToRead" boolean NOT NULL DEFAULT false`);
}
async down(queryRunner) {
await queryRunner.query(`ALTER TABLE "announcement" DROP COLUMN "needEnrollmentTutorialToRead"`);
}
}

View File

@ -91,6 +91,7 @@ export class AnnouncementService {
forExistingUsers: values.forExistingUsers,
silence: values.silence,
needConfirmationToRead: values.needConfirmationToRead,
needEnrollmentTutorialToRead: values.needEnrollmentTutorialToRead,
closeDuration: values.closeDuration,
displayOrder: values.displayOrder,
userId: values.userId,
@ -200,6 +201,7 @@ export class AnnouncementService {
icon: values.icon,
forExistingUsers: values.forExistingUsers,
needConfirmationToRead: values.needConfirmationToRead,
needEnrollmentTutorialToRead: values.needEnrollmentTutorialToRead,
closeDuration: values.closeDuration,
displayOrder: values.displayOrder,
silence: values.silence,

View File

@ -54,6 +54,7 @@ export class AnnouncementEntityService {
display: announcement.display,
forYou: announcement.userId === me?.id,
needConfirmationToRead: announcement.needConfirmationToRead,
needEnrollmentTutorialToRead: announcement.needEnrollmentTutorialToRead,
closeDuration: announcement.closeDuration,
displayOrder: announcement.displayOrder,
silence: announcement.silence,

View File

@ -61,6 +61,11 @@ export class MiAnnouncement {
})
public needConfirmationToRead: boolean;
@Column('boolean', {
default: false,
})
public needEnrollmentTutorialToRead: boolean;
@Column('integer', {
nullable: false,
default: 0,

View File

@ -48,6 +48,10 @@ export const packedAnnouncementSchema = {
type: 'boolean',
optional: false, nullable: false,
},
needEnrollmentTutorialToRead: {
type: 'boolean',
optional: false, nullable: false,
},
forYou: {
type: 'boolean',
optional: false, nullable: false,

View File

@ -62,6 +62,10 @@ export const meta = {
type: 'boolean',
optional: false, nullable: false,
},
needEnrollmentTutorialToRead: {
type: 'boolean',
optional: false, nullable: false,
},
closeDuration: {
type: 'number',
optional: false, nullable: false,
@ -92,6 +96,7 @@ export const paramDef = {
display: { type: 'string', enum: ['normal', 'banner', 'dialog'], default: 'normal' },
forExistingUsers: { type: 'boolean', default: false },
needConfirmationToRead: { type: 'boolean', default: false },
needEnrollmentTutorialToRead: { type: 'boolean', default: false },
closeDuration: { type: 'number', default: 0 },
displayOrder: { type: 'number', default: 0 },
silence: { type: 'boolean', default: false },
@ -115,6 +120,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
display: ps.display,
forExistingUsers: ps.forExistingUsers,
needConfirmationToRead: ps.needConfirmationToRead,
needEnrollmentTutorialToRead: ps.needEnrollmentTutorialToRead,
closeDuration: ps.closeDuration,
displayOrder: ps.displayOrder,
silence: ps.silence,

View File

@ -72,6 +72,10 @@ export const meta = {
type: 'boolean',
optional: false, nullable: false,
},
needEnrollmentTutorialToRead: {
type: 'boolean',
optional: false, nullable: false,
},
closeDuration: {
type: 'number',
optional: false, nullable: false,
@ -139,6 +143,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
isActive: announcement.isActive,
forExistingUsers: announcement.forExistingUsers,
needConfirmationToRead: announcement.needConfirmationToRead,
needEnrollmentTutorialToRead: announcement.needEnrollmentTutorialToRead,
closeDuration: announcement.closeDuration,
displayOrder: announcement.displayOrder,
silence: announcement.silence,

View File

@ -37,6 +37,7 @@ export const paramDef = {
display: { type: 'string', enum: ['normal', 'banner', 'dialog'] },
forExistingUsers: { type: 'boolean' },
needConfirmationToRead: { type: 'boolean' },
needEnrollmentTutorialToRead: { type: 'boolean' },
closeDuration: { type: 'number', default: 0 },
displayOrder: { type: 'number', default: 0 },
silence: { type: 'boolean' },
@ -68,6 +69,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
icon: ps.icon,
forExistingUsers: ps.forExistingUsers,
needConfirmationToRead: ps.needConfirmationToRead,
needEnrollmentTutorialToRead: ps.needEnrollmentTutorialToRead,
closeDuration: ps.closeDuration,
displayOrder: ps.displayOrder,
silence: ps.silence,

View File

@ -46,6 +46,7 @@ export const Default = {
imageUrl: null,
display: 'dialog',
needConfirmationToRead: false,
needEnrollmentTutorialToRead: false,
silence: false,
forYou: true,
},

View File

@ -19,13 +19,16 @@ SPDX-License-Identifier: AGPL-3.0-only
<Mfm :text="announcement.text"/>
<img v-if="announcement.imageUrl" :src="announcement.imageUrl"/>
</div>
<MkButton :class="$style.gotIt" primary full :disabled="gotItDisabled" @click="gotIt">{{ i18n.ts.gotIt }}<span v-if="secVisible"> ({{ sec }})</span></MkButton>
<MkButton :class="$style.gotIt" primary gradate full :disabled="gotItDisabled" @click="gotIt">
{{ !announcement.needEnrollmentTutorialToRead ? i18n.ts.gotIt : i18n.ts._initialAccountSetting.startTutorial }}
<span v-if="secVisible"> ({{ sec }})</span>
</MkButton>
</div>
</MkModal>
</template>
<script lang="ts" setup>
import { onMounted, ref, shallowRef } from 'vue';
import { defineAsyncComponent, onMounted, ref, shallowRef } from 'vue';
import * as Misskey from 'misskey-js';
import * as os from '@/os.js';
import { misskeyApi } from '@/scripts/misskey-api.js';
@ -46,6 +49,18 @@ const secVisible = ref(true);
const sec = ref(props.announcement.closeDuration);
async function gotIt(): Promise<void> {
if (props.announcement.needEnrollmentTutorialToRead) {
modal.value?.close();
const tutorialCompleted = await (new Promise<boolean>(resolve => {
os.popup(defineAsyncComponent(() => import('@/components/MkTutorialDialog.vue')), {}, {
done: () => {
resolve(true);
},
}, 'closed');
}));
if (!tutorialCompleted) return;
}
if (props.announcement.needConfirmationToRead) {
const confirm = await os.confirm({
type: 'question',

View File

@ -167,6 +167,7 @@ const props = defineProps<{
}>();
const emit = defineEmits<{
(ev: 'done'): void;
(ev: 'closed'): void;
}>();
@ -179,6 +180,7 @@ watch(page, (to) => {
//
if (to === 6) {
claimAchievement('tutorialCompleted');
emit('done');
}
});

View File

@ -42,6 +42,10 @@ SPDX-License-Identifier: AGPL-3.0-only
{{ i18n.ts._announcement.needConfirmationToRead }}
<template #caption>{{ i18n.ts._announcement.needConfirmationToReadDescription }}</template>
</MkSwitch>
<MkSwitch v-model="needEnrollmentTutorialToRead">
{{ i18n.ts._announcement.needEnrollmentTutorialToRead }}
<template #caption>{{ i18n.ts._announcement.needEnrollmentTutorialToReadDescription }}</template>
</MkSwitch>
<MkInput v-model="closeDuration" type="number">
<template #label>{{ i18n.ts.dialogCloseDuration }}</template>
<template #suffix>{{ i18n.ts._time.second }}</template>
@ -90,6 +94,7 @@ const text = ref<string>(props.announcement ? props.announcement.text : '');
const icon = ref<string>(props.announcement ? props.announcement.icon : 'info');
const display = ref<string>(props.announcement ? props.announcement.display : 'dialog');
const needConfirmationToRead = ref(props.announcement ? props.announcement.needConfirmationToRead : false);
const needEnrollmentTutorialToRead = ref(props.announcement ? props.announcement.needEnrollmentTutorialToRead : false);
const closeDuration = ref<number>(props.announcement ? props.announcement.closeDuration : 0);
const displayOrder = ref<number>(props.announcement ? props.announcement.displayOrder : 0);
const silence = ref<boolean>(props.announcement ? props.announcement.silence : false);

View File

@ -66,6 +66,9 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkSwitch v-model="announcement.needConfirmationToRead" :helpText="i18n.ts._announcement.needConfirmationToReadDescription">
{{ i18n.ts._announcement.needConfirmationToRead }}
</MkSwitch>
<MkSwitch v-model="announcement.needEnrollmentTutorialToRead" :helpText="i18n.ts._announcement.needEnrollmentTutorialToReadDescription">
{{ i18n.ts._announcement.needEnrollmentTutorialToRead }}
</MkSwitch>
<MkInput v-model="announcement.closeDuration" type="number">
<template #label>{{ i18n.ts.dialogCloseDuration }}</template>
<template #suffix>{{ i18n.ts._time.second }}</template>

View File

@ -34,7 +34,10 @@
</MkA>
</div>
<div v-if="$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 gradate @click="read(announcement)">
<i :class="!announcement.needEnrollmentTutorialToRead ? 'ti ti-check' : 'ti ti-presentation'"/>
{{ !announcement.needEnrollmentTutorialToRead ? i18n.ts.gotIt : i18n.ts._initialAccountSetting.startTutorial }}
</MkButton>
</div>
</div>
<MkError v-else-if="error" @retry="fetch()"/>
@ -45,7 +48,7 @@
</template>
<script lang="ts" setup>
import { ref, computed, watch } from 'vue';
import { ref, computed, watch, defineAsyncComponent } from 'vue';
import * as Misskey from 'misskey-js';
import MkButton from '@/components/MkButton.vue';
import * as os from '@/os.js';
@ -75,6 +78,17 @@ function fetch() {
}
async function read(announcement): Promise<void> {
if (announcement.needEnrollmentTutorialToRead) {
const tutorialCompleted = await (new Promise<boolean>(resolve => {
os.popup(defineAsyncComponent(() => import('@/components/MkTutorialDialog.vue')), {}, {
done: () => {
resolve(true);
},
}, 'closed');
}));
if (!tutorialCompleted) return;
}
if (announcement.needConfirmationToRead) {
const confirm = await os.confirm({
type: 'question',

View File

@ -36,7 +36,10 @@ SPDX-License-Identifier: AGPL-3.0-only
</MkA>
</div>
<div v-if="$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 gradate @click="read(announcement)">
<i :class="!announcement.needEnrollmentTutorialToRead ? 'ti ti-check' : 'ti ti-presentation'"/>
{{ !announcement.needEnrollmentTutorialToRead ? i18n.ts.gotIt : i18n.ts._initialAccountSetting.startTutorial }}
</MkButton>
</div>
</section>
</MkPagination>
@ -47,7 +50,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import { ref, computed, watch } from 'vue';
import { ref, computed, watch, defineAsyncComponent } from 'vue';
import MkPagination from '@/components/MkPagination.vue';
import MkButton from '@/components/MkButton.vue';
import MkInfo from '@/components/MkInfo.vue';
@ -81,6 +84,17 @@ const paginationEl = ref<InstanceType<typeof MkPagination>>();
const tab = ref('current');
async function read(announcement): Promise<void> {
if (announcement.needEnrollmentTutorialToRead) {
const tutorialCompleted = await (new Promise<boolean>(resolve => {
os.popup(defineAsyncComponent(() => import('@/components/MkTutorialDialog.vue')), {}, {
done: () => {
resolve(true);
},
}, 'closed');
}));
if (!tutorialCompleted) return;
}
if (announcement.needConfirmationToRead) {
const confirm = await os.confirm({
type: 'question',

View File

@ -4156,6 +4156,7 @@ export type components = {
/** @enum {string} */
display: 'dialog' | 'normal' | 'banner';
needConfirmationToRead: boolean;
needEnrollmentTutorialToRead: boolean;
forYou: boolean;
closeDuration: number;
displayOrder: number;
@ -6028,6 +6029,8 @@ export type operations = {
forExistingUsers?: boolean;
/** @default false */
needConfirmationToRead?: boolean;
/** @default false */
needEnrollmentTutorialToRead?: boolean;
/** @default 0 */
closeDuration?: number;
/** @default 0 */
@ -6063,6 +6066,7 @@ export type operations = {
display: string;
forYou: boolean;
needConfirmationToRead: boolean;
needEnrollmentTutorialToRead: boolean;
closeDuration: number;
displayOrder: number;
silence: boolean;
@ -6195,6 +6199,7 @@ export type operations = {
display: string;
forExistingUsers: boolean;
needConfirmationToRead: boolean;
needEnrollmentTutorialToRead: boolean;
closeDuration: number;
displayOrder: number;
silence: boolean;
@ -6259,6 +6264,7 @@ export type operations = {
display?: 'normal' | 'banner' | 'dialog';
forExistingUsers?: boolean;
needConfirmationToRead?: boolean;
needEnrollmentTutorialToRead?: boolean;
/** @default 0 */
closeDuration?: number;
/** @default 0 */