refactor: add typescript support to project

This commit is contained in:
HD
2022-06-21 15:08:35 +08:00
parent 88ec2b742a
commit bd799ebea8
259 changed files with 1042 additions and 458 deletions
@@ -1,9 +1,9 @@
// import React from 'react'
import { useDispatch } from "react-redux";
import { addMessage } from "../../app/slices/message";
import { addChannelMsg } from "../../app/slices/message.channel";
import { addUserMsg } from "../../app/slices/message.user";
export default function useAddLocalFileMessage({ context, to }) {
const dispatch = useDispatch();
const addContextMessage = context == "channel" ? addChannelMsg : addUserMsg;
@@ -1,6 +1,8 @@
import { useRef, useEffect } from "react";
// import { useDebounce } from "rooks";
function useChatScroll(deps = []) {
// todo: ref should be initialized to null
const ref = useRef();
// useEffect(() => {
// console.log("chat scroll", ref);
@@ -1,6 +1,6 @@
import { useEffect, useState } from "react";
import { isObjectEqual } from "../utils";
import toast from "react-hot-toast";
import { isObjectEqual } from "../utils";
import {
useUpdateLoginConfigMutation,
useUpdateSMTPConfigMutation,
@@ -11,8 +11,10 @@ import {
useLazyGetSMTPConfigQuery,
useLazyGetLoginConfigQuery
} from "../../app/services/server";
// config: smtp agora login firebase
let originalValue = null;
let originalValue: null | object = null;
export default function useConfig(config = "smtp") {
const [changed, setChanged] = useState(false);
const [values, setValues] = useState({});
@@ -105,6 +107,7 @@ export default function useConfig(config = "smtp") {
setChanged(false);
}
}, [values]);
return {
reset,
changed,
@@ -1,15 +1,15 @@
import { useState, useEffect } from "react";
import toast from "react-hot-toast";
// import { ContentTypes } from "../../../app/config";
import { useSelector } from "react-redux";
import { useNavigate, useMatch } from "react-router-dom";
import { hideAll } from "tippy.js";
import { useRemoveMembersMutation } from "../../app/services/channel";
import { useLazyDeleteContactQuery } from "../../app/services/contact";
import useConfig from "./useConfig";
import useCopy from "./useCopy";
import { useAppSelector } from "../../app/store";
export default function useContactOperation({ uid, cid }) {
export default function useContactOperation({ uid, cid }: { uid: number; cid: number }) {
const [passedUid, setPassedUid] = useState(undefined);
const { values: agoraConfig } = useConfig("agora");
const isUserDetailPath = useMatch(`/contacts/${uid}`);
@@ -17,7 +17,7 @@ export default function useContactOperation({ uid, cid }) {
const [removeInChannel, { isSuccess: removeSuccess }] = useRemoveMembersMutation();
const navigateTo = useNavigate();
const { copy } = useCopy();
const { user, channel, loginUid, isAdmin } = useSelector((store) => {
const { user, channel, loginUid, isAdmin } = useAppSelector((store) => {
return {
user: store.contacts.byId[uid],
channel: store.channels.byId[cid],
@@ -25,6 +25,7 @@ export default function useContactOperation({ uid, cid }) {
isAdmin: store.contacts.byId[store.authData.uid]?.is_admin
};
});
useEffect(() => {
setPassedUid(uid ?? loginUid);
}, [uid, loginUid]);
@@ -37,35 +38,42 @@ export default function useContactOperation({ uid, cid }) {
}
}
}, [removeSuccess, removeUserSuccess, isUserDetailPath]);
const handleRemoveFromChannel = (id) => {
const isNumber = !Number.isNaN(+id);
const finalId = isNumber ? id || passedUid : passedUid;
removeInChannel({ id: +cid, members: [+finalId] });
hideAll();
};
const handleRemove = (id) => {
const isNumber = !Number.isNaN(+id);
const finalId = isNumber ? id || passedUid : passedUid;
removeUser(finalId);
hideAll();
};
const copyEmail = (email) => {
const isString = typeof email == "string";
const finalEmail = isString ? email || user?.email : user?.email;
copy(finalEmail);
hideAll();
};
const startChat = () => {
navigateTo(`/chat/dm/${uid}`);
};
const call = () => {
toast.success("Cooming Soon...");
hideAll();
};
const canRemoveFromChannel =
cid && !channel?.is_public && (isAdmin || channel?.owner == loginUid);
const canCall = agoraConfig.enabled && loginUid != uid;
const canRemove = isAdmin && loginUid != uid && !cid;
return {
canRemove,
removeUser: handleRemove,
@@ -2,6 +2,7 @@ import { useState } from "react";
import { hideAll } from "tippy.js";
import Tippy from "@tippyjs/react";
import Menu from "../component/ContextMenu";
export default function useContextMenu(placement = "right-start") {
const [visible, setVisible] = useState(false);
// for tippy.js
@@ -1,9 +1,10 @@
import { useState } from "react";
import { useSelector } from "react-redux";
import { useLazyDeleteMessageQuery } from "../../app/services/message";
import { useAppSelector } from "../../app/store";
export default function useDeleteMessage() {
const [deleting, setDeleting] = useState(false);
const { loginUser, messageData } = useSelector((store) => {
const { loginUser, messageData } = useAppSelector((store) => {
return {
messageData: store.message,
loginUser: store.contacts.byId[store.authData.uid]
@@ -1,10 +1,10 @@
// import React from 'react'
import { useDispatch, useSelector } from "react-redux";
import { updateDraftMarkdown, updateDraftMixedText } from "../../app/slices/ui";
import { useAppDispatch, useAppSelector } from "../../app/store";
export default function useDraft({ context = "", id = "" }) {
const dispatch = useDispatch();
const dispatch = useAppDispatch();
const _key = `${context}_${id}`;
const { draftMarkdown, draftMixedText } = useSelector((store) => {
const { draftMarkdown, draftMixedText } = useAppSelector((store) => {
return {
draftMarkdown: store.ui.draftMarkdown,
draftMixedText: store.ui.draftMixedText
@@ -17,8 +17,10 @@ export default function useDraft({ context = "", id = "" }) {
dispatch(update({ key: _key, value }));
};
};
const getDraft = (type = "mixed") => {
return type == "mixed" ? draftMixedText[_key] : draftMarkdown[_key];
};
return { getDraft, getUpdateDraft };
}
@@ -1,25 +1,27 @@
import { useState, useEffect } from "react";
import { useSelector } from "react-redux";
import { useLazyRemoveFavoriteQuery, useFavoriteMessageMutation } from "../../app/services/message";
import { useAppSelector } from "../../app/store";
export default function useFavMessage({ cid = null, uid = null }) {
const [removeFav] = useLazyRemoveFavoriteQuery();
const [addFav] = useFavoriteMessageMutation();
const [favorites, setFavorites] = useState([]);
const { favs = [] } = useSelector((store) => {
return {
favs: store.favorites
};
const { favs = [] } = useAppSelector((store) => {
return { favs: store.favorites };
});
const addFavorite = async (mid = []) => {
const mids = Array.isArray(mid) ? mid.map((i) => +i) : [+mid];
if (mids.length == 0) return;
const { error = null } = await addFav(mids);
return !error;
};
const removeFavorite = (id) => {
if (!id) return;
removeFav(id);
};
const isFavorited = (mid = null) => {
if (!mid) return false;
let mids = [];
@@ -31,6 +33,7 @@ export default function useFavMessage({ cid = null, uid = null }) {
});
return mids.findIndex((i) => i == mid) > -1;
};
useEffect(() => {
let filtereds = [];
filtereds = cid
@@ -48,6 +51,7 @@ export default function useFavMessage({ cid = null, uid = null }) {
setFavorites(filtereds);
}, [cid, uid, favs]);
// console.log("filtered", cid, uid, favs);
return {
isFavorited,
@@ -1,25 +1,30 @@
import { useState, useEffect } from "react";
import { useSelector } from "react-redux";
import { useAppSelector } from "../../app/store";
import { Channel } from "../../types/channel";
export default function useFilteredChannels() {
const [input, setInput] = useState("");
const channels = useSelector((store) => Object.values(store.channels.byId));
const [filteredChannels, setfilteredChannels] = useState([]);
const channels = useAppSelector((store) => Object.values(store.channels.byId));
const [filteredChannels, setFilteredChannels] = useState<Channel[]>([]);
useEffect(() => {
if (!input) {
setfilteredChannels(channels);
setFilteredChannels(channels);
} else {
let str = ["", ...input.toLowerCase(), ""].join(".*");
let reg = new RegExp(str);
setfilteredChannels(
setFilteredChannels(
channels.filter((c) => {
return reg.test(c.name.toLowerCase());
})
);
}
}, [input]);
const updateInput = (val) => {
const updateInput = (val: string) => {
setInput(val);
};
return {
input,
channels: filteredChannels,
@@ -1,8 +1,9 @@
import { useState, useEffect } from "react";
import { useSelector } from "react-redux";
import { useAppSelector } from "../../app/store";
export default function useFilteredUsers() {
const [input, setInput] = useState("");
const contacts = useSelector((store) => Object.values(store.contacts.byId));
const contacts = useAppSelector((store) => Object.values(store.contacts.byId));
const [filteredUsers, setFilteredUsers] = useState([]);
useEffect(() => {
if (!input) {
@@ -17,9 +18,11 @@ export default function useFilteredUsers() {
);
}
}, [input]);
const updateInput = (val) => {
const updateInput = (val: string) => {
setInput(val);
};
return {
input,
contacts: filteredUsers,
@@ -2,6 +2,7 @@ import { useState } from "react";
import { useSendChannelMsgMutation } from "../../app/services/channel";
import { useSendMsgMutation } from "../../app/services/contact";
import { useCreateArchiveMutation } from "../../app/services/message";
export default function useForwardMessage() {
const [forwarding, setForwarding] = useState(false);
const [
@@ -1,9 +1,9 @@
import { useState, useEffect } from "react";
// import toast from "react-hot-toast";
import {
useGetGithubAuthConfigQuery,
useUpdateGithubAuthConfigMutation
} from "../../app/services/server";
export default function useGithubAuthConfig() {
const [changed, setChanged] = useState(false);
const [config, setConfig] = useState({});
@@ -1,9 +1,9 @@
import { useState, useEffect } from "react";
// import toast from "react-hot-toast";
import {
useGetGoogleAuthConfigQuery,
useUpdateGoogleAuthConfigMutation
} from "../../app/services/server";
export default function useGoogleAuthConfig() {
const [changed, setChanged] = useState(false);
const [clientId, setClientId] = useState("");
@@ -2,7 +2,8 @@ import { useState, useEffect } from "react";
import useCopy from "./useCopy";
import { useGetSMTPStatusQuery } from "../../app/services/server";
import { useLazyCreateInviteLinkQuery as useCreateChannelInviteLinkQuery } from "../../app/services/channel";
export default function useInviteLink(cid = "") {
export default function useInviteLink(cid: string | null = "") {
const [finalLink, setFinalLink] = useState("");
const { data: SMTPEnabled, isSuccess: smtpStatusFetchSuccess } = useGetSMTPStatusQuery();
const [generateChannelInviteLink, { data: channelInviteLink, isLoading: generatingChannelLink }] =
@@ -1,8 +1,8 @@
// import React from 'react'
import { useSelector } from "react-redux";
import { useUpdateChannelMutation, useLazyLeaveChannelQuery } from "../../app/services/channel";
export default function useLeaveChannel(cid = null) {
const { channel, loginUid } = useSelector((store) => {
import { useAppSelector } from "../../app/store";
export default function useLeaveChannel(cid: number) {
const { channel, loginUid } = useAppSelector((store) => {
return { channel: store.channels.byId[cid], loginUid: store.authData.uid };
});
const [update, { isLoading: transfering, isSuccess: transferSuccess }] =
@@ -1,8 +1,9 @@
import { useState, useEffect } from "react";
import { normalizeArchiveData } from "../../common/utils";
import { normalizeArchiveData } from "../utils";
import { useLazyGetArchiveMessageQuery } from "../../app/services/message";
export default function useNormalizeMessage() {
const [filePath, setFilePath] = useState(null);
const [filePath, setFilePath] = useState<string | null>(null);
const [normalizedMessages, setNormalizedMessages] = useState(null);
const [getArchiveMessage, { data, isError, isLoading, isSuccess }] =
useLazyGetArchiveMessageQuery();
@@ -18,7 +19,7 @@ export default function useNormalizeMessage() {
}
}, [filePath]);
const normalizeMessage = (file_path) => {
const normalizeMessage = (file_path: string) => {
setFilePath(file_path);
};
return {
@@ -1,5 +1,6 @@
import { useEffect } from "react";
import PWABadge from "pwa-badge";
export default function usePWABadge() {
// Create an Instance
const badge = new PWABadge();
@@ -1,9 +1,10 @@
import { useState, useEffect } from "react";
import { useSelector } from "react-redux";
import { usePinMessageMutation, useUnpinMessageMutation } from "../../app/services/message";
export default function usePinMessage(cid = null) {
import { useAppSelector } from "../../app/store";
export default function usePinMessage(cid: number) {
const [pins, setPins] = useState([]);
const { channel, loginUser } = useSelector((store) => {
const { channel, loginUser } = useAppSelector((store) => {
return {
channel: store.channels.byId[cid],
loginUser: store.contacts.byId[store.authData.uid]
@@ -6,6 +6,7 @@ import { addFileMessage, removeFileMessage } from "../../../app/slices/message.f
import { addUserMsg, removeUserMsg } from "../../../app/slices/message.user";
import { updateAfterMid } from "../../../app/slices/footprint";
import { ContentTypes } from "../../../app/config";
const handler = (data, dispatch, currState) => {
const {
mid,
@@ -155,4 +156,5 @@ const handler = (data, dispatch, currState) => {
break;
}
};
export default handler;
@@ -2,7 +2,6 @@ import { useEffect, useState } from "react";
import { fetchEventSource, EventStreamContentType } from "@microsoft/fetch-event-source";
import toast from "react-hot-toast";
import dayjs from "dayjs";
import BASE_URL from "../../../app/config";
import { setReady } from "../../../app/slices/ui";
import { useRenewMutation } from "../../../app/services/auth";
@@ -22,10 +21,12 @@ import {
import { updateUsersByLogs, updateUsersStatus } from "../../../app/slices/contacts";
import { resetAuthData } from "../../../app/slices/auth.data";
import chatMessageHandler from "./chat.handler";
import store from "../../../app/store";
import { useDispatch, useSelector } from "react-redux";
import store, { useAppDispatch, useAppSelector } from "../../../app/store";
class RetriableError extends Error {}
class FatalError extends Error {}
const getQueryString = (params = {}) => {
const sp = new URLSearchParams();
Object.entries(params).forEach(([key, val]) => {
@@ -40,19 +41,21 @@ const getQueryString = (params = {}) => {
// initialized: "initialized",
// streaming: "streaming",
// };
let inter = null;
let inter: number | null = null;
export default function useStreaming() {
const [readyPullData, setReadyPullData] = useState(false);
const {
authData: { uid: loginUid },
ui: { ready, online },
footprint: { afterMid, usersVersion, readUsers, readChannels }
} = useSelector((store) => store);
} = useAppSelector((store) => store);
const [renewToken] = useRenewMutation();
const dispatch = useDispatch();
const dispatch = useAppDispatch();
let initialized = false;
let initializing = false;
let controller = new AbortController();
const startStreaming = async () => {
console.log("start streaming", initialized, initializing);
if (initialized || initializing) return;
@@ -310,15 +313,18 @@ export default function useStreaming() {
// for controlling
return controller;
};
const stopStreaming = () => {
console.log("stop st");
if (controller && controller.abort) {
controller.abort();
}
};
const setStreamingReady = (ready) => {
setReadyPullData(ready);
};
useEffect(() => {
console.log("network changed", online, readyPullData);
if (readyPullData) {
@@ -1,15 +1,14 @@
import { useState, useRef } from "react";
import { useDispatch, useSelector } from "react-redux";
// import { ContentTypes } from "../../app/config";
import toast from "react-hot-toast";
import { updateUploadFiles } from "../../app/slices/ui";
import BASE_URL, { FILE_SLICE_SIZE } from "../../app/config";
import { usePrepareUploadFileMutation, useUploadFileMutation } from "../../app/services/message";
import toast from "react-hot-toast";
import { useAppDispatch, useAppSelector } from "../../app/store";
export default function useUploadFile(props = {}) {
const { context = "", id = "" } = props;
const dispatch = useDispatch();
const { stageFiles, replying } = useSelector((store) => {
const dispatch = useAppDispatch();
const { stageFiles, replying } = useAppSelector((store) => {
return {
stageFiles: store.ui.uploadFiles[`${context}_${id}`] || [],
replying: store.message.replying[`${context}_${id}`]
@@ -35,6 +34,7 @@ export default function useUploadFile(props = {}) {
formData.append("chunk_is_last", is_last);
return uploadFileFn(formData);
};
const uploadFile = async (file) => {
if (!file) return;
setData(null);
@@ -107,12 +107,15 @@ export default function useUploadFile(props = {}) {
setData(res);
return res;
};
const stopUploading = () => {
canneledRef.current = true;
};
const removeStageFile = (idx) => {
dispatch(updateUploadFiles({ context, id, operation: "remove", index: idx }));
};
const addStageFile = (fileData = {}) => {
if (replying) {
toast.error("Only text is supported when replying a message");
@@ -120,9 +123,11 @@ export default function useUploadFile(props = {}) {
}
dispatch(updateUploadFiles({ context, id, data: fileData }));
};
const resetStageFiles = () => {
dispatch(updateUploadFiles({ context, id, operation: "reset" }));
};
const updateStageFile = (idx, data = {}) => {
dispatch(
updateUploadFiles({
@@ -134,6 +139,7 @@ export default function useUploadFile(props = {}) {
})
);
};
return {
stopUploading,
data,