changed load-image-btn in read-mode
authorPhiTux <redacted>
Sat, 4 Oct 2025 10:48:22 +0000 (12:48 +0200)
committerPhiTux <redacted>
Sat, 4 Oct 2025 10:48:22 +0000 (12:48 +0200)
frontend/src/lib/ImageViewer.svelte
frontend/src/routes/(authed)/+layout.svelte
frontend/src/routes/(authed)/read/+page.svelte
frontend/src/routes/(authed)/write/+page.svelte

index b2c752698bafc812a6f53c3c60e7046b04dc76e0..4526fc4d7c5e2a2db7c7995332c0d7569582b526 100644 (file)
                                <Fa icon={faChevronLeft} fw />
                        </button>
                        {#key images[currentIndex].uuid_filename}
-                               <img
-                                       class="fullscreen-image"
-                                       alt={images[currentIndex].filename}
-                                       src={images[currentIndex].src}
-                               />
+                               {#if images[currentIndex].src}
+                                       <img
+                                               class="fullscreen-image"
+                                               alt={images[currentIndex].filename}
+                                               src={images[currentIndex].src}
+                                       />
+                               {:else}
+                                       <div
+                                               class="spinner-border text-light position-absolute top-50 start-50 translate-middle"
+                                               role="status"
+                                       >
+                                               <span class="visually-hidden">Loading...</span>
+                                       </div>
+                               {/if}
                        {/key}
                        <div class="image-info">
                                <span class="image-name">{images[currentIndex].filename}</span>
                                        class="image-container {index === currentIndex ? 'active' : ''}"
                                        onclick={() => (currentIndex = index)}
                                >
-                                       <img class="image" alt={image.filename} src={image.src} />
+                                       <div class="image-thumb-wrapper">
+                                               {#if image.src}
+                                                       <img class="image" alt={image.filename} src={image.src} />
+                                               {:else}
+                                                       <div class="spinner-border text-light spinner-border-sm thumb-spinner" role="status">
+                                                               <span class="visually-hidden">Loading...</span>
+                                                       </div>
+                                               {/if}
+                                       </div>
                                </button>
                        {/each}
                </div>
                        onclick={() => openFullscreen(index)}
                        transition:slide={{ axis: 'x' }}
                >
-                       <img class="image" alt={image.filename} src={image.src} transition:fade />
+                       <div class="image-thumb-wrapper">
+                               {#if image.src}
+                                       <img class="image" alt={image.filename} src={image.src} transition:fade />
+                               {:else}
+                                       <div class="spinner-border text-secondary spinner-border-sm thumb-spinner" role="status">
+                                               <span class="visually-hidden">Loading...</span>
+                                       </div>
+                               {/if}
+                       </div>
                </button>
        {/each}
 </div>
                transition: transform 0.3s ease;
        }
 
+       .image-thumb-wrapper {
+               position: relative;
+               width: 150px;
+               height: 100px;
+               display: flex;
+               align-items: center;
+               justify-content: center;
+       }
+
        .fullscreen-overlay {
                position: fixed;
                top: 0;
index fdda7db852f1a5e0620e2063f2d7daf8f46cab3b..cc24e3d7c50a535b6f6abc9623aae7cf881d9486 100644 (file)
                background-color: rgba(240, 240, 240, 0.9);
                padding: 4px;
                border-radius: 5px;
+               z-index: 10;
        }
 
        .modal-body {
index 96058f4425ec976f908d3b396f6b04e7a8568fa3..83095a4a95ecd943d49ddea7eae56b915a56d613 100644 (file)
@@ -13,7 +13,7 @@
        import { faCloudArrowDown } from '@fortawesome/free-solid-svg-icons';
        import { Fa } from 'svelte-fa';
        import ImageViewer from '$lib/ImageViewer.svelte';
-       import { alwaysShowSidenav } from '$lib/helpers.js';
+       import { alwaysShowSidenav, formatBytes } from '$lib/helpers.js';
        import { getTranslate, getTolgee } from '@tolgee/svelte';
 
        const { t } = getTranslate();
                                        });
                                }
                        });
+                       getImagesTotalSize();
                }
        });
 
                }
        }
 
+       let totalImageSize = $state(0);
+       let totalImageAmount = $state(0);
+       let imageSizeCalculated = false;
+       function getImagesTotalSize() {
+               if (imageSizeCalculated) return;
+               imageSizeCalculated = true;
+               totalImageSize = 0;
+               totalImageAmount = 0;
+
+               for (let i = 0; i < logs.length; i++) {
+                       let log = logs[i];
+
+                       // skip log if no images in this day/log
+                       if (!log.images) {
+                               continue;
+                       }
+
+                       log.images.forEach((image) => {
+                               if (image.size) {
+                                       totalImageSize += image.size;
+                                       totalImageAmount += 1;
+                               }
+                       });
+               }
+       }
+
        let cancelDownload = new AbortController();
 
        function downloadFile(uuid) {
                        return;
                }
                isLoadingMonthForReading = true;
+               imageSizeCalculated = false;
 
                axios
                        .get(API_URL + '/logs/loadMonthForReading', {
                                                                                <div class="d-flex flex-row">
                                                                                        <button type="button" class="loadImageBtn" onclick={() => loadImages()}>
                                                                                                <Fa icon={faCloudArrowDown} class="me-2" size="2x" fw /><br />
-                                                                                               {$t('read.load_images')}
+                                                                                               {$t('read.load_images', {
+                                                                                                       count: totalImageAmount,
+                                                                                                       size: formatBytes(totalImageSize)
+                                                                                               })}
                                                                                        </button>
                                                                                </div>
                                                                        {:else}
                margin-top: 0.5rem;
                border-radius: 5px;
                transition: all ease 0.2s;
+               max-width: 200px;
+       }
+
+       :global(body[data-bs-theme='light'] .loadImageBtn) {
                background-color: #ccc;
        }
 
-       .loadImageBtn:hover {
+       :global(body[data-bs-theme='light'] .loadImageBtn:hover) {
                background-color: #bbb;
        }
 
index 331d5cdfb3f99cc9285a7e44c2c10d12b4493acb..40abbbf4e8f630dbef9edb59ca49029ed38d3b0f 100644 (file)
 </div>
 
 <style>
+       .text-muted.fst-italic {
+               color: rgba(228, 226, 230, 0.4) !important;
+       }
+
        #sidenav {
                padding-left: 1rem;
                padding-right: 1rem;
git clone https://git.99rst.org/PROJECT