debug: SwipeableCalendar가 다음달을 로드하지 못하던 버그를 해결

This commit is contained in:
sechan100 2024-12-27 18:59:57 +09:00
parent 3c8c4a7126
commit d4600c66d8
6 changed files with 144 additions and 85 deletions

View file

@ -1,44 +0,0 @@
/** @jsxImportSource @emotion/react */
import { BaseCalendar, CalendarStyleOptions } from "@shared/components/BaseCalendar";
import { Day, DayFormat } from "@shared/period/day";
import { Month } from "@shared/period/month";
import { useCallback } from "react";
interface Props {
month: Month;
tile: (day: Day) => JSX.Element;
onTileClick: (day: Day) => void;
styleOptions?: CalendarStyleOptions;
}
export const CalendarSlide = ({
month,
tile,
onTileClick,
styleOptions
}: Props) => {
const tileDisabled = useCallback((day: Day) => {
return day.month !== month.monthNum;
}, [month]);
return (
<BaseCalendar
month={month}
setMonth={() => {}}
onTileClick={onTileClick}
tile={tile}
showNavigation={false}
tileDisabled={tileDisabled}
styleOptions={Object.assign({
tileContainer: {
gap: "0",
},
tile: {
border: "0.5px solid black",
borderRadius: "0",
}
}, styleOptions)}
/>
);
};

View file

