From 9914a9d600a8ce31a033e06af2e12f0708625b33 Mon Sep 17 00:00:00 2001 From: Roland Osborne Date: Wed, 20 Jul 2022 15:49:42 -0700 Subject: [PATCH] support cancelling asset posts --- .../src/User/Conversation/Conversation.jsx | 25 +++++++++---- .../User/Conversation/useConversation.hook.js | 10 ++++- net/web/src/context/useAppContext.hook.js | 3 ++ net/web/src/context/useCardContext.hook.js | 2 - net/web/src/context/useChannelContext.hook.js | 2 - net/web/src/context/useUploadContext.hook.js | 37 +++++++++++++++++-- 6 files changed, 63 insertions(+), 16 deletions(-) diff --git a/net/web/src/User/Conversation/Conversation.jsx b/net/web/src/User/Conversation/Conversation.jsx index a4d4f28a..d09975e0 100644 --- a/net/web/src/User/Conversation/Conversation.jsx +++ b/net/web/src/User/Conversation/Conversation.jsx @@ -48,13 +48,24 @@ export function Conversation() { const uploadProgress = () => { let progress = []; for (let entry of state.progress) { - progress.push( -
-
{ entry.index }/{ entry.count }
- - -
- ); + if (entry.error) { + progress.push( +
+
{ entry.index }/{ entry.count }
+ + +
+ ); + } + else { + progress.push( +
+
{ entry.index }/{ entry.count }
+ + +
+ ); + } } return progress; } diff --git a/net/web/src/User/Conversation/useConversation.hook.js b/net/web/src/User/Conversation/useConversation.hook.js index 74dd0d67..4f1369f9 100644 --- a/net/web/src/User/Conversation/useConversation.hook.js +++ b/net/web/src/User/Conversation/useConversation.hook.js @@ -50,7 +50,15 @@ export function useConversation() { }, resync: () => { conversation.actions.resync(); - } + }, + cancel: (topicId) => { + if (cardId) { + upload.actions.cancelContactTopic(cardId, channelId, topicId); + } + else { + upload.actions.cancelTopic(channelId, topicId); + } + }, }; useEffect(() => { diff --git a/net/web/src/context/useAppContext.hook.js b/net/web/src/context/useAppContext.hook.js index 54424252..23a0020a 100644 --- a/net/web/src/context/useAppContext.hook.js +++ b/net/web/src/context/useAppContext.hook.js @@ -12,6 +12,7 @@ import { GroupContext } from './GroupContext'; import { CardContext } from './CardContext'; import { ChannelContext } from './ChannelContext'; import { StoreContext } from './StoreContext'; +import { UploadContext } from './UploadContext'; async function appCreate(username, password, token, updateState, setWebsocket) { await addAccount(username, password, token); @@ -60,6 +61,7 @@ export function useAppContext() { }) } + const uploadContext = useContext(UploadContext); const storeContext = useContext(StoreContext); const accountContext = useContext(AccountContext); const profileContext = useContext(ProfileContext); @@ -83,6 +85,7 @@ export function useAppContext() { logout: () => { appLogout(updateState, clearWebsocket); storeContext.actions.clear(); + uploadContext.actions.clear(); resetData(); }, } diff --git a/net/web/src/context/useCardContext.hook.js b/net/web/src/context/useCardContext.hook.js index 7e6f27f4..b1e38627 100644 --- a/net/web/src/context/useCardContext.hook.js +++ b/net/web/src/context/useCardContext.hook.js @@ -290,11 +290,9 @@ export function useCardContext() { if (files?.length) { const topicId = await addContactChannelTopic(node, token, channelId, null, null); upload.actions.addContactTopic(node, token, cardId, channelId, topicId, files, async (assets) => { - console.log("success, finalize topic"); message.assets = assets; await setContactChannelTopicSubject(node, token, channelId, topicId, message); }, async () => { - console.log("failed, delete topic"); try { await removeContactChannelTopic(node, token, channelId, topicId); } diff --git a/net/web/src/context/useChannelContext.hook.js b/net/web/src/context/useChannelContext.hook.js index 7efcea2a..513273fc 100644 --- a/net/web/src/context/useChannelContext.hook.js +++ b/net/web/src/context/useChannelContext.hook.js @@ -124,11 +124,9 @@ export function useChannelContext() { if (files?.length) { const topicId = await addChannelTopic(access.current, channelId, null, null); upload.actions.addTopic(access.current, channelId, topicId, files, async (assets) => { - console.log("success, finalize topic"); message.assets = assets; await setChannelTopicSubject(access.current, channelId, topicId, message); }, async () => { - console.log("failed, delete topic"); try { await removeChannelTopic(access.current, channelId, topicId); } diff --git a/net/web/src/context/useUploadContext.hook.js b/net/web/src/context/useUploadContext.hook.js index 9e184d42..4331cd79 100644 --- a/net/web/src/context/useUploadContext.hook.js +++ b/net/web/src/context/useUploadContext.hook.js @@ -39,12 +39,25 @@ export function useUploadContext() { if (assets.length) { progress.set(channel, assets.sort((a, b) => (a.upload < b.upload) ? 1 : -1)); } - updateState({ progress }); }); + updateState({ progress }); + } + + const abort = (channelId, topicId) => { + const channel = channels.current.get(channelId); + if (channel) { + const topic = channel.get(topicId); + if (topic) { + topic.cancel.abort(); + channel.delete(topicId); + updateProgress(); + } + } } const actions = { addTopic: (token, channelId, topicId, files, success, failure) => { + const controller = new AbortController(); const entry = { index: index.current, url: `/content/channels/${channelId}/topics/${topicId}/assets?agent=${token}`, @@ -53,7 +66,8 @@ export function useUploadContext() { current: null, error: false, success, - failure + failure, + cancel: controller, } index.current += 1; const key = `:${channelId}`; @@ -65,8 +79,10 @@ export function useUploadContext() { upload(entry, updateProgress, () => { updateComplete(key, topicId) } ); }, cancelTopic: (channelId, topicId) => { + abort(`:${channelId}`, topicId); }, addContactTopic: (server, token, cardId, channelId, topicId, files, success, failure) => { + const controller = new AbortController(); const entry = { index: index.current, url: `https://${server}/content/channels/${channelId}/topics/${topicId}/assets?contact=${token}`, @@ -75,7 +91,8 @@ export function useUploadContext() { current: null, error: false, success, - failure + failure, + cancel: controller, } index.current += 1; const key = `${cardId}:${channelId}`; @@ -87,8 +104,16 @@ export function useUploadContext() { upload(entry, updateProgress, () => { updateComplete(key, topicId) }); }, cancelContactTopic: (cardId, channelId, topicId) => { + abort(`${cardId}:${channelId}`, topicId); }, - reset: () => { + clear: () => { + channels.current.forEach((topics, channelId) => { + topics.forEach((assets, topicId) => { + assets.cancel.abort(); + }); + }); + channels.current.clear(); + updateProgress(); } } @@ -109,6 +134,7 @@ async function upload(entry, update, complete) { formData.append('asset', file.image); let transform = encodeURIComponent(JSON.stringify(["ithumb;photo", "icopy;photo"])); let asset = await axios.post(`${entry.url}&transforms=${transform}`, formData, { + signal: entry.cancel.signal, onUploadProgress: (ev) => { const { loaded, total } = ev; entry.active = { loaded, total } @@ -128,6 +154,7 @@ async function upload(entry, update, complete) { let thumb = 'vthumb;video;' + file.position; let transform = encodeURIComponent(JSON.stringify(["vlq;video", "vhd;video", thumb])); let asset = await axios.post(`${entry.url}&transforms=${transform}`, formData, { + signal: entry.cancel.signal, onUploadProgress: (ev) => { const { loaded, total } = ev; entry.active = { loaded, total } @@ -147,6 +174,7 @@ async function upload(entry, update, complete) { formData.append('asset', file.audio); let transform = encodeURIComponent(JSON.stringify(["acopy;audio"])); let asset = await axios.post(`${entry.url}&transforms=${transform}`, formData, { + signal: entry.cancel.signal, onUploadProgress: (ev) => { const { loaded, total } = ev; entry.active = { loaded, total } @@ -167,6 +195,7 @@ async function upload(entry, update, complete) { console.log(err); entry.failure(); entry.error = true; + update(); } } }