zero-knowledge file sharing
13
fork

Configure Feed

Select the types of activity you want to include in your feed.

add loading screen

Juliet c1220962 4add0fc1

+115 -108
+115 -108
web/src/pages/Upload.tsx
··· 40 40 const [maxFileSize, setMaxFileSize] = createSignal(0); 41 41 const [maxTtl, setMaxTtl] = createSignal(""); 42 42 const [expiryValue, setExpiryValue] = createSignal(""); 43 + const [loading, setLoading] = createSignal(true); 43 44 44 45 let fileInput!: HTMLInputElement; 45 46 let activeXhr: XMLHttpRequest | null = null; ··· 142 143 } 143 144 } 144 145 } catch {} 146 + setLoading(false); 145 147 }); 146 148 147 149 onCleanup(() => { ··· 295 297 </svg> 296 298 297 299 <div class="z-10 flex flex-col items-center text-center"> 298 - <Show when={view() === "result"}> 299 - <div class={viewClass} style={fadeIn}> 300 - <span 301 - class="text-muted" 302 - style={{ "font-size": "clamp(0.75rem, 2vw, 1rem)" }} 303 - > 304 - expires in {expiryValue()} 305 - </span> 306 - <button class={btnClass} style={btnStyle} onClick={copyLink}> 307 - {copied() ? "copied!" : "copy link"} 308 - </button> 309 - <button 310 - class={ghostClass} 311 - onClick={(e) => { 312 - e.stopPropagation(); 313 - setResultUrl(""); 314 - removeFile(); 315 - }} 316 - > 317 - new drop 318 - </button> 319 - </div> 300 + <Show when={loading()}> 301 + <span class="text-muted text-xs">loading…</span> 320 302 </Show> 303 + <Show when={!loading()}> 304 + <Show when={view() === "result"}> 305 + <div class={viewClass} style={fadeIn}> 306 + <span 307 + class="text-muted" 308 + style={{ "font-size": "clamp(0.75rem, 2vw, 1rem)" }} 309 + > 310 + expires in {expiryValue()} 311 + </span> 312 + <button class={btnClass} style={btnStyle} onClick={copyLink}> 313 + {copied() ? "copied!" : "copy link"} 314 + </button> 315 + <button 316 + class={ghostClass} 317 + onClick={(e) => { 318 + e.stopPropagation(); 319 + setResultUrl(""); 320 + removeFile(); 321 + }} 322 + > 323 + new drop 324 + </button> 325 + </div> 326 + </Show> 321 327 322 - <Show when={view() === "uploading"}> 323 - <div class={viewClass} style={fadeIn}> 324 - <span 325 - class="text-accent font-medium tabular-nums" 326 - style={{ "font-size": "clamp(1.5rem, 5vw, 2.5rem)" }} 327 - > 328 - {progress()}% 329 - </span> 330 - <span class="text-muted text-xs"> 331 - {status() === "encrypting" 332 - ? "encrypting\u2026" 333 - : "uploading\u2026"} 334 - </span> 335 - <button 336 - class={ghostClass} 337 - onClick={(e) => { 338 - e.stopPropagation(); 339 - cancelUpload(); 340 - }} 341 - > 342 - cancel 343 - </button> 344 - </div> 345 - </Show> 328 + <Show when={view() === "uploading"}> 329 + <div class={viewClass} style={fadeIn}> 330 + <span 331 + class="text-accent font-medium tabular-nums" 332 + style={{ "font-size": "clamp(1.5rem, 5vw, 2.5rem)" }} 333 + > 334 + {progress()}% 335 + </span> 336 + <span class="text-muted text-xs"> 337 + {status() === "encrypting" 338 + ? "encrypting\u2026" 339 + : "uploading\u2026"} 340 + </span> 341 + <button 342 + class={ghostClass} 343 + onClick={(e) => { 344 + e.stopPropagation(); 345 + cancelUpload(); 346 + }} 347 + > 348 + cancel 349 + </button> 350 + </div> 351 + </Show> 346 352 347 - <Show when={view() === "file"}> 348 - <div class={viewClass} style={fadeIn}> 349 - <span 350 - class="text-text flex gap-1.5 truncate" 351 - style={{ "max-width": "clamp(120px, 40vw, 300px)" }} 352 - > 353 + <Show when={view() === "file"}> 354 + <div class={viewClass} style={fadeIn}> 353 355 <span 354 - class="truncate" 355 - style={{ "font-size": "clamp(0.75rem, 2vw, 1rem)" }} 356 + class="text-text flex gap-1.5 truncate" 357 + style={{ "max-width": "clamp(120px, 40vw, 300px)" }} 356 358 > 357 - {file()!.name} 359 + <span 360 + class="truncate" 361 + style={{ "font-size": "clamp(0.75rem, 2vw, 1rem)" }} 362 + > 363 + {file()!.name} 364 + </span> 365 + <span 366 + class={`shrink-0 font-medium ${tooLarge() ? "text-danger" : "text-muted"}`} 367 + style={{ "font-size": "clamp(0.75rem, 2vw, 1rem)" }} 368 + > 369 + {tooLarge() 370 + ? `${formatBytes(file()!.size)} / ${formatBytes(maxFileSize())}` 371 + : formatBytes(file()!.size)} 372 + </span> 358 373 </span> 374 + <button 375 + class={`${btnClass} disabled:cursor-not-allowed disabled:opacity-40`} 376 + style={btnStyle} 377 + disabled={tooLarge()} 378 + onClick={(e) => { 379 + e.stopPropagation(); 380 + handleUpload(); 381 + }} 382 + > 383 + upload 384 + </button> 385 + <button 386 + class={ghostClass} 387 + onClick={(e) => { 388 + e.stopPropagation(); 389 + removeFile(); 390 + }} 391 + > 392 + remove 393 + </button> 394 + </div> 395 + </Show> 396 + 397 + <Show when={view() === "empty"}> 398 + <div class={viewClass} style={fadeIn}> 359 399 <span 360 - class={`shrink-0 font-medium ${tooLarge() ? "text-danger" : "text-muted"}`} 400 + class="text-muted font-medium" 361 401 style={{ "font-size": "clamp(0.75rem, 2vw, 1rem)" }} 362 402 > 363 - {tooLarge() 364 - ? `${formatBytes(file()!.size)} / ${formatBytes(maxFileSize())}` 365 - : formatBytes(file()!.size)} 403 + drop a file, or 366 404 </span> 367 - </span> 368 - <button 369 - class={`${btnClass} disabled:cursor-not-allowed disabled:opacity-40`} 370 - style={btnStyle} 371 - disabled={tooLarge()} 372 - onClick={(e) => { 373 - e.stopPropagation(); 374 - handleUpload(); 375 - }} 376 - > 377 - upload 378 - </button> 379 - <button 380 - class={ghostClass} 381 - onClick={(e) => { 382 - e.stopPropagation(); 383 - removeFile(); 384 - }} 385 - > 386 - remove 387 - </button> 388 - </div> 389 - </Show> 390 - 391 - <Show when={view() === "empty"}> 392 - <div class={viewClass} style={fadeIn}> 393 - <span 394 - class="text-muted font-medium" 395 - style={{ "font-size": "clamp(0.75rem, 2vw, 1rem)" }} 396 - > 397 - drop a file, or 398 - </span> 399 - <button 400 - class={btnClass} 401 - style={btnStyle} 402 - onClick={(e) => { 403 - e.stopPropagation(); 404 - fileInput.click(); 405 - }} 406 - > 407 - browse 408 - </button> 409 - <Show when={maxFileSize()}> 410 - <span class="text-muted text-xs"> 411 - up to {formatBytes(maxFileSize())} 412 - </span> 413 - </Show> 414 - </div> 405 + <button 406 + class={btnClass} 407 + style={btnStyle} 408 + onClick={(e) => { 409 + e.stopPropagation(); 410 + fileInput.click(); 411 + }} 412 + > 413 + browse 414 + </button> 415 + <Show when={maxFileSize()}> 416 + <span class="text-muted text-xs"> 417 + up to {formatBytes(maxFileSize())} 418 + </span> 419 + </Show> 420 + </div> 421 + </Show> 415 422 </Show> 416 423 </div> 417 424 ··· 425 432 /> 426 433 </div> 427 434 428 - <Show when={view() !== "result"}> 435 + <Show when={!loading() && view() !== "result"}> 429 436 <div class="mx-auto mt-6 flex w-fit flex-col gap-4 text-sm"> 430 437 <label class="text-muted flex items-center gap-3 select-none"> 431 438 lifetime