Skip to content

Commit

Permalink
feat : xquare access key set
Browse files Browse the repository at this point in the history
  • Loading branch information
jidohyun committed Dec 21, 2024
1 parent 6e26ea1 commit d7fd0f3
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 178 deletions.
2 changes: 1 addition & 1 deletion packages/user/.env
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
PROD_VITE_MAIN_URL=sillok.xquare.app
PROD_VITE_SERVER_URL=sillok-stag-server.xquare.app
PROD_VITE_SERVER_URL=sillok-stag-server.xquare.app
2 changes: 1 addition & 1 deletion packages/user/.xquare/config.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
config:
name: Sillok
name: sillok-fe
service_type: fe
port: 3000
domain:
Expand Down
257 changes: 81 additions & 176 deletions packages/user/src/components/Feed/mainFeed.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,37 +3,32 @@ import { FeedCard } from "./feed";
import { useEffect, useState } from "react";
import { toast } from "react-toastify";
import { openDB } from "@/hooks/openDB";
import { Feed } from "@/pages";

interface Feed {
id?: number,
title: string,
content: string,
userName: string,
createdAt: string,
heart: number,
id?: number;
title: string;
content: string;
userName: string;
createdAt: string;
heart: number;
}

export const MainFeed = () => {
const dbName = "FeedDB";
const storeName = "Feeds";
const [feeds, setFeeds] = useState<Feed[]>([]);
const [, setError] = useState<string | null>();
// const handleSelect = (option: string) => {
// setSelected(option);
// if (detailsRef.current) {
// detailsRef.current.open = false; // details 요소 닫기
// }
// };

// IndexedDB에 데이터 저장
const saveFeedToIndexedDB = async (feed: Feed) => {
try {
const db = await openDB(dbName, storeName);
const transaction = db.transaction(storeName, "readwrite");
const store = transaction.objectStore(storeName);
const request = store.add(feed);

const request = store.add(feed);
request.onsuccess = () => {
console.log("IndexedDB에 데이터 저장 성공:", feed);
console.log("IndexedDB에 저장 성공:", feed);
};

request.onerror = (e: any) => {
Expand All @@ -42,188 +37,98 @@ export const MainFeed = () => {
} catch (err) {
console.error("IndexedDB 연결 실패:", err);
}
}
};

useEffect(() => {
const eventSource = new EventSource('http://sillok-stag-server.xquare.app/v1/sse/subscribe');
// IndexedDB에서 데이터 조회
const getAllFromIndexedDB = async (): Promise<Feed[]> => {
try {
const db = await openDB(dbName, storeName);
const transaction = db.transaction(storeName, "readonly");
const store = transaction.objectStore(storeName);

eventSource.onopen = () => {
console.log('SSE 연결 성공');
toast.success("SSE 연결 성공");
setError(null);
};
return new Promise((resolve, reject) => {
const request = store.getAll(); // IndexedDB 요청

// 이벤트 리스너는 onmessage보다 구체적인 이벤트 처리에 유용
eventSource.addEventListener('Sillok event', async (event: MessageEvent) => {
try {
const feedData: Feed = JSON.parse(event.data);
setFeeds((prevFeeds) => {
const updatedFeeds = [feedData, ...prevFeeds]
return updatedFeeds;
}); // 최신 피드를 앞에 추가
await saveFeedToIndexedDB(feedData);
toast.success("새로운 피드 수신");
} catch (err) {
console.error("피드 데이터 파싱 에러:", err);
toast.error("피드 데이터 처리 실패");
setError("피드 데이터를 처리하는 중 오류 발생");
}
});

eventSource.onmessage = (event: MessageEvent) => {
try {
const newFeed: Feed = JSON.parse(event.data);

// 새 피드를 상태에 저장
setFeeds((prevFeeds) => {
const updatedFeeds = [...prevFeeds, newFeed];

// 데이터를 localStorage에 영구 저장
localStorage.setItem("feeds", JSON.stringify(updatedFeeds));
return updatedFeeds;
});
} catch (err) {
console.error("데이터 처리 오류", err);
request.onsuccess = () => {
resolve(request.result as Feed[]); // 요청 성공 시 결과 반환
};

request.onerror = (e) => {
console.error("IndexedDB 조회 오류:", e);
reject(e); // 오류 시 Promise 거부
};
});
} catch (err) {
console.error("IndexedDB 조회 중 예외 발생:", err);
return [];
}
};

// 서버에서 데이터 수신
const fetchFeedsFromServer = async () => {
try {
// 서버에서 피드 데이터를 가져온다고 가정
const serverFeeds: Feed[] = [
{
id: 1,
title: "New Feed",
content: "This is a new feed",
userName: "User1",
createdAt: new Date().toISOString(),
heart: 0,
},
];

// IndexedDB에 저장
for (const feed of serverFeeds) {
await saveFeedToIndexedDB(feed);
}
};

eventSource.onerror = (err) => {
console.error("SSE 연결 오류:", err);
toast.error("SSE 연결 실패");
setError("실시간 알림 연결에 문제가 발생했습니다.");
eventSource.close();
};
toast.success("서버에서 데이터를 받아왔습니다.");
} catch (err) {
console.error("서버 데이터 가져오기 실패:", err);
toast.error("서버에서 데이터를 가져오는 중 문제가 발생했습니다.");
}
};

// 컴포넌트 마운트 시 IndexedDB와 서버 데이터 동기화
useEffect(() => {
const fetchFeeds = async () => {
// IndexedDB에서 데이터 가져오기
const indexedDBFeeds = await getAllFromIndexedDB();
setFeeds(indexedDBFeeds);

// 서버에서 데이터 가져오기
await fetchFeedsFromServer();

return () => {
eventSource.close();
// IndexedDB에서 업데이트된 데이터 가져오기
const updatedFeeds = await getAllFromIndexedDB();
setFeeds(updatedFeeds);
};
}, []);

// const renderComponent = () => {
// if (location.pathname === "/") {
// return (
// <_ArrowWrapper>
// <ArrowMenu ref={detailsRef}>
// <summary>
// <span>{selected}</span>
// <img
// src={ArrowIcon}
// alt=""
// />
// </summary>
// <ul>
// <li onClick={() => handleSelect('추천순')}>추천순</li>
// <li onClick={() => handleSelect('최신순')}>최신순</li>
// <li onClick={() => handleSelect('인기순')}>인기순</li>
// </ul>
// </ArrowMenu>
// </_ArrowWrapper>
// );
// }
// }
fetchFeeds();
}, []);

return (
<_FeedWrapper>
{/* {renderComponent()} */}
{feeds.map((Feed) => (
{feeds.map((feed) => (
<FeedCard
key={Feed.createdAt}
userName={Feed.userName}
createdAt={Feed.createdAt}
title={Feed.title}
content={Feed.content}
heart={Feed.heart}
key={feed.createdAt}
userName={feed.userName}
createdAt={feed.createdAt}
title={feed.title}
content={feed.content}
heart={feed.heart}
/>
))}
</_FeedWrapper>
);
}
};

const _FeedWrapper = styled.ul`
position: relative;
display: grid;
gap: 50px 36px;
grid-template-columns: repeat(4, 1fr); /* 4개의 고정된 열 */
grid-auto-rows: auto; /* 행의 높이는 컨텐츠 크기에 따라 조정 */
/* margin-top: 125px; */
`;

// const ArrowMenu = styled.details`
// position: relative;
// display: inline-block;
// cursor: pointer;

// ul {
// position: absolute;
// top: calc(100% + 20px); /* summary 아래에 8px 간격 */
// left: 50%; /* 부모(summary) 기준 가로 중앙 정렬 */
// transform: translateX(-50%);
// display: flex;
// width: 110px;
// padding: 10px;
// flex-direction: column;
// gap: 10px;
// flex-shrink: 0;
// z-index: 1000; /* 드롭다운이 다른 요소 위에 표시되도록 */
// border-radius: 6px;
// border: 1px solid #E3E3E3;
// background: #FFF;

// & > li {
// padding: 4px;
// color: var(--Gray-70, #645E5E);
// font-family: Roboto;
// font-size: 14px;
// font-style: normal;
// font-weight: 500;
// line-height: normal;
// }

// & > li:hover {
// border-radius: 2px;
// background: #F6F6F6;
// }
// }

// summary {
// list-style: none; /* 기본 화살표 제거 */
// cursor: pointer;
// position: relative;
// display: flex;
// justify-content: center;
// align-items: center;
// gap: 28px;
// color: #645E5E;
// font-family: Roboto;
// font-size: 14px;
// font-style: normal;
// font-weight: 500;
// line-height: normal;
// & img {
// content: "";
// transition: 0.25s transform;
// }
// }

// &[open] img {
// transform: rotate(180deg); /* 화살표 아래로 회전 */
// }
// `;

// const _ArrowWrapper = styled.div`
// position: absolute;
// top: -58px; /* 부모의 위쪽 */
// left: -16px; /* 부모의 왼쪽 */
// display: flex;
// width: 110px;
// height: 34px;
// padding: 10px 14px 9px 17px;
// flex-direction: column;
// justify-content: center;
// align-items: center;
// gap: 10px;
// flex-shrink: 0;
// border-radius: 6px;
// border: 1px solid #C9C9C9;
// background: #FFF;
// `;
Empty file removed packages/user/src/hooks/addDB.ts
Empty file.

0 comments on commit d7fd0f3

Please sign in to comment.