wip
This commit is contained in:
parent
6634727d83
commit
ad752a8931
|
@ -1101,6 +1101,8 @@ export interface Locale {
|
|||
"dialog": string;
|
||||
"icon": string;
|
||||
"forYou": string;
|
||||
"currentAnnouncements": string;
|
||||
"pastAnnouncements": string;
|
||||
"_announcement": {
|
||||
"forExistingUsers": string;
|
||||
"forExistingUsersDescription": string;
|
||||
|
|
|
@ -1098,6 +1098,8 @@ iHaveReadXCarefullyAndAgree: "「{x}」の内容をよく読み、同意しま
|
|||
dialog: "ダイアログ"
|
||||
icon: "アイコン"
|
||||
forYou: "あなたへ"
|
||||
currentAnnouncements: "現在のお知らせ"
|
||||
pastAnnouncements: "過去のお知らせ"
|
||||
|
||||
_announcement:
|
||||
forExistingUsers: "既存ユーザーのみ"
|
||||
|
|
|
@ -33,6 +33,7 @@ export const paramDef = {
|
|||
limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 },
|
||||
sinceId: { type: 'string', format: 'misskey:id' },
|
||||
untilId: { type: 'string', format: 'misskey:id' },
|
||||
isActive: { type: 'boolean', default: true },
|
||||
},
|
||||
required: [],
|
||||
} as const;
|
||||
|
@ -52,7 +53,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
|
|||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
const query = this.queryService.makePaginationQuery(this.announcementsRepository.createQueryBuilder('announcement'), ps.sinceId, ps.untilId)
|
||||
.where('announcement.isActive = true')
|
||||
.where('announcement.isActive = :isActive', { isActive: ps.isActive })
|
||||
.andWhere(new Brackets(qb => {
|
||||
if (me) qb.orWhere('announcement.userId = :meId', { meId: me.id });
|
||||
qb.orWhere('announcement.userId IS NULL');
|
||||
|
|
|
@ -12,10 +12,15 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
:class="$style.input"
|
||||
@keydown.enter="toggle"
|
||||
>
|
||||
<XButton :checked="checked" :disabled="disabled" @toggle="toggle" />
|
||||
<XButton :checked="checked" :disabled="disabled" @toggle="toggle"/>
|
||||
<span :class="$style.body">
|
||||
<!-- TODO: 無名slotの方は廃止 -->
|
||||
<span :class="$style.label" @click="toggle"><slot name="label"></slot><slot></slot></span>
|
||||
<span :class="$style.label">
|
||||
<span @click="toggle">
|
||||
<slot name="label"></slot><slot></slot>
|
||||
</span>
|
||||
<span v-if="helpText" v-tooltip:dialog="helpText" class="_button _help" :class="$style.help"><i class="ti ti-help-circle"></i></span>
|
||||
</span>
|
||||
<p :class="$style.caption"><slot name="caption"></slot></p>
|
||||
</span>
|
||||
</div>
|
||||
|
@ -28,6 +33,7 @@ import XButton from '@/components/MkSwitch.button.vue';
|
|||
const props = defineProps<{
|
||||
modelValue: boolean | Ref<boolean>;
|
||||
disabled?: boolean;
|
||||
helpText?: string;
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
|
@ -38,10 +44,6 @@ const checked = toRefs(props).modelValue;
|
|||
const toggle = () => {
|
||||
if (props.disabled) return;
|
||||
emit('update:modelValue', !checked.value);
|
||||
|
||||
if (!checked.value) {
|
||||
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
|
@ -98,4 +100,10 @@ const toggle = () => {
|
|||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.help {
|
||||
margin-left: 0.5em;
|
||||
font-size: 85%;
|
||||
vertical-align: top;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -32,13 +32,11 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<option value="banner">{{ i18n.ts.banner }}</option>
|
||||
<option value="dialog">{{ i18n.ts.dialog }}</option>
|
||||
</MkRadios>
|
||||
<MkSwitch v-model="announcement.forExistingUsers">
|
||||
<MkSwitch v-model="announcement.forExistingUsers" :helpText="i18n.ts._announcement.forExistingUsersDescription">
|
||||
{{ i18n.ts._announcement.forExistingUsers }}
|
||||
<template #caption>{{ i18n.ts._announcement.forExistingUsersDescription }}</template>
|
||||
</MkSwitch>
|
||||
<MkSwitch v-model="announcement.needConfirmationToRead">
|
||||
<MkSwitch v-model="announcement.needConfirmationToRead" :helpText="i18n.ts._announcement.needConfirmationToReadDescription">
|
||||
{{ i18n.ts._announcement.needConfirmationToRead }}
|
||||
<template #caption>{{ i18n.ts._announcement.needConfirmationToReadDescription }}</template>
|
||||
</MkSwitch>
|
||||
<p v-if="announcement.reads">{{ i18n.t('nUsersRead', { n: announcement.reads }) }}</p>
|
||||
<div class="buttons _buttons">
|
||||
|
|
|
@ -5,9 +5,9 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
|
||||
<template>
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
|
||||
<template #header><MkPageHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs"/></template>
|
||||
<MkSpacer :contentMax="800">
|
||||
<MkPagination ref="paginationEl" v-slot="{items}" :pagination="pagination" class="_gaps_m">
|
||||
<MkPagination ref="paginationEl" :key="tab" v-slot="{items}" :pagination="tab === 'current' ? paginationCurrent : paginationPast" class="_gaps_m">
|
||||
<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">
|
||||
|
@ -27,7 +27,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<MkTime :time="announcement.updatedAt ?? announcement.createdAt" mode="detail"/>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="$i && !announcement.isRead" :class="$style.footer">
|
||||
<div v-if="tab !== 'past' && $i && !announcement.isRead" :class="$style.footer">
|
||||
<MkButton primary @click="read(announcement.id)"><i class="ti ti-check"></i> {{ i18n.ts.gotIt }}</MkButton>
|
||||
</div>
|
||||
</section>
|
||||
|
@ -45,13 +45,26 @@ import { i18n } from '@/i18n';
|
|||
import { definePageMetadata } from '@/scripts/page-metadata';
|
||||
import { $i, updateAccount } from '@/account';
|
||||
|
||||
const pagination = {
|
||||
const paginationCurrent = {
|
||||
endpoint: 'announcements' as const,
|
||||
limit: 10,
|
||||
params: {
|
||||
isActive: true,
|
||||
},
|
||||
};
|
||||
|
||||
const paginationPast = {
|
||||
endpoint: 'announcements' as const,
|
||||
limit: 10,
|
||||
params: {
|
||||
isActive: false,
|
||||
},
|
||||
};
|
||||
|
||||
const paginationEl = ref<InstanceType<typeof MkPagination>>();
|
||||
|
||||
const tab = ref('current');
|
||||
|
||||
function read(id: string) {
|
||||
if (!paginationEl.value) return;
|
||||
paginationEl.value.updateItem(id, announcement => {
|
||||
|
@ -66,7 +79,15 @@ function read(id: string) {
|
|||
|
||||
const headerActions = $computed(() => []);
|
||||
|
||||
const headerTabs = $computed(() => []);
|
||||
const headerTabs = $computed(() => [{
|
||||
key: 'current',
|
||||
title: i18n.ts.currentAnnouncements,
|
||||
icon: 'ti ti-flare',
|
||||
}, {
|
||||
key: 'past',
|
||||
title: i18n.ts.pastAnnouncements,
|
||||
icon: 'ti ti-point',
|
||||
}]);
|
||||
|
||||
definePageMetadata({
|
||||
title: i18n.ts.announcements,
|
||||
|
|
|
@ -86,7 +86,7 @@ const tagUsersPagination = $computed(() => ({
|
|||
endpoint: 'hashtags/users' as const,
|
||||
limit: 30,
|
||||
params: {
|
||||
tag: this.tag,
|
||||
tag: props.tag,
|
||||
origin: 'combined',
|
||||
sort: '+follower',
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue