friends page state
use a separate redux slice for friends page add musician slice to prevent mess up with the other user objects fetched globally. people redux slice would serve as global store having user records that can be referenced elsewhere
This commit is contained in:
parent
eea46feb5d
commit
77359f7fc2
|
|
@ -99,6 +99,10 @@ describe('Friends page with data', () => {
|
|||
cy.intercept('POST', /\S+\/filter\?offset=10/, { fixture: 'people_page2' }).as('getPeople_page2');
|
||||
cy.intercept('POST', /\S+\/filter\?offset=20/, { fixture: 'people_page3' }).as('getPeople_page3');
|
||||
cy.intercept('GET', /\S+\/profile/, { fixture: 'person' });
|
||||
cy.intercept('GET', /\S+\/my_notifications\S+/, {
|
||||
statusCode: 200,
|
||||
body: []
|
||||
});
|
||||
});
|
||||
|
||||
describe('listing users', () => {
|
||||
|
|
@ -116,7 +120,6 @@ describe('Friends page with data', () => {
|
|||
cy.wait('@getPeople_page2')
|
||||
cy.get('[data-testid=paginate-next-page]').click();
|
||||
cy.get('[data-testid=peopleListTable] > tbody tr').should('have.length', 20);
|
||||
//cy.get('[data-testid=paginate-next-page]').should('not.exist');
|
||||
cy.get('[data-testid=paginate-next-page]').click();
|
||||
cy.get('[data-testid=peopleListTable] > tbody tr').should('have.length', 30);
|
||||
cy.get('[data-testid=paginate-next-page]').should('not.exist');
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import JKPeopleSwiper from './JKPeopleSwiper';
|
|||
import { getGenres, getInstruments } from '../../helpers/rest';
|
||||
import { useForm, Controller, useFormState } from 'react-hook-form';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { fetchPeople, resetState, loadPrefetched, preFetchPeople } from '../../store/features/peopleSlice';
|
||||
import { fetchPeople, resetState, loadPrefetched, preFetchPeople } from '../../store/features/musiciansSlice';
|
||||
|
||||
function JKPeopleFilter() {
|
||||
const { t } = useTranslation();
|
||||
|
|
@ -35,11 +35,10 @@ function JKPeopleFilter() {
|
|||
|
||||
const peopleListRef = useRef();
|
||||
|
||||
const people = useSelector(state => state.people.people);
|
||||
//const hasOffset = useSelector(state => state.people.hasOffset);
|
||||
const offset = useSelector(state => state.people.offset);
|
||||
const loadingStatus = useSelector(state => state.people.status);
|
||||
const prefetched = useSelector(state => state.people.prefetched)
|
||||
const people = useSelector(state => state.musician.people);
|
||||
const offset = useSelector(state => state.musician.offset);
|
||||
const loadingStatus = useSelector(state => state.musician.status);
|
||||
const prefetched = useSelector(state => state.musician.prefetched)
|
||||
|
||||
const { register, handleSubmit, setValue, getValues, control } = useForm({
|
||||
defaultValues: {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,166 @@
|
|||
import { createSlice, createAsyncThunk } from "@reduxjs/toolkit"
|
||||
import { getPeople, getPeopleByIds, getPersonById, acceptFriendRequest as accept } from '../../helpers/rest';
|
||||
|
||||
const initialState = {
|
||||
people: [],
|
||||
prefetched: [],
|
||||
status: 'idel',
|
||||
error: null,
|
||||
hasOffset: false,
|
||||
offset: 0
|
||||
}
|
||||
|
||||
export const fetchPeople = createAsyncThunk(
|
||||
'musician/fetchPeople',
|
||||
async (options, thunkAPI) => {
|
||||
const response = await getPeople(options)
|
||||
return response.json()
|
||||
}
|
||||
)
|
||||
|
||||
export const preFetchPeople = createAsyncThunk(
|
||||
'musician/preFetchPeople',
|
||||
async (options, thunkAPI) => {
|
||||
const response = await getPeople(options)
|
||||
return response.json()
|
||||
}
|
||||
)
|
||||
|
||||
export const fetchPeopleByIds = createAsyncThunk(
|
||||
'musician/fetchPeopleByIds',
|
||||
async (options, thunkAPI) => {
|
||||
const response = await getPeopleByIds(options)
|
||||
return response.json()
|
||||
}
|
||||
)
|
||||
|
||||
export const fetchPerson = createAsyncThunk(
|
||||
'musician/fetchPerson',
|
||||
async (options, thunkAPI) => {
|
||||
const {userId} = options
|
||||
const response = await getPersonById(userId)
|
||||
return response.json()
|
||||
}
|
||||
,{
|
||||
condition: (options, {getState, extra}) => {
|
||||
const {people} = getState()
|
||||
const {userId} = options
|
||||
const person = people.people.find(person => person.id === userId)
|
||||
if(person && person.website){
|
||||
//only proceed if full data set for user has not been fetched. person.website is not included in the initial data fetching (i.e: in friends listing ).
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
export const acceptFriendRequest = createAsyncThunk(
|
||||
'musician/acceptFriendRequest',
|
||||
async(options) => {
|
||||
const { userId, ...rest } = options
|
||||
const response = await accept(userId, rest)
|
||||
return response.json()
|
||||
}
|
||||
)
|
||||
|
||||
export const musicianSlice = createSlice({
|
||||
name: 'musician',
|
||||
initialState,
|
||||
reducers: {
|
||||
add: (state, action) => {
|
||||
state.people.push(action.payload)
|
||||
},
|
||||
resetState: (state) => {
|
||||
return { ...initialState }
|
||||
},
|
||||
loadPrefetched: (state, action) => {
|
||||
if(state.prefetched.length > 0){
|
||||
const records = [...state.people, ...state.prefetched];
|
||||
state.people = records;
|
||||
}
|
||||
state.prefetched = []
|
||||
}
|
||||
},
|
||||
extraReducers: (builder) => {
|
||||
builder
|
||||
.addCase(fetchPeople.pending, (state, action) => {
|
||||
state.status = 'loading'
|
||||
})
|
||||
.addCase(fetchPeople.fulfilled, (state, action) => {
|
||||
// const records = [...state.people, ...action.payload.musicians];
|
||||
// state.people = records
|
||||
// state.hasOffset = !!action.payload.offset
|
||||
// state.offset = action.payload.offset
|
||||
// state.status = 'succeeded'
|
||||
//---
|
||||
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.hasOffset = !!action.payload.offset
|
||||
state.offset = action.payload.offset
|
||||
state.status = 'succeeded'
|
||||
})
|
||||
.addCase(fetchPeople.rejected, (state, action) => {
|
||||
state.status = 'failed'
|
||||
state.error = action.error.message
|
||||
})
|
||||
.addCase(preFetchPeople.pending, (state, action) => {
|
||||
state.status = 'loading'
|
||||
})
|
||||
.addCase(preFetchPeople.fulfilled, (state, action) => {
|
||||
// const records = [...state.prefetched, ...action.payload.musicians];
|
||||
// state.prefetched = records
|
||||
// state.hasOffset = !!action.payload.offset
|
||||
// state.offset = action.payload.offset
|
||||
// state.status = 'succeeded'
|
||||
//---
|
||||
const records = new Set([...state.prefetched, ...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.hasOffset = !!action.payload.offset
|
||||
state.offset = action.payload.offset
|
||||
state.status = 'succeeded'
|
||||
})
|
||||
.addCase(preFetchPeople.rejected, (state, action) => {
|
||||
state.error = action.error.message
|
||||
state.status = 'failed'
|
||||
})
|
||||
.addCase(acceptFriendRequest.fulfilled, (state, action) => {
|
||||
})
|
||||
.addCase(fetchPerson.fulfilled, (state, action) => {
|
||||
const person = state.people.find(person => person.id === action.payload.id)
|
||||
if(person){
|
||||
const updated = {
|
||||
...person,
|
||||
...action.payload
|
||||
}
|
||||
const objIndex = state.people.findIndex((p => p.id === updated.id));
|
||||
state.people[objIndex] = updated
|
||||
}else{
|
||||
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'
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
export const selectPersonById = (state, userId) => state.people.find((person) => person.id === userId)
|
||||
|
||||
export const { add, resetState, loadPrefetched } = musicianSlice.actions;
|
||||
|
||||
export default musicianSlice.reducer;
|
||||
|
|
@ -1,30 +1,31 @@
|
|||
import { createSlice, createAsyncThunk } from "@reduxjs/toolkit"
|
||||
import { getPeople, getPeopleByIds, getPersonById, acceptFriendRequest as accept } from '../../helpers/rest';
|
||||
//import { getPeople, getPeopleByIds, getPersonById, acceptFriendRequest as accept } from '../../helpers/rest';
|
||||
import { getPeopleByIds, getPersonById, acceptFriendRequest as accept } from '../../helpers/rest';
|
||||
|
||||
const initialState = {
|
||||
people: [],
|
||||
prefetched: [],
|
||||
//prefetched: [],
|
||||
status: 'idel',
|
||||
error: null,
|
||||
hasOffset: false,
|
||||
offset: 0
|
||||
}
|
||||
|
||||
export const fetchPeople = createAsyncThunk(
|
||||
'people/fetchPeople',
|
||||
async (options, thunkAPI) => {
|
||||
const response = await getPeople(options)
|
||||
return response.json()
|
||||
}
|
||||
)
|
||||
// export const fetchPeople = createAsyncThunk(
|
||||
// 'people/fetchPeople',
|
||||
// async (options, thunkAPI) => {
|
||||
// const response = await getPeople(options)
|
||||
// return response.json()
|
||||
// }
|
||||
// )
|
||||
|
||||
export const preFetchPeople = createAsyncThunk(
|
||||
'people/preFetchPeople',
|
||||
async (options, thunkAPI) => {
|
||||
const response = await getPeople(options)
|
||||
return response.json()
|
||||
}
|
||||
)
|
||||
// export const preFetchPeople = createAsyncThunk(
|
||||
// 'people/preFetchPeople',
|
||||
// async (options, thunkAPI) => {
|
||||
// const response = await getPeople(options)
|
||||
// return response.json()
|
||||
// }
|
||||
// )
|
||||
|
||||
export const fetchPeopleByIds = createAsyncThunk(
|
||||
'people/fetchPeopleByIds',
|
||||
|
|
@ -73,60 +74,60 @@ export const peopleSlice = createSlice({
|
|||
resetState: (state) => {
|
||||
return { ...initialState }
|
||||
},
|
||||
loadPrefetched: (state, action) => {
|
||||
if(state.prefetched.length > 0){
|
||||
const records = [...state.people, ...state.prefetched];
|
||||
state.people = records;
|
||||
}
|
||||
state.prefetched = []
|
||||
}
|
||||
// loadPrefetched: (state, action) => {
|
||||
// if(state.prefetched.length > 0){
|
||||
// const records = [...state.people, ...state.prefetched];
|
||||
// state.people = records;
|
||||
// }
|
||||
// state.prefetched = []
|
||||
// }
|
||||
},
|
||||
extraReducers: (builder) => {
|
||||
builder
|
||||
.addCase(fetchPeople.pending, (state, action) => {
|
||||
state.status = 'loading'
|
||||
})
|
||||
.addCase(fetchPeople.fulfilled, (state, action) => {
|
||||
// const records = [...state.people, ...action.payload.musicians];
|
||||
// state.people = records
|
||||
// state.hasOffset = !!action.payload.offset
|
||||
// state.offset = action.payload.offset
|
||||
// state.status = 'succeeded'
|
||||
//---
|
||||
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.hasOffset = !!action.payload.offset
|
||||
state.offset = action.payload.offset
|
||||
state.status = 'succeeded'
|
||||
})
|
||||
.addCase(fetchPeople.rejected, (state, action) => {
|
||||
state.status = 'failed'
|
||||
state.error = action.error.message
|
||||
})
|
||||
.addCase(preFetchPeople.pending, (state, action) => {
|
||||
state.status = 'loading'
|
||||
})
|
||||
.addCase(preFetchPeople.fulfilled, (state, action) => {
|
||||
// const records = [...state.prefetched, ...action.payload.musicians];
|
||||
// state.prefetched = records
|
||||
// state.hasOffset = !!action.payload.offset
|
||||
// state.offset = action.payload.offset
|
||||
// state.status = 'succeeded'
|
||||
//---
|
||||
const records = new Set([...state.prefetched, ...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.hasOffset = !!action.payload.offset
|
||||
state.offset = action.payload.offset
|
||||
state.status = 'succeeded'
|
||||
})
|
||||
.addCase(preFetchPeople.rejected, (state, action) => {
|
||||
state.error = action.error.message
|
||||
state.status = 'failed'
|
||||
})
|
||||
// .addCase(fetchPeople.pending, (state, action) => {
|
||||
// state.status = 'loading'
|
||||
// })
|
||||
// .addCase(fetchPeople.fulfilled, (state, action) => {
|
||||
// // const records = [...state.people, ...action.payload.musicians];
|
||||
// // state.people = records
|
||||
// // state.hasOffset = !!action.payload.offset
|
||||
// // state.offset = action.payload.offset
|
||||
// // state.status = 'succeeded'
|
||||
// //---
|
||||
// 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.hasOffset = !!action.payload.offset
|
||||
// state.offset = action.payload.offset
|
||||
// state.status = 'succeeded'
|
||||
// })
|
||||
// .addCase(fetchPeople.rejected, (state, action) => {
|
||||
// state.status = 'failed'
|
||||
// state.error = action.error.message
|
||||
// })
|
||||
// .addCase(preFetchPeople.pending, (state, action) => {
|
||||
// state.status = 'loading'
|
||||
// })
|
||||
// .addCase(preFetchPeople.fulfilled, (state, action) => {
|
||||
// // const records = [...state.prefetched, ...action.payload.musicians];
|
||||
// // state.prefetched = records
|
||||
// // state.hasOffset = !!action.payload.offset
|
||||
// // state.offset = action.payload.offset
|
||||
// // state.status = 'succeeded'
|
||||
// //---
|
||||
// const records = new Set([...state.prefetched, ...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.hasOffset = !!action.payload.offset
|
||||
// state.offset = action.payload.offset
|
||||
// state.status = 'succeeded'
|
||||
// })
|
||||
// .addCase(preFetchPeople.rejected, (state, action) => {
|
||||
// state.error = action.error.message
|
||||
// state.status = 'failed'
|
||||
// })
|
||||
.addCase(acceptFriendRequest.fulfilled, (state, action) => {
|
||||
})
|
||||
.addCase(fetchPerson.fulfilled, (state, action) => {
|
||||
|
|
@ -161,6 +162,6 @@ export const peopleSlice = createSlice({
|
|||
|
||||
export const selectPersonById = (state, userId) => state.people.find((person) => person.id === userId)
|
||||
|
||||
export const { add, resetState, loadPrefetched } = peopleSlice.actions;
|
||||
export const { add, resetState } = peopleSlice.actions;
|
||||
|
||||
export default peopleSlice.reducer;
|
||||
|
|
@ -2,6 +2,7 @@ import { configureStore } from "@reduxjs/toolkit"
|
|||
import textMessageReducer from "./features/textMessagesSlice"
|
||||
import lobbyChatMessagesReducer from "./features/lobbyChatMessagesSlice"
|
||||
import peopleReducer from "./features/peopleSlice"
|
||||
import MusicianReducer from "./features/musiciansSlice"
|
||||
import onlineMusicianReducer from "./features/onlineMusiciansSlice"
|
||||
import sessionReducer from "./features/sessionsSlice"
|
||||
import notificationReducer from './features/notificationSlice'
|
||||
|
|
@ -15,6 +16,7 @@ export default configureStore({
|
|||
reducer: {
|
||||
textMessage: textMessageReducer,
|
||||
people: peopleReducer,
|
||||
musician: MusicianReducer,
|
||||
notification: notificationReducer,
|
||||
session: sessionReducer, // this is the slice that holds the currently active sessions
|
||||
latency: latencyReducer,
|
||||
|
|
|
|||
Loading…
Reference in New Issue