@@ -108,9 +83,7 @@ export default function UploadModal({
/>
-
- {b.name}
-
+ {b.name}
(click title to change name)
{`${Math.floor(b.size / 1000)}KB`}
diff --git a/src/common/component/Setting/LogoutConfirmModal.js b/src/common/component/Setting/LogoutConfirmModal.js
index dcaa3543..ba0e69b1 100644
--- a/src/common/component/Setting/LogoutConfirmModal.js
+++ b/src/common/component/Setting/LogoutConfirmModal.js
@@ -2,20 +2,13 @@
import { useEffect, useState } from "react";
import styled from "styled-components";
import { useDispatch } from "react-redux";
-import { useNavigate } from "react-router-dom";
+
import { toggleSetting } from "../../../app/slices/ui";
-import { clearAuthData } from "../../../app/slices/auth.data";
-import { clearMark } from "../../../app/slices/visit.mark";
-import { clearChannels } from "../../../app/slices/channels";
-import { clearContacts } from "../../../app/slices/contacts";
-import { clearChannelMsg } from "../../../app/slices/message.channel";
-import { clearUserMsg } from "../../../app/slices/message.user";
-import { clearPendingMsg } from "../../../app/slices/message.pending";
// import BASE_URL from "../../app/config";
-import { useLazyLogoutQuery } from "../../../app/services/auth";
import StyledModal from "../styled/Modal";
import Button from "../styled/Button";
import Checkbox from "../styled/Checkbox";
+import useLogout from "../../hook/useLogout";
const StyledConfirm = styled(StyledModal)`
.clear {
font-weight: normal;
@@ -37,10 +30,9 @@ const StyledConfirm = styled(StyledModal)`
`;
import Modal from "../Modal";
export default function LogoutConfirmModal({ closeModal }) {
- const [clearLocal, setClearLocal] = useState(false);
const dispatch = useDispatch();
- const navigate = useNavigate();
- const [logout, { isLoading, isSuccess }] = useLazyLogoutQuery();
+ const [clearLocal, setClearLocal] = useState(false);
+ const { logout, exited, exiting, clearLocalData } = useLogout();
const handleLogout = () => {
logout();
};
@@ -48,22 +40,15 @@ export default function LogoutConfirmModal({ closeModal }) {
setClearLocal(evt.target.checked);
};
useEffect(() => {
- if (isSuccess) {
+ if (exited) {
if (clearLocal) {
console.log("clear all store");
- dispatch(clearMark());
- dispatch(clearChannelMsg());
- dispatch(clearUserMsg());
- dispatch(clearChannels());
- dispatch(clearContacts());
- dispatch(clearPendingMsg());
+ clearLocalData();
}
- dispatch(clearAuthData());
// closeModal();
dispatch(toggleSetting());
- navigate("/login");
}
- }, [isSuccess, clearLocal]);
+ }, [exited, clearLocal]);
return (
Cancel
>
}
diff --git a/src/common/component/Setting/config/Firebase.js b/src/common/component/Setting/config/Firebase.js
index 0747fa6f..9f91eb75 100644
--- a/src/common/component/Setting/config/Firebase.js
+++ b/src/common/component/Setting/config/Firebase.js
@@ -2,6 +2,7 @@
import StyledContainer from "./StyledContainer";
// import { useSelector } from "react-redux";
import Input from "../../styled/Input";
+import Textarea from "../../styled/Textarea";
import Toggle from "../../styled/Toggle";
import Label from "../../styled/Label";
import SaveTip from "../../SaveTip";
@@ -62,7 +63,8 @@ export default function ConfigFirebase() {
- {
+ dispatch(clearMark());
+ dispatch(clearChannelMsg());
+ dispatch(clearUserMsg());
+ dispatch(clearChannels());
+ dispatch(clearContacts());
+ dispatch(clearPendingMsg());
+ };
+
+ useEffect(() => {
+ if (isSuccess) {
+ dispatch(clearAuthData());
+ navigate("/login");
+ }
+ }, [isSuccess]);
+
+ return { clearLocalData, logout, exited: isSuccess, exiting: isLoading };
+}
diff --git a/src/routes/chat/ChannelChat/index.js b/src/routes/chat/ChannelChat/index.js
index 2d3e966c..91e84c72 100644
--- a/src/routes/chat/ChannelChat/index.js
+++ b/src/routes/chat/ChannelChat/index.js
@@ -25,11 +25,10 @@ export default function ChannelChat({
// const containerRef = useRef(null);
const [dragFiles, setDragFiles] = useState([]);
const dispatch = useDispatch();
- const { msgs, users, pendingMsgs } = useSelector((store) => {
+ const { msgs, users } = useSelector((store) => {
return {
msgs: store.channelMessage[cid] || {},
users: store.contacts,
- pendingMsgs: store.pendingMessage.channel[cid] || {},
};
});
const handleClearUnreads = () => {
@@ -97,11 +96,11 @@ export default function ChannelChat({
{/* */}
- {[...Object.entries(msgs), ...Object.entries(pendingMsgs)]
+ {Object.entries(msgs)
.sort(([, msg1], [, msg2]) => {
return msg1.created_at - msg2.created_at;
})
- .map(([mid, msg]) => {
+ .map(([mid, msg], idx) => {
if (!msg) return null;
const {
likes = {},
@@ -126,7 +125,7 @@ export default function ChannelChat({
unread={unread}
gid={cid}
mid={mid}
- key={mid}
+ key={idx}
time={created_at}
fromUid={from_uid}
content={content}
diff --git a/src/routes/chat/DMChat/index.js b/src/routes/chat/DMChat/index.js
index 3d990276..57f90574 100644
--- a/src/routes/chat/DMChat/index.js
+++ b/src/routes/chat/DMChat/index.js
@@ -11,10 +11,9 @@ export default function DMChat({ uid = "", dropFiles = [] }) {
console.log("dm files", dropFiles);
const [dragFiles, setDragFiles] = useState([]);
const contacts = useSelector((store) => store.contacts);
- const { msgs, pendingMsgs } = useSelector((store) => {
+ const { msgs } = useSelector((store) => {
return {
msgs: store.userMessage[uid] || {},
- pendingMsgs: store.pendingMessage.user[uid] || {},
};
});
const [currUser, setCurrUser] = useState(null);
@@ -69,11 +68,11 @@ export default function DMChat({ uid = "", dropFiles = [] }) {
>
- {[...Object.entries(msgs), ...Object.entries(pendingMsgs)]
+ {Object.entries(msgs)
.sort(([, msg1], [, msg2]) => {
return msg1.created_at - msg2.created_at;
})
- .map(([mid, msg]) => {
+ .map(([mid, msg], idx) => {
if (!msg) return null;
// console.log("user msg", msg);
const {
@@ -99,7 +98,7 @@ export default function DMChat({ uid = "", dropFiles = [] }) {
unread={unread}
fromUid={from_uid}
mid={mid}
- key={mid}
+ key={idx}
time={created_at}
uid={uid}
content={content}
diff --git a/src/routes/chat/Layout.js b/src/routes/chat/Layout.js
index a4246515..0fac645c 100644
--- a/src/routes/chat/Layout.js
+++ b/src/routes/chat/Layout.js
@@ -1,7 +1,9 @@
-// import { useState } from "react";
+import { useState, useRef, useEffect } from "react";
import { useDrop } from "react-dnd";
import { NativeTypes } from "react-dnd-html5-backend";
import styled from "styled-components";
+import ImagePreviewModal from "../../common/component/ImagePreviewModal";
+
const StyledWrapper = styled.article`
position: relative;
width: 100%;
@@ -75,6 +77,8 @@ export default function Layout({
contacts = null,
setDragFiles,
}) {
+ const messagesContainer = useRef(null);
+ const [previewImage, setPreviewImage] = useState(null);
const [{ isActive }, drop] = useDrop(() => ({
accept: [NativeTypes.FILE],
drop({ files }) {
@@ -86,31 +90,59 @@ export default function Layout({
isActive: monitor.canDrop() && monitor.isOver(),
}),
}));
+ const closePreviewModal = () => {
+ setPreviewImage(null);
+ };
+ useEffect(() => {
+ if (messagesContainer) {
+ const container = messagesContainer.current;
+ container.addEventListener(
+ "click",
+ (evt) => {
+ console.log(evt);
+ const { target } = evt;
+ if (target.nodeType == 1 && target.classList.contains("preview")) {
+ setPreviewImage(target.src);
+ }
+ },
+ true
+ );
+ }
+ }, []);
+
return (
-
-
-
- {children}
- {contacts && {contacts}
}
-
-
+ <>
+ {previewImage && (
+
+ )}
+
+
+
+ {children}
+ {contacts && {contacts}
}
+
-
-
Upload to #Channel
-
- Photos accept jpg, png, max size limit to 10M.
-
+
+
+
Upload to #Channel
+
+ Photos accept jpg, png, max size limit to 10M.
+
+
-
-
+
+ >
);
}
diff --git a/src/routes/chat/MessageList.js b/src/routes/chat/MessageList.js
new file mode 100644
index 00000000..87636cf7
--- /dev/null
+++ b/src/routes/chat/MessageList.js
@@ -0,0 +1,24 @@
+// import React from "react";
+import { VariableSizeList as List } from "react-window";
+import Message from "../../common/component/Message";
+
+export default function MessageList({ messages = [] }) {
+ const Row = ({ index, style }) => (
+
+
+
+ );
+ const getItemSize = (index) =>
+ messages[index].content_type.startsWith("image") ? 150 : 56;
+ return (
+
+ {Row}
+
+ );
+}
diff --git a/src/routes/home/Loading.js b/src/routes/home/Loading.js
index f35cf9d9..d164b9ce 100644
--- a/src/routes/home/Loading.js
+++ b/src/routes/home/Loading.js
@@ -1,9 +1,13 @@
-// import React from 'react'
+import { useState, useEffect } from "react";
import styled from "styled-components";
+import Button from "../../common/component/styled/Button";
+import useLogout from "../../common/hook/useLogout";
const StyledWrapper = styled.div`
width: 100vw;
height: 100vh;
display: flex;
+ flex-direction: column;
+ gap: 15px;
align-items: center;
justify-content: center;
.loading {
@@ -19,11 +23,41 @@ const StyledWrapper = styled.div`
border: 4px solid #999;
border-radius: 50%;
}
+ .reload {
+ visibility: hidden;
+ &.visible {
+ visibility: visible;
+ }
+ }
`;
export default function Loading() {
+ const [reloadVisible, setReloadVisible] = useState(false);
+ const { clearLocalData } = useLogout();
+ const handleReload = () => {
+ clearLocalData();
+ location.reload(true);
+ };
+ useEffect(() => {
+ const inter = setTimeout(() => {
+ setReloadVisible(true);
+ }, 1500);
+
+ return () => {
+ clearTimeout(inter);
+ };
+ }, []);
+
return (
Loading...
+ {reloadVisible && (
+
+ )}
);
}
diff --git a/yarn.lock b/yarn.lock
index 017fd30f..fe8929a8 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -5662,6 +5662,11 @@ memfs@^3.1.2, memfs@^3.4.1:
dependencies:
fs-monkey "1.0.3"
+"memoize-one@>=3.1.1 <6":
+ version "5.2.1"
+ resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.2.1.tgz#8337aa3c4335581839ec01c3d594090cebe8f00e"
+ integrity sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==
+
meow@^8.0.0:
version "8.1.2"
resolved "https://registry.yarnpkg.com/meow/-/meow-8.1.2.tgz#bcbe45bda0ee1729d350c03cffc8395a36c4e897"
@@ -7105,6 +7110,14 @@ react-textarea-autosize@^8.3.3:
use-composed-ref "^1.0.0"
use-latest "^1.0.0"
+react-window@^1.8.6:
+ version "1.8.6"
+ resolved "https://registry.yarnpkg.com/react-window/-/react-window-1.8.6.tgz#d011950ac643a994118632665aad0c6382e2a112"
+ integrity sha512-8VwEEYyjz6DCnGBsd+MgkD0KJ2/OXFULyDtorIiTz+QzwoP94tBoA7CnbtyXMm+cCeAUER5KJcPtWl9cpKbOBg==
+ dependencies:
+ "@babel/runtime" "^7.0.0"
+ memoize-one ">=3.1.1 <6"
+
react@^17.0.2:
version "17.0.2"
resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037"