From f7e79e6136d3928d83f8dc38332a29b4b24bfeb5 Mon Sep 17 00:00:00 2001 From: Ali Orhun Akkirman Date: Sun, 27 Sep 2026 17:53:38 +0300 Subject: [PATCH 1/2] Add offline status backup restore and debounced saves --- README.md | 7 ++ index.html | 110 +++++++++++++++++++++++++- src/app.js | 224 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 334 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index bcb0ca4..6b06864 100644 --- a/README.md +++ b/README.md @@ -87,6 +87,13 @@ Sağ üstteki **Export** düğmesiyle mevcut sekme içeriği şu biçimlerde dı ### Dil Desteği Sağ üstteki **EN / TR** geçişiyle arayüz dili değiştirilebilir. Tercih `localStorage`'a kaydedilir. +### Offline durum, yedekleme ve kayıt +- Alt durum çubuğu tarayıcının çevrimiçi / çevrimdışı durumunu anlık gösterir. +- **Yedek** düğmesi tüm notebook'ları, aktif sekmeyi ve temel görünüm tercihlerini tek bir sürümlü JSON dosyasında dışa aktarır. +- Aynı JSON yedeği geri yüklenebilir; dosya biçimi ve notebook kayıtları uygulanmadan önce doğrulanır. +- Editör yazımları `localStorage`'a 300 ms debounce ile kaydedilir; sekme değişimi, dosya oluşturma/silme ve restore gibi yapısal işlemler anında kalıcılaştırılır. +- Sayfa arka plana geçerken bekleyen kayıt otomatik olarak flush edilir. + --- ## Kullanım diff --git a/index.html b/index.html index bdfcb8b..a5aa175 100644 --- a/index.html +++ b/index.html @@ -66,7 +66,7 @@ border-radius: 6px; padding: 2px; } -#export-btn, #info-btn { +#export-btn, #backup-btn, #info-btn { padding: 4px 10px; border: 1px solid #ced4da; background: #fff; @@ -82,7 +82,7 @@ gap: 4px; white-space: nowrap; } -#export-btn:hover, #info-btn:hover { +#export-btn:hover, #backup-btn:hover, #info-btn:hover { background: #f1f3f5; border-color: #1A71C2; color: #1A71C2; @@ -313,6 +313,33 @@ align-items: center; gap: 4px; } + +#connection-status { + display: inline-flex; + align-items: center; + gap: 5px; + min-width: 58px; + padding: 2px 6px; + border-radius: 999px; + color: #495057; + font-weight: 600; + white-space: nowrap; +} +#connection-status .connection-dot { + width: 7px; + height: 7px; + border-radius: 50%; + background: #40c057; + box-shadow: 0 0 0 2px rgba(64,192,87,0.12); +} +#connection-status.offline { + color: #c92a2a; + background: #fff5f5; +} +#connection-status.offline .connection-dot { + background: #fa5252; + box-shadow: 0 0 0 2px rgba(250,82,82,0.12); +} .zoom-btn { display: inline-flex; align-items: center; @@ -816,6 +843,54 @@ } #modal-confirm:hover, #export-confirm:hover { background: #1864ab; } +.backup-desc { + font-size: 12px; + line-height: 1.5; + color: #6c757d; + margin: -2px 0 14px; +} +.backup-option { + width: 100%; + display: flex; + align-items: flex-start; + gap: 10px; + padding: 11px 12px; + margin: 0 0 8px; + border: 1px solid #dee2e6; + border-radius: 6px; + background: #fff; + color: #343a40; + cursor: pointer; + text-align: left; + font-family: inherit; + transition: border-color 0.15s, background 0.15s; +} +.backup-option:hover { + border-color: #74c0fc; + background: #f8fbff; +} +.backup-option strong { + display: block; + font-size: 13px; + margin-bottom: 2px; +} +.backup-option span { + display: block; + font-size: 11px; + color: #868e96; + line-height: 1.4; +} +.backup-option-icon { + flex: 0 0 auto; + font-size: 16px; + line-height: 1.2; +} +#backup-close { + background: #f1f3f5; + color: #495057; +} +#backup-close:hover { background: #e9ecef; } + /* ── Insert FAB ────────────────────────────────────────────── */ #editor-pane { position: relative; } #insert-fab { @@ -893,6 +968,7 @@
+
@@ -918,6 +994,11 @@ 0 denklem
+ + + Online + + 100% @@ -969,6 +1050,31 @@
+ +