Spaces:
Paused
Paused
Update app.py
Browse files
app.py
CHANGED
|
@@ -1569,7 +1569,7 @@ HTML = """
|
|
| 1569 |
</div>
|
| 1570 |
</section>
|
| 1571 |
|
| 1572 |
-
|
| 1573 |
let projects=[], fb=null;
|
| 1574 |
const grid=document.getElementById('grid'), viewer=document.getElementById('viewer');
|
| 1575 |
pdfjsLib.GlobalWorkerOptions.workerSrc='/static/pdf.worker.js';
|
|
@@ -1584,115 +1584,114 @@ HTML = """
|
|
| 1584 |
// νμ¬ μ΄λ¦° PDFμ ID
|
| 1585 |
let currentPdfId = null;
|
| 1586 |
|
| 1587 |
-
// μ€λμ€ μ»¨ν
μ€νΈμ μ΄κΈ°ν μν κ΄λ¦¬
|
| 1588 |
-
let audioInitialized = false;
|
| 1589 |
-
let audioContext = null;
|
| 1590 |
|
| 1591 |
-
// μ€λμ€ μ΄κΈ°ν ν¨μ
|
| 1592 |
-
function initializeAudio() {
|
| 1593 |
-
|
| 1594 |
-
|
| 1595 |
-
|
| 1596 |
-
|
| 1597 |
-
|
| 1598 |
-
|
| 1599 |
-
|
| 1600 |
-
|
| 1601 |
-
|
| 1602 |
-
|
| 1603 |
-
|
| 1604 |
-
|
| 1605 |
-
|
| 1606 |
-
|
| 1607 |
-
|
| 1608 |
-
|
| 1609 |
-
|
| 1610 |
-
|
| 1611 |
-
|
| 1612 |
-
|
| 1613 |
-
|
| 1614 |
-
|
| 1615 |
-
|
| 1616 |
-
|
| 1617 |
-
|
| 1618 |
-
// μ¬μ©μ μνΈμμ©μ΄ νμν κ²½μ°, μ΄λ²€νΈ 리μ€λ μΆκ°
|
| 1619 |
-
const initOnUserAction = function() {
|
| 1620 |
-
const tempAudio = new Audio('/static/turnPage2.mp3');
|
| 1621 |
-
tempAudio.volume = 0.01;
|
| 1622 |
-
tempAudio.play()
|
| 1623 |
-
.then(() => {
|
| 1624 |
-
tempAudio.pause();
|
| 1625 |
-
audioInitialized = true;
|
| 1626 |
-
console.log('μ¬μ©μ μνΈμμ©μΌλ‘ μ€λμ€ μ΄κΈ°ν μ±κ³΅');
|
| 1627 |
-
resolve();
|
| 1628 |
-
|
| 1629 |
-
// μ΄λ²€νΈ 리μ€λ μ κ±°
|
| 1630 |
-
['click', 'touchstart', 'keydown'].forEach(event => {
|
| 1631 |
-
document.removeEventListener(event, initOnUserAction, { capture: true });
|
| 1632 |
-
});
|
| 1633 |
-
})
|
| 1634 |
-
.catch(e => console.error('μ€λμ€ μ΄κΈ°ν μ€ν¨:', e));
|
| 1635 |
-
};
|
| 1636 |
-
|
| 1637 |
-
// μ¬μ©μ μνΈμμ© μ΄λ²€νΈμ 리μ€λ μΆκ°
|
| 1638 |
-
['click', 'touchstart', 'keydown'].forEach(event => {
|
| 1639 |
-
document.addEventListener(event, initOnUserAction, { once: true, capture: true });
|
| 1640 |
-
});
|
| 1641 |
-
|
| 1642 |
-
// νμ΄μ§ λ‘λ μ§ν μ¬μ©μμκ² μ€λμ€ νμ±ν μμ²
|
| 1643 |
-
if (window.location.pathname.startsWith('/view/')) {
|
| 1644 |
-
// μ€λμ€ νμ±ν μλ΄ λ©μμ§ νμ (λ°λ‘κ°κΈ° λ§ν¬λ‘ μ μν κ²½μ°)
|
| 1645 |
-
setTimeout(() => {
|
| 1646 |
-
const audioPrompt = document.createElement('div');
|
| 1647 |
-
audioPrompt.style.position = 'fixed';
|
| 1648 |
-
audioPrompt.style.bottom = '80px';
|
| 1649 |
-
audioPrompt.style.left = '50%';
|
| 1650 |
-
audioPrompt.style.transform = 'translateX(-50%)';
|
| 1651 |
-
audioPrompt.style.backgroundColor = 'rgba(0,0,0,0.7)';
|
| 1652 |
-
audioPrompt.style.color = 'white';
|
| 1653 |
-
audioPrompt.style.padding = '10px 20px';
|
| 1654 |
-
audioPrompt.style.borderRadius = '20px';
|
| 1655 |
-
audioPrompt.style.zIndex = '10000';
|
| 1656 |
-
audioPrompt.style.cursor = 'pointer';
|
| 1657 |
-
audioPrompt.innerHTML = 'νμ΄μ§ μ΄λλ ν΄λ¦νμ¬ μ리 ν¨κ³Ό νμ±ν <i class="fas fa-volume-up"></i>';
|
| 1658 |
-
audioPrompt.id = 'audioPrompt';
|
| 1659 |
|
| 1660 |
-
//
|
| 1661 |
-
|
| 1662 |
-
|
| 1663 |
-
|
| 1664 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1665 |
|
| 1666 |
-
|
|
|
|
|
|
|
|
|
|
| 1667 |
|
| 1668 |
-
//
|
| 1669 |
-
|
| 1670 |
-
|
| 1671 |
-
|
| 1672 |
-
|
| 1673 |
-
|
| 1674 |
-
|
| 1675 |
-
|
| 1676 |
-
|
| 1677 |
-
|
| 1678 |
-
|
| 1679 |
-
|
| 1680 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1681 |
}
|
| 1682 |
-
});
|
| 1683 |
-
}
|
| 1684 |
-
|
| 1685 |
-
// νμ΄μ§ λ‘λ μ μ€λμ€ μ΄κΈ°ν μλ
|
| 1686 |
-
document.addEventListener('DOMContentLoaded', initializeAudio);
|
| 1687 |
|
| 1688 |
/* ββ μ νΈ ββ */
|
| 1689 |
function $id(id){return document.getElementById(id)}
|
| 1690 |
|
| 1691 |
-
//
|
| 1692 |
-
|
| 1693 |
-
document.addEventListener('DOMContentLoaded', initializeAudio);
|
| 1694 |
console.log("DOM λ‘λ μλ£, μ΄λ²€νΈ μ€μ μμ");
|
| 1695 |
|
|
|
|
|
|
|
|
|
|
| 1696 |
// PDF μ
λ‘λ λ²νΌ
|
| 1697 |
const pdfBtn = document.getElementById('pdfUploadBtn');
|
| 1698 |
const pdfInput = document.getElementById('pdfInput');
|
|
@@ -1727,6 +1726,28 @@ document.addEventListener('DOMContentLoaded', initializeAudio);
|
|
| 1727 |
|
| 1728 |
// κ΄λ¦¬μ λ²νΌ μ΄λ²€νΈ μ€μ
|
| 1729 |
setupAdminFunctions();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1730 |
});
|
| 1731 |
|
| 1732 |
// μλ²μ PDF μ
λ‘λ ν¨μ
|
|
@@ -1763,46 +1784,44 @@ document.addEventListener('DOMContentLoaded', initializeAudio);
|
|
| 1763 |
}
|
| 1764 |
}
|
| 1765 |
|
| 1766 |
-
function addCard(i, thumb, title, isCached = false, pdfId = null) {
|
| 1767 |
-
|
| 1768 |
-
|
| 1769 |
-
|
| 1770 |
-
|
| 1771 |
-
|
| 1772 |
-
|
| 1773 |
-
|
| 1774 |
-
|
| 1775 |
-
|
| 1776 |
-
|
| 1777 |
-
|
| 1778 |
-
|
| 1779 |
-
|
| 1780 |
-
|
| 1781 |
-
|
| 1782 |
-
|
| 1783 |
-
|
| 1784 |
-
|
| 1785 |
-
|
| 1786 |
-
|
| 1787 |
-
|
| 1788 |
-
|
| 1789 |
-
|
| 1790 |
-
|
| 1791 |
-
|
| 1792 |
-
|
| 1793 |
-
|
| 1794 |
-
|
| 1795 |
-
|
| 1796 |
-
|
| 1797 |
-
|
| 1798 |
-
|
| 1799 |
-
|
| 1800 |
-
|
| 1801 |
-
|
| 1802 |
-
|
| 1803 |
-
}
|
| 1804 |
-
|
| 1805 |
-
|
| 1806 |
|
| 1807 |
/* ββ νλ‘μ νΈ μ μ₯ ββ */
|
| 1808 |
function save(pages, title, isCached = false, pdfId = null) {
|
|
@@ -1963,6 +1982,9 @@ function addCard(i, thumb, title, isCached = false, pdfId = null) {
|
|
| 1963 |
/* ββ PDF IDλ‘ PDF μ΄κΈ° ββ */
|
| 1964 |
async function openPdfById(pdfId, pdfPath, isCached = false) {
|
| 1965 |
try {
|
|
|
|
|
|
|
|
|
|
| 1966 |
// λ¨Όμ ν νλ©΄μμ μΉ΄λλ₯Ό μ°Ύμμ ν΄λ¦νλ λ°©λ² μλ
|
| 1967 |
let foundCard = false;
|
| 1968 |
const cards = document.querySelectorAll('.card');
|
|
@@ -2270,157 +2292,138 @@ function addCard(i, thumb, title, isCached = false, pdfId = null) {
|
|
| 2270 |
}
|
| 2271 |
}
|
| 2272 |
|
| 2273 |
-
|
| 2274 |
-
|
| 2275 |
-
console.log('FlipBook μμ± μμ. νμ΄μ§ μ:', pages.length);
|
| 2276 |
-
|
| 2277 |
-
try {
|
| 2278 |
-
// νλ©΄ λΉμ¨ κ³μ°
|
| 2279 |
-
const calculateAspectRatio = () => {
|
| 2280 |
-
const windowWidth = window.innerWidth;
|
| 2281 |
-
const windowHeight = window.innerHeight;
|
| 2282 |
-
const aspectRatio = windowWidth / windowHeight;
|
| 2283 |
|
| 2284 |
-
// λλΉ λλ λμ΄ κΈ°μ€μΌλ‘ μ΅λ 90% μ ν
|
| 2285 |
-
let width, height;
|
| 2286 |
-
if (aspectRatio > 1) { // κ°λ‘ νλ©΄
|
| 2287 |
-
height = Math.min(windowHeight * 0.9, windowHeight - 40);
|
| 2288 |
-
width = height * aspectRatio * 0.8; // κ°λ‘ νλ©΄μμλ μ½κ° μ€μ
|
| 2289 |
-
if (width > windowWidth * 0.9) {
|
| 2290 |
-
width = windowWidth * 0.9;
|
| 2291 |
-
height = width / (aspectRatio * 0.8);
|
| 2292 |
-
}
|
| 2293 |
-
} else { // μΈλ‘ νλ©΄
|
| 2294 |
-
width = Math.min(windowWidth * 0.9, windowWidth - 40);
|
| 2295 |
-
height = width / aspectRatio * 0.9; // μΈλ‘ νλ©΄μμλ μ½κ° λλ¦Ό
|
| 2296 |
-
if (height > windowHeight * 0.9) {
|
| 2297 |
-
height = windowHeight * 0.9;
|
| 2298 |
-
width = height * aspectRatio * 0.9;
|
| 2299 |
-
}
|
| 2300 |
-
}
|
| 2301 |
-
|
| 2302 |
-
// μ΅μ μ¬μ΄μ¦ λ°ν
|
| 2303 |
-
return {
|
| 2304 |
-
width: Math.round(width),
|
| 2305 |
-
height: Math.round(height)
|
| 2306 |
-
};
|
| 2307 |
-
};
|
| 2308 |
-
|
| 2309 |
-
// μ΄κΈ° νλ©΄ λΉμ¨ κ³μ°
|
| 2310 |
-
const size = calculateAspectRatio();
|
| 2311 |
-
viewer.style.width = size.width + 'px';
|
| 2312 |
-
viewer.style.height = size.height + 'px';
|
| 2313 |
-
|
| 2314 |
-
// μ¬μ΄λ μ΄κΈ°ν μ¬λΆ νμΈ
|
| 2315 |
-
if (!audioInitialized) {
|
| 2316 |
-
initializeAudio()
|
| 2317 |
-
.then(() => console.log('FlipBook μμ± μ μ€λμ€ μ΄κΈ°ν μλ£'))
|
| 2318 |
-
.catch(e => console.warn('FlipBook μμ± μ μ€λμ€ μ΄κΈ°ν μ€ν¨:', e));
|
| 2319 |
-
}
|
| 2320 |
-
|
| 2321 |
-
// νμ΄μ§ λ°μ΄ν° μ μ (λΉ νμ΄μ§ μ²λ¦¬)
|
| 2322 |
-
const validPages = pages.map(page => {
|
| 2323 |
-
// srcκ° μλ νμ΄μ§λ λ‘λ© μ€ μ΄λ―Έμ§λ‘ λ체
|
| 2324 |
-
if (!page || !page.src) {
|
| 2325 |
-
return {
|
| 2326 |
-
src: 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAwIiBoZWlnaHQ9IjEwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZjVmNWY1Ii8+PHRleHQgeD0iNTAlIiB5PSI1MCUiIGZvbnQtZmFtaWx5PSJBcmlhbCIgZm9udC1zaXplPSIxMiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZHk9Ii4zZW0iIGZpbGw9IiM1NTUiPkxvYWRpbmcuLi48L3RleHQ+PC9zdmc+',
|
| 2327 |
-
thumb: page && page.thumb ? page.thumb : ''
|
| 2328 |
-
};
|
| 2329 |
-
}
|
| 2330 |
-
return page;
|
| 2331 |
-
});
|
| 2332 |
-
|
| 2333 |
-
fb = new FlipBook(viewer, {
|
| 2334 |
-
pages: validPages,
|
| 2335 |
-
viewMode: 'webgl',
|
| 2336 |
-
autoSize: true,
|
| 2337 |
-
flipDuration: 800,
|
| 2338 |
-
backgroundColor: '#fff',
|
| 2339 |
-
/* π λ΄μ₯ μ¬μ΄λ */
|
| 2340 |
-
sound: true,
|
| 2341 |
-
assets: {flipMp3: '/static/turnPage2.mp3', hardFlipMp3: '/static/turnPage2.mp3'}, // μ λ κ²½λ‘λ‘ μμ
|
| 2342 |
-
controlsProps: {
|
| 2343 |
-
enableFullscreen: true,
|
| 2344 |
-
enableToc: true,
|
| 2345 |
-
enableDownload: false,
|
| 2346 |
-
enablePrint: false,
|
| 2347 |
-
enableZoom: true,
|
| 2348 |
-
enableShare: true, // 곡μ λ²νΌ νμ±ν
|
| 2349 |
-
enableSearch: true,
|
| 2350 |
-
enableAutoPlay: true,
|
| 2351 |
-
enableAnnotation: false,
|
| 2352 |
-
enableSound: true,
|
| 2353 |
-
enableLightbox: false,
|
| 2354 |
-
layout: 10, // λ μ΄μμ μ΅μ
|
| 2355 |
-
skin: 'light', // μ€ν¨ μ€νμΌ
|
| 2356 |
-
autoNavigationTime: 3600, // μλ λκΉ μκ°(μ΄)
|
| 2357 |
-
hideControls: false, // 컨νΈλ‘€ μ¨κΉ λΉνμ±ν
|
| 2358 |
-
paddingTop: 10, // μλ¨ ν¨λ©
|
| 2359 |
-
paddingLeft: 10, // μ’μΈ‘ ν¨λ©
|
| 2360 |
-
paddingRight: 10, // μ°μΈ‘ ν¨λ©
|
| 2361 |
-
paddingBottom: 10, // νλ¨ ν¨λ©
|
| 2362 |
-
pageTextureSize: 1024, // νμ΄μ§ ν
μ€μ² ν¬κΈ°
|
| 2363 |
-
thumbnails: true, // μ¬λ€μΌ νμ±ν
|
| 2364 |
-
autoHideControls: false, // μλ μ¨κΉ λΉνμ±ν
|
| 2365 |
-
controlsTimeout: 8000, // 컨νΈλ‘€ νμ μκ° μ°μ₯
|
| 2366 |
-
shareHandler: copyPdfShareUrl // 곡μ νΈλ€λ¬ μ€μ
|
| 2367 |
-
}
|
| 2368 |
-
});
|
| 2369 |
-
|
| 2370 |
-
// νλ©΄ ν¬κΈ° λ³κ²½ μ FlipBook ν¬κΈ° μ‘°μ
|
| 2371 |
-
window.addEventListener('resize', () => {
|
| 2372 |
-
if (fb) {
|
| 2373 |
-
const newSize = calculateAspectRatio();
|
| 2374 |
-
viewer.style.width = newSize.width + 'px';
|
| 2375 |
-
viewer.style.height = newSize.height + 'px';
|
| 2376 |
-
fb.resize();
|
| 2377 |
-
}
|
| 2378 |
-
});
|
| 2379 |
-
|
| 2380 |
-
// FlipBook μμ± ν 컨νΈλ‘€λ° κ°μ νμ
|
| 2381 |
-
setTimeout(() => {
|
| 2382 |
try {
|
| 2383 |
-
//
|
| 2384 |
-
const
|
| 2385 |
-
|
| 2386 |
-
|
| 2387 |
-
|
| 2388 |
-
|
| 2389 |
-
|
| 2390 |
-
|
| 2391 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2392 |
}
|
| 2393 |
-
|
| 2394 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2395 |
}
|
| 2396 |
-
}
|
| 2397 |
-
|
| 2398 |
-
console.log('FlipBook μμ± μλ£');
|
| 2399 |
-
} catch (error) {
|
| 2400 |
-
console.error('FlipBook μμ± μ€ μ€λ₯ λ°μ:', error);
|
| 2401 |
-
showError("FlipBookμ μμ±νλ μ€ μ€λ₯κ° λ°μνμ΅λλ€.");
|
| 2402 |
-
}
|
| 2403 |
-
}
|
| 2404 |
|
| 2405 |
/* ββ λ€λΉκ²μ΄μ
ββ */
|
| 2406 |
-
$id('homeButton').onclick=()=>{
|
| 2407 |
-
if(fb) {
|
| 2408 |
-
fb.destroy();
|
| 2409 |
-
viewer.innerHTML = '';
|
| 2410 |
-
fb = null;
|
| 2411 |
-
}
|
| 2412 |
-
toggle(true);
|
| 2413 |
-
|
| 2414 |
-
// λ‘λ© μΈλμΌμ΄ν° μ 리
|
| 2415 |
-
if (pageLoadingInterval) {
|
| 2416 |
-
clearInterval(pageLoadingInterval);
|
| 2417 |
-
pageLoadingInterval = null;
|
| 2418 |
-
}
|
| 2419 |
-
$id('loadingPages').style.display = 'none';
|
| 2420 |
-
currentLoadingPdfPath = null;
|
| 2421 |
-
currentPdfId = null;
|
| 2422 |
-
};
|
| 2423 |
-
|
| 2424 |
function toggle(showHome){
|
| 2425 |
$id('home').style.display=showHome?'block':'none';
|
| 2426 |
$id('viewerPage').style.display=showHome?'none':'block';
|
|
@@ -2438,154 +2441,91 @@ function createFlipBook(pages) {
|
|
| 2438 |
/* -- κ΄λ¦¬μ κΈ°λ₯ -- */
|
| 2439 |
function setupAdminFunctions() {
|
| 2440 |
// κ΄λ¦¬μ λ²νΌ ν΄λ¦ - λͺ¨λ¬ νμ
|
| 2441 |
-
|
| 2442 |
-
|
| 2443 |
-
|
| 2444 |
-
|
| 2445 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2446 |
|
| 2447 |
// λͺ¨λ¬ λ«κΈ° λ²νΌ
|
| 2448 |
-
|
| 2449 |
-
|
| 2450 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2451 |
|
| 2452 |
// μν° ν€λ‘ λ‘κ·ΈμΈ
|
| 2453 |
-
|
| 2454 |
-
|
| 2455 |
-
|
| 2456 |
-
|
| 2457 |
-
});
|
| 2458 |
-
|
| 2459 |
-
// λ‘κ·ΈμΈ λ²νΌ
|
| 2460 |
-
$id('adminLoginButton').addEventListener('click', async function() {
|
| 2461 |
-
const password = $id('adminPasswordInput').value;
|
| 2462 |
-
|
| 2463 |
-
try {
|
| 2464 |
-
showLoading("λ‘κ·ΈμΈ μ€...");
|
| 2465 |
-
|
| 2466 |
-
const formData = new FormData();
|
| 2467 |
-
formData.append('password', password);
|
| 2468 |
-
|
| 2469 |
-
const response = await fetch('/api/admin-login', {
|
| 2470 |
-
method: 'POST',
|
| 2471 |
-
body: formData
|
| 2472 |
-
});
|
| 2473 |
-
|
| 2474 |
-
const data = await response.json();
|
| 2475 |
-
|
| 2476 |
-
hideLoading();
|
| 2477 |
-
|
| 2478 |
-
if (data.success) {
|
| 2479 |
-
// λ‘κ·ΈμΈ μ±κ³΅ - κ΄λ¦¬μ νμ΄μ§ νμ
|
| 2480 |
-
$id('adminLoginModal').style.display = 'none';
|
| 2481 |
-
showAdminPage();
|
| 2482 |
-
} else {
|
| 2483 |
-
// λ‘κ·ΈμΈ μ€ν¨
|
| 2484 |
-
showError("κ΄λ¦¬μ μΈμ¦ μ€ν¨: λΉλ°λ²νΈκ° μΌμΉνμ§ μμ΅λλ€.");
|
| 2485 |
}
|
| 2486 |
-
}
|
| 2487 |
-
console.error("κ΄λ¦¬μ λ‘κ·ΈμΈ μ€λ₯:", error);
|
| 2488 |
-
hideLoading();
|
| 2489 |
-
showError("λ‘κ·ΈμΈ μ²λ¦¬ μ€ μ€λ₯κ° λ°μνμ΅λλ€.");
|
| 2490 |
-
}
|
| 2491 |
-
});
|
| 2492 |
-
|
| 2493 |
-
// κ΄λ¦¬μ νμ΄μ§ λ€λ‘κ°κΈ°
|
| 2494 |
-
$id('adminBackButton').addEventListener('click', function() {
|
| 2495 |
-
$id('adminPage').style.display = 'none';
|
| 2496 |
-
$id('home').style.display = 'block';
|
| 2497 |
-
});
|
| 2498 |
-
}
|
| 2499 |
-
|
| 2500 |
-
/* ββ μΉ΄λ β FlipBook ββ */
|
| 2501 |
-
async function open(i) {
|
| 2502 |
-
// κΈ°μ‘΄ open ν¨μ λ΄μ©...
|
| 2503 |
-
}
|
| 2504 |
-
|
| 2505 |
-
/* ββ PDF IDλ‘ PDF μ΄κΈ° ββ */
|
| 2506 |
-
async function openPdfById(pdfId, pdfPath, isCached = false) {
|
| 2507 |
-
try {
|
| 2508 |
-
// μ€λμ€ μ΄κΈ°ν μλ
|
| 2509 |
-
await initializeAudio().catch(e => console.warn('PDF μ΄κΈ° μ μ€λμ€ μ΄κΈ°ν μ€ν¨:', e));
|
| 2510 |
-
|
| 2511 |
-
// λ¨Όμ ν νλ©΄μμ μΉ΄λλ₯Ό μ°Ύμμ ν΄λ¦νλ λ°©λ² μλ
|
| 2512 |
-
let foundCard = false;
|
| 2513 |
-
const cards = document.querySelectorAll('.card');
|
| 2514 |
-
|
| 2515 |
-
for (let i = 0; i < cards.length; i++) {
|
| 2516 |
-
if (cards[i].dataset.pdfId === pdfId) {
|
| 2517 |
-
cards[i].click();
|
| 2518 |
-
foundCard = true;
|
| 2519 |
-
break;
|
| 2520 |
}
|
| 2521 |
-
}
|
| 2522 |
-
|
| 2523 |
-
// μΉ΄λλ₯Ό μ°Ύμ§ λͺ»ν κ²½μ° μ§μ μ€ν
|
| 2524 |
-
if (!foundCard) {
|
| 2525 |
-
toggle(false);
|
| 2526 |
-
showLoading("PDF μ€λΉ μ€...");
|
| 2527 |
-
|
| 2528 |
-
let pages = [];
|
| 2529 |
|
| 2530 |
-
//
|
| 2531 |
-
if (
|
| 2532 |
-
|
| 2533 |
-
|
| 2534 |
-
|
|
|
|
| 2535 |
|
| 2536 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2537 |
hideLoading();
|
| 2538 |
-
|
| 2539 |
-
// νμ¬ μ΄λ¦° PDFμ ID μ μ₯
|
| 2540 |
-
currentPdfId = pdfId;
|
| 2541 |
-
return;
|
| 2542 |
}
|
| 2543 |
-
}
|
| 2544 |
-
console.error("μΊμ λ°μ΄ν° λ‘λ μ€ν¨:", error);
|
| 2545 |
-
}
|
| 2546 |
-
}
|
| 2547 |
-
|
| 2548 |
-
// μΈλ€μΌ κ°μ Έμ€κΈ°
|
| 2549 |
-
try {
|
| 2550 |
-
const thumbResponse = await fetch(`/api/pdf-thumbnail?path=${encodeURIComponent(pdfPath)}`);
|
| 2551 |
-
const thumbData = await thumbResponse.json();
|
| 2552 |
-
|
| 2553 |
-
if (thumbData.thumbnail) {
|
| 2554 |
-
pages = [{
|
| 2555 |
-
src: thumbData.thumbnail,
|
| 2556 |
-
thumb: thumbData.thumbnail,
|
| 2557 |
-
path: pdfPath,
|
| 2558 |
-
cached: isCached
|
| 2559 |
-
}];
|
| 2560 |
-
}
|
| 2561 |
-
} catch (error) {
|
| 2562 |
-
console.error("μΈλ€μΌ λ‘λ μ€ν¨:", error);
|
| 2563 |
}
|
| 2564 |
|
| 2565 |
-
//
|
| 2566 |
-
if (
|
| 2567 |
-
|
| 2568 |
-
|
| 2569 |
-
|
| 2570 |
-
}
|
| 2571 |
}
|
| 2572 |
-
|
| 2573 |
-
// νλ‘μ νΈμ μΆκ°νκ³ λ·°μ΄ μ€ν
|
| 2574 |
-
const projectId = projects.push(pages) - 1;
|
| 2575 |
-
hideLoading();
|
| 2576 |
-
open(projectId);
|
| 2577 |
-
|
| 2578 |
-
// νμ¬ μ΄λ¦° PDFμ ID μ μ₯
|
| 2579 |
-
currentPdfId = pdfId;
|
| 2580 |
}
|
| 2581 |
-
} catch (error) {
|
| 2582 |
-
console.error("PDF IDλ‘ μ΄κΈ° μ€ν¨:", error);
|
| 2583 |
-
hideLoading();
|
| 2584 |
-
showError("PDFλ₯Ό μ΄ μ μμ΅λλ€. λ€μ μλν΄μ£ΌμΈμ.");
|
| 2585 |
-
}
|
| 2586 |
-
}
|
| 2587 |
-
|
| 2588 |
-
|
| 2589 |
|
| 2590 |
// κ΄λ¦¬μ νμ΄μ§ νμ
|
| 2591 |
async function showAdminPage() {
|
|
|
|
| 1569 |
</div>
|
| 1570 |
</section>
|
| 1571 |
|
| 1572 |
+
<script>
|
| 1573 |
let projects=[], fb=null;
|
| 1574 |
const grid=document.getElementById('grid'), viewer=document.getElementById('viewer');
|
| 1575 |
pdfjsLib.GlobalWorkerOptions.workerSrc='/static/pdf.worker.js';
|
|
|
|
| 1584 |
// νμ¬ μ΄λ¦° PDFμ ID
|
| 1585 |
let currentPdfId = null;
|
| 1586 |
|
| 1587 |
+
// μ€λμ€ μ»¨ν
μ€νΈμ μ΄κΈ°ν μν κ΄λ¦¬
|
| 1588 |
+
let audioInitialized = false;
|
| 1589 |
+
let audioContext = null;
|
| 1590 |
|
| 1591 |
+
// μ€λμ€ μ΄κΈ°ν ν¨μ
|
| 1592 |
+
function initializeAudio() {
|
| 1593 |
+
if (audioInitialized) return Promise.resolve();
|
| 1594 |
+
|
| 1595 |
+
return new Promise((resolve) => {
|
| 1596 |
+
// μ€λμ€ μ»¨ν
μ€νΈ μμ± (μ¬μ©μ μνΈμμ©μ΄ νμ μλ μ΄κΈ°ν)
|
| 1597 |
+
audioContext = new (window.AudioContext || window.webkitAudioContext)();
|
| 1598 |
+
|
| 1599 |
+
// MP3 λ‘λ λ° μ΄κΈ°ν
|
| 1600 |
+
const audio = new Audio('/static/turnPage2.mp3');
|
| 1601 |
+
audio.volume = 0.01; // μ΅μ λ³Όλ₯¨μΌλ‘ μ€μ
|
| 1602 |
+
|
| 1603 |
+
// λ‘λλ μ€λμ€ μ¬μ μλ (μ¬μ©μ μνΈμμ© μꡬλ μ μμ)
|
| 1604 |
+
const playPromise = audio.play();
|
| 1605 |
+
|
| 1606 |
+
if (playPromise !== undefined) {
|
| 1607 |
+
playPromise
|
| 1608 |
+
.then(() => {
|
| 1609 |
+
// μ±κ³΅μ μΌλ‘ μ¬μλ¨ - μ¦μ μΌμμ μ§
|
| 1610 |
+
audio.pause();
|
| 1611 |
+
audioInitialized = true;
|
| 1612 |
+
console.log('μ€λμ€ μ΄κΈ°ν μ±κ³΅');
|
| 1613 |
+
resolve();
|
| 1614 |
+
})
|
| 1615 |
+
.catch((error) => {
|
| 1616 |
+
console.log('μλ μ€λμ€ μ΄κΈ°ν μ€ν¨, μ¬μ©μ μνΈμμ© νμ:', error);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1617 |
|
| 1618 |
+
// μ¬μ©μ μνΈμμ©μ΄ νμν κ²½μ°, μ΄λ²€νΈ 리μ€λ μΆκ°
|
| 1619 |
+
const initOnUserAction = function() {
|
| 1620 |
+
const tempAudio = new Audio('/static/turnPage2.mp3');
|
| 1621 |
+
tempAudio.volume = 0.01;
|
| 1622 |
+
tempAudio.play()
|
| 1623 |
+
.then(() => {
|
| 1624 |
+
tempAudio.pause();
|
| 1625 |
+
audioInitialized = true;
|
| 1626 |
+
console.log('μ¬μ©μ μνΈμμ©μΌλ‘ μ€λμ€ μ΄κΈ°ν μ±κ³΅');
|
| 1627 |
+
resolve();
|
| 1628 |
+
|
| 1629 |
+
// μ΄λ²€νΈ 리μ€λ μ κ±°
|
| 1630 |
+
['click', 'touchstart', 'keydown'].forEach(event => {
|
| 1631 |
+
document.removeEventListener(event, initOnUserAction, { capture: true });
|
| 1632 |
+
});
|
| 1633 |
+
})
|
| 1634 |
+
.catch(e => console.error('μ€λμ€ μ΄κΈ°ν μ€ν¨:', e));
|
| 1635 |
+
};
|
| 1636 |
|
| 1637 |
+
// μ¬μ©μ μνΈμμ© μ΄λ²€νΈμ 리μ€λ μΆκ°
|
| 1638 |
+
['click', 'touchstart', 'keydown'].forEach(event => {
|
| 1639 |
+
document.addEventListener(event, initOnUserAction, { once: true, capture: true });
|
| 1640 |
+
});
|
| 1641 |
|
| 1642 |
+
// νμ΄μ§ λ‘λ μ§ν μ¬μ©μμκ² μ€λμ€ νμ±ν μμ²
|
| 1643 |
+
if (window.location.pathname.startsWith('/view/')) {
|
| 1644 |
+
// μ€λμ€ νμ±ν μλ΄ λ©μμ§ νμ (λ°λ‘κ°κΈ° λ§ν¬λ‘ μ μν κ²½μ°)
|
| 1645 |
+
setTimeout(() => {
|
| 1646 |
+
const audioPrompt = document.createElement('div');
|
| 1647 |
+
audioPrompt.style.position = 'fixed';
|
| 1648 |
+
audioPrompt.style.bottom = '80px';
|
| 1649 |
+
audioPrompt.style.left = '50%';
|
| 1650 |
+
audioPrompt.style.transform = 'translateX(-50%)';
|
| 1651 |
+
audioPrompt.style.backgroundColor = 'rgba(0,0,0,0.7)';
|
| 1652 |
+
audioPrompt.style.color = 'white';
|
| 1653 |
+
audioPrompt.style.padding = '10px 20px';
|
| 1654 |
+
audioPrompt.style.borderRadius = '20px';
|
| 1655 |
+
audioPrompt.style.zIndex = '10000';
|
| 1656 |
+
audioPrompt.style.cursor = 'pointer';
|
| 1657 |
+
audioPrompt.innerHTML = 'νμ΄μ§ μ΄λλ ν΄λ¦νμ¬ μ리 ν¨κ³Ό νμ±ν <i class="fas fa-volume-up"></i>';
|
| 1658 |
+
audioPrompt.id = 'audioPrompt';
|
| 1659 |
+
|
| 1660 |
+
// ν΄λ¦ μ μ리 νμ±ν λ° λ©μμ§ μ κ±°
|
| 1661 |
+
audioPrompt.addEventListener('click', function() {
|
| 1662 |
+
initOnUserAction();
|
| 1663 |
+
audioPrompt.remove();
|
| 1664 |
+
});
|
| 1665 |
+
|
| 1666 |
+
document.body.appendChild(audioPrompt);
|
| 1667 |
+
|
| 1668 |
+
// 10μ΄ ν μλμΌλ‘ μ¨κΉ
|
| 1669 |
+
setTimeout(() => {
|
| 1670 |
+
if (document.getElementById('audioPrompt')) {
|
| 1671 |
+
document.getElementById('audioPrompt').remove();
|
| 1672 |
+
}
|
| 1673 |
+
}, 10000);
|
| 1674 |
+
}, 2000);
|
| 1675 |
+
}
|
| 1676 |
+
});
|
| 1677 |
+
} else {
|
| 1678 |
+
// λΈλΌμ°μ κ° Promise κΈ°λ° μ¬μμ μ§μνμ§ μλ κ²½μ°
|
| 1679 |
+
audioInitialized = true;
|
| 1680 |
+
resolve();
|
| 1681 |
+
}
|
| 1682 |
+
});
|
| 1683 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1684 |
|
| 1685 |
/* ββ μ νΈ ββ */
|
| 1686 |
function $id(id){return document.getElementById(id)}
|
| 1687 |
|
| 1688 |
+
// DOMμ΄ λ‘λλλ©΄ μ€ν
|
| 1689 |
+
document.addEventListener('DOMContentLoaded', function() {
|
|
|
|
| 1690 |
console.log("DOM λ‘λ μλ£, μ΄λ²€νΈ μ€μ μμ");
|
| 1691 |
|
| 1692 |
+
// μ€λμ€ μ΄κΈ°ν μλ
|
| 1693 |
+
initializeAudio().catch(e => console.warn('μ€λμ€ μ΄κΈ°ν μ€ν¨:', e));
|
| 1694 |
+
|
| 1695 |
// PDF μ
λ‘λ λ²νΌ
|
| 1696 |
const pdfBtn = document.getElementById('pdfUploadBtn');
|
| 1697 |
const pdfInput = document.getElementById('pdfInput');
|
|
|
|
| 1726 |
|
| 1727 |
// κ΄λ¦¬μ λ²νΌ μ΄λ²€νΈ μ€μ
|
| 1728 |
setupAdminFunctions();
|
| 1729 |
+
|
| 1730 |
+
// ν λ²νΌ μ΄λ²€νΈ μ€μ
|
| 1731 |
+
const homeButton = document.getElementById('homeButton');
|
| 1732 |
+
if (homeButton) {
|
| 1733 |
+
homeButton.addEventListener('click', function() {
|
| 1734 |
+
if(fb) {
|
| 1735 |
+
fb.destroy();
|
| 1736 |
+
viewer.innerHTML = '';
|
| 1737 |
+
fb = null;
|
| 1738 |
+
}
|
| 1739 |
+
toggle(true);
|
| 1740 |
+
|
| 1741 |
+
// λ‘λ© μΈλμΌμ΄ν° μ 리
|
| 1742 |
+
if (pageLoadingInterval) {
|
| 1743 |
+
clearInterval(pageLoadingInterval);
|
| 1744 |
+
pageLoadingInterval = null;
|
| 1745 |
+
}
|
| 1746 |
+
$id('loadingPages').style.display = 'none';
|
| 1747 |
+
currentLoadingPdfPath = null;
|
| 1748 |
+
currentPdfId = null;
|
| 1749 |
+
});
|
| 1750 |
+
}
|
| 1751 |
});
|
| 1752 |
|
| 1753 |
// μλ²μ PDF μ
λ‘λ ν¨μ
|
|
|
|
| 1784 |
}
|
| 1785 |
}
|
| 1786 |
|
| 1787 |
+
function addCard(i, thumb, title, isCached = false, pdfId = null) {
|
| 1788 |
+
const d = document.createElement('div');
|
| 1789 |
+
d.className = 'card fade-in';
|
| 1790 |
+
d.onclick = () => open(i);
|
| 1791 |
+
|
| 1792 |
+
// PDF IDκ° μμΌλ©΄ λ°μ΄ν° μμ±μΌλ‘ μ μ₯
|
| 1793 |
+
if (pdfId) {
|
| 1794 |
+
d.dataset.pdfId = pdfId;
|
| 1795 |
+
}
|
| 1796 |
+
|
| 1797 |
+
// μ λͺ© μ²λ¦¬
|
| 1798 |
+
const displayTitle = title ?
|
| 1799 |
+
(title.length > 15 ? title.substring(0, 15) + '...' : title) :
|
| 1800 |
+
'νλ‘μ νΈ ' + (i+1);
|
| 1801 |
+
|
| 1802 |
+
// μΊμ μν λ±μ§ μΆκ°
|
| 1803 |
+
const cachedBadge = isCached ?
|
| 1804 |
+
'<div class="cached-status">μΊμλ¨</div>' : '';
|
| 1805 |
+
|
| 1806 |
+
// λ°λ‘κ°κΈ° λ§ν¬ μΆκ° (PDF IDκ° μλ κ²½μ°μλ§)
|
| 1807 |
+
const linkHtml = pdfId ?
|
| 1808 |
+
`<div style="position: absolute; bottom: 55px; left: 50%; transform: translateX(-50%); z-index:5;">
|
| 1809 |
+
<a href="/view/${pdfId}" target="_blank" style="color:#4a6ee0; font-size:11px;">Share Link</a>
|
| 1810 |
+
</div>` : '';
|
| 1811 |
+
|
| 1812 |
+
d.innerHTML = `
|
| 1813 |
+
<div class="card-inner">
|
| 1814 |
+
${cachedBadge}
|
| 1815 |
+
<img src="${thumb}" alt="${displayTitle}" loading="lazy">
|
| 1816 |
+
${linkHtml}
|
| 1817 |
+
<p title="${title || 'νλ‘μ νΈ ' + (i+1)}">${displayTitle}</p>
|
| 1818 |
+
</div>
|
| 1819 |
+
`;
|
| 1820 |
+
grid.appendChild(d);
|
| 1821 |
+
|
| 1822 |
+
// νλ‘μ νΈκ° μμΌλ©΄ 'νλ‘μ νΈ μμ' λ©μμ§ μ¨κΈ°κΈ°
|
| 1823 |
+
$id('noProjects').style.display = 'none';
|
| 1824 |
+
}
|
|
|
|
|
|
|
| 1825 |
|
| 1826 |
/* ββ νλ‘μ νΈ μ μ₯ ββ */
|
| 1827 |
function save(pages, title, isCached = false, pdfId = null) {
|
|
|
|
| 1982 |
/* ββ PDF IDλ‘ PDF μ΄κΈ° ββ */
|
| 1983 |
async function openPdfById(pdfId, pdfPath, isCached = false) {
|
| 1984 |
try {
|
| 1985 |
+
// μ€λμ€ μ΄κΈ°ν μλ
|
| 1986 |
+
await initializeAudio().catch(e => console.warn('PDF μ΄κΈ° μ μ€λμ€ μ΄κΈ°ν μ€ν¨:', e));
|
| 1987 |
+
|
| 1988 |
// λ¨Όμ ν νλ©΄μμ μΉ΄λλ₯Ό μ°Ύμμ ν΄λ¦νλ λ°©λ² μλ
|
| 1989 |
let foundCard = false;
|
| 1990 |
const cards = document.querySelectorAll('.card');
|
|
|
|
| 2292 |
}
|
| 2293 |
}
|
| 2294 |
|
| 2295 |
+
function createFlipBook(pages) {
|
| 2296 |
+
console.log('FlipBook μμ± μμ. νμ΄μ§ μ:', pages.length);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2297 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2298 |
try {
|
| 2299 |
+
// νλ©΄ λΉμ¨ κ³μ°
|
| 2300 |
+
const calculateAspectRatio = () => {
|
| 2301 |
+
const windowWidth = window.innerWidth;
|
| 2302 |
+
const windowHeight = window.innerHeight;
|
| 2303 |
+
const aspectRatio = windowWidth / windowHeight;
|
| 2304 |
+
|
| 2305 |
+
// λλΉ λλ λμ΄ κΈ°μ€μΌλ‘ μ΅λ 90% μ ν
|
| 2306 |
+
let width, height;
|
| 2307 |
+
if (aspectRatio > 1) { // κ°λ‘ νλ©΄
|
| 2308 |
+
height = Math.min(windowHeight * 0.9, windowHeight - 40);
|
| 2309 |
+
width = height * aspectRatio * 0.8; // κ°λ‘ νλ©΄μμλ μ½κ° μ€μ
|
| 2310 |
+
if (width > windowWidth * 0.9) {
|
| 2311 |
+
width = windowWidth * 0.9;
|
| 2312 |
+
height = width / (aspectRatio * 0.8);
|
| 2313 |
+
}
|
| 2314 |
+
} else { // μΈλ‘ νλ©΄
|
| 2315 |
+
width = Math.min(windowWidth * 0.9, windowWidth - 40);
|
| 2316 |
+
height = width / aspectRatio * 0.9; // μΈλ‘ νλ©΄μμλ μ½κ° λλ¦Ό
|
| 2317 |
+
if (height > windowHeight * 0.9) {
|
| 2318 |
+
height = windowHeight * 0.9;
|
| 2319 |
+
width = height * aspectRatio * 0.9;
|
| 2320 |
+
}
|
| 2321 |
+
}
|
| 2322 |
+
|
| 2323 |
+
// μ΅μ μ¬μ΄μ¦ λ°ν
|
| 2324 |
+
return {
|
| 2325 |
+
width: Math.round(width),
|
| 2326 |
+
height: Math.round(height)
|
| 2327 |
+
};
|
| 2328 |
+
};
|
| 2329 |
+
|
| 2330 |
+
// μ΄κΈ° νλ©΄ λΉμ¨ κ³μ°
|
| 2331 |
+
const size = calculateAspectRatio();
|
| 2332 |
+
viewer.style.width = size.width + 'px';
|
| 2333 |
+
viewer.style.height = size.height + 'px';
|
| 2334 |
+
|
| 2335 |
+
// μ¬μ΄λ μ΄κΈ°ν μ¬λΆ νμΈ
|
| 2336 |
+
if (!audioInitialized) {
|
| 2337 |
+
initializeAudio()
|
| 2338 |
+
.then(() => console.log('FlipBook μμ± μ μ€λμ€ μ΄κΈ°ν μλ£'))
|
| 2339 |
+
.catch(e => console.warn('FlipBook μμ± μ μ€λμ€ μ΄κΈ°ν μ€ν¨:', e));
|
| 2340 |
}
|
| 2341 |
+
|
| 2342 |
+
// νμ΄μ§ λ°μ΄ν° μ μ (λΉ νμ΄μ§ μ²λ¦¬)
|
| 2343 |
+
const validPages = pages.map(page => {
|
| 2344 |
+
// srcκ° μλ νμ΄μ§λ λ‘λ© μ€ μ΄λ―Έμ§λ‘ λ체
|
| 2345 |
+
if (!page || !page.src) {
|
| 2346 |
+
return {
|
| 2347 |
+
src: 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAwIiBoZWlnaHQ9IjEwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZjVmNWY1Ii8+PHRleHQgeD0iNTAlIiB5PSI1MCUiIGZvbnQtZmFtaWx5PSJBcmlhbCIgZm9udC1zaXplPSIxMiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZHk9Ii4zZW0iIGZpbGw9IiM1NTUiPkxvYWRpbmcuLi48L3RleHQ+PC9zdmc+',
|
| 2348 |
+
thumb: page && page.thumb ? page.thumb : ''
|
| 2349 |
+
};
|
| 2350 |
+
}
|
| 2351 |
+
return page;
|
| 2352 |
+
});
|
| 2353 |
+
|
| 2354 |
+
fb = new FlipBook(viewer, {
|
| 2355 |
+
pages: validPages,
|
| 2356 |
+
viewMode: 'webgl',
|
| 2357 |
+
autoSize: true,
|
| 2358 |
+
flipDuration: 800,
|
| 2359 |
+
backgroundColor: '#fff',
|
| 2360 |
+
/* π λ΄μ₯ μ¬μ΄λ */
|
| 2361 |
+
sound: true,
|
| 2362 |
+
assets: {flipMp3: '/static/turnPage2.mp3', hardFlipMp3: '/static/turnPage2.mp3'}, // μ λ κ²½λ‘λ‘ μμ
|
| 2363 |
+
controlsProps: {
|
| 2364 |
+
enableFullscreen: true,
|
| 2365 |
+
enableToc: true,
|
| 2366 |
+
enableDownload: false,
|
| 2367 |
+
enablePrint: false,
|
| 2368 |
+
enableZoom: true,
|
| 2369 |
+
enableShare: true, // 곡μ λ²νΌ νμ±ν
|
| 2370 |
+
enableSearch: true,
|
| 2371 |
+
enableAutoPlay: true,
|
| 2372 |
+
enableAnnotation: false,
|
| 2373 |
+
enableSound: true,
|
| 2374 |
+
enableLightbox: false,
|
| 2375 |
+
layout: 10, // λ μ΄μμ μ΅μ
|
| 2376 |
+
skin: 'light', // μ€ν¨ μ€νμΌ
|
| 2377 |
+
autoNavigationTime: 3600, // μλ λκΉ μκ°(μ΄)
|
| 2378 |
+
hideControls: false, // 컨νΈλ‘€ μ¨κΉ λΉνμ±ν
|
| 2379 |
+
paddingTop: 10, // μλ¨ ν¨λ©
|
| 2380 |
+
paddingLeft: 10, // μ’μΈ‘ ν¨λ©
|
| 2381 |
+
paddingRight: 10, // μ°μΈ‘ ν¨λ©
|
| 2382 |
+
paddingBottom: 10, // νλ¨ ν¨λ©
|
| 2383 |
+
pageTextureSize: 1024, // νμ΄μ§ ν
μ€μ² ν¬κΈ°
|
| 2384 |
+
thumbnails: true, // μ¬λ€μΌ νμ±ν
|
| 2385 |
+
autoHideControls: false, // μλ μ¨κΉ λΉνμ±ν
|
| 2386 |
+
controlsTimeout: 8000, // 컨νΈλ‘€ νμ μκ° μ°μ₯
|
| 2387 |
+
shareHandler: copyPdfShareUrl // 곡μ νΈλ€λ¬ μ€μ
|
| 2388 |
+
}
|
| 2389 |
+
});
|
| 2390 |
+
|
| 2391 |
+
// νλ©΄ ν¬κΈ° λ³κ²½ μ FlipBook ν¬κΈ° μ‘°μ
|
| 2392 |
+
window.addEventListener('resize', () => {
|
| 2393 |
+
if (fb) {
|
| 2394 |
+
const newSize = calculateAspectRatio();
|
| 2395 |
+
viewer.style.width = newSize.width + 'px';
|
| 2396 |
+
viewer.style.height = newSize.height + 'px';
|
| 2397 |
+
fb.resize();
|
| 2398 |
+
}
|
| 2399 |
+
});
|
| 2400 |
+
|
| 2401 |
+
// FlipBook μμ± ν 컨νΈλ‘€λ° κ°μ νμ
|
| 2402 |
+
setTimeout(() => {
|
| 2403 |
+
try {
|
| 2404 |
+
// 컨νΈλ‘€λ° κ΄λ ¨ μμ μ°ΎκΈ° λ° μ€νμΌ μ μ©
|
| 2405 |
+
const menuBars = document.querySelectorAll('.flipbook-container .fb3d-menu-bar');
|
| 2406 |
+
if (menuBars && menuBars.length > 0) {
|
| 2407 |
+
menuBars.forEach(menuBar => {
|
| 2408 |
+
menuBar.style.display = 'block';
|
| 2409 |
+
menuBar.style.opacity = '1';
|
| 2410 |
+
menuBar.style.visibility = 'visible';
|
| 2411 |
+
menuBar.style.zIndex = '9999';
|
| 2412 |
+
});
|
| 2413 |
+
}
|
| 2414 |
+
} catch (e) {
|
| 2415 |
+
console.warn('컨νΈλ‘€λ° μ€νμΌ μ μ© μ€ μ€λ₯:', e);
|
| 2416 |
+
}
|
| 2417 |
+
}, 1000);
|
| 2418 |
+
|
| 2419 |
+
console.log('FlipBook μμ± μλ£');
|
| 2420 |
+
} catch (error) {
|
| 2421 |
+
console.error('FlipBook μμ± μ€ μ€λ₯ λ°μ:', error);
|
| 2422 |
+
showError("FlipBookμ μμ±νλ μ€ μ€λ₯κ° λ°μνμ΅λλ€.");
|
| 2423 |
}
|
| 2424 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2425 |
|
| 2426 |
/* ββ λ€λΉκ²μ΄μ
ββ */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2427 |
function toggle(showHome){
|
| 2428 |
$id('home').style.display=showHome?'block':'none';
|
| 2429 |
$id('viewerPage').style.display=showHome?'none':'block';
|
|
|
|
| 2441 |
/* -- κ΄λ¦¬μ κΈ°λ₯ -- */
|
| 2442 |
function setupAdminFunctions() {
|
| 2443 |
// κ΄λ¦¬μ λ²νΌ ν΄λ¦ - λͺ¨λ¬ νμ
|
| 2444 |
+
const adminButton = document.getElementById('adminButton');
|
| 2445 |
+
const adminLoginModal = document.getElementById('adminLoginModal');
|
| 2446 |
+
const adminLoginClose = document.getElementById('adminLoginClose');
|
| 2447 |
+
const adminLoginButton = document.getElementById('adminLoginButton');
|
| 2448 |
+
const adminPasswordInput = document.getElementById('adminPasswordInput');
|
| 2449 |
+
const adminBackButton = document.getElementById('adminBackButton');
|
| 2450 |
+
|
| 2451 |
+
if (adminButton) {
|
| 2452 |
+
adminButton.addEventListener('click', function() {
|
| 2453 |
+
if (adminLoginModal) {
|
| 2454 |
+
adminLoginModal.style.display = 'flex';
|
| 2455 |
+
if (adminPasswordInput) {
|
| 2456 |
+
adminPasswordInput.value = '';
|
| 2457 |
+
adminPasswordInput.focus();
|
| 2458 |
+
}
|
| 2459 |
+
}
|
| 2460 |
+
});
|
| 2461 |
+
}
|
| 2462 |
|
| 2463 |
// λͺ¨λ¬ λ«κΈ° λ²νΌ
|
| 2464 |
+
if (adminLoginClose) {
|
| 2465 |
+
adminLoginClose.addEventListener('click', function() {
|
| 2466 |
+
if (adminLoginModal) {
|
| 2467 |
+
adminLoginModal.style.display = 'none';
|
| 2468 |
+
}
|
| 2469 |
+
});
|
| 2470 |
+
}
|
| 2471 |
|
| 2472 |
// μν° ν€λ‘ λ‘κ·ΈμΈ
|
| 2473 |
+
if (adminPasswordInput) {
|
| 2474 |
+
adminPasswordInput.addEventListener('keyup', function(e) {
|
| 2475 |
+
if (e.key === 'Enter' && adminLoginButton) {
|
| 2476 |
+
adminLoginButton.click();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2477 |
}
|
| 2478 |
+
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2479 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2480 |
|
| 2481 |
+
// λ‘κ·ΈμΈ λ²νΌ
|
| 2482 |
+
if (adminLoginButton) {
|
| 2483 |
+
adminLoginButton.addEventListener('click', async function() {
|
| 2484 |
+
if (!adminPasswordInput) return;
|
| 2485 |
+
|
| 2486 |
+
const password = adminPasswordInput.value;
|
| 2487 |
|
| 2488 |
+
try {
|
| 2489 |
+
showLoading("λ‘κ·ΈμΈ μ€...");
|
| 2490 |
+
|
| 2491 |
+
const formData = new FormData();
|
| 2492 |
+
formData.append('password', password);
|
| 2493 |
+
|
| 2494 |
+
const response = await fetch('/api/admin-login', {
|
| 2495 |
+
method: 'POST',
|
| 2496 |
+
body: formData
|
| 2497 |
+
});
|
| 2498 |
+
|
| 2499 |
+
const data = await response.json();
|
| 2500 |
+
|
| 2501 |
+
hideLoading();
|
| 2502 |
+
|
| 2503 |
+
if (data.success) {
|
| 2504 |
+
// λ‘κ·ΈμΈ μ±κ³΅ - κ΄λ¦¬μ νμ΄μ§ νμ
|
| 2505 |
+
if (adminLoginModal) {
|
| 2506 |
+
adminLoginModal.style.display = 'none';
|
| 2507 |
+
}
|
| 2508 |
+
showAdminPage();
|
| 2509 |
+
} else {
|
| 2510 |
+
// λ‘κ·ΈμΈ μ€ν¨
|
| 2511 |
+
showError("κ΄λ¦¬μ μΈμ¦ μ€ν¨: λΉλ°λ²νΈκ° μΌμΉνμ§ μμ΅λλ€.");
|
| 2512 |
+
}
|
| 2513 |
+
} catch (error) {
|
| 2514 |
+
console.error("κ΄λ¦¬μ λ‘κ·ΈμΈ μ€λ₯:", error);
|
| 2515 |
hideLoading();
|
| 2516 |
+
showError("λ‘κ·ΈμΈ μ²λ¦¬ μ€ μ€λ₯κ° λ°μνμ΅λλ€.");
|
|
|
|
|
|
|
|
|
|
| 2517 |
}
|
| 2518 |
+
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2519 |
}
|
| 2520 |
|
| 2521 |
+
// κ΄λ¦¬μ νμ΄μ§ λ€λ‘κ°κΈ°
|
| 2522 |
+
if (adminBackButton) {
|
| 2523 |
+
adminBackButton.addEventListener('click', function() {
|
| 2524 |
+
document.getElementById('adminPage').style.display = 'none';
|
| 2525 |
+
document.getElementById('home').style.display = 'block';
|
| 2526 |
+
});
|
| 2527 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2528 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2529 |
|
| 2530 |
// κ΄λ¦¬μ νμ΄μ§ νμ
|
| 2531 |
async function showAdminPage() {
|