Skip to content

Commit

Permalink
SK-189 Add images support for profile (#120)
Browse files Browse the repository at this point in the history
* SK-189 Add images support for profile

* SK-189 added updateNeedToUploadAvatar to utils

* SK-189 clean up

* SK-189 Minor changes

* SK-189 removed the login field from the edit request

* SK-189 replaced currentuser -> currentUserId store, added getCurrentUserFromParticipants

* Sk-189 fix loop

* Sk-189 updated blur-hash style, added more avatar views

* SK-189 removed all events for upload user's avatar

* SK-189 optimization

* SK-189 removed uploadAvatarsUrls

* SK-189 added hover effect, changed icon

* Sk-189 added style for current/other user pages
  • Loading branch information
Oleksandr1414 authored Jul 11, 2024
1 parent 1baeab3 commit 2e632d4
Show file tree
Hide file tree
Showing 36 changed files with 358 additions and 106 deletions.
1 change: 1 addition & 0 deletions src/_helpers/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const globalConstants = {
"video/webm",
"video/quicktime",
],
allowedAvatarFormats: [".heic", ".HEIC", "image/jpeg", "image/png"],
defaultBlurHash:
"|KO2?U%2Tw=wR6cErDEhOD]~RBVZRip0W9ofwxM_};RPxuwH%3s89]t8$%tLOtxZ%gixtQt8IUS#I.ENa0NZIVt6xFM{M{%1j^M_bcRPX9nht7n+j[rrW;ni%Mt7V@W;t7t8%1bbxat7WBIUR*RjRjRjxuRjs.MxbbV@WY",
weekDays: {
Expand Down
1 change: 1 addition & 0 deletions src/assets/icons/users/AddAvatar.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 6 additions & 6 deletions src/components/attach/AttachHub.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ import {
setLastMessageField,
updateLastMessageField,
} from "@store/values/Conversations";
import { selectCurrentUserId } from "@store/values/CurrentUserId";
import { getIsMobileView } from "@store/values/IsMobileView";
import { getNetworkState } from "@store/values/NetworkState";
import { selectCurrentUser } from "@store/values/CurrentUser";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { useKeyDown } from "@hooks/useKeyDown";
Expand All @@ -39,7 +39,7 @@ export default function AttachHub() {
const messages = useSelector(selectAllMessages);
const selectedConversation = useSelector(getConverastionById);
const selectedCID = selectedConversation._id;
const currentUser = useSelector(selectCurrentUser);
const currentUserId = useSelector(selectCurrentUserId);

const [isPending, setIsPending] = useState(false);
const [isSendMessageDisable, setIsSendMessageDisable] = useState(false);
Expand Down Expand Up @@ -171,12 +171,12 @@ export default function AttachHub() {

inputTextRef.current.value = "";
const cid = selectedCID;
const mid = currentUser._id + Date.now();
const mid = currentUserId + Date.now();

let msg = {
_id: mid,
body,
from: currentUser._id,
from: currentUserId,
t: Date.now(),
attachments: files.map((file) => ({
file_id: file.name,
Expand Down Expand Up @@ -215,7 +215,7 @@ export default function AttachHub() {
msg = {
_id: response.server_mid,
body,
from: currentUser._id,
from: currentUserId,
status: "sent",
t: response.t,
attachments: attachments.map((obj, i) => ({
Expand All @@ -241,7 +241,7 @@ export default function AttachHub() {
[
closeModal,
connectState,
currentUser,
currentUserId,
files,
isSendMessageDisable,
messages,
Expand Down
8 changes: 4 additions & 4 deletions src/components/attach/elements/ItemLoader.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import OvalLoader from "@components/_helpers/OvalLoader";
import { Blurhash } from "react-blurhash";

export default function ItemLoader({ blurHash }) {
export default function ItemLoader({ blurHash, isShowLoader = true }) {
return (
<div className="blur-hash-preloader">
<Blurhash
className="canvas-preloader"
hash={blurHash || "LEHLk~WB2yk8pyo0adR*.7kCMdnj"}
width={70}
height={70}
width={"100%"}
height={"100%"}
resolutionX={32}
resolutionY={32}
/>
<OvalLoader height={50} width={50} />
{isShowLoader ? <OvalLoader height={50} width={50} /> : null}
</div>
);
}
4 changes: 2 additions & 2 deletions src/components/auth/components/LoginLinks.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import showCustomAlert from "@utils/show_alert";
import subscribeForNotifications from "@services/notifications";
import usersService from "@services/usersService";
import { KEY_CODES } from "@helpers/keyCodes";
import { setCurrentUser } from "@store/values/CurrentUser";
import { setCurrentUserId } from "@store/values/CurrentUserId";
import { setSelectedConversation } from "@store/values/SelectedConversation";
import { setUserIsLoggedIn } from "@store/values/UserIsLoggedIn";
import { upsertUser } from "@store/values/Participants";
Expand All @@ -25,7 +25,7 @@ export default function LoginLinks({ changePage, content }) {
subscribeForNotifications();
dispatch(setSelectedConversation({}));
dispatch(setUserIsLoggedIn(true));
dispatch(setCurrentUser(userData));
dispatch(setCurrentUserId(userData._id));
dispatch(upsertUser(userData));
} catch (err) {
localStorage.removeItem("sessionId");
Expand Down
4 changes: 2 additions & 2 deletions src/components/auth/components/SignUpLinks.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import showCustomAlert from "@utils/show_alert";
import subscribeForNotifications from "@services/notifications";
import usersService from "@services/usersService";
import { KEY_CODES } from "@helpers/keyCodes";
import { setCurrentUser } from "@store/values/CurrentUser";
import { setCurrentUserId } from "@store/values/CurrentUserId";
import { setSelectedConversation } from "@store/values/SelectedConversation";
import { setUserIsLoggedIn } from "@store/values/UserIsLoggedIn";
import { upsertUser } from "@store/values/Participants";
Expand All @@ -30,7 +30,7 @@ export default function SignUpLinks({ changePage, content }) {
dispatch(setSelectedConversation({}));
dispatch(setUserIsLoggedIn(true));
dispatch(upsertUser(userData));
dispatch(setCurrentUser(userData));
dispatch(setCurrentUserId(userData._id));
}

showCustomAlert(
Expand Down
10 changes: 5 additions & 5 deletions src/components/hub/chatForm/ChatFormHeader.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
} from "@store/values/Conversations";
import { getIsTabletView } from "@store/values/IsTabletView";
import { getIsMobileView } from "@store/values/IsMobileView";
import { selectCurrentUser } from "@store/values/CurrentUser";
import { selectCurrentUserId } from "@store/values/CurrentUserId";
import { selectParticipantsEntities } from "@store/values/Participants";
import { setAllParams } from "@store/values/ContextMenu";
import { useDispatch, useSelector } from "react-redux";
Expand All @@ -32,12 +32,12 @@ export default function ChatFormHeader({ closeFormFunc }) {

const participants = useSelector(selectParticipantsEntities);
const conversations = useSelector(selectConversationsEntities);
const currentUser = useSelector(selectCurrentUser);
const currentUserId = useSelector(selectCurrentUserId);
const selectedConversation = useSelector(getConverastionById);
const selectedCID = selectedConversation?._id;

const isCurrentUserOwner =
currentUser._id === selectedConversation.owner_id?.toString();
currentUserId === selectedConversation.owner_id?.toString();
const isGroupChat = selectedConversation.type === "g";

const opponentId = useMemo(() => {
Expand All @@ -47,9 +47,9 @@ export default function ChatFormHeader({ closeFormFunc }) {
}

const { owner_id, opponent_id } = conversation;
return participants[owner_id === currentUser._id ? opponent_id : owner_id]
return participants[owner_id === currentUserId ? opponent_id : owner_id]
?._id;
}, [selectedCID, conversations, participants, currentUser]);
}, [selectedCID, conversations, participants, currentUserId]);

const isOpponentExist = useMemo(
() => !!participants[opponentId]?.login,
Expand Down
10 changes: 5 additions & 5 deletions src/components/hub/chatForm/ChatFormInputs.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
updateLastMessageField,
} from "@store/values/Conversations";
import { getNetworkState } from "@store/values/NetworkState";
import { selectCurrentUser } from "@store/values/CurrentUser";
import { selectCurrentUserId } from "@store/values/CurrentUserId";
import { selectParticipantsEntities } from "@store/values/Participants";
import { setSelectedConversation } from "@store/values/SelectedConversation";
import { useDispatch, useSelector } from "react-redux";
Expand All @@ -25,7 +25,7 @@ export default function ChatFormInputs({ chatMessagesBlockRef }) {
const dispatch = useDispatch();

const connectState = useSelector(getNetworkState);
const currentUser = useSelector(selectCurrentUser);
const currentUserId = useSelector(selectCurrentUserId);
const messages = useSelector(selectActiveConversationMessages);
const participants = useSelector(selectParticipantsEntities);
const selectedConversation = useSelector(getConverastionById);
Expand Down Expand Up @@ -56,18 +56,18 @@ export default function ChatFormInputs({ chatMessagesBlockRef }) {

setIsSendMessageDisable(true);
inputRef.current.value = "";
const mid = currentUser._id + Date.now();
const mid = currentUserId + Date.now();
const msg = {
_id: mid,
body,
from: currentUser._id,
from: currentUserId,
t: Date.now(),
};

dispatch(addMessage(msg));
dispatch(updateLastMessageField({ cid: selectedCID, msg }));

const mObject = { mid, body, cid: selectedCID, from: currentUser._id };
const mObject = { mid, body, cid: selectedCID, from: currentUserId };
inputRef.current.focus(); //care..

try {
Expand Down
16 changes: 13 additions & 3 deletions src/components/hub/elements/ChatMessage.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import MessageAttachments from "@components/message/elements/MessageAttachments";
import MessageStatus from "@components/message/elements/MessageStatus";
import MessageUserIcon from "@components/hub/elements/MessageUserIcon";
import addSuffix from "@utils/navigation/add_suffix";
import getUserFullName from "@utils/user/get_user_full_name";
import { urlify } from "@utils/text/urlify";
import { useLocation } from "react-router-dom";
import { useMemo } from "react";

import "@styles/hub/elements/ChatMessage.css";
Expand All @@ -17,6 +19,8 @@ export default function ChatMessage({
isPrevMesssageYours: prev,
isNextMessageYours: next,
}) {
const { pathname, hash } = useLocation();

const { body, from, attachments, status, t } = message;
const isCurrentUser = from === currentUserId;

Expand All @@ -27,15 +31,18 @@ export default function ChatMessage({
}`;
}, [t]);

const openUserProfile = () =>
sender ? addSuffix(pathname + hash, `/user?uid=${from}`) : {};

return (
<div
className={`message__container${isCurrentUser ? "--my" : ""} ${
prev ? "" : "mt-8"
}`}
>
<div className="message-photo">
<div className={`message-photo${sender ? "--hover" : ""}`}>
{next ? null : (
<div className="photo__container fcc">
<div className="photo__container fcc" onClick={openUserProfile}>
<MessageUserIcon
userObject={sender}
isCurrentUser={isCurrentUser}
Expand All @@ -50,7 +57,10 @@ export default function ChatMessage({
<CornerLight className="message-content--corner" />
)}
{prev ? null : (
<div className="content__uname">
<div
className={`content__uname${sender ? "--hover" : ""}`}
onClick={openUserProfile}
>
&zwnj;{getUserFullName(sender) || "Deleted account"}
</div>
)}
Expand Down
16 changes: 14 additions & 2 deletions src/components/hub/elements/ConversationItem.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import LastMessage from "@components/message/LastMessage";
import UserAvatar from "@components/info/elements/UserAvatar";
import getLastUpdateTime from "@utils/conversation/get_last_update_time";
import { useMemo } from "react";

Expand All @@ -11,6 +12,8 @@ export default function ConversationItem({
chatName,
chatObject,
currentUserId,
chatAvatarUrl,
chatAvatarBlutHash,
}) {
const { updated_at, unread_messages_count, type, last_message } = chatObject;

Expand All @@ -22,8 +25,17 @@ export default function ConversationItem({
if (type === "g") {
return <Group />;
}
return chatName ? chatName.slice(0, 2).toUpperCase() : <UnknownPhoto />;
}, [type, chatName]);

return (
<UserAvatar
avatarUrl={chatAvatarUrl}
avatarBlurHash={chatAvatarBlutHash}
defaultIcon={
chatName ? chatName.slice(0, 2).toUpperCase() : <UnknownPhoto />
}
/>
);
}, [type, chatAvatarUrl, chatAvatarBlutHash, chatName]);

return (
<div
Expand Down
20 changes: 11 additions & 9 deletions src/components/hub/elements/ConversationItemList.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import ConversationItem from "@components/hub/elements/ConversationItem";
import getUserFullName from "@src/utils/user/get_user_full_name";
import navigateTo from "@src/utils/navigation/navigate_to";
import { getConverastionById } from "@src/store/values/Conversations";
import { selectCurrentUser } from "@src/store/values/CurrentUser";
import { selectParticipantsEntities } from "@src/store/values/Participants";
import { setSelectedConversation } from "@src/store/values/SelectedConversation";
import getUserFullName from "@utils/user/get_user_full_name";
import navigateTo from "@utils/navigation/navigate_to";
import { getConverastionById } from "@store/values/Conversations";
import { selectCurrentUserId } from "@store/values/CurrentUserId";
import { selectParticipantsEntities } from "@store/values/Participants";
import { setSelectedConversation } from "@store/values/SelectedConversation";
import { useDispatch, useSelector } from "react-redux";

export default function ConversationItemList({ conversations }) {
const dispatch = useDispatch();

const participants = useSelector(selectParticipantsEntities);
const currentUser = useSelector(selectCurrentUser);
const currentUserId = useSelector(selectCurrentUserId);
const selectedConversation = useSelector(getConverastionById);
const activeConversationId = selectedConversation?._id;

Expand All @@ -23,7 +23,7 @@ export default function ConversationItemList({ conversations }) {
return conversations.map((obj) => {
const isSelected = activeConversationId === obj._id;
const chatParticipantId =
obj.owner_id === currentUser._id ? obj.opponent_id : obj.owner_id;
obj.owner_id === currentUserId ? obj.opponent_id : obj.owner_id;
const chatParticipant = participants[chatParticipantId] || {};
const chatName = obj.name || getUserFullName(chatParticipant);

Expand All @@ -33,8 +33,10 @@ export default function ConversationItemList({ conversations }) {
isSelected={isSelected}
onClickFunc={() => convItemOnClickFunc(obj._id)}
chatName={chatName}
chatAvatarUrl={chatParticipant.avatar_url}
chatAvatarBlutHash={chatParticipant.avatar_object?.file_blur_hash}
chatObject={obj}
currentUserId={currentUser._id}
currentUserId={currentUserId}
/>
);
});
Expand Down
7 changes: 6 additions & 1 deletion src/components/hub/elements/MessageUserIcon.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import UserAvatar from "@components/info/elements/UserAvatar";
import getUserInitials from "@utils/user/get_user_initials";

import { ReactComponent as UserIconBlack } from "@icons/users/UserIconBlack.svg";
import { ReactComponent as UserIconWhite } from "@icons/users/UserIconWhite.svg";

export default function MessageUserIcon({ userObject, isCurrentUser }) {
return userObject && !!Object.keys(userObject).length ? (
getUserInitials(userObject)
<UserAvatar
avatarUrl={userObject.avatar_url}
avatarBlurHash={userObject.avatar_object?.file_blur_hash}
defaultIcon={getUserInitials(userObject)}
/>
) : isCurrentUser ? (
<UserIconWhite />
) : (
Expand Down
6 changes: 3 additions & 3 deletions src/components/hub/elements/MessagesList.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
selectParticipantsEntities,
} from "@store/values/Participants";
import { getConverastionById, upsertChat } from "@store/values/Conversations";
import { selectCurrentUser } from "@store/values/CurrentUser";
import { selectCurrentUserId } from "@store/values/CurrentUserId";
import { useCallback, useEffect, useLayoutEffect, useRef } from "react";
import { useDispatch, useSelector } from "react-redux";
import { useLocation } from "react-router-dom";
Expand All @@ -24,7 +24,7 @@ export default function MessagesList({ scrollRef }) {

const messages = useSelector(selectActiveConversationMessages);
const participants = useSelector(selectParticipantsEntities);
const currentUser = useSelector(selectCurrentUser);
const currentUserId = useSelector(selectCurrentUserId);
const selectedConversation = useSelector(getConverastionById);
const selectedCID = selectedConversation?._id;

Expand Down Expand Up @@ -165,7 +165,7 @@ export default function MessagesList({ scrollRef }) {
key={msg._id}
message={msg}
sender={participants[msg.from]}
currentUserId={currentUser._id}
currentUserId={currentUserId}
isPrevMesssageYours={
i > 0
? messages[i - 1].from === messages[i].from &&
Expand Down
Loading

0 comments on commit 2e632d4

Please sign in to comment.