style: format ts file with prettier

This commit is contained in:
Tristan Yang
2023-05-19 17:28:15 +08:00
parent 5bd0183651
commit 54f995803a
70 changed files with 1021 additions and 777 deletions
+2 -2
View File
@@ -1,8 +1,8 @@
import * as localforage from "localforage";
import { extendPrototype } from 'localforage-setitems';
import { extendPrototype } from "localforage-setitems";
import { CACHE_VERSION, KEY_UID } from "../config";
import useRehydrate from "./useRehydrate";
import { KEY_UID, CACHE_VERSION } from "../config";
extendPrototype(localforage);
const tables = [
+7 -6
View File
@@ -1,15 +1,16 @@
import { useState } from "react";
import { useDispatch } from "react-redux";
import { fillReactionMessage } from "../slices/message.reaction";
import { fillServer } from "../slices/server";
import { fillChannels } from "../slices/channels";
import { fillFootprint } from "../slices/footprint";
import { fillMessage } from "../slices/message";
import { fillChannelMsg } from "../slices/message.channel";
import { fillUserMsg } from "../slices/message.user";
import { fillChannels } from "../slices/channels";
import { fillUsers } from "../slices/users";
import { fillFootprint } from "../slices/footprint";
import { fillFileMessage } from "../slices/message.file";
import { fillReactionMessage } from "../slices/message.reaction";
import { fillUserMsg } from "../slices/message.user";
import { fillServer } from "../slices/server";
import { fillUI } from "../slices/ui";
import { fillUsers } from "../slices/users";
const useRehydrate = () => {
const [iterated, setIterated] = useState(false);
@@ -1,4 +1,5 @@
import clearTable from "./clear.handler";
interface Params {
payload: any;
operation: string;
@@ -1,6 +1,8 @@
import localforage from "localforage";
import { Channel } from "@/types/channel";
import clearTable from "./clear.handler";
interface Params {
data: any;
payload: any;
@@ -1,4 +1,5 @@
import clearTable from "./clear.handler";
interface Params {
data: any;
payload: any;
@@ -1,4 +1,5 @@
import clearTable from "./clear.handler";
interface Params {
data: any;
operation: string;
@@ -1,5 +1,7 @@
import localforage from "localforage";
import clearTable from "./clear.handler";
interface Params {
payload: any;
data: any;
@@ -7,7 +9,7 @@ interface Params {
}
const ignores = ["voice_fullscreen", "voice"];
export default async function handler({ operation, data = {}, payload }: Params) {
const table = window.CACHE["footprint"] as typeof localforage;;
const table = window.CACHE["footprint"] as typeof localforage;
if (operation.startsWith("reset")) {
clearTable("footprint");
return;
@@ -34,7 +36,6 @@ export default async function handler({ operation, data = {}, payload }: Params)
table?.setItem("afterMid", afterMid);
}
});
}
break;
case "updateMute":
@@ -48,7 +49,6 @@ export default async function handler({ operation, data = {}, payload }: Params)
const { type } = payload;
if (type == "channel") {
await table?.setItem("historyChannels", data.historyChannels);
} else {
await table?.setItem("historyUsers", data.historyUsers);
}
@@ -1,4 +1,5 @@
import localforage from "localforage";
import clearTable from "./clear.handler";
interface Params {
+4 -1
View File
@@ -1,4 +1,5 @@
import localforage from "localforage";
import { ContactStatus, User } from "@/types/user";
import clearTable from "./clear.handler";
@@ -20,7 +21,9 @@ export default async function handler({ operation, data, payload }) {
break;
case "updateContactStatus":
{
const tmp = payload as { uid: number, status: ContactStatus } | { uid: number, status: ContactStatus }[];
const tmp = payload as
| { uid: number; status: ContactStatus }
| { uid: number; status: ContactStatus }[];
const arr = Array.isArray(tmp) ? tmp : [tmp];
const opts = arr.map(({ uid, status }) => {
return { key: uid + "", value: { ...data.byId[uid], status } };
+13 -12
View File
@@ -1,17 +1,18 @@
import { createListenerMiddleware } from "@reduxjs/toolkit";
import rtkqHandler from "./handler.rtkq";
import channelsHandler from "./handler.channels";
import usersHandler from "./handler.users";
import channelMsgHandler from "./handler.channel.msg";
import dmMsgHandler from "./handler.dm.msg";
import serverHandler from "./handler.server";
import messageHandler from "./handler.message";
import fileMessageHandler from "./handler.file.msg";
import archiveMessageHandler from "./handler.archive.msg";
import reactionHandler from "./handler.reaction";
import UIHandler from "./handler.ui";
import footprintHandler from "./handler.footprint";
import { RootState } from "../store";
import archiveMessageHandler from "./handler.archive.msg";
import channelMsgHandler from "./handler.channel.msg";
import channelsHandler from "./handler.channels";
import dmMsgHandler from "./handler.dm.msg";
import fileMessageHandler from "./handler.file.msg";
import footprintHandler from "./handler.footprint";
import messageHandler from "./handler.message";
import reactionHandler from "./handler.reaction";
import rtkqHandler from "./handler.rtkq";
import serverHandler from "./handler.server";
import UIHandler from "./handler.ui";
import usersHandler from "./handler.users";
const operations = [
"__rtkq",
+5 -4
View File
@@ -1,8 +1,6 @@
import { createApi } from "@reduxjs/toolkit/query/react";
import { nanoid } from "@reduxjs/toolkit";
import baseQuery from "./base.query";
import { setAuthData, updateToken, resetAuthData, updateInitialized } from "../slices/auth.data";
import BASE_URL, { KEY_DEVICE_ID, KEY_DEVICE_TOKEN, KEY_LOCAL_MAGIC_TOKEN } from "../config";
import { createApi } from "@reduxjs/toolkit/query/react";
import {
AuthData,
CredentialResponse,
@@ -11,6 +9,9 @@ import {
RenewTokenResponse
} from "@/types/auth";
import { UserRegDTO, UserRegResponse } from "@/types/user";
import BASE_URL, { KEY_DEVICE_ID, KEY_DEVICE_TOKEN, KEY_LOCAL_MAGIC_TOKEN } from "../config";
import { resetAuthData, setAuthData, updateInitialized, updateToken } from "../slices/auth.data";
import baseQuery from "./base.query";
const getDeviceId = () => {
let d = localStorage.getItem(KEY_DEVICE_ID);
+11 -9
View File
@@ -1,10 +1,11 @@
import { fetchBaseQuery } from "@reduxjs/toolkit/query";
import toast from "react-hot-toast";
import { fetchBaseQuery } from "@reduxjs/toolkit/query";
import dayjs from "dayjs";
import { updateToken, resetAuthData } from "../slices/auth.data";
import BASE_URL, { tokenHeader } from "../config";
import { RootState } from "../store";
import { getLocalAuthData } from "@/utils";
import BASE_URL, { tokenHeader } from "../config";
import { resetAuthData, updateToken } from "../slices/auth.data";
import { RootState } from "../store";
const whiteList = [
"guestLogin",
@@ -102,12 +103,13 @@ const baseQueryWithTokenCheck = async (args: any, api: any, extraOptions: any) =
}
}
break;
case 403: {
const whiteList403 = ["sendMsg"];
if (!whiteList403.includes(api.endpoint)) {
toast.error("Request Not Allowed");
case 403:
{
const whiteList403 = ["sendMsg"];
if (!whiteList403.includes(api.endpoint)) {
toast.error("Request Not Allowed");
}
}
}
break;
case 404:
+22 -18
View File
@@ -1,16 +1,17 @@
import { createApi } from "@reduxjs/toolkit/query/react";
// import toast from "react-hot-toast";
import baseQuery from "./base.query";
import { Channel, ChannelDTO, CreateChannelDTO } from "@/types/channel";
import { ContentTypeKey } from "@/types/message";
import BASE_URL, { ContentTypes } from "../config";
import { updateChannel, removeChannel } from "../slices/channels";
import { updateRememberedNavs } from "../slices/ui";
import { removeChannel, updateChannel } from "../slices/channels";
import { removeMessage } from "../slices/message";
import { removeChannelSession } from "../slices/message.channel";
import { removeReactionMessage } from "../slices/message.reaction";
import { onMessageSendStarted } from "./handlers";
import { Channel, ChannelDTO, CreateChannelDTO } from "@/types/channel";
import { updateRememberedNavs } from "../slices/ui";
import { RootState } from "../store";
import { ContentTypeKey } from "@/types/message";
// import toast from "react-hot-toast";
import baseQuery from "./base.query";
import { onMessageSendStarted } from "./handlers";
export const channelApi = createApi({
reducerPath: "channelApi",
@@ -34,14 +35,19 @@ export const channelApi = createApi({
}
}
}),
createChannel: builder.mutation<{ gid: number, created_at: number } | number, CreateChannelDTO>({
query: (data) => ({
url: "group",
method: "POST",
body: data
})
}),
changeChannelType: builder.mutation<number, { is_public: boolean, id: number, members?: number[] }>({
createChannel: builder.mutation<{ gid: number; created_at: number } | number, CreateChannelDTO>(
{
query: (data) => ({
url: "group",
method: "POST",
body: data
})
}
),
changeChannelType: builder.mutation<
number,
{ is_public: boolean; id: number; members?: number[] }
>({
query: ({ id, is_public, members }) => ({
url: `/group/${id}/change_type`,
method: "POST",
@@ -101,9 +107,7 @@ export const channelApi = createApi({
method: "DELETE"
}),
async onQueryStarted(id, { dispatch, getState, queryFulfilled }) {
const {
channelMessage,
} = getState() as RootState;
const { channelMessage } = getState() as RootState;
try {
await queryFulfilled;
// 删掉该channel下的所有消息&reaction
+5 -3
View File
@@ -2,9 +2,9 @@ import toast from "react-hot-toast";
import { batch } from "react-redux";
import { ContentTypes } from "../config";
import { addMessage, removeMessage, updateMessage } from "../slices/message";
import { addChannelMsg, removeChannelMsg } from "../slices/message.channel";
import { addUserMsg, removeUserMsg } from "../slices/message.user";
import { addMessage, removeMessage, updateMessage } from "../slices/message";
export const onMessageSendStarted = async (
{
@@ -23,7 +23,9 @@ export const onMessageSendStarted = async (
if (type == "archive") return;
// id: who send to ,from_uid: who sent
// console.log("handlers data", content, type, properties, ignoreLocal, id);
const isMedia = properties.content_type ? ["image", "video", "audio"].includes(properties.content_type.split('/')[0]) : false;
const isMedia = properties.content_type
? ["image", "video", "audio"].includes(properties.content_type.split("/")[0])
: false;
// const isImage = properties.content_type?.startsWith("image");
const ts = properties.local_id || +new Date();
const tmpMsg = {
@@ -63,7 +65,7 @@ export const onMessageSendStarted = async (
// toast.error(`Failed to send, blocked maybe.`,);
dispatch(updateMessage({ mid: ts, failed: true }));
} else {
toast.error(`Send Message Failed ${JSON.stringify(error)}`,);
toast.error(`Send Message Failed ${JSON.stringify(error)}`);
dispatch(removeContextMessage({ id, mid: ts }));
dispatch(removeMessage(ts));
}
+38 -25
View File
@@ -1,16 +1,17 @@
import { createApi } from "@reduxjs/toolkit/query/react";
import { ContentTypes } from "../config";
import { updateReadChannels, updateReadUsers, upsertOG } from "../slices/footprint";
import { fillFavorites, populateFavorite, addFavorite, deleteFavorite } from "../slices/favorites";
import { onMessageSendStarted } from "./handlers";
import { normalizeArchiveData } from "@/utils";
import baseQuery from "./base.query";
import { Archive, FavoriteArchive, OG } from "@/types/resource";
import { ChatMessage, ContentTypeKey, UploadFileResponse } from "@/types/message";
import { ChatContext } from "@/types/common";
import { ChatMessage, ContentTypeKey, UploadFileResponse } from "@/types/message";
import { Archive, FavoriteArchive, OG } from "@/types/resource";
import handleChatMessage from "@/hooks/useStreaming/chat.handler";
import { RootState } from "../store";
import { normalizeArchiveData } from "@/utils";
import { ContentTypes } from "../config";
import { addFavorite, deleteFavorite, fillFavorites, populateFavorite } from "../slices/favorites";
import { updateReadChannels, updateReadUsers, upsertOG } from "../slices/footprint";
import { upsertArchiveMessage } from "../slices/message.archive";
import { RootState } from "../store";
import baseQuery from "./base.query";
import { onMessageSendStarted } from "./handlers";
export const messageApi = createApi({
reducerPath: "messageApi",
@@ -73,15 +74,18 @@ export const messageApi = createApi({
dispatch(upsertOG({ key: url, value: data }));
} catch (err) {
console.log("get og error", err);
dispatch(upsertOG({
key: url, value: {
images: [],
audios: [],
videos: [],
title: "",
url,
}
}));
dispatch(
upsertOG({
key: url,
value: {
images: [],
audios: [],
videos: [],
title: "",
url
}
})
);
}
}
}),
@@ -176,12 +180,15 @@ export const messageApi = createApi({
}
}
}),
loadMoreMessages: builder.query<ChatMessage[], { context?: ChatContext, id: number; mid?: number; limit?: number }>({
loadMoreMessages: builder.query<
ChatMessage[],
{ context?: ChatContext; id: number; mid?: number; limit?: number }
>({
query: ({ context = "channel", id, mid = "", limit = 100 }) => {
const url = context == "channel" ?
`/group/${id}/history?limit=${limit}${mid ? `&before=${mid}` : ""}`
:
`/user/${id}/history?limit=${limit}${mid ? `&before=${mid}` : ""}`;
const url =
context == "channel"
? `/group/${id}/history?limit=${limit}${mid ? `&before=${mid}` : ""}`
: `/user/${id}/history?limit=${limit}${mid ? `&before=${mid}` : ""}`;
return {
url
};
@@ -198,7 +205,13 @@ export const messageApi = createApi({
}),
replyMessage: builder.mutation<
number,
{ from_uid: number, reply_mid: number; content: string; type: ContentTypeKey, properties?: {} }
{
from_uid: number;
reply_mid: number;
content: string;
type: ContentTypeKey;
properties?: {};
}
>({
query: ({ reply_mid, content, type = "text", properties }) => ({
headers: {
@@ -245,7 +258,7 @@ export const messageApi = createApi({
method: "HEAD",
responseHandler: "text"
})
}),
})
})
});
+61 -46
View File
@@ -1,30 +1,31 @@
import { createApi } from "@reduxjs/toolkit/query/react";
import BASE_URL, { ContentTypes, IS_OFFICIAL_DEMO, PAYMENT_URL_PREFIX } from "../config";
import { updateInfo } from "../slices/server";
import baseQuery from "./base.query";
import { RootState } from "../store";
import { User } from "@/types/user";
import {
FirebaseConfig,
GoogleAuthConfig,
LoginConfig,
Server,
TestEmailDTO,
CreateAdminDTO,
SMTPConfig,
AgoraConfig,
GithubAuthConfig,
LicenseResponse,
RenewLicense,
RenewLicenseResponse,
AgoraTokenResponse,
AgoraVoicingListResponse,
SystemCommon,
AgoraChannelUsersResponse
} from "@/types/server";
import { Channel } from "@/types/channel";
import { ContentTypeKey } from "@/types/message";
import {
AgoraChannelUsersResponse,
AgoraConfig,
AgoraTokenResponse,
AgoraVoicingListResponse,
CreateAdminDTO,
FirebaseConfig,
GithubAuthConfig,
GoogleAuthConfig,
LicenseResponse,
LoginConfig,
RenewLicense,
RenewLicenseResponse,
Server,
SMTPConfig,
SystemCommon,
TestEmailDTO
} from "@/types/server";
import { User } from "@/types/user";
import BASE_URL, { ContentTypes, IS_OFFICIAL_DEMO, PAYMENT_URL_PREFIX } from "../config";
import { updateInfo } from "../slices/server";
import { updateCallInfo, upsertVoiceList } from "../slices/voice";
import { RootState } from "../store";
import baseQuery from "./base.query";
const defaultExpireDuration = 2 * 24 * 60 * 60;
@@ -69,9 +70,7 @@ export const serverApi = createApi({
async onQueryStarted(data, { dispatch, queryFulfilled }) {
try {
const resp = await queryFulfilled;
dispatch(
updateInfo({ version: resp.data })
);
dispatch(updateInfo({ version: resp.data }));
} catch {
console.error("get server version error");
}
@@ -117,18 +116,26 @@ export const serverApi = createApi({
getAgoraConfig: builder.query<AgoraConfig, void>({
query: () => ({ url: `/admin/agora/config` })
}),
getAgoraChannels: builder.query<AgoraVoicingListResponse, { page_no: number, page_size: number }>({
query: (param = { page_no: 0, page_size: 100 }) => ({ url: `/admin/agora/channel/${param.page_no}/${param.page_size}` }),
getAgoraChannels: builder.query<
AgoraVoicingListResponse,
{ page_no: number; page_size: number }
>({
query: (param = { page_no: 0, page_size: 100 }) => ({
url: `/admin/agora/channel/${param.page_no}/${param.page_size}`
}),
async onQueryStarted(data, { dispatch, queryFulfilled, getState }) {
try {
const { voice: { callingFrom }, authData } = getState() as RootState;
const {
voice: { callingFrom },
authData
} = getState() as RootState;
const { data: resp } = await queryFulfilled;
const { success } = resp;
if (success) {
const arr = resp.data.channels.map(data => {
const arr = resp.data.channels.map((data) => {
const [type, id] = data.channel_name.split(":").slice(-2);
const count = data.user_count;
const context = type === "group" ? "channel" as const : "dm" as const;
const context = type === "group" ? ("channel" as const) : ("dm" as const);
return {
id: +id,
context,
@@ -137,7 +144,9 @@ export const serverApi = createApi({
};
});
dispatch(upsertVoiceList(arr));
const hasMyself = arr.some(data => data.context === "dm" && data.id == authData?.user?.uid);
const hasMyself = arr.some(
(data) => data.context === "dm" && data.id == authData?.user?.uid
);
const sendByMe = callingFrom && callingFrom === authData?.user?.uid;
// reset dm call setting
if (callingFrom && !sendByMe && !hasMyself) {
@@ -187,9 +196,7 @@ export const serverApi = createApi({
async onQueryStarted(data, { dispatch, queryFulfilled }) {
try {
const resp = await queryFulfilled;
dispatch(
updateInfo(resp.data)
);
dispatch(updateInfo(resp.data));
} catch {
console.error("get server common error");
}
@@ -204,9 +211,7 @@ export const serverApi = createApi({
async onQueryStarted(data, { dispatch, queryFulfilled }) {
try {
await queryFulfilled;
dispatch(
updateInfo(data)
);
dispatch(updateInfo(data));
} catch {
console.error("update server common error");
}
@@ -309,7 +314,7 @@ export const serverApi = createApi({
url: `/admin/system/update_frontend_url`,
method: "POST",
headers: {
"content-type": 'text/plain',
"content-type": "text/plain"
},
body: url
})
@@ -324,16 +329,16 @@ export const serverApi = createApi({
const rootStore = getState() as RootState;
const { upgraded: prevValue } = rootStore.server;
try {
const { data: { user_limit } } = await queryFulfilled;
const {
data: { user_limit }
} = await queryFulfilled;
const currValue = user_limit > 20;
if (prevValue !== currValue) {
dispatch(updateInfo({ upgraded: currValue }));
}
} catch {
console.error("update license upgraded status failed ");
}
}
}),
@@ -363,15 +368,25 @@ export const serverApi = createApi({
body: { license }
})
}),
getBotRelatedChannels: builder.query<Channel[], { api_key: string, public_only?: boolean }>({
getBotRelatedChannels: builder.query<Channel[], { api_key: string; public_only?: boolean }>({
query: ({ api_key, public_only = false }) => ({
url: public_only ? `/bot?public_only=${public_only}` : `/bot`,
headers: {
"x-api-key": api_key
},
}
})
}),
sendMessageByBot: builder.mutation<number, { uid?: number, cid?: number, api_key: string, content: string, type?: ContentTypeKey, properties?: object }>({
sendMessageByBot: builder.mutation<
number,
{
uid?: number;
cid?: number;
api_key: string;
content: string;
type?: ContentTypeKey;
properties?: object;
}
>({
query: ({ uid, cid, api_key, type = "text", properties, content }) => ({
headers: {
"x-api-key": api_key,
@@ -384,7 +399,7 @@ export const serverApi = createApi({
method: "POST",
body: content
})
}),
})
})
});
+44 -28
View File
@@ -1,13 +1,25 @@
import { createApi } from "@reduxjs/toolkit/query/react";
// import toast from "react-hot-toast";
import baseQuery from "./base.query";
import { ContentTypeKey, MuteDTO } from "@/types/message";
import {
AutoDeleteMsgDTO,
BotAPIKey,
ContactAction,
ContactResponse,
ContactStatus,
User,
UserCreateDTO,
UserDTO,
UserForAdmin,
UserForAdminDTO
} from "@/types/user";
import BASE_URL, { ContentTypes } from "../config";
import { updateAutoDeleteSetting, updateMute } from "../slices/footprint";
import { fillUsers, updateContactStatus as updateStatus } from "../slices/users";
import BASE_URL, { ContentTypes } from "../config";
import { onMessageSendStarted } from "./handlers";
import { AutoDeleteMsgDTO, BotAPIKey, ContactAction, ContactResponse, ContactStatus, User, UserCreateDTO, UserDTO, UserForAdmin, UserForAdminDTO } from "@/types/user";
import { ContentTypeKey, MuteDTO } from "@/types/message";
import { RootState } from "../store";
// import toast from "react-hot-toast";
import baseQuery from "./base.query";
import { onMessageSendStarted } from "./handlers";
export const userApi = createApi({
reducerPath: "userApi",
@@ -29,14 +41,20 @@ export const userApi = createApi({
async onQueryStarted(data, { dispatch, queryFulfilled, getState }) {
try {
const { data: users } = await queryFulfilled;
const { authData: { user: loginUser } } = getState() as RootState;
dispatch(fillUsers(users.map((u) => {
const status = loginUser?.uid == u.uid ? "added" : "";
return {
...u,
status
};
})));
const {
authData: { user: loginUser }
} = getState() as RootState;
dispatch(
fillUsers(
users.map((u) => {
const status = loginUser?.uid == u.uid ? "added" : "";
return {
...u,
status
};
})
)
);
} catch {
console.log("get user list error");
}
@@ -71,7 +89,7 @@ export const userApi = createApi({
method: "POST"
})
}),
searchUser: builder.mutation<User, { search_type: "id" | "email", keyword: string }>({
searchUser: builder.mutation<User, { search_type: "id" | "email"; keyword: string }>({
query: (input) => ({
url: `/user/search`,
body: input,
@@ -123,7 +141,7 @@ export const userApi = createApi({
}
}),
updateContactStatus: builder.mutation<void, { action: ContactAction, target_uid: number }>({
updateContactStatus: builder.mutation<void, { action: ContactAction; target_uid: number }>({
query: (payload) => ({
url: `/user/update_contact_status`,
method: "POST",
@@ -131,10 +149,10 @@ export const userApi = createApi({
}),
async onQueryStarted(data, { dispatch, queryFulfilled }) {
const map = {
"add": "added",
"block": "blocked",
"remove": "",
"unblock": "",
add: "added",
block: "blocked",
remove: "",
unblock: ""
};
try {
await queryFulfilled;
@@ -170,7 +188,7 @@ export const userApi = createApi({
body: data
})
}),
updateAvatarByAdmin: builder.mutation<void, { uid: number, file: File }>({
updateAvatarByAdmin: builder.mutation<void, { uid: number; file: File }>({
query: ({ uid, file }) => ({
headers: {
"content-type": "image/png"
@@ -184,18 +202,17 @@ export const userApi = createApi({
query: (uid) => ({ url: `/admin/user/${uid}` })
}),
// bot operations
createBotAPIKey: builder.mutation<void, { uid: number, name: string }>({
createBotAPIKey: builder.mutation<void, { uid: number; name: string }>({
query: ({ uid, name }) => ({
url: `/admin/user/bot-api-key/${uid}`,
method: "POST",
body: { name },
}),
body: { name }
})
}),
getBotAPIKeys: builder.query<BotAPIKey[], number>({
query: (uid) => ({ url: `/admin/user/bot-api-key/${uid}` })
}),
deleteBotAPIKey: builder.query<void, { uid: number, kid: number }>({
deleteBotAPIKey: builder.query<void, { uid: number; kid: number }>({
query: ({ uid, kid }) => ({ url: `/admin/user/bot-api-key/${uid}/${kid}`, method: "DELETE" })
}),
// bot operations end
@@ -225,8 +242,7 @@ export const userApi = createApi({
// @ts-ignore
await onMessageSendStarted.call(this, param1, param2, "user");
}
}),
})
})
});
+14 -5
View File
@@ -1,15 +1,17 @@
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
import { AuthData, RenewTokenResponse } from "@/types/auth";
// import { isNull, omitBy } from "lodash";
import {
KEY_EXPIRE,
KEY_PWA_INSTALLED,
KEY_LOGIN_USER,
KEY_PWA_INSTALLED,
KEY_REFRESH_TOKEN,
KEY_TOKEN,
KEY_UID
} from "../config";
import { AuthData, RenewTokenResponse } from "@/types/auth";
import { StoredUser } from "./users";
// import { updateUsersByLogs } from './users';
interface State {
@@ -71,7 +73,7 @@ const authDataSlice = createSlice({
if (!state.user) return;
const obj = { ...state.user, ...payload };
Object.keys(obj).forEach(key => {
Object.keys(obj).forEach((key) => {
// @ts-ignore
if (obj[key] === undefined) {
// @ts-ignore
@@ -108,7 +110,7 @@ const authDataSlice = createSlice({
localStorage.setItem(KEY_TOKEN, token);
localStorage.setItem(KEY_REFRESH_TOKEN, refresh_token);
}
},
}
// extraReducers: (builder) => {
// builder.addCase(updateUsersByLogs, (state, action) => {
// const changeLogs = action.payload;
@@ -131,5 +133,12 @@ const authDataSlice = createSlice({
// }
});
export const { updateInitialized, updateLoginUser, setAuthData, resetAuthData, updateToken, updateRoleChanged } = authDataSlice.actions;
export const {
updateInitialized,
updateLoginUser,
setAuthData,
resetAuthData,
updateToken,
updateRoleChanged
} = authDataSlice.actions;
export default authDataSlice.reducer;
+7 -6
View File
@@ -1,7 +1,9 @@
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
import { isNull, omitBy } from "lodash";
import BASE_URL from "../config";
import { Channel, UpdateChannelDTO, UpdatePinnedMessageDTO } from "@/types/channel";
import BASE_URL from "../config";
// import { updateVoicingInfo } from "./voice";
interface StoredChannel extends Channel {
@@ -35,7 +37,7 @@ const channelsSlice = createSlice({
icon:
c.avatar_updated_at == 0
? ""
: `${BASE_URL}/resource/group_avatar?gid=${c.gid}&t=${c.avatar_updated_at}`,
: `${BASE_URL}/resource/group_avatar?gid=${c.gid}&t=${c.avatar_updated_at}`
};
});
},
@@ -50,7 +52,7 @@ const channelsSlice = createSlice({
icon:
avatar_updated_at == 0
? ""
: `${BASE_URL}/resource/group_avatar?gid=${gid}&t=${avatar_updated_at}`,
: `${BASE_URL}/resource/group_avatar?gid=${gid}&t=${avatar_updated_at}`
};
},
updateChannel(state, action: PayloadAction<UpdateChannelDTO>) {
@@ -109,8 +111,7 @@ const channelsSlice = createSlice({
delete state.byId[gid];
}
}
},
}
});
export const {
@@ -119,7 +120,7 @@ export const {
fillChannels,
addChannel,
updateChannel,
removeChannel,
removeChannel
} = channelsSlice.actions;
export default channelsSlice.reducer;
+1
View File
@@ -1,4 +1,5 @@
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
// import BASE_URL from "../config";
export interface Favorite {
+27 -16
View File
@@ -1,14 +1,23 @@
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
import { ChatContext } from "@/types/common";
import { MuteDTO } from "@/types/message";
import { OG } from "@/types/resource";
import { AutoDeleteMessageSettingDTO, AutoDeleteMsgForGroup, AutoDeleteMsgForUser, AutoDeleteSettingForChannels, AutoDeleteSettingForUsers, PinChat, PinChatTarget } from "@/types/sse";
import {
AutoDeleteMessageSettingDTO,
AutoDeleteMsgForGroup,
AutoDeleteMsgForUser,
AutoDeleteSettingForChannels,
AutoDeleteSettingForUsers,
PinChat,
PinChatTarget
} from "@/types/sse";
import { resetAuthData } from "./auth.data";
import { ChatContext } from "@/types/common";
type ChannelAside = "members" | "voice" | "voice_fullscreen" | null;
type DMAside = "voice" | "voice_fullscreen" | null;
export interface State {
og: { [url: string]: OG }
og: { [url: string]: OG };
usersVersion: number;
afterMid: number;
historyUsers: { [uid: number]: string | "reached" };
@@ -24,7 +33,6 @@ export interface State {
pinChats: PinChat[];
}
const initialState: State = {
og: {},
usersVersion: 0,
@@ -99,9 +107,9 @@ const footprintSlice = createSlice({
switch (key) {
case "burn_after_reading_users": {
const updates = (payload as AutoDeleteSettingForUsers).burn_after_reading_users;
updates.map(item => {
updates.map((item) => {
const { uid } = item;
const idx = state.autoDeleteMsgUsers.findIndex(tmp => tmp.uid == uid);
const idx = state.autoDeleteMsgUsers.findIndex((tmp) => tmp.uid == uid);
if (idx !== -1) {
// update
state.autoDeleteMsgUsers[idx] = item;
@@ -114,9 +122,9 @@ const footprintSlice = createSlice({
}
case "burn_after_reading_groups": {
const updates = (payload as AutoDeleteSettingForChannels).burn_after_reading_groups;
updates.map(item => {
updates.map((item) => {
const { gid } = item;
const idx = state.autoDeleteMsgChannels.findIndex(tmp => tmp.gid == gid);
const idx = state.autoDeleteMsgChannels.findIndex((tmp) => tmp.gid == gid);
if (idx !== -1) {
// update
state.autoDeleteMsgChannels[idx] = item;
@@ -169,7 +177,7 @@ const footprintSlice = createSlice({
}
});
},
upsertPinChats(state, action: PayloadAction<{ pins: PinChat[], override?: boolean }>) {
upsertPinChats(state, action: PayloadAction<{ pins: PinChat[]; override?: boolean }>) {
const { pins, override = false } = action.payload;
if (override) {
state.pinChats = pins;
@@ -179,17 +187,20 @@ const footprintSlice = createSlice({
},
removePinChats(state, action: PayloadAction<PinChatTarget[]>) {
const pins = action.payload;
state.pinChats = state.pinChats.filter(pin => {
state.pinChats = state.pinChats.filter((pin) => {
const key = "uid" in pin.target ? "uid" : "gid";
// @ts-ignore
return !pins.some(p => p[key] == pin.target[key]);
return !pins.some((p) => p[key] == pin.target[key]);
});
},
upsertOG(state, action: PayloadAction<{ key: string, value: OG }>) {
upsertOG(state, action: PayloadAction<{ key: string; value: OG }>) {
const { key, value } = action.payload;
state.og[key] = value;
},
updateHistoryMark(state, action: PayloadAction<{ type: ChatContext, id: number, mid: string, }>) {
updateHistoryMark(
state,
action: PayloadAction<{ type: ChatContext; id: number; mid: string }>
) {
const { type, id, mid } = action.payload;
if (type == "channel") {
state.historyChannels[id] = mid;
@@ -211,14 +222,14 @@ const footprintSlice = createSlice({
state.readChannels[gid] = mid;
});
},
updateChannelVisibleAside(state, action: PayloadAction<{ id: number, aside: ChannelAside }>) {
updateChannelVisibleAside(state, action: PayloadAction<{ id: number; aside: ChannelAside }>) {
const { id, aside } = action.payload;
state.channelAsides[id] = aside;
},
updateDMVisibleAside(state, action: PayloadAction<{ id: number, aside: DMAside }>) {
updateDMVisibleAside(state, action: PayloadAction<{ id: number; aside: DMAside }>) {
const { id, aside } = action.payload;
state.dmAsides[id] = aside;
},
}
},
extraReducers: (builder) => {
builder.addCase(resetAuthData, (state) => {
+7 -9
View File
@@ -1,13 +1,14 @@
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
// import { ContentTypes } from "../config";
// import { normalizeFileMessage } from "../../common/utils";
// import { ContentType } from "@/types/message";
import { Archive } from "@/types/resource";
export interface State {
[key: string]: Archive;
}
const initialState: State = {
};
const initialState: State = {};
const messageArchiveSlice = createSlice({
name: "archiveMessage",
@@ -19,17 +20,14 @@ const messageArchiveSlice = createSlice({
fillArchiveMessage(state, action) {
return Object.assign({ ...initialState }, action.payload);
},
upsertArchiveMessage(state, action: PayloadAction<{ filePath: string, data: Archive }>) {
upsertArchiveMessage(state, action: PayloadAction<{ filePath: string; data: Archive }>) {
const { filePath, data } = action.payload;
state[filePath] = data;
},
}
}
});
export const {
resetArchiveMessage,
fillArchiveMessage,
upsertArchiveMessage
} = messageArchiveSlice.actions;
export const { resetArchiveMessage, fillArchiveMessage, upsertArchiveMessage } =
messageArchiveSlice.actions;
export default messageArchiveSlice.reducer;
+1 -1
View File
@@ -27,7 +27,7 @@ const channelMsgSlice = createSlice({
const localMsgExisted = state[id]!.findIndex((id) => id == local_id) > -1;
if (midExisted || localMsgExisted) return;
// 每次入库,都排序
const newArr = [...state[id] as number[], +mid].sort((a, b) => a - b);
const newArr = [...(state[id] as number[]), +mid].sort((a, b) => a - b);
state[id] = newArr;
} else {
state[id] = [+mid];
+4 -2
View File
@@ -1,7 +1,9 @@
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
import { ContentType } from "@/types/message";
// import { ContentTypes } from "../config";
import { normalizeFileMessage } from "@/utils";
import { ContentType } from "@/types/message";
export interface MessagePayload {
mid: number;
from_uid?: number;
@@ -45,7 +47,7 @@ const messageSlice = createSlice({
fillMessage(state, action) {
return Object.assign({ ...initialState }, action.payload);
},
updateMessage(state, action: PayloadAction<{ mid: number;[key: string | number]: any }>) {
updateMessage(state, action: PayloadAction<{ mid: number; [key: string | number]: any }>) {
const { mid, ...rest } = action.payload;
state[mid] = { ...state[mid], ...rest };
},
+1 -1
View File
@@ -40,7 +40,7 @@ const userMsgSlice = createSlice({
state.ids.push(+id);
}
},
removeUserMsg(state, action: PayloadAction<{ id: number, mid: number }>) {
removeUserMsg(state, action: PayloadAction<{ id: number; mid: number }>) {
const { id, mid } = action.payload;
if (state.byId[id]) {
const idx = state.byId[id].findIndex((i: number) => i == mid);
+15 -3
View File
@@ -1,9 +1,10 @@
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
import { Server } from "@/types/server";
export interface StoredServer extends Server {
version: string,
upgraded: boolean,
version: string;
upgraded: boolean;
logo: string;
inviteLink?: {
link: string;
@@ -49,7 +50,18 @@ const serverSlice = createSlice({
contact_verification_enable = false,
chat_layout_mode = "Left"
} = action.payload || {};
return { version, upgraded, name, logo, description, inviteLink, show_user_online_status, webclient_auto_update, contact_verification_enable, chat_layout_mode };
return {
version,
upgraded,
name,
logo,
description,
inviteLink,
show_user_online_status,
webclient_auto_update,
contact_verification_enable,
chat_layout_mode
};
},
updateInfo(state, action: PayloadAction<Partial<StoredServer>>) {
const values = action.payload || {};
+1 -1
View File
@@ -1,6 +1,6 @@
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
export type ListView = "item" | "grid"
export type ListView = "item" | "grid";
export interface State {
online: boolean;
ready: boolean;
+12 -5
View File
@@ -1,15 +1,16 @@
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
import { isNull, omitBy } from "lodash";
import BASE_URL from "../config";
import { Contact, ContactStatus } from "@/types/user";
import { UserLog, UserState } from "@/types/sse";
import { Contact, ContactStatus } from "@/types/user";
import BASE_URL from "../config";
type DMAside = "voice" | null;
export interface StoredUser extends Contact {
online?: boolean;
voice?: boolean;
avatar?: string;
visibleAside?: DMAside
visibleAside?: DMAside;
}
export interface State {
@@ -99,7 +100,12 @@ const usersSlice = createSlice({
}
});
},
updateContactStatus(state, action: PayloadAction<{ uid: number, status: ContactStatus } | { uid: number, status: ContactStatus }[]>) {
updateContactStatus(
state,
action: PayloadAction<
{ uid: number; status: ContactStatus } | { uid: number; status: ContactStatus }[]
>
) {
const arr = Array.isArray(action.payload) ? action.payload : [action.payload];
arr.forEach((data) => {
if (state.byId[data.uid]) {
@@ -110,5 +116,6 @@ const usersSlice = createSlice({
}
});
export const { updateContactStatus, resetUsers, fillUsers, updateUsersByLogs, updateUsersStatus } = usersSlice.actions;
export const { updateContactStatus, resetUsers, fillUsers, updateUsersByLogs, updateUsersStatus } =
usersSlice.actions;
export default usersSlice.reducer;
+56 -46
View File
@@ -1,53 +1,55 @@
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
import { KEY_UID } from "../config";
import { ConnectionState } from "agora-rtc-sdk-ng";
import { resetAuthData } from "./auth.data";
import { ChatContext } from "@/types/common";
import { KEY_UID } from "../config";
import { resetAuthData } from "./auth.data";
export type VoiceBasicInfo = {
context: ChatContext,
from?: number,
id: number,// means to in dm context
}
context: ChatContext;
from?: number;
id: number; // means to in dm context
};
export type VoicingInfo = {
downlinkNetworkQuality?: number,
joining?: boolean,
connectionState?: ConnectionState
} & VoiceBasicInfo & VoicingMemberInfo
downlinkNetworkQuality?: number;
joining?: boolean;
connectionState?: ConnectionState;
} & VoiceBasicInfo &
VoicingMemberInfo;
export type VoicingMemberInfo = {
speakingVolume?: number,
muted?: boolean,
deafen?: boolean,
video?: boolean,
shareScreen?: boolean
}
speakingVolume?: number;
muted?: boolean;
deafen?: boolean;
video?: boolean;
shareScreen?: boolean;
};
export type VoicingMembers = {
ids: number[],
ids: number[];
byId: {
[key: number]: VoicingMemberInfo
},
pin?: number
}
[key: number]: VoicingMemberInfo;
};
pin?: number;
};
export type VoiceInfo = {
channelName: string,
memberCount: number
} & VoiceBasicInfo
channelName: string;
memberCount: number;
} & VoiceBasicInfo;
export type DeviceInfo = Pick<MediaDeviceInfo, "deviceId" | "groupId" | "kind" | "label">;
export type MediaDeviceKind = "audioinput" | "audiooutput" | "videoinput"
export type MediaDeviceKind = "audioinput" | "audiooutput" | "videoinput";
interface State {
callingFrom: number,
callingTo: number,
calling: boolean,
voicing: VoicingInfo | null,
voicingMembers: VoicingMembers,
list: VoiceInfo[],
devices: DeviceInfo[],
audioInputDeviceId: string,
audioOutputDeviceId: string,
videoInputDeviceId: string,
callingFrom: number;
callingTo: number;
calling: boolean;
voicing: VoicingInfo | null;
voicingMembers: VoicingMembers;
list: VoiceInfo[];
devices: DeviceInfo[];
audioInputDeviceId: string;
audioOutputDeviceId: string;
videoInputDeviceId: string;
}
const initialState: State = {
calling: false,
@@ -68,7 +70,10 @@ const voiceSlice = createSlice({
name: "voice",
initialState,
reducers: {
updateCallInfo(state, { payload }: PayloadAction<{ from: number, to?: number, calling?: boolean }>) {
updateCallInfo(
state,
{ payload }: PayloadAction<{ from: number; to?: number; calling?: boolean }>
) {
const { from, to = 0, calling } = payload;
state.callingFrom = from;
state.callingTo = to;
@@ -80,9 +85,9 @@ const voiceSlice = createSlice({
state.devices = payload;
if (payload.length > 0) {
// 默认选择第一个
const audioInputDevice = payload.find(v => v.kind == "audioinput");
const audioOutputDevice = payload.find(v => v.kind == "audiooutput");
const videoInputDevice = payload.find(v => v.kind == "videoinput");
const audioInputDevice = payload.find((v) => v.kind == "audioinput");
const audioOutputDevice = payload.find((v) => v.kind == "audiooutput");
const videoInputDevice = payload.find((v) => v.kind == "videoinput");
if (audioInputDevice) {
state.audioInputDeviceId = audioInputDevice.deviceId;
}
@@ -97,7 +102,10 @@ const voiceSlice = createSlice({
updateCalling(state, { payload }: PayloadAction<boolean>) {
state.calling = payload;
},
updateSelectDeviceId(state, { payload }: PayloadAction<{ kind: MediaDeviceKind, value: string }>) {
updateSelectDeviceId(
state,
{ payload }: PayloadAction<{ kind: MediaDeviceKind; value: string }>
) {
const { kind, value } = payload;
switch (kind) {
case "audioinput":
@@ -152,7 +160,6 @@ const voiceSlice = createSlice({
}
});
}
} else {
// reset
state.voicing = payload;
@@ -177,7 +184,7 @@ const voiceSlice = createSlice({
state.list = payload;
} else {
const { id, context } = payload;
const idx = state.list.findIndex(v => v.id == id && v.context == context);
const idx = state.list.findIndex((v) => v.id == id && v.context == context);
if (idx > -1) {
state.list.splice(idx, 1, payload);
} else {
@@ -203,14 +210,17 @@ const voiceSlice = createSlice({
delete state.voicingMembers.byId[payload];
}
},
updateVoicingMember(state, { payload }: PayloadAction<{ uid: number, info: VoicingMemberInfo }>) {
updateVoicingMember(
state,
{ payload }: PayloadAction<{ uid: number; info: VoicingMemberInfo }>
) {
const idx = state.voicingMembers.ids.findIndex((uid) => uid == payload.uid);
if (idx > -1) {
const { uid, info } = payload;
state.voicingMembers.byId[uid] = { ...state.voicingMembers.byId[uid], ...info };
}
},
updatePin(state, { payload }: PayloadAction<{ uid: number, action: "pin" | "unpin" }>) {
updatePin(state, { payload }: PayloadAction<{ uid: number; action: "pin" | "unpin" }>) {
const idx = state.voicingMembers.ids.findIndex((uid) => uid == payload.uid);
if (idx > -1) {
state.voicingMembers.pin = payload.action == "pin" ? payload.uid : undefined;
@@ -223,13 +233,13 @@ const voiceSlice = createSlice({
if (window.VOICE_CLIENT) {
window.VOICE_CLIENT.leave();
Object.entries(window.VOICE_TRACK_MAP).forEach(([uid, track]) => {
if (track && 'close' in track) {
if (track && "close" in track) {
track.close();
}
delete window.VOICE_TRACK_MAP[+uid];
});
Object.entries(window.VIDEO_TRACK_MAP).forEach(([uid, track]) => {
if (track && 'close' in track) {
if (track && "close" in track) {
track?.close();
}
delete window.VOICE_TRACK_MAP[+uid];
+17 -16
View File
@@ -1,26 +1,27 @@
import { TypedUseSelectorHook, useDispatch, useSelector } from "react-redux";
import { combineReducers, configureStore } from "@reduxjs/toolkit";
import { setupListeners } from "@reduxjs/toolkit/query";
import { TypedUseSelectorHook, useDispatch, useSelector } from "react-redux";
import listenerMiddleware from "./listener.middleware";
import authDataReducer from "./slices/auth.data";
import voiceReducer from "./slices/voice";
import footprintReducer from "./slices/footprint";
import serverReducer from "./slices/server";
import uiReducer from "./slices/ui";
import channelsReducer from "./slices/channels";
import usersReducer from "./slices/users";
import reactionMsgReducer from "./slices/message.reaction";
import channelMsgReducer from "./slices/message.channel";
import userMsgReducer from "./slices/message.user";
import favoritesReducer from "./slices/favorites";
import fileMsgReducer from "./slices/message.file";
import archiveMsgReducer from "./slices/message.archive";
import messageReducer from "./slices/message";
import { authApi } from "./services/auth";
import { userApi } from "./services/user";
import { channelApi } from "./services/channel";
import { messageApi } from "./services/message";
import { serverApi } from "./services/server";
import { userApi } from "./services/user";
import authDataReducer from "./slices/auth.data";
import channelsReducer from "./slices/channels";
import favoritesReducer from "./slices/favorites";
import footprintReducer from "./slices/footprint";
import messageReducer from "./slices/message";
import archiveMsgReducer from "./slices/message.archive";
import channelMsgReducer from "./slices/message.channel";
import fileMsgReducer from "./slices/message.file";
import reactionMsgReducer from "./slices/message.reaction";
import userMsgReducer from "./slices/message.user";
import serverReducer from "./slices/server";
import uiReducer from "./slices/ui";
import usersReducer from "./slices/users";
import voiceReducer from "./slices/voice";
const reducer = combineReducers({
authData: authDataReducer,