feat: 未読の通知のみ表示する機能
This commit is contained in:
parent
27c056cbbf
commit
ec05c07321
|
@ -14,7 +14,9 @@
|
||||||
- アカウント登録にメールアドレスの設定を必須にするオプション
|
- アカウント登録にメールアドレスの設定を必須にするオプション
|
||||||
- クライアント: アニメーションを減らす設定をメニューのアニメーションにも適用するように
|
- クライアント: アニメーションを減らす設定をメニューのアニメーションにも適用するように
|
||||||
- クライアント: MFM関数構文のサジェストを実装
|
- クライアント: MFM関数構文のサジェストを実装
|
||||||
|
- クライアント: 未読の通知のみ表示する機能
|
||||||
- ActivityPub: HTML -> MFMの変換を強化
|
- ActivityPub: HTML -> MFMの変換を強化
|
||||||
|
- API: i/notifications に unreadOnly オプションを追加
|
||||||
- API: ap系のエンドポイントをログイン必須化+レートリミット追加
|
- API: ap系のエンドポイントをログイン必須化+レートリミット追加
|
||||||
- Misskeyのコマンドラインオプションを廃止
|
- Misskeyのコマンドラインオプションを廃止
|
||||||
- 代わりに環境変数で設定することができます
|
- 代わりに環境変数で設定することができます
|
||||||
|
|
|
@ -792,6 +792,7 @@ unresolved: "未解決"
|
||||||
itsOn: "オンになっています"
|
itsOn: "オンになっています"
|
||||||
itsOff: "オフになっています"
|
itsOff: "オフになっています"
|
||||||
emailRequiredForSignup: "アカウント登録にメールアドレスを必須にする"
|
emailRequiredForSignup: "アカウント登録にメールアドレスを必須にする"
|
||||||
|
unread: "未読"
|
||||||
|
|
||||||
_signup:
|
_signup:
|
||||||
almostThere: "ほとんど完了です"
|
almostThere: "ほとんど完了です"
|
||||||
|
|
|
@ -48,6 +48,11 @@ export default defineComponent({
|
||||||
required: false,
|
required: false,
|
||||||
default: null,
|
default: null,
|
||||||
},
|
},
|
||||||
|
unreadOnly: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
|
@ -58,6 +63,7 @@ export default defineComponent({
|
||||||
limit: 10,
|
limit: 10,
|
||||||
params: () => ({
|
params: () => ({
|
||||||
includeTypes: this.allIncludeTypes || undefined,
|
includeTypes: this.allIncludeTypes || undefined,
|
||||||
|
unreadOnly: this.unreadOnly,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -76,6 +82,11 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
deep: true
|
deep: true
|
||||||
},
|
},
|
||||||
|
unreadOnly: {
|
||||||
|
handler() {
|
||||||
|
this.reload();
|
||||||
|
},
|
||||||
|
},
|
||||||
// TODO: vue/vuexのバグか仕様かは不明なものの、プロフィール更新するなどして $i が更新されると、
|
// TODO: vue/vuexのバグか仕様かは不明なものの、プロフィール更新するなどして $i が更新されると、
|
||||||
// mutingNotificationTypes に変化が無くてもこのハンドラーが呼び出され無駄なリロードが発生するのを直す
|
// mutingNotificationTypes に変化が無くてもこのハンドラーが呼び出され無駄なリロードが発生するのを直す
|
||||||
'$i.mutingNotificationTypes': {
|
'$i.mutingNotificationTypes': {
|
||||||
|
|
|
@ -2,13 +2,13 @@
|
||||||
<div>
|
<div>
|
||||||
<MkHeader :info="header"/>
|
<MkHeader :info="header"/>
|
||||||
<div class="clupoqwt" v-size="{ min: [800] }">
|
<div class="clupoqwt" v-size="{ min: [800] }">
|
||||||
<XNotifications class="notifications" @before="before" @after="after" page/>
|
<XNotifications class="notifications" @before="before" @after="after" :unread-only="tab === 'unread'"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from 'vue';
|
import { computed, defineComponent } from 'vue';
|
||||||
import Progress from '@client/scripts/loading';
|
import Progress from '@client/scripts/loading';
|
||||||
import XNotifications from '@client/components/notifications.vue';
|
import XNotifications from '@client/components/notifications.vue';
|
||||||
import * as os from '@client/os';
|
import * as os from '@client/os';
|
||||||
|
@ -26,7 +26,8 @@ export default defineComponent({
|
||||||
icon: 'fas fa-bell',
|
icon: 'fas fa-bell',
|
||||||
bg: 'var(--bg)',
|
bg: 'var(--bg)',
|
||||||
},
|
},
|
||||||
header: {
|
tab: 'all',
|
||||||
|
header: computed(() => ({
|
||||||
title: this.$ts.notifications,
|
title: this.$ts.notifications,
|
||||||
icon: 'fas fa-bell',
|
icon: 'fas fa-bell',
|
||||||
bg: 'var(--bg)',
|
bg: 'var(--bg)',
|
||||||
|
@ -35,9 +36,18 @@ export default defineComponent({
|
||||||
icon: 'fas fa-check',
|
icon: 'fas fa-check',
|
||||||
handler: () => {
|
handler: () => {
|
||||||
os.apiWithDialog('notifications/mark-all-as-read');
|
os.apiWithDialog('notifications/mark-all-as-read');
|
||||||
}
|
},
|
||||||
}]
|
}],
|
||||||
},
|
tabs: [{
|
||||||
|
active: this.tab === 'all',
|
||||||
|
title: this.$ts.all,
|
||||||
|
onClick: () => { this.tab = 'all'; },
|
||||||
|
}, {
|
||||||
|
active: this.tab === 'unread',
|
||||||
|
title: this.$ts.unread,
|
||||||
|
onClick: () => { this.tab = 'unread'; },
|
||||||
|
},]
|
||||||
|
})),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,11 @@ export const meta = {
|
||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
|
|
||||||
|
unreadOnly: {
|
||||||
|
validator: $.optional.bool,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
|
||||||
markAsRead: {
|
markAsRead: {
|
||||||
validator: $.optional.bool,
|
validator: $.optional.bool,
|
||||||
default: true
|
default: true
|
||||||
|
@ -105,6 +110,10 @@ export default define(meta, async (ps, user) => {
|
||||||
query.andWhere(`notification.type NOT IN (:...excludeTypes)`, { excludeTypes: ps.excludeTypes });
|
query.andWhere(`notification.type NOT IN (:...excludeTypes)`, { excludeTypes: ps.excludeTypes });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ps.unreadOnly) {
|
||||||
|
query.andWhere(`notification.isRead = false`);
|
||||||
|
}
|
||||||
|
|
||||||
const notifications = await query.take(ps.limit!).getMany();
|
const notifications = await query.take(ps.limit!).getMany();
|
||||||
|
|
||||||
// Mark all as read
|
// Mark all as read
|
||||||
|
|
Loading…
Reference in a new issue