Update app.py
Browse files
app.py
CHANGED
|
@@ -400,9 +400,13 @@ def create_pwa_files():
|
|
| 400 |
"description": "현대 도시 속 디지털 의례 공간",
|
| 401 |
"start_url": "/",
|
| 402 |
"display": "standalone",
|
| 403 |
-
"background_color": "#
|
| 404 |
-
"theme_color": "#
|
| 405 |
"orientation": "portrait",
|
|
|
|
|
|
|
|
|
|
|
|
|
| 406 |
"icons": [
|
| 407 |
{
|
| 408 |
"src": "/static/icons/icon-72x72.png",
|
|
@@ -452,6 +456,14 @@ def create_pwa_files():
|
|
| 452 |
"type": "image/png",
|
| 453 |
"purpose": "any maskable"
|
| 454 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 455 |
]
|
| 456 |
}
|
| 457 |
with open(manifest_path, 'w', encoding='utf-8') as f:
|
|
@@ -532,7 +544,21 @@ self.addEventListener('fetch', event => {
|
|
| 532 |
<meta name="apple-mobile-web-app-capable" content="yes">
|
| 533 |
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
| 534 |
<meta name="apple-mobile-web-app-title" content="디지털 굿판">
|
| 535 |
-
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 536 |
<style>
|
| 537 |
/* iOS 상태바 영역 보호 */
|
| 538 |
body {
|
|
@@ -552,15 +578,142 @@ self.addEventListener('fetch', event => {
|
|
| 552 |
#gradio-app {
|
| 553 |
background: #0b0f19 !important;
|
| 554 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 555 |
</style>
|
| 556 |
<script>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 557 |
// 페이지 로드 시 상단으로 스크롤
|
| 558 |
window.addEventListener('load', function() {
|
| 559 |
setTimeout(() => {
|
| 560 |
window.scrollTo(0, 0);
|
| 561 |
}, 100);
|
| 562 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 563 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 564 |
// 화면 꺼짐 방지
|
| 565 |
async function preventSleep() {
|
| 566 |
try {
|
|
|
|
| 400 |
"description": "현대 도시 속 디지털 의례 공간",
|
| 401 |
"start_url": "/",
|
| 402 |
"display": "standalone",
|
| 403 |
+
"background_color": "#0b0f19",
|
| 404 |
+
"theme_color": "#0b0f19",
|
| 405 |
"orientation": "portrait",
|
| 406 |
+
"categories": ["art", "entertainment"],
|
| 407 |
+
"lang": "ko",
|
| 408 |
+
"dir": "ltr",
|
| 409 |
+
"prefer_related_applications": false,
|
| 410 |
"icons": [
|
| 411 |
{
|
| 412 |
"src": "/static/icons/icon-72x72.png",
|
|
|
|
| 456 |
"type": "image/png",
|
| 457 |
"purpose": "any maskable"
|
| 458 |
}
|
| 459 |
+
],
|
| 460 |
+
"screenshots": [
|
| 461 |
+
{
|
| 462 |
+
"src": "/static/screenshots/screenshot1.png",
|
| 463 |
+
"sizes": "1280x720",
|
| 464 |
+
"type": "image/png",
|
| 465 |
+
"label": "홈 화면"
|
| 466 |
+
}
|
| 467 |
]
|
| 468 |
}
|
| 469 |
with open(manifest_path, 'w', encoding='utf-8') as f:
|
|
|
|
| 544 |
<meta name="apple-mobile-web-app-capable" content="yes">
|
| 545 |
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
| 546 |
<meta name="apple-mobile-web-app-title" content="디지털 굿판">
|
| 547 |
+
<meta name="description" content="현대 도시 속 디지털 의례 공간">
|
| 548 |
+
|
| 549 |
+
<!-- iOS에서의 앱 아이콘 -->
|
| 550 |
+
<link rel="apple-touch-icon" href="/static/icons/icon-192x192.png">
|
| 551 |
+
<link rel="apple-touch-icon" sizes="152x152" href="/static/icons/icon-152x152.png">
|
| 552 |
+
<link rel="apple-touch-icon" sizes="180x180" href="/static/icons/icon-180x180.png">
|
| 553 |
+
<link rel="apple-touch-icon" sizes="167x167" href="/static/icons/icon-167x167.png">
|
| 554 |
+
|
| 555 |
+
<!-- iOS 스플래시 스크린 -->
|
| 556 |
+
<link rel="apple-touch-startup-image" href="/static/splash/apple-splash-2048-2732.png" media="(device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2)">
|
| 557 |
+
<link rel="apple-touch-startup-image" href="/static/splash/apple-splash-1668-2388.png" media="(device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2)">
|
| 558 |
+
<link rel="apple-touch-startup-image" href="/static/splash/apple-splash-1536-2048.png" media="(device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2)">
|
| 559 |
+
<link rel="apple-touch-startup-image" href="/static/splash/apple-splash-1125-2436.png" media="(device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3)">
|
| 560 |
+
<link rel="apple-touch-startup-image" href="/static/splash/apple-splash-828-1792.png" media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2)">
|
| 561 |
+
|
| 562 |
<style>
|
| 563 |
/* iOS 상태바 영역 보호 */
|
| 564 |
body {
|
|
|
|
| 578 |
#gradio-app {
|
| 579 |
background: #0b0f19 !important;
|
| 580 |
}
|
| 581 |
+
.install-prompt {
|
| 582 |
+
position: fixed;
|
| 583 |
+
bottom: 20px;
|
| 584 |
+
left: 50%;
|
| 585 |
+
transform: translateX(-50%);
|
| 586 |
+
background: #2a2f3e;
|
| 587 |
+
color: white;
|
| 588 |
+
padding: 15px 20px;
|
| 589 |
+
border-radius: 12px;
|
| 590 |
+
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
| 591 |
+
display: none;
|
| 592 |
+
z-index: 1000;
|
| 593 |
+
width: 90%;
|
| 594 |
+
max-width: 400px;
|
| 595 |
+
text-align: center;
|
| 596 |
+
}
|
| 597 |
+
|
| 598 |
+
.install-button {
|
| 599 |
+
background: #4a90e2;
|
| 600 |
+
color: white;
|
| 601 |
+
border: none;
|
| 602 |
+
padding: 10px 20px;
|
| 603 |
+
border-radius: 6px;
|
| 604 |
+
margin-top: 10px;
|
| 605 |
+
cursor: pointer;
|
| 606 |
+
font-weight: bold;
|
| 607 |
+
}
|
| 608 |
+
|
| 609 |
+
.close-prompt {
|
| 610 |
+
position: absolute;
|
| 611 |
+
top: 5px;
|
| 612 |
+
right: 10px;
|
| 613 |
+
background: none;
|
| 614 |
+
border: none;
|
| 615 |
+
color: white;
|
| 616 |
+
font-size: 20px;
|
| 617 |
+
cursor: pointer;
|
| 618 |
+
}
|
| 619 |
</style>
|
| 620 |
<script>
|
| 621 |
+
let deferredPrompt;
|
| 622 |
+
|
| 623 |
+
window.addEventListener('beforeinstallprompt', (e) => {
|
| 624 |
+
e.preventDefault();
|
| 625 |
+
deferredPrompt = e;
|
| 626 |
+
showInstallPrompt();
|
| 627 |
+
});
|
| 628 |
+
|
| 629 |
+
function showInstallPrompt() {
|
| 630 |
+
const prompt = document.createElement('div');
|
| 631 |
+
prompt.className = 'install-prompt';
|
| 632 |
+
prompt.innerHTML = `
|
| 633 |
+
<button class="close-prompt">×</button>
|
| 634 |
+
<p>디지털 굿판을 앱으로 설치하여 더 나은 경험을 누려보세요!</p>
|
| 635 |
+
<button class="install-button">앱 설치하기</button>
|
| 636 |
+
`;
|
| 637 |
+
document.body.appendChild(prompt);
|
| 638 |
+
|
| 639 |
+
// 설치 프롬프트 표시
|
| 640 |
+
setTimeout(() => {
|
| 641 |
+
prompt.style.display = 'block';
|
| 642 |
+
}, 2000);
|
| 643 |
+
|
| 644 |
+
// 닫기 버튼
|
| 645 |
+
prompt.querySelector('.close-prompt').addEventListener('click', () => {
|
| 646 |
+
prompt.remove();
|
| 647 |
+
});
|
| 648 |
+
|
| 649 |
+
// 설치 버튼
|
| 650 |
+
prompt.querySelector('.install-button').addEventListener('click', async () => {
|
| 651 |
+
if (deferredPrompt) {
|
| 652 |
+
deferredPrompt.prompt();
|
| 653 |
+
const { outcome } = await deferredPrompt.userChoice;
|
| 654 |
+
if (outcome === 'accepted') {
|
| 655 |
+
console.log('사용자가 앱 설치를 수락했습니다');
|
| 656 |
+
}
|
| 657 |
+
deferredPrompt = null;
|
| 658 |
+
prompt.remove();
|
| 659 |
+
}
|
| 660 |
+
});
|
| 661 |
+
}
|
| 662 |
+
|
| 663 |
+
// iOS Safari에서 설치 안내
|
| 664 |
+
if (navigator.standalone === false && navigator.userAgent.match(/Safari/i)) {
|
| 665 |
+
setTimeout(() => {
|
| 666 |
+
const iosPrompt = document.createElement('div');
|
| 667 |
+
iosPrompt.className = 'install-prompt';
|
| 668 |
+
iosPrompt.innerHTML = `
|
| 669 |
+
<button class="close-prompt">×</button>
|
| 670 |
+
<p>iOS에서 설치하기:<br>
|
| 671 |
+
1. 공유 버튼을 탭하세요 📤<br>
|
| 672 |
+
2. "홈 화면에 추가"를 선택하세요 ➕</p>
|
| 673 |
+
`;
|
| 674 |
+
document.body.appendChild(iosPrompt);
|
| 675 |
+
iosPrompt.style.display = 'block';
|
| 676 |
+
|
| 677 |
+
iosPrompt.querySelector('.close-prompt').addEventListener('click', () => {
|
| 678 |
+
iosPrompt.remove();
|
| 679 |
+
});
|
| 680 |
+
}, 2000);
|
| 681 |
+
}
|
| 682 |
// 페이지 로드 시 상단으로 스크롤
|
| 683 |
window.addEventListener('load', function() {
|
| 684 |
setTimeout(() => {
|
| 685 |
window.scrollTo(0, 0);
|
| 686 |
}, 100);
|
| 687 |
});
|
| 688 |
+
async function preventSleep() {
|
| 689 |
+
try {
|
| 690 |
+
if ('wakeLock' in navigator) {
|
| 691 |
+
const wakeLock = await navigator.wakeLock.request('screen');
|
| 692 |
+
console.log('화면 켜짐 유지 활성화');
|
| 693 |
+
|
| 694 |
+
document.addEventListener('visibilitychange', async () => {
|
| 695 |
+
if (document.visibilityState === 'visible') {
|
| 696 |
+
await preventSleep();
|
| 697 |
+
}
|
| 698 |
+
});
|
| 699 |
+
}
|
| 700 |
+
} catch (err) {
|
| 701 |
+
console.log('화면 켜짐 유지 실패:', err);
|
| 702 |
+
}
|
| 703 |
+
}
|
| 704 |
|
| 705 |
+
if ('serviceWorker' in navigator) {
|
| 706 |
+
window.addEventListener('load', async () => {
|
| 707 |
+
try {
|
| 708 |
+
const registration = await navigator.serviceWorker.register('/static/service-worker.js');
|
| 709 |
+
console.log('ServiceWorker 등록 성공:', registration.scope);
|
| 710 |
+
await preventSleep();
|
| 711 |
+
} catch (err) {
|
| 712 |
+
console.log('ServiceWorker 등록 실패:', err);
|
| 713 |
+
}
|
| 714 |
+
});
|
| 715 |
+
}
|
| 716 |
+
|
| 717 |
// 화면 꺼짐 방지
|
| 718 |
async function preventSleep() {
|
| 719 |
try {
|