Handle includes in the front for the hisory
This commit is contained in:
@@ -51,6 +51,7 @@ export class HistoryService {
|
||||
orderBy: { playDate: 'desc' },
|
||||
skip,
|
||||
take,
|
||||
include: { song: true }
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -139,6 +139,8 @@ export default class API {
|
||||
}
|
||||
throw e;
|
||||
});
|
||||
if (!handler.transformer)
|
||||
return handler.validator.cast(validated);
|
||||
return handler.transformer(handler.validator.cast(validated));
|
||||
} catch (e) {
|
||||
if (e instanceof SyntaxError) throw new Error("Error while parsing Server's response");
|
||||
|
||||
@@ -25,10 +25,7 @@ const TabNavigationDesktop = (props: TabNavigationDesktopProps) => {
|
||||
? require('../../assets/icon_light.png')
|
||||
: require('../../assets/icon_dark.png')
|
||||
);
|
||||
const playHistoryQuery = useQuery(API.getUserPlayHistory);
|
||||
const songHistory = useQueries(
|
||||
playHistoryQuery.data?.map(({ songID }) => API.getSong(songID)) ?? []
|
||||
);
|
||||
const history = useQuery(API.getUserPlayHistory);
|
||||
// settings is displayed separately (with logout)
|
||||
const buttons = props.tabs.filter((tab) => tab.id !== 'settings');
|
||||
|
||||
@@ -110,7 +107,7 @@ const TabNavigationDesktop = (props: TabNavigationDesktopProps) => {
|
||||
>
|
||||
Recently played
|
||||
</Text>
|
||||
{songHistory.length === 0 && (
|
||||
{history.data?.length === 0 && (
|
||||
<Text
|
||||
style={{
|
||||
paddingHorizontal: 16,
|
||||
@@ -120,9 +117,8 @@ const TabNavigationDesktop = (props: TabNavigationDesktopProps) => {
|
||||
No songs played yet
|
||||
</Text>
|
||||
)}
|
||||
{songHistory
|
||||
.map((h) => h.data)
|
||||
.filter((data): data is Song => data !== undefined)
|
||||
{history.data
|
||||
?.map(x => x.song)
|
||||
.filter(
|
||||
(song, i, array) =>
|
||||
array.map((s) => s.id).findIndex((id) => id == song.id) == i
|
||||
|
||||
@@ -2,7 +2,7 @@ import * as yup from 'yup';
|
||||
|
||||
type ResponseHandler<APIType, ModelType = APIType> = {
|
||||
validator: yup.Schema<APIType>;
|
||||
transformer: (value: APIType) => ModelType;
|
||||
transformer?: (value: APIType) => ModelType;
|
||||
};
|
||||
|
||||
export default ResponseHandler;
|
||||
|
||||
@@ -1,23 +1,19 @@
|
||||
import * as yup from 'yup';
|
||||
import ResponseHandler from './ResponseHandler';
|
||||
import { SongValidator } from './Song';
|
||||
|
||||
export const SongHistoryItemValidator = yup.object({
|
||||
songID: yup.number().required(),
|
||||
song: SongValidator.required(),
|
||||
userID: yup.number().required(),
|
||||
score: yup.number().required(),
|
||||
playDate: yup.date().required(),
|
||||
difficulties: yup.mixed().required(),
|
||||
});
|
||||
export type SongHistoryItem = yup.InferType<typeof SongHistoryItemValidator>;
|
||||
|
||||
export const SongHistoryItemHandler: ResponseHandler<
|
||||
yup.InferType<typeof SongHistoryItemValidator>,
|
||||
SongHistoryItem
|
||||
> = {
|
||||
export const SongHistoryItemHandler: ResponseHandler<SongHistoryItem> = {
|
||||
validator: SongHistoryItemValidator,
|
||||
transformer: (value) => ({
|
||||
...value,
|
||||
difficulties: value.difficulties,
|
||||
}),
|
||||
};
|
||||
|
||||
export const SongHistoryValidator = yup.object({
|
||||
@@ -29,18 +25,6 @@ export type SongHistory = yup.InferType<typeof SongHistoryValidator>;
|
||||
|
||||
export const SongHistoryHandler: ResponseHandler<SongHistory> = {
|
||||
validator: SongHistoryValidator,
|
||||
transformer: (value) => ({
|
||||
...value,
|
||||
history: value.history.map((item) => SongHistoryItemHandler.transformer(item)),
|
||||
}),
|
||||
};
|
||||
|
||||
export type SongHistoryItem = {
|
||||
songID: number;
|
||||
userID: number;
|
||||
score: number;
|
||||
playDate: Date;
|
||||
difficulties: object;
|
||||
};
|
||||
|
||||
export default SongHistory;
|
||||
|
||||
Reference in New Issue
Block a user