Skip to content

Commit

Permalink
Merge branch 'main' into fix-simulator-context
Browse files Browse the repository at this point in the history
  • Loading branch information
imamiya-masaki committed Dec 5, 2024
2 parents 229f38d + eac5d9f commit ea4ce4c
Show file tree
Hide file tree
Showing 18 changed files with 177 additions and 122 deletions.
11 changes: 10 additions & 1 deletion bench/benchmarker/world/owner.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package world
import (
"fmt"
"log/slog"
"math"
"math/rand/v2"
"sync/atomic"
"time"
Expand Down Expand Up @@ -102,7 +103,7 @@ func (p *Owner) Tick(ctx *Context) error {
if err := p.ValidateSales(last.ServerCompletedAt, res); err != nil {
return WrapCodeError(ErrorCodeSalesMismatched, err)
}
if increase := res.Total/15000 - p.createChairTryCount; increase > 0 {
if increase := desiredChairNum(res.Total) - p.createChairTryCount; increase > 0 {
ctx.ContestantLogger().Info("一定の売上が立ったためオーナーの椅子が増加します", slog.Int("id", int(p.ID)), slog.Int("increase", increase))
for range increase {
p.createChairTryCount++
Expand Down Expand Up @@ -233,3 +234,11 @@ func (p *Owner) ValidateChairs(serverSide *GetOwnerChairsResponse) error {
}
return nil
}

func desiredChairNum(s int) int {
const (
a = 15000
r = 1.02
)
return int(math.Log((a-float64(s)*(1-r))/a) / math.Log(r))
}
14 changes: 14 additions & 0 deletions bench/benchmarker/world/owner_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package world

import "testing"

func TestDesiredChairNum(t *testing.T) {
n := 0
for i := 0; i < 10000; i++ {
num := desiredChairNum(i * 100)
if num > n {
n = num
t.Logf("num: %d (original: %d), sales: %d", num, i*100/15000, i*100)
}
}
}
4 changes: 3 additions & 1 deletion frontend/app/components/icon/chair.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,9 @@ export const ChairIcon: FC<{ model: string } & ComponentProps<"svg">> = ({
...props
}) => {
const chairType = useMemo(() => {
return ChairTypes[model ? model.charCodeAt(0) % ChairTypes.length : 0];
return ChairTypes[
model ? (model.charCodeAt(0) + model.length) % ChairTypes.length : 0
];
}, [model]);
return <Chair chairType={chairType} {...props} />;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ const StatusList = {
PICKUP: ["乗車待ち", colors.amber["500"]],
CARRYING: ["賃走", colors.red["500"]],
ARRIVED: ["到着", colors.emerald["500"]],
COMPLETED: ["完了", colors.emerald["500"]],
} as const;
COMPLETED: ["空車", colors.sky["500"]],
} as const satisfies Record<RideStatus, [string, string]>;

export const SimulatorChairRideStatus: FC<
ComponentProps<"div"> & {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,37 +99,37 @@ const ChairProgress: FC<{
return rideStatus !== undefined ? getSimulatorStartCoordinate() : null;
}, [rideStatus]);

const pickupProgress: number = useMemo(() => {
const progressToPickup: number = useMemo(() => {
if (!rideStatus || !pickupLoc || !startLoc || !currentLoc) {
return 0;
}
switch (rideStatus) {
case "MATCHING":
case "COMPLETED":
return 0;
case "PICKUP":
case "ARRIVED":
case "CARRYING":
case "COMPLETED":
return 100;
default:
return progress(startLoc, currentLoc, pickupLoc);
}
}, [rideStatus, pickupLoc, startLoc, currentLoc]);

const distanceProgress: number = useMemo(() => {
const progressToDestination: number = useMemo(() => {
if (!rideStatus || !destLoc || !pickupLoc || !currentLoc) {
return 0;
}
switch (rideStatus) {
case "MATCHING":
case "COMPLETED":
case "PICKUP":
case "ENROUTE":
return 0;
case "ARRIVED":
case "COMPLETED":
return 100;
default:
return progress(destLoc, currentLoc, pickupLoc);
return progress(pickupLoc, currentLoc, destLoc);
}
}, [rideStatus, destLoc, pickupLoc, currentLoc]);

Expand All @@ -140,30 +140,29 @@ const ChairProgress: FC<{
<PinIcon color={colors.red[500]} width={20} />
<div className="relative w-full ms-6">
{rideStatus &&
["PICKUP", "CARRYING", "ARRIVED", "COMPLETED"].includes(
rideStatus,
) && (
["PICKUP", "CARRYING", "ARRIVED"].includes(rideStatus) && (
<ChairIcon
model={model}
className={`size-6 absolute top-[-2px] ${rideStatus === "CARRYING" ? "animate-shake" : ""}`}
style={{ right: `${distanceProgress}%` }}
style={{ right: `${progressToDestination}%` }}
/>
)}
</div>
</div>
<div className="flex w-1/2">
<PinIcon color={colors.black} width={20} />
<div className="relative w-full ms-6">
{rideStatus && ["MATCHING", "ENROUTE"].includes(rideStatus) && (
<ChairIcon
model={model}
className={twMerge(
"size-6 absolute top-[-2px]",
rideStatus === "ENROUTE" && "animate-shake",
)}
style={{ right: `${pickupProgress}%` }}
/>
)}
{rideStatus &&
["MATCHING", "COMPLETED", "ENROUTE"].includes(rideStatus) && (
<ChairIcon
model={model}
className={twMerge(
"size-6 absolute top-[-2px]",
rideStatus === "ENROUTE" && "animate-shake",
)}
style={{ right: `${progressToPickup}%` }}
/>
)}
</div>
</div>
</div>
Expand Down
8 changes: 3 additions & 5 deletions frontend/app/contexts/client-context.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
} from "~/api/api-components";
import { isClientApiError } from "~/types";
import { getCookieValue } from "~/utils/get-cookie-value";
import { getUserAccessToken, getUserId } from "~/utils/storage";
import { getUserId } from "~/utils/storage";

function jsonFromSSEResponse<T>(value: string) {
const data = value.slice("data:".length).trim();
Expand Down Expand Up @@ -140,13 +140,11 @@ export const useNotification = ():
type ClientContextProps = {
data?: AppGetNotificationResponse["data"];
userId?: string | null;
accessToken?: string | null;
};

const ClientContext = createContext<ClientContextProps>({});

export const UserProvider = ({ children }: { children: ReactNode }) => {
const [accessToken] = useState(() => getUserAccessToken());
export const ClientProvider = ({ children }: { children: ReactNode }) => {
const [userId] = useState(() => getUserId());
const navigate = useNavigate();
const data = useNotification();
Expand All @@ -160,7 +158,7 @@ export const UserProvider = ({ children }: { children: ReactNode }) => {
}, [navigate]);

return (
<ClientContext.Provider value={{ data, userId, accessToken }}>
<ClientContext.Provider value={{ data, userId }}>
{children}
</ClientContext.Provider>
);
Expand Down
39 changes: 36 additions & 3 deletions frontend/app/contexts/simulator-context.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@ import {
createContext,
useContext,
useEffect,
useMemo,
useState,
} from "react";
import type { Coordinate } from "~/api/api-schemas";
import { getSimulateChair } from "~/utils/get-initial-data";
import {
getSimulateChair,
getSimulateChairFromToken,
} from "~/utils/get-initial-data";

import { apiBaseURL } from "~/api/api-base-url";
import {
Expand All @@ -15,11 +19,13 @@ import {
} from "~/api/api-components";
import { SimulatorChair } from "~/types";
import { getSimulatorCurrentCoordinate } from "~/utils/storage";
import { getCookieValue } from "~/utils/get-cookie-value";

type SimulatorContextProps = {
chair?: SimulatorChair;
data?: ChairGetNotificationResponse["data"];
setCoordinate?: (coordinate: Coordinate) => void;
setToken?: (token: string) => void;
};

const SimulatorContext = createContext<SimulatorContextProps>({});
Expand All @@ -29,8 +35,6 @@ function jsonFromSseResult<T>(value: string) {
return JSON.parse(data) as T;
}

const simulateChair = getSimulateChair();

const useNotification = (): ChairGetNotificationResponse["data"] => {
const [isSse, setIsSse] = useState(false);
const [notification, setNotification] =
Expand Down Expand Up @@ -61,6 +65,9 @@ const useNotification = (): ChairGetNotificationResponse["data"] => {
| undefined;
setNotification(json);
} catch (error) {
if (error instanceof DOMException && error.name === "AbortError") {
return;
}
console.error(error);
}
};
Expand Down Expand Up @@ -134,6 +141,9 @@ const useNotification = (): ChairGetNotificationResponse["data"] => {
});
timeoutId = setTimeout(() => void polling(), retryAfterMs);
} catch (error) {
if (error instanceof DOMException && error.name === "AbortError") {
return;
}
console.error(error);
}
};
Expand All @@ -149,8 +159,30 @@ const useNotification = (): ChairGetNotificationResponse["data"] => {
return notification?.data;
};



export const SimulatorProvider = ({ children }: { children: ReactNode }) => {

const [token, setToken] = useState<string>();

const simulateChair = useMemo(() => {
return token ? getSimulateChairFromToken(token) : getSimulateChair();
}, [token]);

useEffect(() => {
const token = getCookieValue(document.cookie, "chair_session");
if (token) {
setToken(token);
return;
}
// TODO: tokenがなければUI上で選択させるようにする
if (simulateChair?.token) {
document.cookie = `chair_session=${simulateChair.token}; path=/`;
}
}, [simulateChair]);

const data = useNotification();

const [coordinate, setCoordinate] = useState<Coordinate>(() => {
const coordinate = getSimulatorCurrentCoordinate();
return coordinate ?? { latitude: 0, longitude: 0 };
Expand All @@ -168,6 +200,7 @@ export const SimulatorProvider = ({ children }: { children: ReactNode }) => {
data,
chair: simulateChair ? { ...simulateChair, coordinate } : undefined,
setCoordinate,
setToken
}}
>
{children}
Expand Down
17 changes: 1 addition & 16 deletions frontend/app/globals.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,4 @@
*/
declare const __API_BASE_URL__: string;

declare const __INITIAL_OWNER_DATA__:
| {
owners: {
id: string;
name: string;
token: string;
}[];
targetSimulatorChair: {
id: string;
owner_id: string;
name: string;
model: string;
token: string;
};
}
| undefined;
declare const __INITIAL_DATA__: object;
7 changes: 2 additions & 5 deletions frontend/app/routes/client._index/driving-state/arrived.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,14 @@ import { useClientContext } from "~/contexts/client-context";
import confetti from "canvas-confetti";

export const Arrived = ({ onEvaluated }: { onEvaluated: () => void }) => {
const { accessToken, data } = useClientContext();
const { data } = useClientContext();
const [rating, setRating] = useState(0);

const onClick: MouseEventHandler<HTMLButtonElement> = useCallback(
(e) => {
e.preventDefault();
try {
void fetchAppPostRideEvaluation({
headers: {
Authorization: `Bearer ${accessToken}`,
},
pathParams: {
rideId: data?.ride_id ?? "",
},
Expand All @@ -35,7 +32,7 @@ export const Arrived = ({ onEvaluated }: { onEvaluated: () => void }) => {
}
onEvaluated();
},
[onEvaluated, accessToken, data?.ride_id, rating],
[onEvaluated, data?.ride_id, rating],
);

useEffect(() => {
Expand Down
25 changes: 11 additions & 14 deletions frontend/app/routes/client._index/route.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,26 +89,19 @@ export default function Index() {
if (!currentLocation || !destLocation) {
return;
}
const abortController = new AbortController();
fetchAppPostRidesEstimatedFare(
{
body: {
pickup_coordinate: currentLocation,
destination_coordinate: destLocation,
},
fetchAppPostRidesEstimatedFare({
body: {
pickup_coordinate: currentLocation,
destination_coordinate: destLocation,
},
abortController.signal,
)
})
.then((res) =>
setEstimatePrice({ fare: res.fare, discount: res.discount }),
)
.catch((err) => {
console.error(err);
.catch((error) => {
console.error(error);
setEstimatePrice(undefined);
});
return () => {
abortController.abort();
};
}, [currentLocation, destLocation]);

const handleRideRequest = useCallback(async () => {
Expand Down Expand Up @@ -150,6 +143,9 @@ export default function Index() {
});
setDisplayedChairs(chairs);
} catch (error) {
if (error instanceof DOMException && error.name === "AbortError") {
return;
}
console.error(error);
}
};
Expand Down Expand Up @@ -282,6 +278,7 @@ export default function Index() {
statusModalRef.current?.close();
setCurrentLocation(destLocation);
setDestLocation(undefined);
setEstimatePrice(undefined);
}}
/>
)}
Expand Down
Loading

0 comments on commit ea4ce4c

Please sign in to comment.