111 lines
3.1 KiB
JavaScript
111 lines
3.1 KiB
JavaScript
/**
|
|
* 덱 즐겨찾기
|
|
* 로그인 사용자는 계정 DB, 비로그인 사용자는 localStorage를 사용한다.
|
|
*/
|
|
(function initDeckFavorites() {
|
|
const STORAGE_KEY = 'uadeck.deckFavorites';
|
|
/** @type {Set<string>} */
|
|
let favorites = new Set();
|
|
/** @type {Promise<void>|null} */
|
|
let initPromise = null;
|
|
|
|
/**
|
|
* 브라우저 즐겨찾기 읽기
|
|
* @returns {Set<string>}
|
|
*/
|
|
function readLocalSet() {
|
|
try {
|
|
const raw = localStorage.getItem(STORAGE_KEY);
|
|
const list = raw ? JSON.parse(raw) : [];
|
|
return new Set(Array.isArray(list) ? list : []);
|
|
} catch {
|
|
return new Set();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 브라우저 즐겨찾기 저장
|
|
* @param {Set<string>} set
|
|
*/
|
|
function writeLocalSet(set) {
|
|
localStorage.setItem(STORAGE_KEY, JSON.stringify([...set]));
|
|
}
|
|
|
|
/**
|
|
* 즐겨찾기 초기화 및 기존 브라우저 데이터 이전
|
|
* @returns {Promise<void>}
|
|
*/
|
|
function init() {
|
|
if (initPromise) return initPromise;
|
|
initPromise = (async () => {
|
|
const localFavorites = readLocalSet();
|
|
if (!UaDeckApi.getToken()) {
|
|
favorites = localFavorites;
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const data = localFavorites.size
|
|
? await UaDeckApi.syncFavorites([...localFavorites])
|
|
: await UaDeckApi.getFavorites();
|
|
favorites = new Set(data.favorites || []);
|
|
localStorage.removeItem(STORAGE_KEY);
|
|
} catch (err) {
|
|
favorites = localFavorites;
|
|
console.warn('[favorites] 계정 즐겨찾기 동기화 실패', err);
|
|
}
|
|
})();
|
|
return initPromise;
|
|
}
|
|
|
|
/**
|
|
* @param {string} shareCode
|
|
* @returns {boolean}
|
|
*/
|
|
function isFavorite(shareCode) {
|
|
return Boolean(shareCode) && favorites.has(shareCode);
|
|
}
|
|
|
|
/**
|
|
* 즐겨찾기 상태 변경
|
|
* @param {string} shareCode
|
|
* @returns {Promise<boolean>} 변경 후 즐겨찾기 여부
|
|
*/
|
|
async function toggle(shareCode) {
|
|
if (!shareCode) return false;
|
|
await init();
|
|
const next = !favorites.has(shareCode);
|
|
|
|
if (UaDeckApi.getToken()) {
|
|
if (next) {
|
|
await UaDeckApi.addFavorite(shareCode);
|
|
} else {
|
|
await UaDeckApi.removeFavorite(shareCode);
|
|
}
|
|
}
|
|
|
|
if (next) favorites.add(shareCode);
|
|
else favorites.delete(shareCode);
|
|
if (!UaDeckApi.getToken()) writeLocalSet(favorites);
|
|
return next;
|
|
}
|
|
|
|
/**
|
|
* 삭제된 덱을 현재 화면 상태에서도 제거
|
|
* @param {string} shareCode
|
|
*/
|
|
function forget(shareCode) {
|
|
favorites.delete(shareCode);
|
|
if (!UaDeckApi.getToken()) writeLocalSet(favorites);
|
|
}
|
|
|
|
/**
|
|
* @returns {string[]}
|
|
*/
|
|
function getAll() {
|
|
return [...favorites];
|
|
}
|
|
|
|
window.UaDeckFavorites = { init, isFavorite, toggle, forget, getAll };
|
|
})();
|