Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions src/apis/aquarium.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,3 +125,52 @@ export async function getAquariumDetail(): Promise<AquariumDetail> {
});
}
}

/**
* 아쿠아리움 물고기 노출 설정을 벌크로 업데이트합니다.
* @param fishSettings 물고기별 노출 설정 배열
*/
export async function updateAquariumFishVisibility(
fishSettings: Array<{ id: number; visible: boolean }>,
): Promise<void> {
try {
await api.post("/aquatics/aquarium/fishes/visibility/", {
fish_settings: fishSettings,
});
} catch (error) {
throwMapped(error, {
400: "잘못된 요청입니다. 물고기 ID를 확인해주세요.",
401: "로그인이 필요합니다.",
500: "서버 오류로 물고기 노출 설정을 업데이트하지 못했습니다.",
});
}
}

/**
* 유저가 보유한 모든 물고기 목록을 반환합니다.
* @returns 사용자가 보유한 모든 물고기 목록 (visibility와 관계없이)
*/
export interface UserFish {
id: number;
species_name: string;
repository_full_name: string;
group_code: string;
maturity: number;
github_username: string;
commit_count: number;
is_visible_in_fishtank: boolean;
is_visible_in_aquarium: boolean;
aquarium: number | null;
}

export async function getMyFishes(): Promise<UserFish[]> {
try {
const res = await api.get<UserFish[]>("/aquatics/my-fishes/");
return res.data;
} catch (e) {
throwMapped(e, {
401: "로그인이 필요합니다.",
500: "서버 오류로 물고기 목록을 불러오지 못했습니다.",
});
}
}
93 changes: 8 additions & 85 deletions src/apis/fishtank.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,6 @@
import { api } from "./axios";
import type { AxiosError } from "axios";

export interface FishtankBackground {
id: number; // OwnBackground의 id
background: {
id: number;
name: string;
code: string;
svg_template?: string;
};
unlocked_at: string;
// background_image는 프론트엔드에서 로컬 assets를 사용하므로 제외
}
import type { Fish } from "@/types/fish";

