Spaces:
Running
Running
Update index.html
Browse files- index.html +219 -199
index.html
CHANGED
@@ -47,12 +47,73 @@
|
|
47 |
color: white;
|
48 |
-webkit-text-stroke: 1px #333;
|
49 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
50 |
</style>
|
51 |
</head>
|
52 |
<body>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
53 |
<div class="container" id="cardsContainer"></div>
|
54 |
|
55 |
<script>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
56 |
// Hugging Face์ spaces/models URL ๋ชฉ๋ก
|
57 |
const urls = [
|
58 |
"https://huggingface.co/spaces/ginipick/Tech_Hangman_Game",
|
@@ -64,161 +125,8 @@
|
|
64 |
"https://huggingface.co/spaces/VIDraft/PHI4-Multimodal",
|
65 |
"https://huggingface.co/spaces/ginigen/Ovis2-8B",
|
66 |
"https://huggingface.co/spaces/ginigen/Graph-Mind",
|
67 |
-
|
68 |
-
|
69 |
-
"https://huggingface.co/spaces/ginigen/Design",
|
70 |
-
"https://huggingface.co/spaces/ginigen/Diagram",
|
71 |
-
"https://huggingface.co/spaces/ginigen/Mockup",
|
72 |
-
"https://huggingface.co/spaces/ginigen/Infographic",
|
73 |
-
"https://huggingface.co/spaces/ginigen/Flowchart",
|
74 |
-
"https://huggingface.co/spaces/aiqcamp/FLUX-Vision",
|
75 |
-
"https://huggingface.co/spaces/ginigen/VoiceClone-TTS",
|
76 |
-
"https://huggingface.co/spaces/openfree/Perceptron-Network",
|
77 |
-
"https://huggingface.co/spaces/openfree/Article-Generator",
|
78 |
-
"https://huggingface.co/spaces/openfree/Math-Game",
|
79 |
-
"https://huggingface.co/spaces/openfree/PDF-TTS",
|
80 |
-
"https://huggingface.co/spaces/openfree/chess",
|
81 |
-
"https://huggingface.co/spaces/fantos/Panorama",
|
82 |
-
"https://huggingface.co/spaces/ginigen/Multi-LoRAgen",
|
83 |
-
"https://huggingface.co/spaces/ginigen/canvas-studio",
|
84 |
-
"https://huggingface.co/spaces/ginipick/Fashion-Style",
|
85 |
-
"https://huggingface.co/spaces/ginipick/Time-Stream",
|
86 |
-
"https://huggingface.co/spaces/ginipick/AccuVision-Diffusion",
|
87 |
-
"https://huggingface.co/spaces/fantos/Magic-Drawings",
|
88 |
-
"https://huggingface.co/spaces/ginigen/Lumina-Image-PLUS",
|
89 |
-
"https://huggingface.co/spaces/fantaxy/fantasy-novel",
|
90 |
-
"https://huggingface.co/spaces/fantaxy/eros",
|
91 |
-
"https://huggingface.co/spaces/fantaxy/adult-novel",
|
92 |
-
"https://huggingface.co/spaces/fantaxy/kungfu-novel",
|
93 |
-
"https://huggingface.co/spaces/fantaxy/love-novel",
|
94 |
-
"https://huggingface.co/spaces/VIDraft/mouse-webgen",
|
95 |
-
"https://huggingface.co/spaces/immunobiotech/MUSIC-Jukebox",
|
96 |
-
"https://huggingface.co/spaces/seawolf2357/Flowise-AI",
|
97 |
-
"https://huggingface.co/spaces/ginigen/Flux-LayerDiffuse",
|
98 |
-
"https://huggingface.co/spaces/VIDraft/Portrait-Animation",
|
99 |
-
"https://huggingface.co/spaces/VIDraft/Deepseek-Multimodal",
|
100 |
-
"https://huggingface.co/spaces/VIDraft/BLIP2",
|
101 |
-
"https://huggingface.co/spaces/ginigen/text3d-r1",
|
102 |
-
"https://huggingface.co/spaces/immunobiotech/drug-discovery",
|
103 |
-
"https://huggingface.co/spaces/openfree/VisionOCR-Chat",
|
104 |
-
"https://huggingface.co/spaces/immunobiotech/MICHELIN",
|
105 |
-
"https://huggingface.co/spaces/immunobiotech/MICHELIN-korea",
|
106 |
-
"https://huggingface.co/spaces/immunobiotech/MICHELIN-japan",
|
107 |
-
"https://huggingface.co/spaces/immunobiotech/MICHELIN-china",
|
108 |
-
"https://huggingface.co/spaces/VIDraft/money-radar-korea",
|
109 |
-
"https://huggingface.co/spaces/VIDraft/money-radar",
|
110 |
-
"https://huggingface.co/spaces/ginipick/PharmAI-Korea",
|
111 |
-
"https://huggingface.co/spaces/ginigen/MagicFace-V3",
|
112 |
-
"https://huggingface.co/spaces/aiqcamp/MindMap",
|
113 |
-
"https://huggingface.co/spaces/ginigen/3D-LLAMA",
|
114 |
-
"https://huggingface.co/spaces/openfree/VectorFlow",
|
115 |
-
"https://huggingface.co/spaces/openfree/webtoon-gen",
|
116 |
-
"https://huggingface.co/spaces/VIDraft/topic-prediction",
|
117 |
-
"https://huggingface.co/spaces/VIDraft/PapersImpact",
|
118 |
-
"https://huggingface.co/spaces/VIDraft/EveryRAG",
|
119 |
-
"https://huggingface.co/spaces/VIDraft/korea-president-DJ",
|
120 |
-
"https://huggingface.co/spaces/VIDraft/korea-president-PARK",
|
121 |
-
"https://huggingface.co/spaces/openfree/image-to-vector",
|
122 |
-
"https://huggingface.co/spaces/ginipick/QR-Canvas-plus",
|
123 |
-
"https://huggingface.co/spaces/ginigen/text3d-R1",
|
124 |
-
"https://huggingface.co/spaces/openfree/MagicFace-V3",
|
125 |
-
"https://huggingface.co/spaces/ginipick/DeepSeekR1-LIVE",
|
126 |
-
"https://huggingface.co/spaces/ginigen/ColPali-multi",
|
127 |
-
"https://huggingface.co/spaces/ginigen/Janus-Pro-7B",
|
128 |
-
"https://huggingface.co/spaces/ginigen/Animagine",
|
129 |
-
"https://huggingface.co/spaces/openfree/PDF-RAG",
|
130 |
-
"https://huggingface.co/spaces/fantos/Ranking-Tracker",
|
131 |
-
"https://huggingface.co/spaces/aiqcamp/Multilingual-Images",
|
132 |
-
"https://huggingface.co/spaces/aiqcamp/Gemini2-Flash-Thinking",
|
133 |
-
"https://huggingface.co/spaces/openfree/pepe",
|
134 |
-
"https://huggingface.co/spaces/openfree/korea-president-yoon",
|
135 |
-
"https://huggingface.co/spaces/openfree/CryptoVision",
|
136 |
-
"https://huggingface.co/spaces/fantos/VoiceClone",
|
137 |
-
"https://huggingface.co/spaces/seawolf2357/ocrlatex",
|
138 |
-
"https://huggingface.co/spaces/seawolf2357/img2vid",
|
139 |
-
"https://huggingface.co/spaces/seawolf2357/sd-prompt-gen",
|
140 |
-
"https://huggingface.co/spaces/openfree/tarotcard",
|
141 |
-
"https://huggingface.co/spaces/aiqcamp/Polaroid",
|
142 |
-
"https://huggingface.co/spaces/ginigen/cartoon",
|
143 |
-
"https://huggingface.co/spaces/ginigen/Book-Cover",
|
144 |
-
"https://huggingface.co/spaces/aiqcamp/fash",
|
145 |
-
"https://huggingface.co/spaces/gunship999/Korea-Daily-News",
|
146 |
-
"https://huggingface.co/spaces/immunobiotech/ChicagoGallery",
|
147 |
-
"https://huggingface.co/spaces/immunobiotech/MetropolitanMuseum",
|
148 |
-
"https://huggingface.co/spaces/immunobiotech/opensky",
|
149 |
-
"https://huggingface.co/spaces/aiqtech/FLUX-military",
|
150 |
-
"https://huggingface.co/spaces/fantaxy/Rolls-Royce",
|
151 |
-
"https://huggingface.co/spaces/seawolf2357/flux-korea-hanbok-lora",
|
152 |
-
"https://huggingface.co/spaces/seawolf2357/flux-korea-palace-lora",
|
153 |
-
"https://huggingface.co/spaces/aiqcamp/flux-cat-lora",
|
154 |
-
"https://huggingface.co/spaces/gunship999/SexyImages",
|
155 |
-
"https://huggingface.co/spaces/aiqtech/flux-claude-monet-lora",
|
156 |
-
"https://huggingface.co/spaces/seawolf2357/3D-Avatar-Generator",
|
157 |
-
"https://huggingface.co/spaces/fantaxy/playground25",
|
158 |
-
"https://huggingface.co/spaces/openfree/ultpixgen",
|
159 |
-
"https://huggingface.co/spaces/seawolf2357/REALVISXL-V5",
|
160 |
-
"https://huggingface.co/spaces/fantos/flxcontrol",
|
161 |
-
"https://huggingface.co/spaces/ginipick/FLUX-Prompt-Generator",
|
162 |
-
"https://huggingface.co/spaces/fantaxy/flxloraexp",
|
163 |
-
"https://huggingface.co/spaces/fantos/flxloraexp",
|
164 |
-
"https://huggingface.co/spaces/seawolf2357/flxloraexp",
|
165 |
-
"https://huggingface.co/spaces/ginipick/flxloraexp",
|
166 |
-
"https://huggingface.co/spaces/fantos/textcutobject",
|
167 |
-
"https://huggingface.co/spaces/aiqcamp/imagemagic",
|
168 |
-
"https://huggingface.co/spaces/openfree/ColorRevive",
|
169 |
-
"https://huggingface.co/spaces/VIDraft/RAGOndevice",
|
170 |
-
"https://huggingface.co/spaces/aiqcamp/AudioLlama",
|
171 |
-
"https://huggingface.co/spaces/ginigen/FLUXllama-Multilingual",
|
172 |
-
"https://huggingface.co/openfree/president-k-dj",
|
173 |
-
"https://huggingface.co/openfree/president-pjh",
|
174 |
-
"https://huggingface.co/openfree/flux-lora-korea-palace",
|
175 |
-
"https://huggingface.co/seawolf2357/hanbok",
|
176 |
-
"https://huggingface.co/seawolf2357/ntower",
|
177 |
-
"https://huggingface.co/openfree/pepe",
|
178 |
-
"https://huggingface.co/openfree/korea-president-yoon",
|
179 |
-
"https://huggingface.co/seawolf2357/flux-lora-military-artillery-k9",
|
180 |
-
"https://huggingface.co/openfree/claude-monet",
|
181 |
-
"https://huggingface.co/ginipick/flux-lora-eric-cat",
|
182 |
-
"https://huggingface.co/seawolf2357/flux-lora-car-rolls-royce",
|
183 |
-
"https://huggingface.co/spaces/aiqcamp/Fashion-FLUX",
|
184 |
-
"https://huggingface.co/spaces/fantaxy/flx-pulid",
|
185 |
-
"https://huggingface.co/spaces/fantaxy/flx-upscale",
|
186 |
-
"https://huggingface.co/spaces/fantos/flx8lora",
|
187 |
-
"https://huggingface.co/spaces/ginipick/FitGen",
|
188 |
-
"https://huggingface.co/spaces/fantaxy/FLUX-Animations",
|
189 |
-
"https://huggingface.co/spaces/fantaxy/Remove-Video-Background",
|
190 |
-
"https://huggingface.co/spaces/fantaxy/ofai-flx-logo",
|
191 |
-
"https://huggingface.co/spaces/fantos/x-mas",
|
192 |
-
"https://huggingface.co/spaces/openfree/Korean-Leaderboard",
|
193 |
-
"https://huggingface.co/spaces/ginipick/FLUXllama",
|
194 |
-
"https://huggingface.co/spaces/fantaxy/Sound-AI-SFX",
|
195 |
-
"https://huggingface.co/spaces/openfree/trending-board",
|
196 |
-
"https://huggingface.co/spaces/ginipick/Realtime-FLUX",
|
197 |
-
"https://huggingface.co/spaces/aiqtech/kofaceid",
|
198 |
-
"https://huggingface.co/spaces/fantaxy/fastvideogen",
|
199 |
-
"https://huggingface.co/spaces/fantos/flxfashmodel",
|
200 |
-
"https://huggingface.co/spaces/fantos/kolcontrl",
|
201 |
-
"https://huggingface.co/spaces/aiqtech/imaginpaint",
|
202 |
-
"https://huggingface.co/spaces/ginipick/spaces-research-korea",
|
203 |
-
"https://huggingface.co/spaces/ginipick/spaces-research-think",
|
204 |
-
"https://huggingface.co/spaces/VIDraft/mouse-Visual-Chat",
|
205 |
-
"https://huggingface.co/spaces/VIDraft/mouse-file-chat",
|
206 |
-
"https://huggingface.co/spaces/openfree/Datasets-Convertor",
|
207 |
-
"https://huggingface.co/spaces/openfree/Parquet-CSV-Convertor",
|
208 |
-
"https://huggingface.co/spaces/ginigen/FLUX-Eternity",
|
209 |
-
"https://huggingface.co/spaces/ginipick/live-detect-pose",
|
210 |
-
"https://huggingface.co/spaces/ginigen/OmniParser-v2-pro",
|
211 |
-
"https://huggingface.co/spaces/ginigen/Celebrity",
|
212 |
-
"https://huggingface.co/spaces/ginigen/Fashion-Pose-Control",
|
213 |
-
"https://huggingface.co/spaces/ginigen/zonos-longform",
|
214 |
-
"https://huggingface.co/spaces/aiqtech/cinevid",
|
215 |
-
"https://huggingface.co/spaces/aiqtech/FLUX-Ghibli-Studio-LoRA",
|
216 |
-
"https://huggingface.co/spaces/aiqtech/flxgif",
|
217 |
-
"https://huggingface.co/spaces/ginipick/3D-GAME",
|
218 |
-
"https://huggingface.co/spaces/ginipick/Flipper-Code-Generator",
|
219 |
-
"https://huggingface.co/spaces/ginipick/Baby-Name-Generator",
|
220 |
-
"https://huggingface.co/spaces/ginipick/secreen-capture-OCR",
|
221 |
-
"https://huggingface.co/spaces/ginipick/face-pose-detect"
|
222 |
];
|
223 |
|
224 |
// URL์ ๋ง์ง๋ง ๋ถ๋ถ์ ์ ๋ชฉ์ผ๋ก ์ถ์ถ (์ธ๋๋ฐ, ํ์ดํ์ ๊ณต๋ฐฑ์ผ๋ก ๋ณํ)
|
@@ -228,58 +136,170 @@
|
|
228 |
return title.replace(/[_-]/g, " ");
|
229 |
}
|
230 |
|
231 |
-
//
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
}
|
246 |
|
247 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
248 |
|
249 |
-
//
|
250 |
-
|
251 |
-
|
252 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
253 |
|
254 |
-
//
|
255 |
-
|
256 |
-
|
257 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
258 |
|
259 |
-
|
260 |
-
const linkEl = document.createElement("a");
|
261 |
-
linkEl.href = url;
|
262 |
-
linkEl.textContent = url;
|
263 |
-
linkEl.target = "_blank";
|
264 |
-
card.appendChild(linkEl);
|
265 |
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
274 |
}
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
|
|
280 |
|
281 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
282 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
283 |
</script>
|
284 |
</body>
|
285 |
-
</html>
|
|
|
47 |
color: white;
|
48 |
-webkit-text-stroke: 1px #333;
|
49 |
}
|
50 |
+
/* ๋ก๊ทธ์ธ ์ํ ํ์ ๋ฐ ์ปจํธ๋กค */
|
51 |
+
.user-controls {
|
52 |
+
padding: 1rem;
|
53 |
+
margin-bottom: 1rem;
|
54 |
+
background-color: #f0f0f0;
|
55 |
+
border-radius: 5px;
|
56 |
+
display: flex;
|
57 |
+
justify-content: space-between;
|
58 |
+
align-items: center;
|
59 |
+
}
|
60 |
+
/* ๋ก๋ฉ ํ์ */
|
61 |
+
.loading {
|
62 |
+
position: fixed;
|
63 |
+
top: 0;
|
64 |
+
left: 0;
|
65 |
+
right: 0;
|
66 |
+
bottom: 0;
|
67 |
+
background-color: rgba(255, 255, 255, 0.7);
|
68 |
+
display: flex;
|
69 |
+
justify-content: center;
|
70 |
+
align-items: center;
|
71 |
+
z-index: 1000;
|
72 |
+
font-size: 1.5rem;
|
73 |
+
display: none;
|
74 |
+
}
|
75 |
</style>
|
76 |
</head>
|
77 |
<body>
|
78 |
+
<!-- ๋ก๊ทธ์ธ ์ํ ๋ฐ ์ฌ์ฉ์ ์ปจํธ๋กค -->
|
79 |
+
<div class="user-controls" id="userControls">
|
80 |
+
<div>
|
81 |
+
<span>๋ก๊ทธ์ธ: </span>
|
82 |
+
<span id="loginStatus">๋ก๊ทธ์ธ๋์ง ์์</span>
|
83 |
+
</div>
|
84 |
+
<div>
|
85 |
+
<input type="text" id="usernameInput" placeholder="์ฌ์ฉ์ ์ด๋ฆ" />
|
86 |
+
<button id="loginButton">๋ก๊ทธ์ธ</button>
|
87 |
+
<button id="logoutButton" style="display: none;">๋ก๊ทธ์์</button>
|
88 |
+
</div>
|
89 |
+
</div>
|
90 |
+
|
91 |
+
<!-- ๋ก๋ฉ ํ์ -->
|
92 |
+
<div class="loading" id="loadingIndicator">
|
93 |
+
๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์ค๋ ์ค...
|
94 |
+
</div>
|
95 |
+
|
96 |
+
<!-- ์นด๋ ์ปจํ
์ด๋ -->
|
97 |
<div class="container" id="cardsContainer"></div>
|
98 |
|
99 |
<script>
|
100 |
+
// ์ํ ๊ด๋ฆฌ
|
101 |
+
const state = {
|
102 |
+
currentUser: null,
|
103 |
+
likedUrls: {},
|
104 |
+
isLoading: false
|
105 |
+
};
|
106 |
+
|
107 |
+
// DOM ์์ ์ฐธ์กฐ
|
108 |
+
const elements = {
|
109 |
+
loginStatus: document.getElementById('loginStatus'),
|
110 |
+
usernameInput: document.getElementById('usernameInput'),
|
111 |
+
loginButton: document.getElementById('loginButton'),
|
112 |
+
logoutButton: document.getElementById('logoutButton'),
|
113 |
+
cardsContainer: document.getElementById('cardsContainer'),
|
114 |
+
loadingIndicator: document.getElementById('loadingIndicator')
|
115 |
+
};
|
116 |
+
|
117 |
// Hugging Face์ spaces/models URL ๋ชฉ๋ก
|
118 |
const urls = [
|
119 |
"https://huggingface.co/spaces/ginipick/Tech_Hangman_Game",
|
|
|
125 |
"https://huggingface.co/spaces/VIDraft/PHI4-Multimodal",
|
126 |
"https://huggingface.co/spaces/ginigen/Ovis2-8B",
|
127 |
"https://huggingface.co/spaces/ginigen/Graph-Mind",
|
128 |
+
// ์ ์ฒด URL ๋ชฉ๋ก ์ค ์ผ๋ถ๋ง ํ์ (์ค์ ๋ก๋ ๋ชจ๋ URL์ ํฌํจํด์ผ ํจ)
|
129 |
+
// ... ๋๋จธ์ง URL
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
130 |
];
|
131 |
|
132 |
// URL์ ๋ง์ง๋ง ๋ถ๋ถ์ ์ ๋ชฉ์ผ๋ก ์ถ์ถ (์ธ๋๋ฐ, ํ์ดํ์ ๊ณต๋ฐฑ์ผ๋ก ๋ณํ)
|
|
|
136 |
return title.replace(/[_-]/g, " ");
|
137 |
}
|
138 |
|
139 |
+
// ๋ก๋ฉ ์ํ ํ์ ํจ์
|
140 |
+
function setLoading(isLoading) {
|
141 |
+
state.isLoading = isLoading;
|
142 |
+
elements.loadingIndicator.style.display = isLoading ? 'flex' : 'none';
|
143 |
+
}
|
144 |
+
|
145 |
+
// ์ฌ์ฉ์ ์ข์์ ๋ฐ์ดํฐ ์ ์ฅ (์๋ฒ API ํธ์ถ๋ก ๋์ฒด ๊ฐ๋ฅ)
|
146 |
+
function saveLikes(username, likes) {
|
147 |
+
return new Promise((resolve) => {
|
148 |
+
// ์ค์ ๊ตฌํ์์๋ ์๋ฒ API๋ฅผ ํธ์ถํ์ฌ DB์ ์ ์ฅ
|
149 |
+
// ์์๋ก localStorage๋ฅผ ์ฌ์ฉ (์ฌ์ฉ์๋ณ ์ข์์ ๋ฐ์ดํฐ ์ ์ฅ)
|
150 |
+
localStorage.setItem(`likes_${username}`, JSON.stringify(likes));
|
151 |
+
setTimeout(resolve, 300); // ๋คํธ์ํฌ ์ง์ฐ ์๋ฎฌ๋ ์ด์
|
152 |
+
});
|
153 |
}
|
154 |
|
155 |
+
// ์ฌ์ฉ์ ์ข์์ ๋ฐ์ดํฐ ๋ก๋ (์๋ฒ API ํธ์ถ๋ก ๋์ฒด ๊ฐ๋ฅ)
|
156 |
+
function loadLikes(username) {
|
157 |
+
return new Promise((resolve) => {
|
158 |
+
// ์ค์ ๊ตฌํ์์๋ ์๋ฒ API๋ฅผ ํธ์ถํ์ฌ DB์์ ๋ถ๋ฌ์ด
|
159 |
+
// ์์๋ก localStorage๋ฅผ ์ฌ์ฉ
|
160 |
+
const likes = JSON.parse(localStorage.getItem(`likes_${username}`)) || {};
|
161 |
+
setTimeout(() => resolve(likes), 300); // ๋คํธ์ํฌ ์ง์ฐ ์๋ฎฌ๋ ์ด์
|
162 |
+
});
|
163 |
+
}
|
164 |
+
|
165 |
+
// ๋ก๊ทธ์ธ ์ฒ๋ฆฌ
|
166 |
+
async function login(username) {
|
167 |
+
if (!username.trim()) {
|
168 |
+
alert('์ฌ์ฉ์ ์ด๋ฆ์ ์
๋ ฅํด์ฃผ์ธ์.');
|
169 |
+
return;
|
170 |
+
}
|
171 |
+
|
172 |
+
setLoading(true);
|
173 |
+
|
174 |
+
try {
|
175 |
+
// ์ฌ์ฉ์ ์ข์์ ๋ฐ์ดํฐ ๋ก๋
|
176 |
+
const likes = await loadLikes(username);
|
177 |
+
|
178 |
+
// ์ํ ์
๋ฐ์ดํธ
|
179 |
+
state.currentUser = username;
|
180 |
+
state.likedUrls = likes;
|
181 |
+
|
182 |
+
// UI ์
๋ฐ์ดํธ
|
183 |
+
elements.loginStatus.textContent = `${username}๋์ผ๋ก ๋ก๊ทธ์ธ๋จ`;
|
184 |
+
elements.usernameInput.style.display = 'none';
|
185 |
+
elements.loginButton.style.display = 'none';
|
186 |
+
elements.logoutButton.style.display = 'inline-block';
|
187 |
+
|
188 |
+
// ์นด๋ ๋ค์ ๋ ๋๋ง
|
189 |
+
renderCards();
|
190 |
+
} catch (error) {
|
191 |
+
alert('๋ก๊ทธ์ธ ์ค ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค.');
|
192 |
+
console.error('๋ก๊ทธ์ธ ์ค๋ฅ:', error);
|
193 |
+
} finally {
|
194 |
+
setLoading(false);
|
195 |
+
}
|
196 |
+
}
|
197 |
|
198 |
+
// ๋ก๊ทธ์์ ์ฒ๋ฆฌ
|
199 |
+
function logout() {
|
200 |
+
// ์ํ ์ด๊ธฐํ
|
201 |
+
state.currentUser = null;
|
202 |
+
state.likedUrls = {};
|
203 |
+
|
204 |
+
// UI ์
๋ฐ์ดํธ
|
205 |
+
elements.loginStatus.textContent = '๋ก๊ทธ์ธ๋์ง ์์';
|
206 |
+
elements.usernameInput.style.display = 'inline-block';
|
207 |
+
elements.usernameInput.value = '';
|
208 |
+
elements.loginButton.style.display = 'inline-block';
|
209 |
+
elements.logoutButton.style.display = 'none';
|
210 |
|
211 |
+
// ์นด๋ ๋ค์ ๋ ๋๋ง
|
212 |
+
renderCards();
|
213 |
+
}
|
214 |
+
|
215 |
+
// ์ข์์ ํ ๊ธ ์ฒ๋ฆฌ
|
216 |
+
async function toggleLike(url, button) {
|
217 |
+
if (!state.currentUser) {
|
218 |
+
alert('์ข์์๋ฅผ ํ๋ ค๋ฉด ๋ก๊ทธ์ธ์ด ํ์ํฉ๋๋ค.');
|
219 |
+
return;
|
220 |
+
}
|
221 |
|
222 |
+
setLoading(true);
|
|
|
|
|
|
|
|
|
|
|
223 |
|
224 |
+
try {
|
225 |
+
// ์ข์์ ์ํ ํ ๊ธ
|
226 |
+
if (state.likedUrls[url]) {
|
227 |
+
delete state.likedUrls[url];
|
228 |
+
button.classList.remove("liked");
|
229 |
+
button.classList.add("not-liked");
|
230 |
+
} else {
|
231 |
+
state.likedUrls[url] = true;
|
232 |
+
button.classList.add("liked");
|
233 |
+
button.classList.remove("not-liked");
|
234 |
+
}
|
235 |
+
|
236 |
+
// ๋ณ๊ฒฝ์ฌํญ ์ ์ฅ
|
237 |
+
await saveLikes(state.currentUser, state.likedUrls);
|
238 |
+
} catch (error) {
|
239 |
+
alert('์ข์์ ์ฒ๋ฆฌ ์ค ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค.');
|
240 |
+
console.error('์ข์์ ์ค๋ฅ:', error);
|
241 |
+
} finally {
|
242 |
+
setLoading(false);
|
243 |
}
|
244 |
+
}
|
245 |
+
|
246 |
+
// ์นด๋ ๋ ๋๋ง
|
247 |
+
function renderCards() {
|
248 |
+
// ์นด๋ ์ปจํ
์ด๋ ์ด๊ธฐํ
|
249 |
+
elements.cardsContainer.innerHTML = '';
|
250 |
|
251 |
+
// ๊ฐ URL์ ๋ํด ์นด๋ ์์ฑ
|
252 |
+
urls.forEach(url => {
|
253 |
+
const card = document.createElement("div");
|
254 |
+
card.className = "card";
|
255 |
+
|
256 |
+
// ์ ๋ชฉ
|
257 |
+
const titleEl = document.createElement("h3");
|
258 |
+
titleEl.textContent = extractTitle(url);
|
259 |
+
card.appendChild(titleEl);
|
260 |
+
|
261 |
+
// URL ๋งํฌ
|
262 |
+
const linkEl = document.createElement("a");
|
263 |
+
linkEl.href = url;
|
264 |
+
linkEl.textContent = url;
|
265 |
+
linkEl.target = "_blank";
|
266 |
+
card.appendChild(linkEl);
|
267 |
+
|
268 |
+
// ์ข์์ ๋ฒํผ (โฅ ์์ด์ฝ)
|
269 |
+
const likeBtn = document.createElement("button");
|
270 |
+
likeBtn.className = "like-button";
|
271 |
+
likeBtn.textContent = "โฅ";
|
272 |
+
if (state.likedUrls[url]) {
|
273 |
+
likeBtn.classList.add("liked");
|
274 |
+
} else {
|
275 |
+
likeBtn.classList.add("not-liked");
|
276 |
+
}
|
277 |
+
likeBtn.addEventListener("click", function(e) {
|
278 |
+
e.preventDefault(); // ๋งํฌ ํด๋ฆญ ๋ฐฉ์ง
|
279 |
+
toggleLike(url, likeBtn);
|
280 |
+
});
|
281 |
+
card.appendChild(likeBtn);
|
282 |
+
|
283 |
+
elements.cardsContainer.appendChild(card);
|
284 |
+
});
|
285 |
+
}
|
286 |
+
|
287 |
+
// ์ด๋ฒคํธ ๋ฆฌ์ค๋ ์ค์
|
288 |
+
elements.loginButton.addEventListener('click', () => {
|
289 |
+
login(elements.usernameInput.value);
|
290 |
});
|
291 |
+
|
292 |
+
elements.logoutButton.addEventListener('click', logout);
|
293 |
+
|
294 |
+
// ์ํฐ ํค๋ก ๋ก๊ทธ์ธ ๊ฐ๋ฅํ๊ฒ
|
295 |
+
elements.usernameInput.addEventListener('keypress', (event) => {
|
296 |
+
if (event.key === 'Enter') {
|
297 |
+
login(elements.usernameInput.value);
|
298 |
+
}
|
299 |
+
});
|
300 |
+
|
301 |
+
// ์ด๊ธฐ ๋ ๋๋ง
|
302 |
+
renderCards();
|
303 |
</script>
|
304 |
</body>
|
305 |
+
</html>
|