Skip to content

Commit

Permalink
Animation bugfix and added UserList Skeleton
Browse files Browse the repository at this point in the history
  • Loading branch information
hppanpaliya committed Apr 27, 2023
1 parent 136331f commit 45eda98
Show file tree
Hide file tree
Showing 5 changed files with 138 additions and 38 deletions.
11 changes: 10 additions & 1 deletion src/components/Chat/ChatMessages/MessageList/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,19 @@ const DateSeparator = styled(Typography)(({ theme }) => ({

const MessageList = ({ messages, currentUserUid }) => {
const lastMessageRef = useRef(null);
const isMountedRef = useRef(false);

useEffect(() => {
if (lastMessageRef.current) {
if (isMountedRef.current && lastMessageRef.current) {
lastMessageRef.current.scrollIntoView({ behavior: "smooth" });
} else {
if (lastMessageRef.current) {
lastMessageRef.current.scrollIntoView();
}

setTimeout(() => {
isMountedRef.current = true;
}, 1000);
}
}, [messages]);

Expand Down
7 changes: 7 additions & 0 deletions src/components/Chat/UserList/UserList.css
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,10 @@
color: #999;
margin-top: 2px;
}

.search-box {
width: 100%;
display: flex;
justify-self: start;
justify-content: center;
}
40 changes: 3 additions & 37 deletions src/components/Chat/UserList/UserList.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React, { useState } from "react";
import { useSelector } from "react-redux";
import { Link } from "react-router-dom";
import "./UserList.css";
import useFetchUsers from "./useFetchUsers";
import { TextField, Typography } from "@mui/material";
import CircularProgress from "@mui/material/CircularProgress";
import UsersListItems from "./UsersListItems";
import UsersListSkeleton from "./UsersListItems/Skeleton";

const UsersList = () => {
// State for search input value and loading indicator
Expand All @@ -30,7 +30,7 @@ const UsersList = () => {
{/* Search input */}
<SearchBox searchValue={searchValue} handleSearch={handleSearch} />
{/* Loading indicator */}
{loading ? <CircularProgress /> : ""}
{loading ? <UsersListSkeleton /> : ""}
{/* List of filtered users */}
{!loading && <UsersListItems users={filteredUsers} />}
</div>
Expand Down Expand Up @@ -63,38 +63,4 @@ const SearchBox = ({ searchValue, handleSearch }) => (
<TextField value={searchValue} onChange={handleSearch} placeholder="Search for users..." className="search-box" sx={{ mt: 2 }} />
);

const formatDate = (timestamp) => {
const date = new Date(timestamp);
const options = {
year: "numeric",
month: "short",
day: "numeric",
hour: "2-digit",
minute: "2-digit",
};
return new Intl.DateTimeFormat("en-US", options).format(date);
};

// List of filtered users component
const UsersListItems = ({ users }) => (
<ul className="users-list">
{users.map((user) => (
<li key={user.uid}>
{/* {console.log("Users", users)} */}
<Link to={`/chat/${user.uid}`} className="user-link">
<div className="user-item">
{user.username}
{user.lastMessage && (
<div className="last-message">
{user.lastMessage.text.length > 30 ? user.lastMessage.text.substring(0, 30) + "..." : user.lastMessage.text}
<div className="message-date-time">{formatDate(user.lastMessage.timestamp)}</div>
</div>
)}
</div>
</Link>
</li>
))}
</ul>
);

export default UsersList;
36 changes: 36 additions & 0 deletions src/components/Chat/UserList/UsersListItems/Skeleton.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React from "react";
import { Box, Skeleton } from "@mui/material";
const UsersListSkeleton = () => {
return (
<Box sx={{ width: "100%" }}>
<Box sx={{ display: "flex", flexDirection: "column", alignItems: "center" }}>
<Box sx={{ display: "flex", alignItems: "center", width: "100%", padding: "8px", borderBottom: "1px solid #eee" }}>
<Skeleton variant="circular" width={36} height={36} sx={{ mr: "16px" }} />
<Box sx={{ display: "flex", flexDirection: "column", alignItems: "flex-start", flexGrow: 1 }}>
<Skeleton variant="text" width={100} height={30} sx={{ mb: "4px" }} />
<Skeleton variant="text" width={200} height={20} />
</Box>
<Skeleton variant="text" width={100} height={20} />
</Box>
<Box sx={{ display: "flex", alignItems: "center", width: "100%", padding: "8px", borderBottom: "1px solid #eee" }}>
<Skeleton variant="circular" width={36} height={36} sx={{ mr: "16px" }} />
<Box sx={{ display: "flex", flexDirection: "column", alignItems: "flex-start", flexGrow: 1 }}>
<Skeleton variant="text" width={100} height={30} sx={{ mb: "4px" }} />
<Skeleton variant="text" width={200} height={20} />
</Box>
<Skeleton variant="text" width={100} height={20} />
</Box>
<Box sx={{ display: "flex", alignItems: "center", width: "100%", padding: "8px", borderBottom: "1px solid #eee" }}>
<Skeleton variant="circular" width={36} height={36} sx={{ mr: "16px" }} />
<Box sx={{ display: "flex", flexDirection: "column", alignItems: "flex-start", flexGrow: 1 }}>
<Skeleton variant="text" width={100} height={30} sx={{ mb: "4px" }} />
<Skeleton variant="text" width={200} height={20} />
</Box>
<Skeleton variant="text" width={100} height={20} />
</Box>
</Box>
</Box>
);
};

export default UsersListSkeleton;
82 changes: 82 additions & 0 deletions src/components/Chat/UserList/UsersListItems/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import * as React from "react";
import { Link } from "react-router-dom";
import { motion } from "framer-motion";
import { styled } from "@mui/material/styles";
import { Avatar, Box, ListItem, ListItemAvatar, ListItemText, Typography } from "@mui/material";

const UsersList = styled(Box)({
width: "100%",
".user-link": {
textDecoration: "none",
},
".user-avatar": {
color: "#fff",

fontWeight: "bold",
fontSize: "18px",
width: "36px",
height: "36px",
marginRight: "16px",
},
".list-item": {
display: "flex",
justifyContent: "space-between",
alignItems: "center",
width: "100%",
padding: "8px",
borderBottom: "1px solid #eee",
cursor: "pointer",
"&:hover": {
backgroundColor: "#f9f9f9",
},
},
});

const formatDate = (timestamp) => {
const date = new Date(timestamp);
const options = {
year: "numeric",
month: "short",
day: "numeric",
hour: "2-digit",
minute: "2-digit",
};
return new Intl.DateTimeFormat("en-US", options).format(date);
};

const UsersListItems = ({ users }) => (
<UsersList component="div">
{users.map((user) => (
<motion.div key={user.uid} whileHover={{ scale: 1.05 }} whileTap={{ scale: 0.95 }}>
<Link to={`/chat/${user.uid}`} className="user-link">
<ListItem disablePadding className="list-item">
<ListItemAvatar>
<Avatar className="user-avatar">{user.username.charAt(0).toUpperCase()}</Avatar>
</ListItemAvatar>
<ListItemText
primary={
<Typography variant="subtitle1" component="div">
{user.username}
</Typography>
}
secondary={
<Typography variant="body2" component="div" sx={{ color: "text.secondary" }}>
{user.lastMessage
? user.lastMessage.text.length > 30
? `${user.lastMessage.text.substring(0, 30)}...`
: user.lastMessage.text
: "No messages yet"}
</Typography>
}
/>
<Typography variant="body2" sx={{ color: "text.secondary" }}>
{user.lastMessage && formatDate(user.lastMessage.timestamp)}
</Typography>
</ListItem>
</Link>
</motion.div>
))}
</UsersList>
);

export default UsersListItems;

0 comments on commit 45eda98

Please sign in to comment.