Show detailed photo upload status
This commit is contained in:
@@ -22,6 +22,7 @@ export default class PlacePhotoUploadItem extends Component {
|
|||||||
@tracked thumbnailUrl = '';
|
@tracked thumbnailUrl = '';
|
||||||
@tracked blurhash = '';
|
@tracked blurhash = '';
|
||||||
@tracked error = '';
|
@tracked error = '';
|
||||||
|
@tracked statusText = '';
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super(...arguments);
|
super(...arguments);
|
||||||
@@ -47,6 +48,7 @@ export default class PlacePhotoUploadItem extends Component {
|
|||||||
|
|
||||||
uploadTask = task(async (file) => {
|
uploadTask = task(async (file) => {
|
||||||
this.error = '';
|
this.error = '';
|
||||||
|
this.statusText = 'Processing';
|
||||||
try {
|
try {
|
||||||
// 1. Process main image and generate blurhash in worker
|
// 1. Process main image and generate blurhash in worker
|
||||||
const mainData = await this.imageProcessor.process(
|
const mainData = await this.imageProcessor.process(
|
||||||
@@ -71,18 +73,34 @@ export default class PlacePhotoUploadItem extends Component {
|
|||||||
let mainResult, thumbResult;
|
let mainResult, thumbResult;
|
||||||
const isMobileDevice = isMobile();
|
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) {
|
if (isMobileDevice) {
|
||||||
// Mobile: sequential uploads to preserve bandwidth and memory
|
// Mobile: sequential uploads to preserve bandwidth and memory
|
||||||
mainResult = await this.blossom.upload(mainData.blob, {
|
mainResult = await this.blossom.upload(mainData.blob, {
|
||||||
sequential: true,
|
sequential: true,
|
||||||
|
onProgress: mainProgress,
|
||||||
});
|
});
|
||||||
thumbResult = await this.blossom.upload(thumbData.blob, {
|
thumbResult = await this.blossom.upload(thumbData.blob, {
|
||||||
sequential: true,
|
sequential: true,
|
||||||
|
onProgress: thumbProgress,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// Desktop: concurrent uploads
|
// Desktop: concurrent uploads
|
||||||
const mainUploadPromise = this.blossom.upload(mainData.blob);
|
const mainUploadPromise = this.blossom.upload(mainData.blob, {
|
||||||
const thumbUploadPromise = this.blossom.upload(thumbData.blob);
|
onProgress: mainProgress,
|
||||||
|
});
|
||||||
|
const thumbUploadPromise = this.blossom.upload(thumbData.blob, {
|
||||||
|
onProgress: thumbProgress,
|
||||||
|
});
|
||||||
|
|
||||||
[mainResult, thumbResult] = await Promise.all([
|
[mainResult, thumbResult] = await Promise.all([
|
||||||
mainUploadPromise,
|
mainUploadPromise,
|
||||||
@@ -127,6 +145,9 @@ export default class PlacePhotoUploadItem extends Component {
|
|||||||
@color="white"
|
@color="white"
|
||||||
class="spin-animation"
|
class="spin-animation"
|
||||||
/>
|
/>
|
||||||
|
{{#if this.statusText}}
|
||||||
|
<span class="upload-status-text">{{this.statusText}}</span>
|
||||||
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
|
|||||||
@@ -60,10 +60,13 @@ export default class BlossomService extends Service {
|
|||||||
return `Nostr ${base64url}`;
|
return `Nostr ${base64url}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
async _uploadToServer(file, hash, serverUrl) {
|
async _uploadToServer(file, hash, serverUrl, onProgress) {
|
||||||
const uploadUrl = getBlossomUrl(serverUrl, 'upload');
|
const uploadUrl = getBlossomUrl(serverUrl, 'upload');
|
||||||
|
|
||||||
|
if (onProgress) onProgress('signing');
|
||||||
const authHeader = await this._getAuthHeader('upload', hash, serverUrl);
|
const authHeader = await this._getAuthHeader('upload', hash, serverUrl);
|
||||||
|
|
||||||
|
if (onProgress) onProgress('uploading');
|
||||||
// eslint-disable-next-line warp-drive/no-external-request-patterns
|
// eslint-disable-next-line warp-drive/no-external-request-patterns
|
||||||
const response = await fetch(uploadUrl, {
|
const response = await fetch(uploadUrl, {
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
@@ -109,14 +112,20 @@ export default class BlossomService extends Service {
|
|||||||
|
|
||||||
if (options.sequential) {
|
if (options.sequential) {
|
||||||
// Sequential upload logic
|
// Sequential upload logic
|
||||||
mainResult = await this._uploadToServer(file, payloadHash, mainServer);
|
mainResult = await this._uploadToServer(
|
||||||
|
file,
|
||||||
|
payloadHash,
|
||||||
|
mainServer,
|
||||||
|
options.onProgress
|
||||||
|
);
|
||||||
|
|
||||||
for (const serverUrl of fallbackServers) {
|
for (const serverUrl of fallbackServers) {
|
||||||
try {
|
try {
|
||||||
const result = await this._uploadToServer(
|
const result = await this._uploadToServer(
|
||||||
file,
|
file,
|
||||||
payloadHash,
|
payloadHash,
|
||||||
serverUrl
|
serverUrl,
|
||||||
|
options.onProgress
|
||||||
);
|
);
|
||||||
fallbackUrls.push(result.url);
|
fallbackUrls.push(result.url);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -125,9 +134,14 @@ export default class BlossomService extends Service {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Concurrent upload logic
|
// Concurrent upload logic
|
||||||
const mainPromise = this._uploadToServer(file, payloadHash, mainServer);
|
const mainPromise = this._uploadToServer(
|
||||||
|
file,
|
||||||
|
payloadHash,
|
||||||
|
mainServer,
|
||||||
|
options.onProgress
|
||||||
|
);
|
||||||
const fallbackPromises = fallbackServers.map((serverUrl) =>
|
const fallbackPromises = fallbackServers.map((serverUrl) =>
|
||||||
this._uploadToServer(file, payloadHash, serverUrl)
|
this._uploadToServer(file, payloadHash, serverUrl, options.onProgress)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Main server MUST succeed
|
// Main server MUST succeed
|
||||||
|
|||||||
@@ -285,10 +285,20 @@ body {
|
|||||||
inset: 0;
|
inset: 0;
|
||||||
background: rgb(0 0 0 / 60%);
|
background: rgb(0 0 0 / 60%);
|
||||||
display: flex;
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: 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 {
|
.photo-upload-item .error-overlay {
|
||||||
background: rgb(224 108 117 / 80%);
|
background: rgb(224 108 117 / 80%);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|||||||
Reference in New Issue
Block a user