Improve Blossom UI with thumbnails and full-width layout (v0.37.0)
Some checks failed
Go / build-and-release (push) Has been cancelled

- Make Blossom view use full available width
- Add "Upload new files" label with Select Files button on right
- Show image/video thumbnails in file list (48x48px)
- Add emoji icons for audio (🎵) and documents (📄)
- Show full hash on screens > 720px, truncated on smaller

Files modified:
- app/web/src/BlossomView.svelte: UI layout and thumbnail changes
- app/web/dist/*: Rebuilt bundle

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-25 13:07:25 +01:00
parent 0de4137a10
commit aea8fd31e7
5 changed files with 79 additions and 30 deletions

View File

@@ -159,10 +159,10 @@
function getMimeIcon(mimeType) {
const category = getMimeCategory(mimeType);
switch (category) {
case "image": return "";
case "video": return "";
case "audio": return "";
default: return "";
case "image": return "🖼️";
case "video": return "🎬";
case "audio": return "🎵";
default: return "📄";
}
}
@@ -464,6 +464,7 @@
{#if !isAdminView && !selectedAdminUser}
<div class="upload-section">
<span class="upload-label">Upload new files</span>
<input
type="file"
multiple
@@ -471,9 +472,6 @@
on:change={handleFileSelect}
class="file-input-hidden"
/>
<button class="select-btn" on:click={triggerFileInput} disabled={isUploading}>
Select Files
</button>
{#if selectedFiles.length > 0}
<span class="selected-count">{selectedFiles.length} file(s) selected</span>
<button
@@ -484,6 +482,9 @@
{isUploading ? uploadProgress : "Upload"}
</button>
{/if}
<button class="select-btn" on:click={triggerFileInput} disabled={isUploading}>
Select Files
</button>
</div>
{/if}
@@ -552,12 +553,19 @@
role="button"
tabindex="0"
>
<div class="blob-icon">
{getMimeIcon(blob.type)}
<div class="blob-thumbnail">
{#if getMimeCategory(blob.type) === "image"}
<img src={getBlobUrl(blob)} alt="" class="thumbnail-img" />
{:else if getMimeCategory(blob.type) === "video"}
<video src={getBlobUrl(blob)} class="thumbnail-video" muted preload="metadata"></video>
{:else}
<span class="thumbnail-icon">{getMimeIcon(blob.type)}</span>
{/if}
</div>
<div class="blob-info">
<div class="blob-hash" title={blob.sha256}>
{truncateHash(blob.sha256)}
<span class="hash-full">{blob.sha256}</span>
<span class="hash-truncated">{truncateHash(blob.sha256)}</span>
</div>
<div class="blob-meta">
<span class="blob-size">{formatSize(blob.size)}</span>
@@ -678,7 +686,7 @@
<style>
.blossom-view {
padding: 1em;
max-width: 900px;
width: 100%;
}
.header-section {
@@ -777,6 +785,12 @@
flex-wrap: wrap;
}
.upload-label {
color: var(--text-color);
font-size: 0.95em;
flex: 1;
}
.file-input-hidden {
display: none;
}
@@ -861,10 +875,27 @@
background-color: var(--sidebar-bg);
}
.blob-icon {
.blob-thumbnail {
width: 48px;
height: 48px;
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
background-color: var(--bg-color);
border-radius: 4px;
overflow: hidden;
}
.thumbnail-img,
.thumbnail-video {
width: 100%;
height: 100%;
object-fit: cover;
}
.thumbnail-icon {
font-size: 1.5em;
width: 2em;
text-align: center;
}
.blob-info {
@@ -878,6 +909,14 @@
color: var(--text-color);
}
.hash-full {
display: inline;
}
.hash-truncated {
display: none;
}
.blob-meta {
display: flex;
gap: 1em;
@@ -1263,6 +1302,16 @@
color: var(--text-color);
}
@media (max-width: 720px) {
.hash-full {
display: none;
}
.hash-truncated {
display: inline;
}
}
@media (max-width: 600px) {
.blob-item {
flex-wrap: wrap;
@@ -1271,7 +1320,7 @@
.blob-date {
width: 100%;
margin-top: 0.5em;
padding-left: 3em;
padding-left: 3.5em;
}
.modal-footer {