feat(server): track upload status via manifest and /status API

- Persist per-box file metadata in a .warpbox.json manifest, including IDs and status fields (pending/uploading/complete/failed)
- Add GET /box/:id/status to return current file states for clients polling upload progress
- Update upload handling to mark failures and completion in the manifest and decorate responses
- Add CSS states for loading/failed files and disable interactions for unavailable itemsfeat(server): track upload status via manifest and /status API

- Persist per-box file metadata in a .warpbox.json manifest, including IDs and status fields (pending/uploading/complete/failed)
- Add GET /box/:id/status to return current file states for clients polling upload progress
- Update upload handling to mark failures and completion in the manifest and decorate responses
- Add CSS states for loading/failed files and disable interactions for unavailable items
This commit is contained in:
2026-04-27 17:33:52 +03:00
parent b69ec8b99f
commit 698166d23d
6 changed files with 547 additions and 28 deletions

View File

@@ -40,14 +40,14 @@
<code>/box/{{ .BoxID }}</code>
</div>
<div class="win98-panel box-panel">
<div class="win98-panel box-panel" data-box-id="{{ .BoxID }}">
{{ if .Files }}
<div class="box-file-grid" aria-label="Uploaded files">
{{ range .Files }}
<a class="box-file" href="{{ .DownloadPath }}" download>
<a class="box-file {{ if .IsComplete }}is-complete{{ else if eq .Status "failed" }}is-failed{{ else }}is-loading{{ end }}" href="{{ if .IsComplete }}{{ .DownloadPath }}{{ else }}#{{ end }}" title="{{ .Title }}" data-file-id="{{ .ID }}" data-status="{{ .Status }}" {{ if .IsComplete }}download{{ else }}aria-disabled="true"{{ end }}>
<img class="box-file-icon" src="{{ .IconPath }}" alt="" aria-hidden="true">
<span class="box-file-name">{{ .Name }}</span>
<span class="box-file-meta">{{ .SizeLabel }} · {{ .MimeType }}</span>
<span class="box-file-meta">{{ .StatusLabel }} · {{ .SizeLabel }}</span>
</a>
{{ end }}
</div>
@@ -62,5 +62,6 @@
</div>
</section>
</main>
<script src="/static/js/box.js"></script>
</body>
</html>