export interface RepositoryOwner {
id: number;
Expand Down Expand Up @@ -39,21 +28,6 @@ export interface Repository {
my_commit_count: number; // 현재 로그인한 사용자의 해당 레포지토리 커밋 수
}

export interface ContributionFishSpecies {
id: number;
name: string;
maturity: number;
required_commits: number;
svg_template: string;
group_code: string;
}

export interface ContributionFish {
id: number;
is_visible_in_fishtank: boolean;
species: ContributionFishSpecies;
}

export interface SelectableFish {
id: number | null; // 할당되지 않은 물고기는 null
username: string | null; // 할당되지 않은 물고기는 null
Expand All @@ -67,18 +41,12 @@ export interface SelectableFish {
svg_template?: string; // SVG 템플릿 코드
}

export interface Contributor {
id: number;
user: string;
commit_count: number;
fish: ContributionFish | null;
}

export interface FishtankDetail {
id: number;
repository: string;
svg_path: string | null;
contributors: Contributor[];
repository_full_name: string;
svg_url: string | null;
background_name: string;
fish_list: Fish[]; // types/fish.ts의 Fish 인터페이스 사용
}

/** AxiosError 타입 가드 */
Expand Down Expand Up @@ -152,23 +120,6 @@ export async function getMyBackgrounds(): Promise<MyBackground[]> {
}
}

/**
* 유저가 보유한 배경(OwnBackground)의 원본 Background 데이터를 반환합니다.
* @deprecated getMyBackgrounds()를 사용하세요
* @returns 사용자가 보유한 피쉬탱크 배경 목록
*/
export async function getFishtankBackgrounds(): Promise<FishtankBackground[]> {
try {
const res = await api.get<FishtankBackground[]>("/aquatics/fishtank/backgrounds/");
return res.data;
} catch (e) {
throwMapped(e, {
401: "로그인이 필요합니다.",
500: "서버 오류로 배경 목록을 불러오지 못했습니다.",
});
}
}

/**
* repo ID를 기반으로 FishTank 내부 정보(기여자, 물고기)를 조회합니다.
* @param repoId repo ID
Expand All @@ -188,13 +139,13 @@ export async function getFishtankDetail(repoId: string): Promise<FishtankDetail>
}

/**
* 사용자가 소유한 OwnBackground 중 하나를 fishtank 배경으로 적용합니다.
* 사용자가 소유한 배경을 fishtank 배경으로 적용합니다.
* @param repoId 레포지토리 ID
* @param backgroundId 유저가 소유한 OwnBackground.background.id
* @param backgroundId Background.id (사용자가 소유한 배경의 background_id)
*/
export async function applyFishtankBackground(repoId: string, backgroundId: number): Promise<void> {
try {
await api.post(`/aquatics/fishtank/${repoId}/apply-background/`, {
await api.post(`/aquatics/fishtank/${repoId}/background/`, {
background_id: backgroundId,
});
} catch (e) {
Expand Down Expand Up @@ -226,31 +177,3 @@ export async function getSelectableFish(repoId: string): Promise<SelectableFish[
});
}
}

export interface FishtankSpriteData {
background_url: string;
background_id: number | null;
fishes: Array<{
id: number;
label: string;
svg_source: string;
}>;
}

/**
* 특정 Repository의 Fishtank 스프라이트 데이터를 조회합니다.
* @param repoId 레포지토리 ID
* @returns 배경 URL과 물고기 스프라이트 데이터
*/
export async function getFishtankSprites(repoId: string): Promise<FishtankSpriteData> {
try {
const res = await api.get<FishtankSpriteData>(`/aquatics/fishtank/${repoId}/sprites/`);
return res.data;
} catch (e) {
throwMapped(e, {
401: "로그인이 필요합니다.",
404: "피쉬탱크를 찾을 수 없습니다.",
500: "서버 오류로 스프라이트 데이터를 불러오지 못했습니다.",
});
}
}
12 changes: 6 additions & 6 deletions src/assets/png/Backgrounds/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import bgOcean from "@/assets/png/Backgrounds/bg-ocean.png";
import bgDeep1 from "@/assets/png/Backgrounds/bg-deep-1.png";
import bgDeep2 from "@/assets/png/Backgrounds/bg-deep-2.png";
import bg1 from "@/assets/png/Backgrounds/bg-deep-1.png";
import bg2 from "@/assets/png/Backgrounds/bg-deep-2.png";
import bg3 from "@/assets/png/Backgrounds/bg-ocean.png";

const BACKGROUND_IMAGES: Record<string, string> = {
"Bg Ocean": bgOcean,
"Bg Deep 1": bgDeep1,
"Bg Deep 2": bgDeep2,
"Bg Ocean": bg1,
"Bg Deep 1": bg2,
"Bg Deep 2": bg3,
};

export function getBackgroundImage(name?: string): string | null {
Expand Down
21 changes: 21 additions & 0 deletions src/assets/svg/FishSprites/map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ import * as sprites from ".";

const SPRITES = sprites as Record<string, string>;

/**
* 물고기 종 이름으로 SVG를 찾습니다.
* @param species 물고기 종 이름 (예: "SpaceOcto_6", "ShrimpWich_2")
*/
export function getFishSpriteSvg(species: string): string {
// === 1) LaptopSunfish 특수 처리 ===========================
// species가 "LaptopSunfish_4", "LaptopSunfish_999"처럼 들어오면
Expand All @@ -23,3 +27,20 @@ export function getFishSpriteSvg(species: string): string {

return svg;
}

/**
* group_code와 maturity를 조합해서 SVG를 찾습니다.
* @param groupCode 그룹 코드 (예: "SpaceOcto", "ShrimpWich")
* @param maturity 성장 단계 (1~6)
*/
export function getFishSpriteSvgByGroupAndMaturity(groupCode: string, maturity: number): string {
const fileName = `${groupCode}_${maturity}`;
const svg = SPRITES[fileName];
if (!svg) {
console.warn(
`[FishTank] Unknown fish: ${fileName} (group_code: ${groupCode}, maturity: ${maturity})`,
);
return SPRITES["LaptopSunfish"] ?? "";
}
return svg;
}
Loading