@ -3,10 +3,6 @@ import { VirtualSwiper } from "@shared/components/VirtualSwiper";
import { Month } from "@shared/period/month";
import { useCallback, useState } from "react";
import { CalendarNavigation } from "./Nav";
import { CalendarSlide } from "./CalendarSlide";
import { useLeaf } from "@shared/view/use-leaf";
import { Day, DayFormat } from "@shared/period/day";
import { CalendarStyleOptions } from "../BaseCalendar";
@ -31,17 +27,13 @@ const getKey = (month: Month) => month.startDay.format()
interface Props {
month: Month;
onTileClick: (day: Day) => void;
tile: (day: Day) => JSX.Element;
children: (month: Month, index?: number) => React.ReactNode;
verticalHeight?: number;
stylesOption?: CalendarStyleOptions;
}
export const SwipeableCalendar = ({
month: propsMonth,
onTileClick,
tile,
children,
verticalHeight,
stylesOption
}: Props) => {
const [months, setMonths] = useState<Month[]>(loadMonths(propsMonth));
const [activeMonth, setActiveMonth] = useState<Month>(propsMonth);
@ -71,14 +63,7 @@ export const SwipeableCalendar = ({
onSlideChange={onSlideChange}
verticalHeight={verticalHeight}
>
{(month) => (
<CalendarSlide
month={month}
onTileClick={onTileClick}
tile={tile}
styleOptions={stylesOption}
/>
)}
{children}
</VirtualSwiper>
</div>
)

View file

@ -0,0 +1,69 @@
/** @jsxImportSource @emotion/react */
import { Task } from "@entities/note";
import { BaseCalendar } from "@shared/components/BaseCalendar";
import { Day } from "@shared/period/day";
import { Month } from "@shared/period/month";
import { useAsync } from "@shared/utils/use-async";
import { useCallback, useMemo } from "react";
import { CalendarTile } from "./CalendarTile";
import { loadCalendar } from "../model/load-calendar";
import { Tile } from "../model/types";
import { useTabRoute } from "@shared/tab/use-tab-route";
interface CalendarSlideProps {
month: Month;
}
export const CalendarSlide = ({ month }: CalendarSlideProps) => {
const calendarAsync = useAsync(async () => await loadCalendar(month), [month]);
const route = useTabRoute(s=>s.route);
const tiles = useMemo<Map<string, Tile>>(() => {
if(calendarAsync.value) {
return calendarAsync.value.tiles;
} else {
return new Map();
}
}, [calendarAsync.value]);
const tile = useCallback((day: Day) => {
let tile = {
day,
tasks: [] as Task[]
};
tile = tiles.get(day.format()) || tile;
return <CalendarTile tile={tile} />;
}, [tiles]);
const tileDisabled = useCallback((day: Day) => {
return day.month !== month.monthNum;
}, [month]);
const onTileClick = useCallback((day: Day) => {
route("note", { day });
}, [route]);
if (calendarAsync.loading) return <div>Loading...</div>;
return (
<BaseCalendar
month={month}
setMonth={() => {}}
onTileClick={onTileClick}
tile={tile}
showNavigation={false}
tileDisabled={tileDisabled}
styleOptions={{
tileContainer: {
gap: "0",
},
tile: {
border: "0.5px solid black",
borderRadius: "0",
}
}}
/>
);
};

View file

@ -1,6 +1,6 @@
/** @jsxImportSource @emotion/react */
import { Day } from "@shared/period/day";
import { Tile } from "../model/types"
import { Tile } from "../model/load-tile-map";
import { TEXT_CSS } from "@shared/components/text-style";
import { Task } from "@entities/note";
import { css } from "@emotion/react";

View file

@ -4,47 +4,34 @@ import { useCallback, useMemo, useState } from "react";
import { useLeaf } from "@shared/view/use-leaf";
import { SwipeableCalendar } from "@shared/components/swipeable-calender/SwipeableCalendar";
import { useAsync } from "@shared/utils/use-async";
import { loadCalendar } from "../model/load-calendar";
import { loadTileMap } from "../model/load-tile-map";
import { useTabRoute } from "@shared/tab/use-tab-route";
import { Day } from "@shared/period/day";
import { CalendarTile } from "./CalendarTile";
import { Task } from "@entities/note";
import { useTabHeight } from "@app/ui/use-tab-height";
import { TileHeightInfoProvider } from "./tile-height-info-context";
import { CalendarSlide } from "./CalendarSlide";
type Props = {
month: Month;
}
export const CalendarWidget = ({ month }: Props) => {
// const leafBgColor = useLeaf(s=>s.leafBgColor);
const calendarAsync = useAsync(async () => await loadCalendar(month), [month]);
const route = useTabRoute(s=>s.route);
const tabHeight = useTabHeight();
const renderTile = useCallback((day: Day) => {
let tile = {
day,
tasks: [] as Task[]
};
tile = calendarAsync.value?.tiles.get(day.format()) || tile;
return <CalendarTile tile={tile} />;
}, [calendarAsync.value?.tiles]);
const onTileClick = useCallback((day: Day) => {
route("note", { day });
}, [route]);
if(!calendarAsync.value || calendarAsync.loading) return <div>Loading...</div>;
return (
<TileHeightInfoProvider>
<SwipeableCalendar
month={month}
onTileClick={onTileClick}
tile={renderTile}
verticalHeight={tabHeight}
/>
>
{month => (
<CalendarSlide
month={month}
/>
)}
</SwipeableCalendar>
</TileHeightInfoProvider>
)

View file

@ -0,0 +1,62 @@
/** @jsxImportSource @emotion/react */
import { NoteEntity, noteRepository, Task } from "@entities/note";
import { BaseCalendar } from "@shared/components/BaseCalendar";
import { Day } from "@shared/period/day";
import { Month } from "@shared/period/month";
import { useAsync } from "@shared/utils/use-async";
import { useCallback, useMemo } from "react";
import { useTabRoute } from "@shared/tab/use-tab-route";
import { PerformanceCircle } from "@features/performance";
interface CalendarSlideProps {
month: Month;
}
export const CalendarSlide = ({ month }: CalendarSlideProps) => {
const notesAsync = useAsync(async () => await noteRepository.loadBetween(month.startDay, month.endDay), [month]);
const route = useTabRoute(s=>s.route);
const tile = useCallback((tileDay: Day) => {
let performance = NoteEntity.getEmptyNotePerformance();
if(notesAsync.value){
const note = notesAsync.value.find(note => note.day.isSameDay(tileDay));
if(note){
performance = NoteEntity.getPerformance(note);
}
}
return (
<PerformanceCircle performance={performance} text={tileDay.date.toString()} />
)
}, [notesAsync.value]);
const onTileClick = useCallback((day: Day) => {
route("note", { day });
}, [route]);
const tileDisabled = useCallback((day: Day) => {
return day.month !== month.monthNum;
}, [month]);
if(notesAsync.loading) return <div>Loading...</div>;
return (
<BaseCalendar
month={month}
setMonth={() => {}}
onTileClick={onTileClick}
tile={tile}
showNavigation={false}
tileDisabled={tileDisabled}
styleOptions={{
tileContainer: {
gap: "0",
},
tile: {
border: "0"
}
}}
/>
);
};