diff --git a/net/web/src/session/conversation/topicItem/audioAsset/AudioAsset.jsx b/net/web/src/session/conversation/topicItem/audioAsset/AudioAsset.jsx
index d074dce6..a34b5ef8 100644
--- a/net/web/src/session/conversation/topicItem/audioAsset/AudioAsset.jsx
+++ b/net/web/src/session/conversation/topicItem/audioAsset/AudioAsset.jsx
@@ -1,9 +1,10 @@
import React, { useEffect, useState, useRef } from 'react';
-import { Modal, Spin } from 'antd';
+import { Progress, Modal, Spin } from 'antd';
import ReactResizeDetector from 'react-resize-detector';
import { PlayCircleOutlined, MinusCircleOutlined, SoundOutlined } from '@ant-design/icons';
import { AudioAssetWrapper, AudioModalWrapper } from './AudioAsset.styled';
import { useAudioAsset } from './useAudioAsset.hook';
+import Colors from 'constants/Colors';
import background from 'images/audio.png';
@@ -56,6 +57,9 @@ export function AudioAsset({ asset }) {
{ state.loading && !state.error && (
+ { state.total != 0 && (
+
+ )}
)}
{ !state.ready && !state.loading && (
diff --git a/net/web/src/session/conversation/topicItem/audioAsset/AudioAsset.styled.js b/net/web/src/session/conversation/topicItem/audioAsset/AudioAsset.styled.js
index e3dcd5c0..27d5431a 100644
--- a/net/web/src/session/conversation/topicItem/audioAsset/AudioAsset.styled.js
+++ b/net/web/src/session/conversation/topicItem/audioAsset/AudioAsset.styled.js
@@ -80,6 +80,8 @@ export const AudioModalWrapper = styled.div`
position: absolute;
color: white;
border-radius: 8px;
+ display: flex;
+ flex-direction: column;
.ant-spin-dot-item {
background-color: ${Colors.white};
diff --git a/net/web/src/session/conversation/topicItem/audioAsset/useAudioAsset.hook.js b/net/web/src/session/conversation/topicItem/audioAsset/useAudioAsset.hook.js
index 6dd0d523..a93cc27d 100644
--- a/net/web/src/session/conversation/topicItem/audioAsset/useAudioAsset.hook.js
+++ b/net/web/src/session/conversation/topicItem/audioAsset/useAudioAsset.hook.js
@@ -11,6 +11,8 @@ export function useAudioAsset(asset) {
error: false,
ready: false,
url: null,
+ block: 0,
+ total: 0,
});
const updateState = (value) => {
@@ -23,7 +25,7 @@ export function useAudioAsset(asset) {
try {
const view = index.current;
updateState({ active: true, ready: false, error: false, loading: true, url: null });
- const blob = await asset.getDecryptedBlob(() => view != index.current);
+ const blob = await asset.getDecryptedBlob(() => view != index.current, (block, total) => updateState({ block, total }));
const url = URL.createObjectURL(blob);
revoke.current = url;
updateState({ loading: false, url });
diff --git a/net/web/src/session/conversation/topicItem/imageAsset/ImageAsset.jsx b/net/web/src/session/conversation/topicItem/imageAsset/ImageAsset.jsx
index 57514679..88c46c9a 100644
--- a/net/web/src/session/conversation/topicItem/imageAsset/ImageAsset.jsx
+++ b/net/web/src/session/conversation/topicItem/imageAsset/ImageAsset.jsx
@@ -1,8 +1,9 @@
import React, { useState } from 'react';
-import { Modal, Spin } from 'antd';
+import { Progress, Modal, Spin } from 'antd';
import ReactResizeDetector from 'react-resize-detector';
import { ImageAssetWrapper, ImageModalWrapper } from './ImageAsset.styled';
import { useImageAsset } from './useImageAsset.hook';
+import Colors from 'constants/Colors';
export function ImageAsset({ asset }) {
@@ -42,6 +43,9 @@ export function ImageAsset({ asset }) {
{ !state.error && (
+ { state.total != 0 && (
+
+ )}
)}
{ state.error && (
diff --git a/net/web/src/session/conversation/topicItem/imageAsset/ImageAsset.styled.js b/net/web/src/session/conversation/topicItem/imageAsset/ImageAsset.styled.js
index 1d4e6cb8..7162a19e 100644
--- a/net/web/src/session/conversation/topicItem/imageAsset/ImageAsset.styled.js
+++ b/net/web/src/session/conversation/topicItem/imageAsset/ImageAsset.styled.js
@@ -76,6 +76,8 @@ export const ImageModalWrapper = styled.div`
position: absolute;
color: white;
border-radius: 8px;
+ display: flex;
+ flex-direction: column;
.ant-spin-dot-item {
background-color: ${Colors.white};
diff --git a/net/web/src/session/conversation/topicItem/imageAsset/useImageAsset.hook.js b/net/web/src/session/conversation/topicItem/imageAsset/useImageAsset.hook.js
index e278d43f..f1aff86c 100644
--- a/net/web/src/session/conversation/topicItem/imageAsset/useImageAsset.hook.js
+++ b/net/web/src/session/conversation/topicItem/imageAsset/useImageAsset.hook.js
@@ -11,7 +11,9 @@ export function useImageAsset(asset) {
height: 0,
loading: false,
error: false,
- url: null,
+ url: null,
+ block: 0,
+ total: 0,
});
const updateState = (value) => {
@@ -24,7 +26,7 @@ export function useImageAsset(asset) {
try {
const view = index.current;
updateState({ popout: true, width, height, error: false, loading: true, url: null });
- const blob = await asset.getDecryptedBlob(() => view != index.current);
+ const blob = await asset.getDecryptedBlob(() => view != index.current, (block, total) => updateState({ block, total }));
const url = URL.createObjectURL(blob);
updateState({ loading: false, url });
revoke.current = url;
diff --git a/net/web/src/session/conversation/topicItem/useTopicItem.hook.js b/net/web/src/session/conversation/topicItem/useTopicItem.hook.js
index 6fd97da5..c017bd38 100644
--- a/net/web/src/session/conversation/topicItem/useTopicItem.hook.js
+++ b/net/web/src/session/conversation/topicItem/useTopicItem.hook.js
@@ -30,7 +30,7 @@ export function useTopicItem(topic, contentKey) {
if (asset.encrypted) {
const encrypted = true;
const { type, thumb, label, parts } = asset.encrypted;
- const getDecryptedBlob = async (abort) => {
+ const getDecryptedBlob = async (abort, progress) => {
let pos = 0;
let len = 0;
@@ -39,6 +39,7 @@ export function useTopicItem(topic, contentKey) {
if (abort()) {
throw new Error("asset unseal aborted");
}
+ progress(i, parts.length);
const part = parts[i];
const url = topic.assetUrl(part.partId, topic.id);
const response = await fetchWithTimeout(url, { method: 'GET' });
@@ -48,6 +49,7 @@ export function useTopicItem(topic, contentKey) {
slices.push(slice);
len += slice.byteLength;
};
+ progress(parts.length, parts.length);
const data = new Uint8Array(len)
for (let i = 0; i < slices.length; i++) {
diff --git a/net/web/src/session/conversation/topicItem/videoAsset/VideoAsset.jsx b/net/web/src/session/conversation/topicItem/videoAsset/VideoAsset.jsx
index 76b1eae2..7ca4cebf 100644
--- a/net/web/src/session/conversation/topicItem/videoAsset/VideoAsset.jsx
+++ b/net/web/src/session/conversation/topicItem/videoAsset/VideoAsset.jsx
@@ -1,8 +1,9 @@
-import { Modal, Spin } from 'antd';
+import { Modal, Spin, Progress } from 'antd';
import ReactResizeDetector from 'react-resize-detector';
import { VideoCameraOutlined } from '@ant-design/icons';
import { VideoAssetWrapper, VideoModalWrapper } from './VideoAsset.styled';
import { useVideoAsset } from './useVideoAsset.hook';
+import Colors from 'constants/Colors';
export function VideoAsset({ asset }) {
@@ -51,6 +52,9 @@ export function VideoAsset({ asset }) {
{ !state.error && (
+ { state.total != 0 && (
+
+ )}
)}
diff --git a/net/web/src/session/conversation/topicItem/videoAsset/VideoAsset.styled.js b/net/web/src/session/conversation/topicItem/videoAsset/VideoAsset.styled.js
index 892c468c..c0b5db69 100644
--- a/net/web/src/session/conversation/topicItem/videoAsset/VideoAsset.styled.js
+++ b/net/web/src/session/conversation/topicItem/videoAsset/VideoAsset.styled.js
@@ -48,6 +48,8 @@ export const VideoModalWrapper = styled.div`
position: absolute;
color: white;
border-radius: 8px;
+ display: flex;
+ flex-direction: column;
.ant-spin-dot-item {
background-color: ${Colors.white};
diff --git a/net/web/src/session/conversation/topicItem/videoAsset/useVideoAsset.hook.js b/net/web/src/session/conversation/topicItem/videoAsset/useVideoAsset.hook.js
index ff353d12..bfeca798 100644
--- a/net/web/src/session/conversation/topicItem/videoAsset/useVideoAsset.hook.js
+++ b/net/web/src/session/conversation/topicItem/videoAsset/useVideoAsset.hook.js
@@ -14,6 +14,8 @@ export function useVideoAsset(asset) {
error: false,
url: null,
loaded: false,
+ block: 0,
+ total: 0,
});
const updateState = (value) => {
@@ -26,7 +28,7 @@ export function useVideoAsset(asset) {
try {
const view = index.current;
updateState({ active: true, width, height, error: false, loaded: false, loading: true, url: null });
- const blob = await asset.getDecryptedBlob(() => view != index.current);
+ const blob = await asset.getDecryptedBlob(() => view != index.current, (block, total) => updateState({ block, total }));
const url = URL.createObjectURL(blob);
revoke.current = url;
updateState({ url, loading: false });