feat: mute

This commit is contained in:
zerosoul
2022-04-11 10:12:42 +08:00
parent 23496d0baf
commit 365a14cdfa
5 changed files with 147 additions and 18 deletions
@@ -18,6 +18,12 @@ export default async function handler({ operation, data = {}, payload }) {
await table.setItem("afterMid", afterMid); await table.setItem("afterMid", afterMid);
} }
break; break;
case "updateMute":
{
await table.setItem("muteUsers", data.muteUsers || {});
await table.setItem("muteChannels", data.muteChannels || {});
}
break;
case "updateReadChannels": case "updateReadChannels":
{ {
await table.setItem("readChannels", data.readChannels); await table.setItem("readChannels", data.readChannels);
+17
View File
@@ -3,6 +3,7 @@ import { createApi } from "@reduxjs/toolkit/query/react";
import { KEY_UID } from "../config"; import { KEY_UID } from "../config";
import baseQuery from "./base.query"; import baseQuery from "./base.query";
import { resetAuthData, setUid } from "../slices/auth.data"; import { resetAuthData, setUid } from "../slices/auth.data";
import { updateMute } from "../slices/footprint";
import { fullfillContacts } from "../slices/contacts"; import { fullfillContacts } from "../slices/contacts";
import BASE_URL, { ContentTypes } from "../config"; import BASE_URL, { ContentTypes } from "../config";
import { onMessageSendStarted } from "./handlers"; import { onMessageSendStarted } from "./handlers";
@@ -47,6 +48,21 @@ export const contactApi = createApi({
deleteContact: builder.query({ deleteContact: builder.query({
query: (uid) => ({ url: `/admin/user/${uid}`, method: "DELETE" }), query: (uid) => ({ url: `/admin/user/${uid}`, method: "DELETE" }),
}), }),
updateMuteSetting: builder.mutation({
query: (data) => ({
url: `/user/mute`,
method: "POST",
body: data,
}),
async onQueryStarted(data, { dispatch, queryFulfilled }) {
try {
await queryFulfilled;
dispatch(updateMute(data));
} catch (error) {
console.log("update mute failed", error);
}
},
}),
updateAvatar: builder.mutation({ updateAvatar: builder.mutation({
query: (data) => ({ query: (data) => ({
headers: { headers: {
@@ -89,6 +105,7 @@ export const contactApi = createApi({
}); });
export const { export const {
useUpdateMuteSettingMutation,
useLazyDeleteContactQuery, useLazyDeleteContactQuery,
useUpdateInfoMutation, useUpdateInfoMutation,
useUpdateAvatarMutation, useUpdateAvatarMutation,
+54 -1
View File
@@ -4,6 +4,8 @@ const initialState = {
afterMid: 0, afterMid: 0,
readUsers: {}, readUsers: {},
readChannels: {}, readChannels: {},
muteUsers: {},
muteChannels: {},
}; };
const footprintSlice = createSlice({ const footprintSlice = createSlice({
name: "footprint", name: "footprint",
@@ -18,8 +20,17 @@ const footprintSlice = createSlice({
afterMid = 0, afterMid = 0,
readUsers = {}, readUsers = {},
readChannels = {}, readChannels = {},
muteUsers = {},
muteChannels = {},
} = action.payload; } = action.payload;
return { usersVersion, afterMid, readUsers, readChannels }; return {
usersVersion,
afterMid,
readUsers,
readChannels,
muteUsers,
muteChannels,
};
}, },
updateUsersVersion(state, action) { updateUsersVersion(state, action) {
const usersVersion = action.payload; const usersVersion = action.payload;
@@ -29,6 +40,47 @@ const footprintSlice = createSlice({
const afterMid = action.payload; const afterMid = action.payload;
state.afterMid = afterMid; state.afterMid = afterMid;
}, },
updateMute(state, action) {
const payload = action.payload || {};
Object.keys(payload).forEach((key) => {
switch (key) {
case "remove_users":
{
const uids = payload.remove_users;
uids.forEach((id) => {
delete state.muteUsers[id];
});
}
break;
case "remove_groups":
{
const gids = payload.remove_groups;
gids.forEach((id) => {
delete state.muteChannels[id];
});
}
break;
case "add_users":
{
const mutes = payload.add_users;
mutes.forEach(({ uid, expired_in = null }) => {
state.muteUsers[uid] = { expired_in };
});
}
break;
case "add_groups":
{
const mutes = payload.add_groups;
mutes.forEach(({ gid, expired_in = null }) => {
state.muteChannels[gid] = { expired_in };
});
}
break;
default:
break;
}
});
},
updateReadUsers(state, action) { updateReadUsers(state, action) {
const reads = action.payload || []; const reads = action.payload || [];
if (reads.length == 0) return; if (reads.length == 0) return;
@@ -52,5 +104,6 @@ export const {
updateUsersVersion, updateUsersVersion,
updateReadChannels, updateReadChannels,
updateReadUsers, updateReadUsers,
updateMute,
} = footprintSlice.actions; } = footprintSlice.actions;
export default footprintSlice.reducer; export default footprintSlice.reducer;
+40 -3
View File
@@ -19,6 +19,7 @@ import {
updateUsersVersion, updateUsersVersion,
updateReadChannels, updateReadChannels,
updateReadUsers, updateReadUsers,
updateMute,
} from "../../../app/slices/footprint"; } from "../../../app/slices/footprint";
import { import {
updateUsersByLogs, updateUsersByLogs,
@@ -151,9 +152,45 @@ export default function useStreaming() {
case "user_settings_changed": case "user_settings_changed":
{ {
console.log("users settings"); console.log("users settings");
const { read_index_users = [], read_index_groups = [] } = data; Object.keys(data).forEach((key) => {
dispatch(updateReadChannels(read_index_groups)); switch (key) {
dispatch(updateReadUsers(read_index_users)); case "read_index_groups":
dispatch(updateReadChannels(data[key]));
break;
case "read_index_users":
dispatch(updateReadUsers(data[key]));
break;
case "add_mute_users":
case "mute_users":
case "add_mute_groups":
case "mute_groups":
{
const arr = data[key];
if (arr && arr.length) {
const _key = key.endsWith("users")
? "add_users"
: "add_groups";
dispatch(updateMute({ [_key]: arr }));
}
}
break;
case "remove_mute_users":
case "remove_mute_groups":
{
const arr = data[key];
if (arr && arr.length) {
const _key = key.endsWith("users")
? "remove_users"
: "remove_groups";
dispatch(updateMute({ [_key]: arr }));
}
}
break;
default:
break;
}
});
} }
break; break;
case "users_state": case "users_state":
+23 -7
View File
@@ -8,6 +8,7 @@ import ContextMenu from "../../../common/component/ContextMenu";
import Tooltip from "../../../common/component/Tooltip"; import Tooltip from "../../../common/component/Tooltip";
// import { useDebounce} from "rooks"; // import { useDebounce} from "rooks";
import { useReadMessageMutation } from "../../../app/services/message"; import { useReadMessageMutation } from "../../../app/services/message";
import { useUpdateMuteSettingMutation } from "../../../app/services/contact";
import StyledLink from "./styled"; import StyledLink from "./styled";
import { toggleChannelSetting } from "../../../app/slices/ui"; import { toggleChannelSetting } from "../../../app/slices/ui";
@@ -17,6 +18,7 @@ import { getUnreadCount } from "../utils";
const NavItem = ({ id, setFiles, toggleRemoveConfirm }) => { const NavItem = ({ id, setFiles, toggleRemoveConfirm }) => {
const dispatch = useDispatch(); const dispatch = useDispatch();
const navigate = useNavigate(); const navigate = useNavigate();
const [muteChannel] = useUpdateMuteSettingMutation();
const [updateReadIndex] = useReadMessageMutation(); const [updateReadIndex] = useReadMessageMutation();
const { const {
@@ -25,17 +27,23 @@ const NavItem = ({ id, setFiles, toggleRemoveConfirm }) => {
handleContextMenuEvent, handleContextMenuEvent,
hideContextMenu, hideContextMenu,
} = useContextMenu(); } = useContextMenu();
const { channel, mids, messageData, readIndex, loginUid } = useSelector( const {
(store) => { channel,
mids,
messageData,
readIndex,
muted,
loginUid,
} = useSelector((store) => {
return { return {
channel: store.channels.byId[id], channel: store.channels.byId[id],
mids: store.channelMessage[id], mids: store.channelMessage[id],
messageData: store.message, messageData: store.message,
loginUid: store.authData.uid, loginUid: store.authData.uid,
readIndex: store.footprint.readChannels[id], readIndex: store.footprint.readChannels[id],
muted: store.footprint.muteChannels[id],
}; };
} });
);
const handleChannelSetting = (evt) => { const handleChannelSetting = (evt) => {
evt.preventDefault(); evt.preventDefault();
evt.stopPropagation(); evt.stopPropagation();
@@ -66,8 +74,15 @@ const NavItem = ({ id, setFiles, toggleRemoveConfirm }) => {
updateReadIndex(param); updateReadIndex(param);
} }
}; };
const handleMute = () => {
const data = muted
? { remove_groups: [id] }
: { add_groups: [{ gid: id }] };
muteChannel(data);
};
const { is_public, name } = channel; const { is_public, name } = channel;
const unreads = getUnreadCount({ mids, messageData, readIndex, loginUid }); const unreads = getUnreadCount({ mids, messageData, readIndex, loginUid });
const isDot = muted || unreads > 99;
return ( return (
<Tippy <Tippy
interactive interactive
@@ -86,7 +101,8 @@ const NavItem = ({ id, setFiles, toggleRemoveConfirm }) => {
handler: handleReadAll, handler: handleReadAll,
}, },
{ {
title: "Mute", title: muted ? "Unmute" : "Mute",
handler: handleMute,
}, },
{ {
title: "Notification Settings", title: "Notification Settings",
@@ -123,8 +139,8 @@ const NavItem = ({ id, setFiles, toggleRemoveConfirm }) => {
<i className="setting" onClick={handleChannelSetting}></i> <i className="setting" onClick={handleChannelSetting}></i>
</Tooltip> </Tooltip>
{unreads > 0 && ( {unreads > 0 && (
<i className={`badge ${unreads > 99 ? "dot" : ""}`}> <i className={`badge ${isDot ? "dot" : ""}`}>
{unreads > 99 ? null : unreads} {isDot ? null : unreads}
</i> </i>
)} )}
</div> </div>