now notifications in header drawer scrollable
This commit is contained in:
parent
499cd7e16b
commit
ef79d3a8c0
|
|
@ -9,24 +9,23 @@ import { isIterableArray } from '../../helpers/utils';
|
||||||
import FalconCardHeader from '../common/FalconCardHeader';
|
import FalconCardHeader from '../common/FalconCardHeader';
|
||||||
import Notification from '../notification/JKNotification';
|
import Notification from '../notification/JKNotification';
|
||||||
import { Scrollbar } from 'react-scrollbars-custom';
|
import { Scrollbar } from 'react-scrollbars-custom';
|
||||||
|
|
||||||
import { fetchNotifications } from '../../store/features/notificationSlice';
|
|
||||||
import { useDispatch, useSelector } from 'react-redux';
|
|
||||||
import { useAuth } from '../../context/UserAuth';
|
import { useAuth } from '../../context/UserAuth';
|
||||||
|
|
||||||
import { readNotifications } from '../../helpers/rest';
|
import { readNotifications } from '../../helpers/rest';
|
||||||
|
import useNotifications from '../../hooks/useNotifications';
|
||||||
|
|
||||||
const JKNotificationDropdown = () => {
|
const JKNotificationDropdown = () => {
|
||||||
const { currentUser, isAuthenticated } = useAuth();
|
const { currentUser, isAuthenticated } = useAuth();
|
||||||
const dispatch = useDispatch();
|
const {
|
||||||
const notifications = useSelector(state => state.notification.notifications);
|
notifications,
|
||||||
const next = useSelector(state => state.notification.next);
|
offset,
|
||||||
const status = useSelector(state => state.notification.status);
|
setOffset,
|
||||||
const unread_total = useSelector(state => state.notification.unread_total);
|
next,
|
||||||
|
unread_total,
|
||||||
|
loadNotifications,
|
||||||
|
} = useNotifications(currentUser);
|
||||||
|
|
||||||
const LIMIT = 20;
|
const LIMIT = 20;
|
||||||
const MAX_COUNT_ON_BADGE = 99;
|
const MAX_COUNT_ON_BADGE = 99;
|
||||||
const [offset, setOffset] = useState(0);
|
|
||||||
|
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
const [isAllRead, setIsAllRead] = useState(false);
|
const [isAllRead, setIsAllRead] = useState(false);
|
||||||
|
|
@ -39,19 +38,6 @@ const JKNotificationDropdown = () => {
|
||||||
setIsOpen(!isOpen);
|
setIsOpen(!isOpen);
|
||||||
};
|
};
|
||||||
|
|
||||||
const loadNotifications = async () => {
|
|
||||||
try {
|
|
||||||
const options = {
|
|
||||||
userId: currentUser.id,
|
|
||||||
offset: offset,
|
|
||||||
limit: LIMIT
|
|
||||||
};
|
|
||||||
await dispatch(fetchNotifications(options)).unwrap();
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isOpen) {
|
if (isOpen) {
|
||||||
readNotifications(currentUser.id)
|
readNotifications(currentUser.id)
|
||||||
|
|
@ -65,11 +51,12 @@ const JKNotificationDropdown = () => {
|
||||||
}, [isOpen]);
|
}, [isOpen]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
loadNotifications();
|
if(isAuthenticated)
|
||||||
}, []);
|
loadNotifications();
|
||||||
|
}, [currentUser]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (offset > 0 && next !== null) {
|
if (isAuthenticated && offset > 0 && next !== null) {
|
||||||
loadNotifications();
|
loadNotifications();
|
||||||
}
|
}
|
||||||
}, [offset]);
|
}, [offset]);
|
||||||
|
|
@ -107,9 +94,16 @@ const JKNotificationDropdown = () => {
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
{isIterableArray(notifications) && notifications.length > 0 && !isAllRead && unread_total > 0 && (
|
{isIterableArray(notifications) && notifications.length > 0 && !isAllRead && unread_total > 0 && (
|
||||||
<div className="num-circle" onClick={handleToggle}>{unread_total < MAX_COUNT_ON_BADGE ? unread_total : `${MAX_COUNT_ON_BADGE}+`}</div>
|
<div className="num-circle" onClick={handleToggle}>
|
||||||
|
{unread_total < MAX_COUNT_ON_BADGE ? unread_total : `${MAX_COUNT_ON_BADGE}+`}
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
<FontAwesomeIcon icon={['fas', 'bell']} transform="shrink-5" className="fs-4 bell-icon" onClick={handleToggle} />
|
<FontAwesomeIcon
|
||||||
|
icon={['fas', 'bell']}
|
||||||
|
transform="shrink-5"
|
||||||
|
className="fs-4 bell-icon"
|
||||||
|
onClick={handleToggle}
|
||||||
|
/>
|
||||||
</DropdownToggle>
|
</DropdownToggle>
|
||||||
<DropdownMenu right className="dropdown-menu-card" data-testid="notificationDropdown">
|
<DropdownMenu right className="dropdown-menu-card" data-testid="notificationDropdown">
|
||||||
<Card className="card-notification shadow-none" style={{ maxWidth: '20rem' }}>
|
<Card className="card-notification shadow-none" style={{ maxWidth: '20rem' }}>
|
||||||
|
|
@ -129,7 +123,7 @@ const JKNotificationDropdown = () => {
|
||||||
mobileNative={true}
|
mobileNative={true}
|
||||||
trackClickBehavior="step"
|
trackClickBehavior="step"
|
||||||
>
|
>
|
||||||
{isIterableArray(notifications) &&
|
{isIterableArray(notifications) &&
|
||||||
notifications.map(notification => (
|
notifications.map(notification => (
|
||||||
<ListGroupItem
|
<ListGroupItem
|
||||||
key={`notification-drop-item-${notification.notification_id}`}
|
key={`notification-drop-item-${notification.notification_id}`}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { useEffect} from 'react';
|
import React from 'react';
|
||||||
import ProfileAvatar from '../profile/JKProfileAvatar'
|
import ProfileAvatar from '../profile/JKProfileAvatar'
|
||||||
import TimeAgo from '../common/JKTimeAgo';
|
import TimeAgo from '../common/JKTimeAgo';
|
||||||
import { useAuth } from '../../context/UserAuth';
|
import { useAuth } from '../../context/UserAuth';
|
||||||
|
|
@ -34,11 +34,6 @@ function JKFriendRequestNotification(props) {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!user)
|
|
||||||
dispatch(fetchPerson({ userId: source_user_id }))
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="notification-avatar mr-3">
|
<div className="notification-avatar mr-3">
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,16 @@
|
||||||
import React, { useEffect } from 'react'
|
import React from 'react'
|
||||||
import ProfileAvatar from '../profile/JKProfileAvatar'
|
import ProfileAvatar from '../profile/JKProfileAvatar'
|
||||||
import TimeAgo from '../common/JKTimeAgo';
|
import TimeAgo from '../common/JKTimeAgo';
|
||||||
import useUserProfile from '../../hooks/useUserProfile';
|
import useUserProfile from '../../hooks/useUserProfile';
|
||||||
import { useDispatch, useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
import { fetchPerson } from '../../store/features/peopleSlice';
|
|
||||||
|
|
||||||
const JKGenericNotification = (notification) => {
|
const JKGenericNotification = (notification) => {
|
||||||
|
|
||||||
const {formatted_msg, created_at, source_user_id} = notification;
|
const {formatted_msg, created_at, source_user_id} = notification;
|
||||||
|
|
||||||
const dispatch = useDispatch();
|
|
||||||
|
|
||||||
const user = useSelector(state => state.people.people.find(person => person.id === source_user_id));
|
const user = useSelector(state => state.people.people.find(person => person.id === source_user_id));
|
||||||
const { photoUrl } = useUserProfile(user); // user is the person who sent the message
|
const { photoUrl } = useUserProfile(user); // user is the person who sent the message
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
dispatch(fetchPerson({ userId: source_user_id }))
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="notification-avatar mr-3">
|
<div className="notification-avatar mr-3">
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ import {useAuth} from '../../context/UserAuth';
|
||||||
import { useDispatch } from 'react-redux';
|
import { useDispatch } from 'react-redux';
|
||||||
import { removeNotification } from '../../store/features/notificationSlice';
|
import { removeNotification } from '../../store/features/notificationSlice';
|
||||||
|
|
||||||
|
|
||||||
import JKGenericNotification from './JKGenericNotification';
|
import JKGenericNotification from './JKGenericNotification';
|
||||||
import JKFriendRequestNotification from './JKFriendRequestNotification';
|
import JKFriendRequestNotification from './JKFriendRequestNotification';
|
||||||
import TextMessageNotification from './JKTextMessageNotification';
|
import TextMessageNotification from './JKTextMessageNotification';
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
import React, { useEffect } from 'react';
|
import React from 'react';
|
||||||
import { useAuth } from '../../context/UserAuth';
|
import { useAuth } from '../../context/UserAuth';
|
||||||
import { useDispatch, useSelector } from 'react-redux';
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
import { fetchPerson, add as addPerson } from '../../store/features/peopleSlice';
|
|
||||||
import JKMessageButton from '../profile/JKMessageButton';
|
import JKMessageButton from '../profile/JKMessageButton';
|
||||||
import ProfileAvatar from '../profile/JKProfileAvatar';
|
import ProfileAvatar from '../profile/JKProfileAvatar';
|
||||||
import TimeAgo from '../common/JKTimeAgo';
|
import TimeAgo from '../common/JKTimeAgo';
|
||||||
|
|
@ -10,19 +9,10 @@ import useUserProfile from '../../hooks/useUserProfile';
|
||||||
|
|
||||||
function JKTextMessageNotification(props) {
|
function JKTextMessageNotification(props) {
|
||||||
const { source_user, source_user_id, message, created_at } = props.notification;
|
const { source_user, source_user_id, message, created_at } = props.notification;
|
||||||
|
|
||||||
const { currentUser } = useAuth();
|
const { currentUser } = useAuth();
|
||||||
const dispatch = useDispatch();
|
|
||||||
|
|
||||||
const user = useSelector(state => state.people.people.find(person => person.id === source_user_id));
|
const user = useSelector(state => state.people.people.find(person => person.id === source_user_id));
|
||||||
|
|
||||||
const { photoUrl } = useUserProfile(user); // user is the person who sent the message
|
const { photoUrl } = useUserProfile(user); // user is the person who sent the message
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if(!user)
|
|
||||||
dispatch(fetchPerson({ userId: source_user_id }))
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="notification-avatar mr-3">
|
<div className="notification-avatar mr-3">
|
||||||
|
|
|
||||||
|
|
@ -5,35 +5,45 @@ import FalconCardHeader from '../common/FalconCardHeader';
|
||||||
import Loader from '../common/Loader';
|
import Loader from '../common/Loader';
|
||||||
import { isIterableArray } from '../../helpers/utils';
|
import { isIterableArray } from '../../helpers/utils';
|
||||||
|
|
||||||
import { fetchNotifications } from '../../store/features/notificationSlice';
|
|
||||||
import { useDispatch, useSelector } from 'react-redux';
|
|
||||||
import { useAuth } from '../../context/UserAuth';
|
import { useAuth } from '../../context/UserAuth';
|
||||||
|
import useNotifications from '../../hooks/useNotifications';
|
||||||
|
|
||||||
const JKNotifications = () => {
|
const JKNotifications = () => {
|
||||||
const { currentUser } = useAuth();
|
const { currentUser, isAuthenticated } = useAuth();
|
||||||
const dispatch = useDispatch();
|
const {
|
||||||
const notifications = useSelector(state => state.notification.notifications);
|
notifications,
|
||||||
const loadingState = useSelector(state => state.notification.state);
|
offset,
|
||||||
|
setOffset,
|
||||||
const LIMIT = 20;
|
next,
|
||||||
const [page, setPage] = useState(0);
|
unread_total,
|
||||||
|
loadNotifications,
|
||||||
const loadNotifications = async () => {
|
notificationStatus: loadingState
|
||||||
try {
|
} = useNotifications(currentUser);
|
||||||
const options = {
|
|
||||||
userId: currentUser.id,
|
|
||||||
offset: page * LIMIT,
|
|
||||||
limit: LIMIT
|
|
||||||
};
|
|
||||||
await dispatch(fetchNotifications(options)).unwrap();
|
|
||||||
//setPage(prev => prev + 1);
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
loadNotifications();
|
if(isAuthenticated)
|
||||||
|
loadNotifications();
|
||||||
|
}, [currentUser]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (isAuthenticated && offset > 0 && next !== null) {
|
||||||
|
loadNotifications();
|
||||||
|
}
|
||||||
|
}, [offset]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const onscroll = () => {
|
||||||
|
console.log("scrolling", window.scrollY, window.innerHeight, document.body.scrollHeight);
|
||||||
|
const scrolledTo = window.scrollY + window.innerHeight;
|
||||||
|
const isReachBottom = document.body.scrollHeight === scrolledTo;
|
||||||
|
if (isReachBottom) {
|
||||||
|
setOffset(offset + 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
window.addEventListener("scroll", onscroll);
|
||||||
|
return () => {
|
||||||
|
window.removeEventListener("scroll", onscroll);
|
||||||
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ const JKMessageButton = props => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<JKMessageModal show={showModal} setShow={setShowModal} user={user} currentUser={currentUser} />
|
<JKMessageModal show={showModal} setShow={setShowModal} user={user} />
|
||||||
<Button
|
<Button
|
||||||
id={"text-message-user-" + user.id}
|
id={"text-message-user-" + user.id}
|
||||||
onClick={() => setShowModal(!showModal)}
|
onClick={() => setShowModal(!showModal)}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import { useDispatch, useSelector } from 'react-redux';
|
||||||
import { fetchMessagesByReceiverId, postNewMessage } from '../../store/features/textMessagesSlice';
|
import { fetchMessagesByReceiverId, postNewMessage } from '../../store/features/textMessagesSlice';
|
||||||
import { isIterableArray } from '../../helpers/utils';
|
import { isIterableArray } from '../../helpers/utils';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
import useUserProfile from '../../hooks/useUserProfile';
|
||||||
|
|
||||||
const JKMessageModal = props => {
|
const JKMessageModal = props => {
|
||||||
const { show, setShow, user } = props;
|
const { show, setShow, user } = props;
|
||||||
|
|
@ -26,6 +27,9 @@ const JKMessageModal = props => {
|
||||||
const messageTextBox = useRef();
|
const messageTextBox = useRef();
|
||||||
const scrolledToBottom = useRef(false);
|
const scrolledToBottom = useRef(false);
|
||||||
|
|
||||||
|
const { photoUrl: userPhotoUrl } = useUserProfile(user);
|
||||||
|
const { photoUrl: currentUserPhotoUrl } = useUserProfile(currentUser);
|
||||||
|
|
||||||
const messages = useSelector(state =>
|
const messages = useSelector(state =>
|
||||||
state.textMessage.messages
|
state.textMessage.messages
|
||||||
.filter(
|
.filter(
|
||||||
|
|
@ -150,7 +154,7 @@ const JKMessageModal = props => {
|
||||||
<div className="d-flex mb-3 mr-1 text-message-row" key={message.id}>
|
<div className="d-flex mb-3 mr-1 text-message-row" key={message.id}>
|
||||||
<div className="avatar avatar-2xl d-inline-block">
|
<div className="avatar avatar-2xl d-inline-block">
|
||||||
<JKProfileAvatar
|
<JKProfileAvatar
|
||||||
url={message.receiverId === currentUser.id ? currentUser.photo_url : user.photo_url}
|
src={message.receiverId === currentUser.id ? userPhotoUrl : currentUserPhotoUrl }
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="d-inline-block">
|
<div className="d-inline-block">
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import useOnScreen from '../../hooks/useOnScreen';
|
||||||
import useKeepScrollPosition from '../../hooks/useKeepScrollPosition';
|
import useKeepScrollPosition from '../../hooks/useKeepScrollPosition';
|
||||||
|
|
||||||
import { useLobbyChat } from './JKLobbyChatContext';
|
import { useLobbyChat } from './JKLobbyChatContext';
|
||||||
|
import useUserProfile from '../../hooks/useUserProfile';
|
||||||
|
|
||||||
function JKLobbyChat() {
|
function JKLobbyChat() {
|
||||||
const CHANNEL_LOBBY = 'lobby';
|
const CHANNEL_LOBBY = 'lobby';
|
||||||
|
|
@ -28,6 +29,8 @@ function JKLobbyChat() {
|
||||||
const [messagesArrived, setMessagesArrived] = useState(false);
|
const [messagesArrived, setMessagesArrived] = useState(false);
|
||||||
//const [offset, setOffset] = useState(0);
|
//const [offset, setOffset] = useState(0);
|
||||||
|
|
||||||
|
const userProfile = useUserProfile(currentUser);
|
||||||
|
|
||||||
const { t } = useTranslation('sessions');
|
const { t } = useTranslation('sessions');
|
||||||
|
|
||||||
const chatMessages = useSelector(state => state.lobbyChat.records.messages);
|
const chatMessages = useSelector(state => state.lobbyChat.records.messages);
|
||||||
|
|
@ -165,7 +168,7 @@ function JKLobbyChat() {
|
||||||
<div className="d-flex mb-3 mr-1 text-message-row" key={greaterThan ? `desktop_${message.id}` : `mobile_${message.id}`}>
|
<div className="d-flex mb-3 mr-1 text-message-row" key={greaterThan ? `desktop_${message.id}` : `mobile_${message.id}`}>
|
||||||
<div className='d-flex align-items-center' ref={ref => (i === 0 ? setLastMessageRef(ref) : null)}>
|
<div className='d-flex align-items-center' ref={ref => (i === 0 ? setLastMessageRef(ref) : null)}>
|
||||||
<div className="avatar avatar-2xl">
|
<div className="avatar avatar-2xl">
|
||||||
<JKProfileAvatar url={message.user.photo_url} />
|
<JKProfileAvatar src={message.user.photo_url} />
|
||||||
</div>
|
</div>
|
||||||
<div className="pt-2">
|
<div className="pt-2">
|
||||||
<div className="d-flex flex-column">
|
<div className="d-flex flex-column">
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,67 @@
|
||||||
|
import { useState, useEffect } from 'react';
|
||||||
|
import { fetchNotifications } from '../store/features/notificationSlice';
|
||||||
|
import { fetchPeopleByIds } from '../store/features/peopleSlice';
|
||||||
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
|
|
||||||
|
const useNotifications = user => {
|
||||||
|
const LIMIT = 20;
|
||||||
|
const [offset, setOffset] = useState(0);
|
||||||
|
const [notifications, setNotifications] = useState([]);
|
||||||
|
|
||||||
|
const reduxNotifications = useSelector(state => state.notification.notifications);
|
||||||
|
const next = useSelector(state => state.notification.next);
|
||||||
|
const notificationStatus = useSelector(state => state.notification.status);
|
||||||
|
const unread_total = useSelector(state => state.notification.unread_total);
|
||||||
|
const peopleStatus = useSelector(state => state.people.status);
|
||||||
|
const people = useSelector(state => state.people.people);
|
||||||
|
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
|
const loadNotifications = async () => {
|
||||||
|
const options = {
|
||||||
|
userId: user.id,
|
||||||
|
offset: offset,
|
||||||
|
limit: LIMIT
|
||||||
|
};
|
||||||
|
try {
|
||||||
|
await dispatch(fetchNotifications(options)).unwrap();
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const fetchNotificationSourceUsers = async () => {
|
||||||
|
const sourceUserIds = reduxNotifications.map(notification => notification.source_user_id).filter((value, index, self) => self.indexOf(value) === index);
|
||||||
|
const options = { userId: user.id, ids: sourceUserIds };
|
||||||
|
try {
|
||||||
|
await dispatch(fetchPeopleByIds(options)).unwrap();
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (reduxNotifications && reduxNotifications.length && notificationStatus === 'succeeded') {
|
||||||
|
fetchNotificationSourceUsers();
|
||||||
|
}
|
||||||
|
}, [reduxNotifications, notificationStatus]);
|
||||||
|
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const newNotifications = reduxNotifications.filter(notification => !notifications.find(n => n.id === notification.id));
|
||||||
|
setNotifications(prev => [...prev, ...newNotifications]);
|
||||||
|
}, [people]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
notifications,
|
||||||
|
offset,
|
||||||
|
setOffset,
|
||||||
|
loadNotifications,
|
||||||
|
next,
|
||||||
|
unread_total,
|
||||||
|
notificationStatus,
|
||||||
|
peopleStatus
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useNotifications;
|
||||||
|
|
@ -1,44 +1,46 @@
|
||||||
import { getPersonById } from '../helpers/rest';
|
|
||||||
import { useEffect, useState, useMemo } from 'react';
|
import { useEffect, useState, useMemo } from 'react';
|
||||||
|
import { useSelector, useDispatch } from 'react-redux';
|
||||||
|
import { fetchPerson } from '../store/features/peopleSlice';
|
||||||
|
|
||||||
const useUserProfile = (user) => {
|
const useUserProfile = user => {
|
||||||
const [userProfile, setUserProfile] = useState(null)
|
const [userProfile, setUserProfile] = useState(null);
|
||||||
|
const people = useSelector(state => state.people.people);
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!user) {
|
if (!user) {
|
||||||
setUserProfile(null);
|
setUserProfile(null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
getPersonById(user.id)
|
const person = people.find(person => person.id === user.id);
|
||||||
.then(response => {
|
if (person) {
|
||||||
if (response.ok) {
|
setUserProfile(person);
|
||||||
return response.json();
|
} else {
|
||||||
}
|
dispatch(fetchPerson({ userId: user.id }))
|
||||||
})
|
.unwrap()
|
||||||
.then(data => {
|
.then(resp => {
|
||||||
setUserProfile(data)
|
setUserProfile(resp);
|
||||||
})
|
});
|
||||||
.catch(error => console.error(error));
|
}
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
setUserProfile(null);
|
setUserProfile(null);
|
||||||
}
|
};
|
||||||
}, [user]);
|
}, [user]);
|
||||||
|
|
||||||
|
|
||||||
const photoUrl = useMemo(() => {
|
const photoUrl = useMemo(() => {
|
||||||
if(userProfile && userProfile.v2_photo_uploaded){
|
if (userProfile && userProfile.v2_photo_uploaded) {
|
||||||
return userProfile.v2_photo_url
|
return userProfile.v2_photo_url;
|
||||||
}else if(userProfile && !userProfile.v2_photo_uploaded){
|
} else if (userProfile && !userProfile.v2_photo_uploaded) {
|
||||||
return user.photo_url
|
return user.photo_url;
|
||||||
}
|
}
|
||||||
return null
|
return null;
|
||||||
}, [userProfile])
|
}, [userProfile]);
|
||||||
|
|
||||||
return{
|
return {
|
||||||
userProfile,
|
userProfile,
|
||||||
photoUrl
|
photoUrl
|
||||||
}
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
export default useUserProfile;
|
export default useUserProfile;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
|
import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
|
||||||
import {getNotifications, deleteNotification} from '../../helpers/rest'
|
import {getNotifications, deleteNotification} from '../../helpers/rest'
|
||||||
|
|
||||||
const initialState = {
|
const initialState = {
|
||||||
notifications: [],
|
notifications: [],
|
||||||
next: null,
|
next: null,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { createSlice, createAsyncThunk } from "@reduxjs/toolkit"
|
import { createSlice, createAsyncThunk } from "@reduxjs/toolkit"
|
||||||
import { getPeople, getPersonById, acceptFriendRequest as accept } from '../../helpers/rest';
|
import { getPeople, getPeopleByIds, getPersonById, acceptFriendRequest as accept } from '../../helpers/rest';
|
||||||
|
|
||||||
const initialState = {
|
const initialState = {
|
||||||
people: [],
|
people: [],
|
||||||
|
|
@ -21,12 +21,19 @@ export const fetchPeople = createAsyncThunk(
|
||||||
export const preFetchPeople = createAsyncThunk(
|
export const preFetchPeople = createAsyncThunk(
|
||||||
'people/preFetchPeople',
|
'people/preFetchPeople',
|
||||||
async (options, thunkAPI) => {
|
async (options, thunkAPI) => {
|
||||||
|
|
||||||
const response = await getPeople(options)
|
const response = await getPeople(options)
|
||||||
return response.json()
|
return response.json()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
export const fetchPeopleByIds = createAsyncThunk(
|
||||||
|
'people/fetchPeopleByIds',
|
||||||
|
async (options, thunkAPI) => {
|
||||||
|
const response = await getPeopleByIds(options)
|
||||||
|
return response.json()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
export const fetchPerson = createAsyncThunk(
|
export const fetchPerson = createAsyncThunk(
|
||||||
'people/fetchPerson',
|
'people/fetchPerson',
|
||||||
async (options, thunkAPI) => {
|
async (options, thunkAPI) => {
|
||||||
|
|
@ -135,6 +142,20 @@ export const peopleSlice = createSlice({
|
||||||
state.people.push(action.payload)
|
state.people.push(action.payload)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
.addCase(fetchPeopleByIds.pending, (state, action) => {
|
||||||
|
state.status = 'loading'
|
||||||
|
})
|
||||||
|
.addCase(fetchPeopleByIds.fulfilled, (state, action) => {
|
||||||
|
const records = new Set([...state.people, ...action.payload.musicians]);
|
||||||
|
const unique = [];
|
||||||
|
records.map(x => unique.filter(p => p.id === x.id).length > 0 ? null : unique.push(x))
|
||||||
|
state.people = unique
|
||||||
|
state.status = 'succeeded'
|
||||||
|
})
|
||||||
|
.addCase(fetchPeopleByIds.rejected, (state, action) => {
|
||||||
|
state.error = action.error.message
|
||||||
|
state.status = 'failed'
|
||||||
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ node :is_blank_filter do |foo|
|
||||||
end
|
end
|
||||||
|
|
||||||
child(:results => :musicians) {
|
child(:results => :musicians) {
|
||||||
attributes :id, :first_name, :last_name, :name, :city, :state, :country, :online, :musician, :photo_url, :biography, :regionname, :score, :full_score, :is_friend, :is_following, :pending_friend_request, :last_active_timestamp
|
attributes :id, :first_name, :last_name, :name, :city, :state, :country, :online, :musician, :photo_url, :biography, :regionname, :score, :full_score, :is_friend, :is_following, :pending_friend_request, :last_active_timestamp, :v2_photo_url, :v2_photo_uploaded
|
||||||
|
|
||||||
# node :is_friend do |musician|
|
# node :is_friend do |musician|
|
||||||
# @search.is_friend?(musician)
|
# @search.is_friend?(musician)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue