Show detailed photo upload status
All checks were successful
CI / Lint (push) Successful in 31s
CI / Test (push) Successful in 56s

This commit is contained in:
2026-04-24 11:28:23 +01:00
parent cb4b9c6b40
commit b4a70233cf
3 changed files with 52 additions and 7 deletions

View File

@@ -22,6 +22,7 @@ export default class PlacePhotoUploadItem extends Component {
@tracked thumbnailUrl = '';
@tracked blurhash = '';
@tracked error = '';
@tracked statusText = '';
constructor() {
super(...arguments);
@@ -47,6 +48,7 @@ export default class PlacePhotoUploadItem extends Component {
uploadTask = task(async (file) => {
this.error = '';
this.statusText = 'Processing';
try {
// 1. Process main image and generate blurhash in worker
const mainData = await this.imageProcessor.process(
@@ -71,18 +73,34 @@ export default class PlacePhotoUploadItem extends Component {
let mainResult, thumbResult;
const isMobileDevice = isMobile();
const mainProgress = (status) => {
if (status === 'signing') this.statusText = 'Signing photo upload';
if (status === 'uploading') this.statusText = 'Uploading photo';
};
const thumbProgress = (status) => {
if (status === 'signing') this.statusText = 'Signing thumbnail upload';
if (status === 'uploading') this.statusText = 'Uploading thumbnail';
};
if (isMobileDevice) {
// Mobile: sequential uploads to preserve bandwidth and memory
mainResult = await this.blossom.upload(mainData.blob, {
sequential: true,
onProgress: mainProgress,
});
thumbResult = await this.blossom.upload(thumbData.blob, {
sequential: true,
onProgress: thumbProgress,
});
} else {
// Desktop: concurrent uploads
const mainUploadPromise = this.blossom.upload(mainData.blob);
const thumbUploadPromise = this.blossom.upload(thumbData.blob);
const mainUploadPromise = this.blossom.upload(mainData.blob, {
onProgress: mainProgress,
});
const thumbUploadPromise = this.blossom.upload(thumbData.blob, {
onProgress: thumbProgress,
});
[mainResult, thumbResult] = await Promise.all([
mainUploadPromise,
@@ -127,6 +145,9 @@ export default class PlacePhotoUploadItem extends Component {
@color="white"
class="spin-animation"
/>
{{#if this.statusText}}
<span class="upload-status-text">{{this.statusText}}</span>
{{/if}}
</div>
{{/if}}

View File

@@ -60,10 +60,13 @@ export default class BlossomService extends Service {
return `Nostr ${base64url}`;
}
async _uploadToServer(file, hash, serverUrl) {
async _uploadToServer(file, hash, serverUrl, onProgress) {
const uploadUrl = getBlossomUrl(serverUrl, 'upload');
if (onProgress) onProgress('signing');
const authHeader = await this._getAuthHeader('upload', hash, serverUrl);
if (onProgress) onProgress('uploading');
// eslint-disable-next-line warp-drive/no-external-request-patterns
const response = await fetch(uploadUrl, {
method: 'PUT',
@@ -109,14 +112,20 @@ export default class BlossomService extends Service {
if (options.sequential) {
// Sequential upload logic
mainResult = await this._uploadToServer(file, payloadHash, mainServer);
mainResult = await this._uploadToServer(
file,
payloadHash,
mainServer,
options.onProgress
);
for (const serverUrl of fallbackServers) {
try {
const result = await this._uploadToServer(
file,
payloadHash,
serverUrl
serverUrl,
options.onProgress
);
fallbackUrls.push(result.url);
} catch (error) {
@@ -125,9 +134,14 @@ export default class BlossomService extends Service {
}
} else {
// Concurrent upload logic
const mainPromise = this._uploadToServer(file, payloadHash, mainServer);
const mainPromise = this._uploadToServer(
file,
payloadHash,
mainServer,
options.onProgress
);
const fallbackPromises = fallbackServers.map((serverUrl) =>
this._uploadToServer(file, payloadHash, serverUrl)
this._uploadToServer(file, payloadHash, serverUrl, options.onProgress)
);
// Main server MUST succeed

View File

@@ -285,10 +285,20 @@ body {
inset: 0;
background: rgb(0 0 0 / 60%);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.upload-status-text {
color: white;
margin-top: 1rem;
font-size: 0.9rem;
text-shadow: 0 1px 3px rgb(0 0 0 / 80%);
text-align: center;
padding: 0 1rem;
}
.photo-upload-item .error-overlay {
background: rgb(224 108 117 / 80%);
cursor: pointer;