<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;
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;
}