Sharkey/packages/frontend/src/components/MkAnnouncementDialog.vue
2023-09-30 21:53:52 +02:00

104 lines
2.6 KiB
Vue

<!--
SPDX-FileCopyrightText: syuilo and other misskey contributors
SPDX-License-Identifier: AGPL-3.0-only
-->
<template>
<MkModal ref="modal" :zPriority="'middle'" @closed="$emit('closed')" @click="onBgClick">
<div ref="rootEl" :class="$style.root">
<div :class="$style.header">
<span :class="$style.icon">
<i v-if="announcement.icon === 'info'" class="ph-info ph-bold ph-lg"></i>
<i v-else-if="announcement.icon === 'warning'" class="ph-warning-circle ph-bold ph-lg" style="color: var(--warn);"></i>
<i v-else-if="announcement.icon === 'error'" class="ph-seal-warning ph-bold ph-lg" style="color: var(--error);"></i>
<i v-else-if="announcement.icon === 'success'" class="ph-check-circle ph-bold ph-lg" style="color: var(--success);"></i>
</span>
<span :class="$style.title">{{ announcement.title }}</span>
</div>
<div :class="$style.text"><Mfm :text="announcement.text"/></div>
<MkButton primary full @click="ok">{{ i18n.ts.ok }}</MkButton>
</div>
</MkModal>
</template>
<script lang="ts" setup>
import { onMounted, shallowRef } from 'vue';
import * as Misskey from 'misskey-js';
import * as os from '@/os.js';
import MkModal from '@/components/MkModal.vue';
import MkButton from '@/components/MkButton.vue';
import { i18n } from '@/i18n.js';
import { $i, updateAccount } from '@/account.js';
const props = withDefaults(defineProps<{
announcement: Misskey.entities.Announcement;
}>(), {
});
const rootEl = shallowRef<HTMLDivElement>();
const modal = shallowRef<InstanceType<typeof MkModal>>();
async function ok() {
if (props.announcement.needConfirmationToRead) {
const confirm = await os.confirm({
type: 'question',
title: i18n.ts._announcement.readConfirmTitle,
text: i18n.t('_announcement.readConfirmText', { title: props.announcement.title }),
});
if (confirm.canceled) return;
}
modal.value.close();
os.api('i/read-announcement', { announcementId: props.announcement.id });
updateAccount({
unreadAnnouncements: $i!.unreadAnnouncements.filter(a => a.id !== props.announcement.id),
});
}
function onBgClick() {
rootEl.value.animate([{
offset: 0,
transform: 'scale(1)',
}, {
offset: 0.5,
transform: 'scale(1.1)',
}, {
offset: 1,
transform: 'scale(1)',
}], {
duration: 100,
});
}
onMounted(() => {
});
</script>
<style lang="scss" module>
.root {
margin: auto;
position: relative;
padding: 32px;
min-width: 320px;
max-width: 480px;
box-sizing: border-box;
background: var(--panel);
border-radius: var(--radius);
}
.header {
font-size: 120%;
}
.icon {
margin-right: 0.5em;
}
.title {
font-weight: bold;
}
.text {
margin: 1em 0;
}
</style>