From afaaaab5f05622d4849f81540d4e20b4d3660df2 Mon Sep 17 00:00:00 2001 From: Iu Date: Tue, 20 Oct 2026 22:27:24 +0300 Subject: [PATCH] =?UTF-8?q?feat(web):=20=D0=BE=D1=84=D0=BB=D0=B0=D0=B9?= =?UTF-8?q?=D0=BD-=D1=80=D0=B5=D0=B6=D0=B8=D0=BC=20=D1=81=20=D0=BA=D0=B5?= =?UTF-8?q?=D1=88=D0=B5=D0=BC=20=D1=8D=D1=81=D0=BA=D0=B8=D0=B7=D0=BE=D0=B2?= =?UTF-8?q?=20=D0=B8=20=D0=BF=D1=80=D0=B5=D0=B2=D1=8C=D1=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Добавлен service worker: оболочка приложения, ответы API и варианты изображений (эскиз, превью, средний) сохраняются в офлайн-кеше браузера. Ключ кеша картинки — путь объекта без подписи, поэтому обновление подписи не плодит записи; оригиналы и видео не кешируются. Кеш ограничен по размеру и вытесняет старые записи, при выходе из аккаунта очищается, а в верхней панели появляется индикатор «Офлайн». Добавлен манифест PWA; манифест отдаётся с типом application/manifest+json. --- README.md | 3 +- backend/internal/app/app.go | 5 + frontend/src/app.html | 4 + frontend/src/lib/components/AppShell.svelte | 22 ++ frontend/src/lib/offline.test.ts | 29 +++ frontend/src/lib/offline.ts | 49 +++++ frontend/src/service-worker.ts | 216 ++++++++++++++++++++ frontend/static/manifest.webmanifest | 17 ++ openspec/specs/ui-workspace/spec.md | 29 +++ 9 files changed, 373 insertions(+), 1 deletion(-) create mode 100644 frontend/src/lib/offline.test.ts create mode 100644 frontend/src/lib/offline.ts create mode 100644 frontend/src/service-worker.ts create mode 100644 frontend/static/manifest.webmanifest diff --git a/README.md b/README.md index 5ef8d4b..f97d1a1 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,8 @@ SvelteKit через `go:embed`, запуск через systemd. - **Backend:** Go, Gin, pgx (PostgreSQL на `pg.localnet`), AWS SDK v2 (Garage на `s3.localnet`, path-style), нативный SSE, golang-migrate, slog. -- **Frontend:** SvelteKit 2 + Svelte 5, adapter-static, TypeScript, TailwindCSS. +- **Frontend:** SvelteKit 2 + Svelte 5, adapter-static, TypeScript, TailwindCSS, + service worker с офлайн-кешем оболочки, списков и эскизов/превью фотографий. - **Обработка изображений:** `disintegration/imaging` + `gen2brain/webp` + `rwcarlsen/goexif` (всё чистый Go). diff --git a/backend/internal/app/app.go b/backend/internal/app/app.go index d30488e..ec1ca8b 100644 --- a/backend/internal/app/app.go +++ b/backend/internal/app/app.go @@ -364,6 +364,11 @@ func (s *Server) registerStatic(r *gin.Engine) { if clean != "" { if f, err := sub.Open(clean); err == nil { f.Close() + // Манифест PWA отдаём с правильным типом: в системной таблице + // mime расширения .webmanifest нет. + if strings.HasSuffix(clean, ".webmanifest") { + c.Header("Content-Type", "application/manifest+json") + } fileServer.ServeHTTP(c.Writer, c.Request) return } diff --git a/frontend/src/app.html b/frontend/src/app.html index 06cf16b..6bf0a33 100644 --- a/frontend/src/app.html +++ b/frontend/src/app.html @@ -6,6 +6,10 @@ + + + + @@ -245,6 +257,16 @@
+ {#if !online} + + {/if} {#if panel && panelVisible}