summaryrefslogtreecommitdiff
path: root/packages/frontend/src/pages
diff options
context:
space:
mode:
authorおさむのひと <46447427+samunohito@users.noreply.github.com>2025-11-07 08:39:21 +0900
committerGitHub <noreply@github.com>2025-11-07 08:39:21 +0900
commit729abbef621aea5b8b697644181915935b74bbf8 (patch)
tree27545c0cfd3e6272dd40de2c77daf0d2adec3e6c /packages/frontend/src/pages
parentBump version to 2025.11.0-alpha.1 (diff)
downloadmisskey-729abbef621aea5b8b697644181915935b74bbf8.tar.gz
misskey-729abbef621aea5b8b697644181915935b74bbf8.tar.bz2
misskey-729abbef621aea5b8b697644181915935b74bbf8.zip
feat: チャンネルミュートの実装 (#14105)
* add channel_muting table and entities * add channel_muting services * タイムライン取得処理への組み込み * misskey-jsの型とインターフェース生成 * Channelスキーマにミュート情報を追加 * フロントエンドの実装 * 条件が逆だったのを修正 * 期限切れミュートを掃除する機能を実装 * TLの抽出条件調節 * 名前の変更と変更不要の差分をロールバック * 修正漏れ * isChannelRelatedの条件に誤りがあった * [wip] テスト追加 * テストの追加と検出した不備の修正 * fix test * fix CHANGELOG.md * 通常はFTTにしておく * 実装忘れ対応 * fix merge * fix merge * add channel tl test * fix CHANGELOG.md * remove unused import * fix lint * fix test * fix favorite -> favorited * exclude -> include * fix CHANGELOG.md * fix CHANGELOG.md * maintenance * fix CHANGELOG.md * fix * fix ci * regenerate * fix * Revert "fix" This reverts commit 699d50c6ec798777d8e9667cb5d45a26b06bfc93. * fixed --------- Co-authored-by: syuilo <4439005+syuilo@users.noreply.github.com>
Diffstat (limited to 'packages/frontend/src/pages')
-rw-r--r--packages/frontend/src/pages/channel.vue82
1 files changed, 74 insertions, 8 deletions
diff --git a/packages/frontend/src/pages/channel.vue b/packages/frontend/src/pages/channel.vue
index 7c19e6798d..dff8be2a57 100644
--- a/packages/frontend/src/pages/channel.vue
+++ b/packages/frontend/src/pages/channel.vue
@@ -129,24 +129,25 @@ useInterval(() => {
});
watch(() => props.channelId, async () => {
- channel.value = await misskeyApi('channels/show', {
+ const _channel = await misskeyApi('channels/show', {
channelId: props.channelId,
});
- if (channel.value == null) return; // TSを黙らすため
- favorited.value = channel.value.isFavorited ?? false;
- if (favorited.value || channel.value.isFollowing) {
+ favorited.value = _channel.isFavorited ?? false;
+ if (favorited.value || _channel.isFollowing) {
tab.value = 'timeline';
}
- if ((favorited.value || channel.value.isFollowing) && channel.value.lastNotedAt) {
- const lastReadedAt: number = miLocalStorage.getItemAsJson(`channelLastReadedAt:${channel.value.id}`) ?? 0;
- const lastNotedAt = Date.parse(channel.value.lastNotedAt);
+ if ((favorited.value || _channel.isFollowing) && _channel.lastNotedAt) {
+ const lastReadedAt: number = miLocalStorage.getItemAsJson(`channelLastReadedAt:${_channel.id}`) ?? 0;
+ const lastNotedAt = Date.parse(_channel.lastNotedAt);
if (lastNotedAt > lastReadedAt) {
- miLocalStorage.setItemAsJson(`channelLastReadedAt:${channel.value.id}`, lastNotedAt);
+ miLocalStorage.setItemAsJson(`channelLastReadedAt:${_channel.id}`, lastNotedAt);
}
}
+
+ channel.value = _channel;
}, { immediate: true });
function edit() {
@@ -190,6 +191,53 @@ async function unfavorite() {
});
}
+async function mute() {
+ if (!channel.value) return;
+ const _channel = channel.value;
+
+ const { canceled, result: period } = await os.select({
+ title: i18n.ts.mutePeriod,
+ items: [{
+ value: 'indefinitely', text: i18n.ts.indefinitely,
+ }, {
+ value: 'tenMinutes', text: i18n.ts.tenMinutes,
+ }, {
+ value: 'oneHour', text: i18n.ts.oneHour,
+ }, {
+ value: 'oneDay', text: i18n.ts.oneDay,
+ }, {
+ value: 'oneWeek', text: i18n.ts.oneWeek,
+ }],
+ default: 'indefinitely',
+ });
+ if (canceled) return;
+
+ const expiresAt = period === 'indefinitely' ? null
+ : period === 'tenMinutes' ? Date.now() + (1000 * 60 * 10)
+ : period === 'oneHour' ? Date.now() + (1000 * 60 * 60)
+ : period === 'oneDay' ? Date.now() + (1000 * 60 * 60 * 24)
+ : period === 'oneWeek' ? Date.now() + (1000 * 60 * 60 * 24 * 7)
+ : null;
+
+ os.apiWithDialog('channels/mute/create', {
+ channelId: _channel.id,
+ expiresAt,
+ }).then(() => {
+ _channel.isMuting = true;
+ });
+}
+
+async function unmute() {
+ if (!channel.value) return;
+ const _channel = channel.value;
+
+ os.apiWithDialog('channels/mute/delete', {
+ channelId: _channel.id,
+ }).then(() => {
+ _channel.isMuting = false;
+ });
+}
+
async function search() {
if (!channel.value) return;
@@ -243,6 +291,24 @@ const headerActions = computed(() => {
});
}
+ if (!channel.value.isMuting) {
+ headerItems.push({
+ icon: 'ti ti-volume',
+ text: i18n.ts.mute,
+ handler: async (): Promise<void> => {
+ await mute();
+ },
+ });
+ } else {
+ headerItems.push({
+ icon: 'ti ti-volume-off',
+ text: i18n.ts.unmute,
+ handler: async (): Promise<void> => {
+ await unmute();
+ },
+ });
+ }
+
if (($i && $i.id === channel.value.userId) || iAmModerator) {
headerItems.push({
icon: 'ti ti-settings',