fixes related to beta site profile edit and lobby page
This commit is contained in:
parent
4c161025e8
commit
8cf7048b7f
|
|
@ -1,16 +0,0 @@
|
|||
import React, {useEffect} from "react";
|
||||
import { useAuth } from '../../context/UserAuth';
|
||||
import avatar from "../../assets/img/team/avatar.png";
|
||||
|
||||
const JKCurrentUserAvatar = () => {
|
||||
const { currentUser } = useAuth();
|
||||
|
||||
if(currentUser && currentUser.photo_url) {
|
||||
return ( <img className="avatar avatar-xl rounded-circle mr-1" src={currentUser.photo_url} /> );
|
||||
}else {
|
||||
return ( <img className="avatar avatar-xl rounded-circle mr-1" src={avatar} /> );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default JKCurrentUserAvatar;
|
||||
|
|
@ -3,7 +3,7 @@ import { Card, CardBody, Col, Row, CardHeader, Form, FormGroup, Label, Input, Bu
|
|||
import Select from 'react-select';
|
||||
import FalconCardHeader from '../common/FalconCardHeader';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import JKCurrentUserAvatar from '../navbar/JKCurrentUserAvatar';
|
||||
import JKProfileAvatar from '../profile/JKProfileAvatar';
|
||||
import { useAuth } from '../../context/UserAuth';
|
||||
import { useForm, Controller } from 'react-hook-form';
|
||||
import {
|
||||
|
|
@ -15,7 +15,7 @@ import {
|
|||
getRegions,
|
||||
getCities
|
||||
} from '../../helpers/rest';
|
||||
import JKModalDialog from '../common/JKModalDialog';
|
||||
import JKProfileAvatarUpload from '../profile/JKProfileAvatarUpload';
|
||||
|
||||
function JKEditProfile() {
|
||||
const { t } = useTranslation('profile');
|
||||
|
|
@ -28,7 +28,8 @@ function JKEditProfile() {
|
|||
const [countries, setCountries] = useState([]);
|
||||
const [regions, setRegions] = useState([]);
|
||||
const [cities, setCities] = useState([]);
|
||||
const [showPhotoModal, setShowPhotoModal] = useState(false);
|
||||
const [showAvatarUpload, setShowAvatarUpload] = useState(false);
|
||||
//const [userData, setUserData] = useState({});
|
||||
|
||||
const [_, forceUpdate] = useReducer(x => x + 1, 0);
|
||||
|
||||
|
|
@ -64,6 +65,7 @@ function JKEditProfile() {
|
|||
setCurrentUserLoaded(true);
|
||||
fetchCurentUser().then(data => {
|
||||
console.log("userData", data)
|
||||
//setUserData(data);
|
||||
updateUserData(data);
|
||||
fetchInstruments();
|
||||
fetchGenres();
|
||||
|
|
@ -370,8 +372,8 @@ function JKEditProfile() {
|
|||
.catch(error => console.log(error));
|
||||
};
|
||||
|
||||
const togglePhotoModel = () => {
|
||||
setShowPhotoModal(!showPhotoModal);
|
||||
const toggleAvatarUpload = () => {
|
||||
setShowAvatarUpload(!showAvatarUpload);
|
||||
};
|
||||
|
||||
return (
|
||||
|
|
@ -427,14 +429,14 @@ function JKEditProfile() {
|
|||
<Col md={4}>
|
||||
<div className="d-flex align-items-center">
|
||||
<div>
|
||||
<JKCurrentUserAvatar size="sm" />
|
||||
<JKProfileAvatar src={currentUser.photo_url} size="s" />
|
||||
</div>
|
||||
<div>
|
||||
<a
|
||||
href="#"
|
||||
onClick={e => {
|
||||
e.preventDefault();
|
||||
togglePhotoModel();
|
||||
toggleAvatarUpload();
|
||||
}}
|
||||
>
|
||||
{t('change_photo')}
|
||||
|
|
@ -693,27 +695,7 @@ function JKEditProfile() {
|
|||
</Form>
|
||||
</CardBody>
|
||||
</Card>
|
||||
<JKModalDialog
|
||||
show={showPhotoModal}
|
||||
onToggle={togglePhotoModel}
|
||||
title={t('lobby.chat_notifications.title', { ns: 'sessions' })}
|
||||
showFooter={false}
|
||||
>
|
||||
<div className='d-flex flex-column'>
|
||||
<div className='d-flex justify-content-center'>
|
||||
<JKCurrentUserAvatar size="xl" />
|
||||
</div>
|
||||
|
||||
<div className="d-flex justify-content-center">
|
||||
<Button color="secondary" outline className="ml-2" onClick={() => {}}>
|
||||
{t('photo_modal.upload', { ns: 'profile' })}
|
||||
</Button>
|
||||
<Button color="secondary" outline className="ml-2" onClick={() => {}}>
|
||||
{t('photo_modal.delete', { ns: 'profile' })}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</JKModalDialog>
|
||||
<JKProfileAvatarUpload show={showAvatarUpload} toggle={toggleAvatarUpload} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import React, { useEffect, useLayoutEffect, useState } from 'react';
|
||||
import { Col, Row, Card, CardBody, Button, CardHeader, Nav, NavItem, NavLink, TabContent, TabPane } from 'reactstrap';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useResponsive } from '@farfetch/react-context-responsive';
|
||||
|
|
@ -18,6 +18,7 @@ import JKTooltip from '../common/JKTooltip';
|
|||
import { updateUser } from '../../helpers/rest';
|
||||
import { postUserAppInteraction } from '../../helpers/rest';
|
||||
import { useVisbilityState } from '../../hooks/useVisibilityState';
|
||||
import { useHistory } from 'react-router-dom'
|
||||
|
||||
function JKMusicSessionsLobby() {
|
||||
const INTERACTION_CLIENT = 'browser';
|
||||
|
|
@ -31,6 +32,7 @@ function JKMusicSessionsLobby() {
|
|||
const { currentUser } = useAuth();
|
||||
const isNativeAppAvailable = useNativeAppCheck();
|
||||
const { nativeAppUnavailable, setNativeAppUnavailable } = useNativeApp();
|
||||
const history = useHistory();
|
||||
|
||||
const onlineMusicians = useSelector(state => state.onlineMusician.musicians);
|
||||
const loadingStatus = useSelector(state => state.onlineMusician.status);
|
||||
|
|
@ -39,7 +41,10 @@ function JKMusicSessionsLobby() {
|
|||
const [submitted, setSubmitted] = useState(false);
|
||||
const [activeTab, setActiveTab] = useState('1');
|
||||
const [showNotificationsModal, setShowNotificationsModal] = useState(false);
|
||||
const NOTIFICATION_INTERVAL = 1000 * 10 //10 seconds
|
||||
|
||||
const NOTIFICATION_MODAL_INTERVAL = 1000 * 10 //10 seconds
|
||||
const MUSICIANS_FETCH_INTERVAL = 1000 * 20 //20 seconds
|
||||
const LIVENESS_UPDATE_INTERVAL = 1000 * 60 * 1 //1 minute
|
||||
|
||||
const documentVisibility = useVisbilityState();
|
||||
|
||||
|
|
@ -54,13 +59,21 @@ function JKMusicSessionsLobby() {
|
|||
} else {
|
||||
setTimeout(() => {
|
||||
setShowNotificationsModal(true);
|
||||
}, NOTIFICATION_INTERVAL);
|
||||
}, NOTIFICATION_MODAL_INTERVAL);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log('Error reading localStorage', error);
|
||||
}
|
||||
}, []);
|
||||
|
||||
//periodically fetch online musicians
|
||||
useEffect(() => {
|
||||
const interval = setInterval(() => {
|
||||
dispatch(fetchOnlineMusicians());
|
||||
}, MUSICIANS_FETCH_INTERVAL);
|
||||
return () => clearInterval(interval);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (loadingStatus === 'succeeded' && onlineMusicians.length > 0) {
|
||||
const userIds = onlineMusicians.map(p => p.id);
|
||||
|
|
@ -69,12 +82,39 @@ function JKMusicSessionsLobby() {
|
|||
}
|
||||
}, [loadingStatus]);
|
||||
|
||||
//update user liveness when user switches tabs
|
||||
useEffect(() => {
|
||||
if(currentUser){
|
||||
postInteraction(documentVisibility);
|
||||
}
|
||||
}, [documentVisibility]);
|
||||
|
||||
//update user liveness when user leaves the page
|
||||
useEffect(() => {
|
||||
const unlisten = history.listen(() => {
|
||||
console.log('User is leaving the page');
|
||||
// Do something before the user leaves the page
|
||||
postInteraction('hidden');
|
||||
});
|
||||
|
||||
return () => {
|
||||
console.log('Component is unmounting');
|
||||
unlisten();
|
||||
// Do something before the component unmounts
|
||||
};
|
||||
}, [history]);
|
||||
|
||||
//periodically update user liveness
|
||||
useEffect(() => {
|
||||
const interval = setInterval(() => {
|
||||
if(documentVisibility === 'visible'){
|
||||
postInteraction('visible');
|
||||
}
|
||||
}, LIVENESS_UPDATE_INTERVAL);
|
||||
return () => clearInterval(interval);
|
||||
}, [])
|
||||
|
||||
|
||||
const postInteraction = visibilityState => {
|
||||
|
||||
const options = {
|
||||
|
|
@ -208,7 +248,6 @@ function JKMusicSessionsLobby() {
|
|||
<Col>
|
||||
<div className="table-responsive-xl px-2">
|
||||
<JKLobbyUserList
|
||||
loadingStatus={loadingStatus}
|
||||
onlineMusicians={onlineMusicians}
|
||||
setSelectedUsers={setSelectedUsers}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,58 @@
|
|||
import React, { useEffect } from 'react'
|
||||
import * as filestack from 'filestack-js';
|
||||
import { Button } from 'reactstrap';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import JKModalDialog from '../common/JKModalDialog';
|
||||
import JKProfileAvatar from './JKProfileAvatar';
|
||||
import { useAuth } from '../../context/UserAuth';
|
||||
import { getUserDetails } from '../../helpers/rest';
|
||||
|
||||
const JKProfileAvatarUpload = ({show, toggle}) => {
|
||||
const { t } = useTranslation('profile');
|
||||
const { currentUser } = useAuth();
|
||||
|
||||
useEffect(() => {
|
||||
if(currentUser) {
|
||||
console.log(currentUser.photo_url);
|
||||
getUserDetails(currentUser.id).then(response => {
|
||||
console.log('_userDetails', response);
|
||||
});
|
||||
}
|
||||
}, [currentUser]);
|
||||
|
||||
const openFilePicker = () => {
|
||||
const client = filestack.init(window.gon.fp_apikey);
|
||||
client.picker({
|
||||
accept: 'image/*',
|
||||
maxFiles: 1,
|
||||
onFileUploadFinished: (response) => {
|
||||
console.log(response);
|
||||
}
|
||||
}).open();
|
||||
}
|
||||
return (
|
||||
<JKModalDialog
|
||||
show={show}
|
||||
onToggle={toggle}
|
||||
title={t('lobby.chat_notifications.title', { ns: 'sessions' })}
|
||||
showFooter={true}
|
||||
>
|
||||
<div className='d-flex flex-column'>
|
||||
<div className='d-flex justify-content-center'>
|
||||
<JKProfileAvatar src={currentUser.photo_url} size="5xl" />
|
||||
</div>
|
||||
|
||||
<div className="d-flex justify-content-center">
|
||||
<Button color="secondary" outline className="ml-2" onClick={openFilePicker}>
|
||||
{t('photo_modal.upload', { ns: 'profile' })}
|
||||
</Button>
|
||||
<Button color="secondary" outline className="ml-2" onClick={() => {}}>
|
||||
{t('photo_modal.delete', { ns: 'profile' })}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</JKModalDialog>
|
||||
)
|
||||
}
|
||||
|
||||
export default JKProfileAvatarUpload
|
||||
|
|
@ -3,38 +3,35 @@ import { Table } from 'reactstrap';
|
|||
import { useTranslation } from 'react-i18next';
|
||||
import JKLobbyUser from './JKLobbyUser';
|
||||
import { isIterableArray } from '../../helpers/utils';
|
||||
import Loader from '../common/Loader';
|
||||
|
||||
function JKLobbyUserList({ loadingStatus, onlineMusicians, selectedUsers, setSelectedUsers }) {
|
||||
function JKLobbyUserList({ onlineMusicians, selectedUsers, setSelectedUsers }) {
|
||||
const { t } = useTranslation('sessions');
|
||||
|
||||
return (
|
||||
<>
|
||||
{loadingStatus === 'loading' && onlineMusicians.length === 0 ? (
|
||||
<Loader />
|
||||
) : (
|
||||
<Table striped bordered className="fs--1" data-testid="sessionsLobbyUsersTable">
|
||||
<thead className="bg-200 text-900">
|
||||
<Table striped bordered className="fs--1" data-testid="sessionsLobbyUsersTable">
|
||||
<thead className="bg-200 text-900">
|
||||
<tr>
|
||||
<th width="75%" scope="col">
|
||||
{t('lobby.users.header.musician', { ns: 'sessions' })}
|
||||
</th>
|
||||
<th scope="col" className="text-center">
|
||||
{t('lobby.users.header.actions', { ns: 'sessions' })}
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="list">
|
||||
{isIterableArray(onlineMusicians) ? (
|
||||
onlineMusicians.map(musician => (
|
||||
<JKLobbyUser key={musician.id} user={musician} setSelectedUsers={setSelectedUsers} />
|
||||
))
|
||||
) : (
|
||||
<tr>
|
||||
<th width="75%" scope="col">
|
||||
{t('lobby.users.header.musician', { ns: 'sessions' })}
|
||||
</th>
|
||||
<th scope="col" className="text-center">
|
||||
{t('lobby.users.header.actions', { ns: 'sessions' })}
|
||||
</th>
|
||||
<td colSpan={2}>{t('lobby.users.not_found')}</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="list">
|
||||
{isIterableArray(onlineMusicians) ? (
|
||||
onlineMusicians.map(musician => <JKLobbyUser key={musician.id} user={musician} setSelectedUsers={setSelectedUsers} />)
|
||||
) : (
|
||||
<tr>
|
||||
<td colSpan={2}>{t('lobby.users.not_found')}</td>
|
||||
</tr>
|
||||
)}
|
||||
</tbody>
|
||||
</Table>
|
||||
)}
|
||||
)}
|
||||
</tbody>
|
||||
</Table>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,15 @@ export const getPersonById = id => {
|
|||
);
|
||||
};
|
||||
|
||||
export const getUserDetails = options => {
|
||||
const { id, ...rest } = options;
|
||||
return new Promise((resolve, reject) =>
|
||||
apiFetch(`/users/${id}?${new URLSearchParams(rest)}`)
|
||||
.then(response => resolve(response))
|
||||
.catch(error => reject(error))
|
||||
);
|
||||
}
|
||||
|
||||
export const getPeople = ({ data, offset, limit } = {}) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
apiFetch(`/filter?offset=${offset}&limit=${limit}`, {
|
||||
|
|
|
|||
|
|
@ -36,6 +36,12 @@ export const onlineMusiciansSlice = createSlice({
|
|||
console.log('fetchOnlineMusicians.fulfilled', action.payload)
|
||||
state.status = 'succeeded'
|
||||
state.musicians = action.payload
|
||||
// if (action.payload && action.payload.length > 0) {
|
||||
// const difference = state.musicians.filter((element) => !action.payload.includes(element));
|
||||
// if (difference.length > 0) {
|
||||
// state.musicians = action.payload
|
||||
// }
|
||||
// }
|
||||
})
|
||||
.addCase(fetchOnlineMusicians.rejected, (state, action) => {
|
||||
state.status = 'failed'
|
||||
|
|
|
|||
|
|
@ -317,18 +317,22 @@ module JamRuby
|
|||
#the users that have opened the lobby page but now in a different tab or window or
|
||||
#the users that have been active in the last 15 minutes
|
||||
query = User.joins(:app_interactions).where("
|
||||
(app_interactions.client = 'browser' AND app_interactions.action_at > ? AND app_interactions.screen = 'lobby' AND app_interactions.action = 'page:enter' AND app_interactions.user_id <> ?)
|
||||
OR (app_interactions.client = 'browser' AND app_interactions.action_at > ? AND app_interactions.screen = 'lobby' AND app_interactions.action = 'page:exit' AND app_interactions.user_id = ? AND users.accept_desktop_notifications = ?)
|
||||
OR (users.last_jam_updated_at IS NOT NULL AND users.last_jam_updated_at > ? AND users.id <> ?)",
|
||||
10.minutes.ago,
|
||||
(app_interactions.client = 'browser' AND app_interactions.action_at > ? AND app_interactions.screen = 'session:lobby' AND app_interactions.action = 'page:enter' AND app_interactions.user_id <> ?)
|
||||
OR (app_interactions.client = 'browser' AND app_interactions.action_at > ? AND app_interactions.screen = 'session:lobby' AND app_interactions.action = 'page:exit' AND app_interactions.user_id <> ? AND users.accept_desktop_notifications = ?)
|
||||
OR (users.last_jam_updated_at IS NOT NULL AND users.last_jam_updated_at > ? AND users.id <> ? AND users.accept_desktop_notifications = ?)
|
||||
",
|
||||
5.minutes.ago,
|
||||
current_user.id,
|
||||
10.minutes.ago,
|
||||
5.minutes.ago,
|
||||
current_user.id,
|
||||
true,
|
||||
10.minutes.ago,
|
||||
current_user.id
|
||||
5.minutes.ago,
|
||||
current_user.id,
|
||||
true
|
||||
)
|
||||
|
||||
#
|
||||
|
||||
#the users that are currently not in a music session
|
||||
live_music_sessions = ActiveMusicSession
|
||||
if live_music_sessions.count > 0
|
||||
|
|
|
|||
Loading…
Reference in New Issue