pwa works

This commit is contained in:
2026-06-14 23:38:06 +03:00
parent 7745bb2614
commit 933e56207e
8 changed files with 4998 additions and 88 deletions
+4 -2
View File
@@ -3,10 +3,12 @@
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
<link rel="apple-touch-icon" href="/icon-192.png" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover" />
<meta name="theme-color" content="#7c3aed" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="mobile-web-app-capable" content="yes" />
<title>JapLearn</title>
</head>
<body>
+4929 -46
View File
File diff suppressed because it is too large Load Diff
+1
View File
@@ -15,6 +15,7 @@
},
"dependencies": {
"@bokuweb/zstd-wasm": "^0.0.27",
"vite-plugin-pwa": "^1.3.0",
"wa-sqlite": "^1.0.0"
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

+5 -4
View File
@@ -1,11 +1,12 @@
{
"name": "Мое SQLite Приложение",
"short_name": "SQLite App",
"description": "Описание вашего приложения",
"name": "JapLearn",
"short_name": "JapLearn",
"description": "Интервальные повторения японских слов",
"start_url": "/",
"display": "standalone",
"orientation": "portrait",
"background_color": "#ffffff",
"theme_color": "#000000",
"theme_color": "#7c3aed",
"icons": [
{
"src": "/icon-192.png",
+28 -4
View File
@@ -36,13 +36,18 @@
* {
box-sizing: border-box;
-webkit-tap-highlight-color: transparent;
}
body {
margin: 0;
min-height: 100dvh;
min-height: 100svh;
display: flex;
flex-direction: column;
overscroll-behavior: none;
-webkit-overflow-scrolling: touch;
touch-action: manipulation;
}
#app {
@@ -53,10 +58,14 @@ body {
width: 100%;
margin: 0 auto;
padding: 0;
padding-left: env(safe-area-inset-left);
padding-right: env(safe-area-inset-right);
padding-bottom: env(safe-area-inset-bottom);
}
.app-header {
padding: 1.5rem 1.25rem 0.5rem;
padding-top: calc(1.5rem + env(safe-area-inset-top));
text-align: center;
}
@@ -134,9 +143,10 @@ body {
font-family: var(--sans);
font-size: 0.9rem;
font-weight: 600;
padding: 0.65rem 1rem;
padding: 0.75rem 1rem;
min-height: 48px;
border: 1px solid var(--border);
border-radius: 8px;
border-radius: 10px;
background: var(--card-bg);
color: var(--text-h);
cursor: pointer;
@@ -145,6 +155,9 @@ body {
align-items: center;
justify-content: center;
gap: 0.4rem;
-webkit-tap-highlight-color: transparent;
touch-action: manipulation;
user-select: none;
}
.btn:hover {
@@ -154,6 +167,7 @@ body {
.btn:active {
transform: scale(0.97);
opacity: 0.9;
}
.btn:disabled {
@@ -180,6 +194,7 @@ body {
background: var(--accent-light);
color: var(--text);
margin-top: auto;
min-height: 36px;
}
.status-bar.error {
@@ -194,6 +209,7 @@ body {
.app-footer {
padding: 1rem 1.25rem;
padding-bottom: calc(1rem + env(safe-area-inset-bottom));
text-align: center;
font-size: 0.75rem;
color: var(--text);
@@ -294,6 +310,7 @@ body {
position: sticky;
bottom: 0;
z-index: 10;
padding-bottom: env(safe-area-inset-bottom);
}
.nav-btn {
@@ -302,11 +319,14 @@ body {
font-size: 0.85rem;
font-weight: 600;
padding: 0.75rem 0.5rem;
min-height: 52px;
border: none;
background: transparent;
color: var(--text);
cursor: pointer;
transition: all 0.2s;
-webkit-tap-highlight-color: transparent;
touch-action: manipulation;
}
.nav-btn.active {
@@ -337,12 +357,14 @@ body {
}
.sets-list li {
padding: 12px 14px;
padding: 14px 14px;
min-height: 48px;
cursor: pointer;
border-bottom: 1px solid var(--border);
transition: background 0.15s;
font-weight: 500;
color: var(--text-h);
-webkit-tap-highlight-color: transparent;
}
.sets-list li:last-child {
@@ -379,7 +401,8 @@ body {
.sets-detail .mode-select {
width: 100%;
margin: 10px 0;
padding: 8px 10px;
padding: 10px;
min-height: 48px;
border: 1px solid var(--border);
border-radius: 8px;
background: var(--bg);
@@ -465,6 +488,7 @@ body {
.vote-btn {
font-size: 0.85rem;
padding: 0.75rem 0.5rem;
min-height: 52px;
}
.vote-easy {
+29 -30
View File
@@ -1,51 +1,49 @@
import { defineConfig } from 'vite';
import basicSsl from '@vitejs/plugin-basic-ssl'; // npm i -D @vitejs/plugin-basic-ssl
import basicSsl from '@vitejs/plugin-basic-ssl';
import { VitePWA } from 'vite-plugin-pwa';
export default defineConfig({
plugins: [basicSsl(),
VitePWA({
registerType: 'autoUpdate', // Автоматически обновлять SW при изменении кода
includeAssets: ['favicon.ico', 'apple-touch-icon.png', 'masked-icon.svg'],
plugins: [
// basicSsl(),
VitePWA({
registerType: 'autoUpdate',
includeAssets: ['favicon.svg', 'icon-192.png', 'icon-512.png'],
manifest: {
name: 'Мое PWA Приложение',
short_name: 'Моё PWA',
description: 'Описание моего приложения, работающего оффлайн',
theme_color: '#ffffff',
name: 'JapLearn',
short_name: 'JapLearn',
description: 'Интервальные повторения японских слов',
theme_color: '#7c3aed',
background_color: '#ffffff',
display: 'standalone', // Важно для открытия без интерфейса браузера
display: 'standalone',
orientation: 'portrait',
scope: '/',
start_url: '/',
// Иконки обязательны для iOS и Android. Минимум 192x192 и 512x512
icons: [
{
src: 'pwa-192x192.png',
src: 'icon-192.png',
sizes: '192x192',
type: 'image/png'
type: 'image/png',
},
{
src: 'pwa-512x512.png',
sizes: '512x512',
type: 'image/png'
},
{
src: 'pwa-512x512.png',
src: 'icon-512.png',
sizes: '512x512',
type: 'image/png',
purpose: 'any maskable' // Для адаптивных иконок Android
}
]
},
{
src: 'icon-512.png',
sizes: '512x512',
type: 'image/png',
purpose: 'any maskable',
},
],
},
workbox: {
// Стратегия кэширования для оффлайн-работы
globPatterns: ['**/*.{js,css,html,ico,png,svg,woff2}'],
// Если пользователь оффлайн и переходит по роуту, отдаем index.html
globPatterns: ['**/*.{js,css,html,ico,png,svg,woff2,wasm}'],
navigateFallback: '/index.html',
// Игнорируем запросы к API или внешним ресурсам, если они не должны кэшироваться
navigateFallbackDenylist: [/^\/api\//],
}
})
], // Добавит локальный HTTPS
},
}),
],
build: {
target: 'esnext',
@@ -59,6 +57,7 @@ export default defineConfig({
'Cross-Origin-Opener-Policy': 'same-origin',
'Cross-Origin-Embedder-Policy': 'require-corp',
},
host: true
host: true,
allowedHosts: ['jl.micialware.ru']
},
});