Skip to content

Commit 41c9dcb

Browse files
authored
fix: display uploaded file actions after uploading
1 parent c38a5d5 commit 41c9dcb

4 files changed

Lines changed: 90 additions & 62 deletions

File tree

html/src/Components/ItemComponent.tsx

Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,22 @@
1-
import { ActionIcon, Box, Button, Center, Flex, Paper, Popover, rem, RingProgress, Text, Tooltip } from "@mantine/core";
1+
import { ActionIcon, Box, Button, Center, Flex, Paper, Popover, rem, RingProgress, Text, ThemeIcon, Tooltip } from "@mantine/core";
22
import { IconCheck, IconDownload, IconTrash, IconX } from "@tabler/icons-react";
3-
import { QueueItem } from "../UploadQueue";
4-
import { humanFileSize, Item } from "../hupload";
3+
import { humanFileSize, UploadableItem } from "../hupload";
54
import classes from './ItemComponent.module.css';
65
import { ReactNode } from "react";
76
import { useTranslation } from "react-i18next";
87

9-
export function ItemComponent(props: {download: boolean, onDelete?: (item:string) => void, canDelete: boolean, item?: Item, queueItem?: QueueItem}) {
8+
export function ItemComponent(props: {download: boolean, onDelete?: (item:string) => void, canDelete: boolean, item: UploadableItem}) {
109
const { t } = useTranslation();
1110

1211
// Initialize props
13-
const {download, canDelete, onDelete, item, queueItem} = props
14-
15-
// Other initializations
12+
const {download, canDelete, onDelete, item} = props
1613

1714
// key is item Path, or file name for files being added
18-
const key = item?item.Path:queueItem?.file.name
15+
const key = item.Path
1916

2017
// fileName is item Path last path component, or file name for files being
2118
// added
22-
const fileName = item?item.Path.split('/')[1]:queueItem?.file.name
19+
const fileName = item.Path.split('/')[1]
2320

2421
// Function to add tooltip to an element, used to display error message
2522
const addTooltip = (tooltip: string,element: ReactNode) => {
@@ -39,34 +36,34 @@ export function ItemComponent(props: {download: boolean, onDelete?: (item:string
3936
<Text truncate="end">{fileName}</Text>
4037
<Box flex={1} ta={"right"}>
4138
<Flex align={"center"} justify={"right"}>
42-
{queueItem?
43-
addTooltip(queueItem.failed?queueItem.error:"",<RingProgress
39+
{item.QueueItem?
40+
addTooltip(item.QueueItem.failed?item.QueueItem.error:"",<RingProgress
4441
size={45}
4542
thickness={3}
4643
sections={[
47-
{ value: (queueItem.finished)?(100):(100*queueItem.loaded/queueItem.total), color: (queueItem.failed)?('red'):((queueItem.finished)?'teal':'blue')},
44+
{ value: (item.QueueItem.finished)?(100):(100*item.QueueItem.loaded/item.QueueItem.total), color: (item.QueueItem.failed)?('red'):((item.QueueItem.finished)?'teal':'blue')},
4845
]}
4946
label={
50-
(queueItem.failed)?
47+
(item.QueueItem.failed)?
5148
(<Center>
52-
<ActionIcon color="red" variant="light" radius="xl" size="xl">
49+
<ThemeIcon color="red" variant="light" radius="xl" size="xl">
5350
<IconX style={{ width: rem(20), height: rem(20) }} />
54-
</ActionIcon>
55-
</Center>) // queueItem.failed
51+
</ThemeIcon>
52+
</Center>) // item.QueueItem.failed
5653
:
57-
((queueItem.finished)?
54+
((item.QueueItem.finished)?
5855
(<Center>
59-
<ActionIcon color="teal" variant="light" radius="xl" size="xl">
56+
<ThemeIcon color="teal" variant="light" radius="xl" size="xl">
6057
<IconCheck style={{ width: rem(20), height: rem(20) }} />
61-
</ActionIcon>
62-
</Center>) // queueItem.finished
58+
</ThemeIcon>
59+
</Center>) // item.QueueItem.finished
6360
:
6461
<Text c="blue" fw={700} size="xs" ta="center" >
65-
{(100*queueItem.loaded/queueItem.total).toFixed(0) + '%'}
66-
</Text>) // queueItem not finished
62+
{(100*item.QueueItem.loaded/item.QueueItem.total).toFixed(0) + '%'}
63+
</Text>) // item.QueueItem not finished
6764
}
6865
/>)
69-
:item&&
66+
:
7067
<>
7168
<Text size="xs" c="gray" style={{whiteSpace: "nowrap"}}>{humanFileSize(item.ItemInfo.Size)}</Text>
7269
{canDelete &&

html/src/Pages/SharePage.tsx

Lines changed: 59 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { useCallback, useEffect, useState } from "react";
55
import { H } from "../APIClient";
66
import { UploadQueue, QueueItem } from "../UploadQueue";
77
import {ItemComponent} from "@/Components";
8-
import { Item } from "../hupload";
8+
import { UploadableItem } from "../hupload";
99
import { useAuthContext } from "@/AuthContext";
1010
import { Message } from "@/Components/Message";
1111
import { useShare } from "@/hooks";
@@ -16,9 +16,7 @@ import { ErrorPage } from "./ErrorPage";
1616
export function SharePage() {
1717
const { t } = useTranslation();
1818

19-
const [items, setItems] = useState<Item[]|undefined>(undefined)
20-
const [queueItems, setQueueItems] = useState<QueueItem[]>([])
21-
//const [expired,setExpired] = useState(false)
19+
const [items, setItems] = useState<UploadableItem[]>([])
2220
const [error, setError] = useState<undefined|AxiosError>(undefined)
2321

2422
// Initialize hooks
@@ -29,17 +27,41 @@ export function SharePage() {
2927
const expired = (shareError?.response?.status === 410)
3028

3129
const updateProgress = useCallback((progress: QueueItem[]) => {
32-
setQueueItems((currentQueue) => {
33-
const j = currentQueue.map((currentItem) => {
34-
const p = progress.find((p) => p.file.name === currentItem.file.name)
30+
setItems((currentItems) => {
31+
const i = currentItems.map((currentItem) => {
32+
const p = progress.find((p) => p.file.name === currentItem.Path.split("/")[1])
3533
if (p) {
36-
return p
34+
if (p.finished) {
35+
setTimeout(() => {
36+
setItems((currentItems) => {
37+
return currentItems.map((currentItem) => {
38+
if (currentItem.ItemInfo.Name === p.file.name) {
39+
return {...currentItem, QueueItem: undefined}
40+
}
41+
return currentItem
42+
})
43+
})
44+
},2000)
45+
}
46+
return {...currentItem, QueueItem: p}
3747
}
3848
return currentItem
3949
})
40-
const k = progress.filter((p) => !j.some((i) => i.file.name === p.file.name))
41-
return [...k, ...j]
42-
})
50+
return i
51+
})
52+
53+
54+
// setQueueItems((currentQueue) => {
55+
// const j = currentQueue.map((currentItem) => {
56+
// const p = progress.find((p) => p.file.name === currentItem.file.name)
57+
// if (p) {
58+
// return p
59+
// }
60+
// return currentItem
61+
// })
62+
// const k = progress.filter((p) => !j.some((i) => i.file.name === p.file.name))
63+
// return [...k, ...j]
64+
// })
4365
},[])
4466

4567
const queue = new UploadQueue(H,"/shares/"+share?.name, updateProgress)
@@ -50,7 +72,7 @@ export function SharePage() {
5072
// Get items from share
5173
if (share) {
5274
H.get('/shares/' + share.name + '/items').then((res) => {
53-
setItems(res as Item[])
75+
setItems(res as UploadableItem[])
5476
})
5577
.catch((e) => {
5678
setError(e)
@@ -153,10 +175,10 @@ export function SharePage() {
153175
// deleteItem deletes an item from the share.
154176
const deleteItem = (item: string) => {
155177
H.delete('/shares/' + share.name + '/items/' + item).then(() => {
156-
setItems(items?.filter((i) => i.Path !== share.name + "/" + item))
178+
setItems(items?.filter((i) => i.Path !== share.name + "/" + item))
157179
})
158180
.catch((e) => {
159-
console.log(e)
181+
console.log(e)
160182
})
161183
}
162184

@@ -172,7 +194,7 @@ export function SharePage() {
172194
</Tooltip>
173195
)}
174196
</CopyButton>
175-
{canDownload() && items.length + queueItems.filter((i) => i.failed === false && i.finished === true ).length > 0 &&
197+
{canDownload() && items.length &&
176198
<Tooltip withArrow arrowOffset={10} arrowSize={4} label={t("download_all")}>
177199
<Button component="a" href={'/d/'+share.name} justify="center" variant="outline" size="xs"><IconDownload style={{ width: '70%', height: '70%' }} stroke={1.5}/>{t("download_button")}</Button>
178200
</Tooltip>
@@ -193,24 +215,32 @@ export function SharePage() {
193215
<>
194216
<Dropzone
195217
onDrop={(files) => {
196-
// Filter out files that are already uploaded
197-
const newItems = items.filter((i) => {
198-
return !files.some((f) => f.name === i.Path.split("/")[1])
218+
const uploadableItems = files.map((f) => {
219+
return {
220+
Path: share.name + "/" + f.name,
221+
ItemInfo: {
222+
Name: f.name,
223+
Size: f.size,
224+
},
225+
QueueItem: {},
226+
} as UploadableItem
227+
})
228+
229+
setItems((currentItems) => {
230+
const i = [...currentItems, ...uploadableItems]
231+
return i
199232
})
233+
// // Filter out files that are already uploaded
234+
// const newItems = items.filter((i) => {
235+
// return !files.some((f) => f.name === i.Path.split("/")[1])
236+
// })
200237

201-
setItems(newItems)
238+
// setItems(newItems)
202239

203240
queue.addFiles(files)
204-
// .then((r) => {
205-
206-
// //const finishedItems = r as Item[]
207-
208-
// //setQueueItems([])
209-
// setItems([...finishedItems, ...newItems])
210-
// })
211-
.catch((e) => {
212-
console.log(e)
213-
})
241+
.catch((e) => {
242+
console.log(e)
243+
})
214244
}}
215245

216246
onReject={(files) => console.log('rejected files', files)}
@@ -243,14 +273,6 @@ export function SharePage() {
243273
</Dropzone>
244274
</>}
245275

246-
{
247-
// Display upload queue items (queue items uploading or finished
248-
// uploading)
249-
queueItems.map((q) => (
250-
<ItemComponent download={false} canDelete={false} key={'up_' + q.file.name} queueItem={q} />
251-
))
252-
}
253-
254276
{
255277
// Display share items
256278
items.map((item) => (

html/src/UploadQueue.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,18 @@ export class UploadQueue {
2222
this.path = path
2323
this.progressCallback = progress
2424
}
25+
2526
addFiles(files: File[]) {
2627
files.map((f) => {
27-
this.files[f.name] = {
28+
const qi = {
2829
file: f,
2930
loaded: 0,
3031
total: f.size,
3132
finished: false,
3233
failed: false,
3334
error:'',
34-
}
35+
} as QueueItem
36+
this.files[f.name] = qi
3537
})
3638

3739
const promises=Object.keys(this.files).map((k) => {

html/src/hupload.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
// Interfaces
22

3+
import { QueueItem } from "./UploadQueue";
4+
35
export interface ShareOptions {
46
exposure?: string;
57
validity?: number;
@@ -22,8 +24,13 @@ export interface Item {
2224
ItemInfo: ItemInfo;
2325
}
2426

27+
export interface UploadableItem extends Item {
28+
QueueItem?: QueueItem
29+
}
30+
2531
export interface ItemInfo {
2632
Size: number;
33+
Name: string
2734
}
2835

2936
export interface Message {

0 commit comments

Comments
 (0)