refactor: lots updates

This commit is contained in:
zerosoul
2022-03-17 11:15:13 +08:00
parent 4bc9932d0f
commit f22c7a01cb
69 changed files with 4625 additions and 1640 deletions
+31 -31
View File
@@ -1,72 +1,73 @@
// import { Picker } from "emoji-mart";
// import "emoji-mart/css/emoji-mart.css";
// import Picker from "../EmojiPicker";
import { useRef } from "react";
import styled from "styled-components";
import { useOutsideClick } from "rooks";
import { useSelector } from "react-redux";
import { useReactMessageMutation } from "../../../app/services/message";
import { Emojis } from "../../../app/config";
import Emoji from "../Emoji";
const StyledPicker = styled.div`
border: 1px solid rgba(0, 0, 0, 0.08);
border-radius: 6px;
position: absolute;
left: -10px;
top: 0;
transform: translateX(-100%);
background-color: #fff;
padding: 5px;
.emojis {
display: flex;
gap: 4px;
padding: 4px;
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 8px;
background: #ffffff;
filter: drop-shadow(0px 25px 50px rgba(31, 41, 55, 0.25));
border-radius: 12px;
&.reacting {
opacity: 0.6;
}
.emoji {
cursor: pointer;
border-radius: 4px;
border-radius: 8px;
padding: 4px;
font-size: 30px;
&:hover,
&.reacted {
background-color: #f3f4f6;
background-color: #f5f6f7;
}
> * {
display: flex;
}
}
}
`;
const emojis = {
["U+1F44D"]: "👍",
["U+1F44C"]: "👌",
["U+2764"]: "❤️",
};
export default function EmojiPicker({ mid, hidePicker }) {
const wrapperRef = useRef(null);
const [reactMessage, { isLoading }] = useReactMessageMutation();
const { reactionData, currUid } = useSelector((store) => {
return {
reactionData: store.reactionMessage[mid],
reactionData: store.reactionMessage[mid] || {},
currUid: store.authData.uid,
};
});
useOutsideClick(wrapperRef, hidePicker);
const handleReact = (action) => {
console.log("react", action);
reactMessage({ mid, action });
const handleReact = (emoji) => {
console.log("react", emoji);
reactMessage({ mid, action: emoji });
hidePicker();
};
return (
<StyledPicker ref={wrapperRef}>
{/* <Picker
onSelect={handleReact}
className={`picker ${isLoading ? "reacting" : ""}`}
/> */}
<ul className={`emojis ${isLoading ? "reacting" : ""}`}>
{Object.entries(emojis).map(([key, emoji]) => {
{Emojis.map((emoji) => {
let reacted =
reactionData &&
reactionData[key] &&
reactionData[key].includes(currUid);
reactionData[emoji] &&
reactionData[emoji].findIndex((id) => id == currUid) > -1;
return (
<li
className={`emoji ${reacted ? "reacted" : ""}`}
key={key}
onClick={handleReact.bind(null, key)}
key={emoji}
onClick={handleReact.bind(null, emoji)}
>
{emoji}
<Emoji native={emoji} size={24} />
</li>
);
})}
@@ -74,4 +75,3 @@ export default function EmojiPicker({ mid, hidePicker }) {
</StyledPicker>
);
}
export { emojis };
+94 -29
View File
@@ -1,54 +1,119 @@
import React from "react";
import { useDispatch, useSelector } from "react-redux";
import { useState } from "react";
import { useSelector } from "react-redux";
import styled from "styled-components";
import { emojis } from "./EmojiPicker";
import Emoji from "../Emoji";
import EmojiPicker from "./EmojiPicker";
import { useReactMessageMutation } from "../../../app/services/message";
// import { Emojis } from "../../../app/config";
import addEmojiIcon from "../../../assets/icons/add.emoji.svg?url";
const StyledWrapper = styled.span`
z-index: 99;
position: relative;
margin-top: 8px;
margin-bottom: 4px;
display: flex;
gap: 8px;
font-size: 16px;
align-items: center;
gap: 4px;
width: fit-content;
/* align-items: center; */
.reaction {
cursor: pointer;
background-color: #ecfdff;
border-radius: 6px;
position: relative;
display: flex;
align-items: center;
gap: 6px;
em {
gap: 4px;
padding: 4px;
> .emoji {
> * {
display: flex;
}
}
&:hover {
background-color: #cff9fe;
}
&.reacted {
border: 1px solid #06aed4;
background-color: #a5f0fc;
}
> .count {
font-weight: 400;
font-size: 12px;
color: #999;
line-height: 16px;
color: #06aed4;
}
}
> .add {
visibility: hidden;
width: 24px;
height: 24px;
background-color: #ecfdff;
border-radius: 6px;
border: none;
background-image: url(${addEmojiIcon});
background-size: 16px;
background-repeat: no-repeat;
background-position: center;
&:hover {
background-color: #cff9fe;
}
}
.picker {
position: absolute;
right: 0;
top: 0;
transform: translateX(105%);
}
&:hover > .add {
visibility: visible;
}
`;
export default function Reaction({ reactions = null }) {
// const {
// messageData,
// reactionMessageData,
// contactsData,
// loginedUser,
// } = useSelector((store) => {
// return {
// reactionMessageData: store.reactionMessage,
// messageData: store.message,
// contactsData: store.contacts.byId,
// loginedUser: store.authData.user,
// };
// });
if (!reactions) return null;
export default function Reaction({ mid, reactions = null }) {
const [pickerVisible, setPickerVisible] = useState(false);
const [reactWithEmoji] = useReactMessageMutation();
const { currUid } = useSelector((store) => {
return {
currUid: store.authData.uid,
};
});
const handleReact = (emoji) => {
reactWithEmoji({ mid, action: emoji });
};
const togglePickerVisible = (wtf) => {
console.log("clicked", wtf);
setPickerVisible((prev) => !prev);
};
console.log("curr reactions", reactions);
if (!reactions || Object.entries(reactions).length == 0) return null;
return (
<StyledWrapper className="reactions">
{Object.entries(reactions).map(([reaction, uids]) => {
const reacted = uids.findIndex((id) => id == currUid) > -1;
return uids.length > 0 ? (
<i
className="reaction"
<span
onClick={handleReact.bind(null, reaction)}
className={`reaction ${reacted ? "reacted" : ""}`}
// data-count={count > 1 ? count : ""}
key={reaction}
>
{emojis[reaction]}
<i className="emoji">
<Emoji native={reaction} />
</i>
{uids.length > 1 ? <em>{`+${uids.length}`} </em> : null}
</i>
{uids.length > 1 ? (
<em className="count">{`${uids.length}`} </em>
) : null}
</span>
) : null;
})}
<button onClick={togglePickerVisible} className="add"></button>
{pickerVisible && (
<div className="picker">
<EmojiPicker mid={mid} hidePicker={togglePickerVisible} />
</div>
)}
</StyledWrapper>
);
}
+12 -4
View File
@@ -8,12 +8,14 @@ import Reply from "./Reply";
import Profile from "../Profile";
import Avatar from "../Avatar";
import { readMessage } from "../../../app/slices/message";
import { useReadMessageMutation } from "../../../app/services/message";
import StyledWrapper from "./styled";
import Commands from "./Commands";
import EditMessage from "./EditMessage";
import renderContent from "./renderContent";
function Message({ contextId = 0, mid = "" }) {
function Message({ contextId = 0, mid = "", read = true, context = "user" }) {
const [updateReadIndex] = useReadMessageMutation();
const [myRef, inView] = useInViewRef();
const [edit, setEdit] = useState(false);
const [emojiPopVisible, setEmojiPopVisible] = useState(false);
@@ -47,10 +49,15 @@ function Message({ contextId = 0, mid = "" }) {
// console.log("message", mid, messageData[mid]);
useEffect(() => {
if (inView && !message.read) {
if (inView && !read) {
disptach(readMessage(mid));
const data =
context == "user"
? { users: [{ uid: +contextId, mid }] }
: { groups: [{ gid: +contextId, mid }] };
updateReadIndex(data);
}
}, [mid, message, inView]);
}, [mid, read, inView]);
if (!message) return null;
const {
reply_mid,
@@ -65,6 +72,7 @@ function Message({ contextId = 0, mid = "" }) {
const currUser = contactsData[fromUid] || {};
return (
<StyledWrapper
data-mid={mid}
ref={myRef}
className={`message ${menuVisible ? "menu" : ""} ${
inView ? "in_view" : ""
@@ -85,7 +93,6 @@ function Message({ contextId = 0, mid = "" }) {
<div className="up">
<span className="name">{currUser.name}</span>
<i className="time">{dayjs(time).format("YYYY-MM-DD h:mm:ss A")}</i>
{reactions && <Reaction reactions={reactions} />}
</div>
<div className={`down ${sending ? "sending" : ""}`}>
{edit ? (
@@ -97,6 +104,7 @@ function Message({ contextId = 0, mid = "" }) {
) : (
renderContent(content_type, content, edited)
)}
{reactions && <Reaction mid={mid} reactions={reactions} />}
</div>
</div>
{!edit && (
+12 -1
View File
@@ -1,6 +1,7 @@
import Linkify from "react-linkify";
import dayjs from "dayjs";
import BASE_URL from "../../../app/config";
import MrakdownRender from "../MrakdownRender";
const renderContent = (type, content, edited = false) => {
let ctn = null;
switch (type) {
@@ -9,7 +10,12 @@ const renderContent = (type, content, edited = false) => {
<>
<Linkify
componentDecorator={(decoratedHref, decoratedText, key) => (
<a target="blank" href={decoratedHref} key={key}>
<a
target="_blank"
href={decoratedHref}
key={key}
rel="noreferrer"
>
{decoratedText}
</a>
)}
@@ -27,6 +33,11 @@ const renderContent = (type, content, edited = false) => {
</>
);
break;
case "text/markdown":
{
ctn = <MrakdownRender content={content} />;
}
break;
case "image/png":
case "image/jpeg":
ctn = (
+1 -1
View File
@@ -4,7 +4,7 @@ const StyledMsg = styled.div`
display: flex;
align-items: flex-start;
gap: 16px;
padding: 4px;
padding: 4px 8px;
margin: 8px 0;
border-radius: 8px;
content-visibility: auto;