mirror of
https://github.com/balzack/databag.git
synced 2025-04-23 18:15:19 +00:00
show decrypt progress
This commit is contained in:
parent
f2bf282026
commit
ae2f4f7813
@ -21,6 +21,12 @@
|
||||
z-index: 1;
|
||||
transition: all 400ms;
|
||||
|
||||
.progress {
|
||||
position: absolute;
|
||||
bottom: 16px;
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
.close {
|
||||
position: absolute;
|
||||
top: 16px;
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { MediaAsset } from '../../conversation/Conversation';
|
||||
import { useImageAsset } from './useImageAsset.hook';
|
||||
import { ActionIcon, Image } from '@mantine/core'
|
||||
import { Progress, ActionIcon, Image } from '@mantine/core'
|
||||
import classes from './ImageAsset.module.css'
|
||||
import { IconX } from '@tabler/icons-react'
|
||||
|
||||
@ -46,6 +46,9 @@ export function ImageAsset({ topicId, asset }: { topicId: string, asset: MediaAs
|
||||
<img className={classes.image} src={state.dataUrl} />
|
||||
</div>
|
||||
)}
|
||||
{ state.loading && state.loadPercent > 0 && (
|
||||
<Progress className={classes.progress} value={state.loadPercent} />
|
||||
)}
|
||||
<ActionIcon className={classes.close} variant="subtle" size="lg" onClick={hide}>
|
||||
<IconX size="lg" />
|
||||
</ActionIcon>
|
||||
|
@ -9,6 +9,8 @@ export function useImageAsset(topicId: string, asset: MediaAsset) {
|
||||
const [state, setState] = useState({
|
||||
thumbUrl: null,
|
||||
dataUrl: null,
|
||||
loading: false,
|
||||
loadPercent: 0,
|
||||
})
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
@ -40,13 +42,15 @@ export function useImageAsset(topicId: string, asset: MediaAsset) {
|
||||
loadImage: async () => {
|
||||
const { focus } = app.state;
|
||||
const assetId = asset.image ? asset.image.full : asset.encrypted ? asset.encrypted.parts : null;
|
||||
if (focus && assetId != null) {
|
||||
if (focus && assetId != null && !state.loading) {
|
||||
updateState({ loading: true, loadPercent: 0 });
|
||||
try {
|
||||
const dataUrl = await focus.getTopicAssetUrl(topicId, assetId);
|
||||
const dataUrl = await focus.getTopicAssetUrl(topicId, assetId, (loadPercent: number)=>{ updateState({ loadPercent }) });
|
||||
updateState({ dataUrl });
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
}
|
||||
updateState({ loading: false });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
13380
app/client/web/yarn.lock
13380
app/client/web/yarn.lock
File diff suppressed because it is too large
Load Diff
@ -131,7 +131,7 @@ export interface Focus {
|
||||
|
||||
viewMoreTopics(): Promise<void>;
|
||||
|
||||
getTopicAssetUrl(topicId: string, assetId: string, progress: (percent: number) => boolean): Promise<string>;
|
||||
getTopicAssetUrl(topicId: string, assetId: string, progress?: (percent: number) => boolean|void): Promise<string>;
|
||||
|
||||
flagTopic(topicId: string): Promise<void>;
|
||||
setBlockTopic(topicId: string): Promise<void>;
|
||||
|
@ -241,7 +241,7 @@ export class FocusModule implements Focus {
|
||||
}
|
||||
}
|
||||
|
||||
private downloadBlock(topicId: string, blockId: string): Promise<string> {
|
||||
private downloadBlock(topicId: string, blockId: string, progress: (percent: number)=>void): Promise<string> {
|
||||
const { cardId, channelId, connection } = this;
|
||||
if (!connection) {
|
||||
throw new Error('disconnected from channel');
|
||||
@ -253,6 +253,7 @@ export class FocusModule implements Focus {
|
||||
return new Promise(function (resolve, reject) {
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', url, true);
|
||||
xhr.onprogress = (ev: ProgressEvent<EventTarget>)=>{ progress((ev.loaded * 100) / ev.total) };
|
||||
xhr.setRequestHeader('Content-Type', 'text/plain');
|
||||
xhr.onload = () => {
|
||||
if (xhr.status >= 200 && xhr.status < 300) {
|
||||
@ -761,7 +762,7 @@ export class FocusModule implements Focus {
|
||||
await this.removeRemoteChannelTopic(topicId);
|
||||
}
|
||||
|
||||
public async getTopicAssetUrl(topicId: string, assetId: string, progress: null | ((percent: number) => boolean)): Promise<string> {
|
||||
public async getTopicAssetUrl(topicId: string, assetId: string, progress?: ((percent: number) => boolean|void)): Promise<string> {
|
||||
const entry = this.topicEntries.get(topicId);
|
||||
if (!entry) {
|
||||
throw new Error('topic entry not found');
|
||||
@ -783,7 +784,21 @@ export class FocusModule implements Focus {
|
||||
const write = await media.write();
|
||||
this.closeMedia.push(write.close);
|
||||
for (let i = 0; i < asset.split.length; i++) {
|
||||
const block = await this.downloadBlock(topicId, asset.split[i].partId);
|
||||
let download = true;
|
||||
const block = await this.downloadBlock(topicId, asset.split[i].partId, (percent: number)=>{
|
||||
if (progress && download !== false) {
|
||||
download = progress(Math.floor((i * 100 + percent) / asset.split.length));
|
||||
}
|
||||
});
|
||||
if (download === false) {
|
||||
throw new Error('aborted asset load');
|
||||
}
|
||||
if (progress) {
|
||||
download = progress(Math.floor((i * 100) / asset.split.length));
|
||||
}
|
||||
if (download === false) {
|
||||
throw new Error('aborted asset load');
|
||||
}
|
||||
const { data } = await crypto.aesDecrypt(block, asset.split[i].blockIv, channelKey);
|
||||
await write.setData(data);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user