mirror of
https://github.com/streetwriters/notesnook.git
synced 2026-02-23 19:49:56 +01:00
web: improve attachment progress events & ui
This commit is contained in:
committed by
Ammar Ahmed
parent
3b6fde2ea6
commit
08296793f1
@@ -123,34 +123,46 @@ export default function AppEffects({ setShow }: AppEffectsProps) {
|
||||
// );
|
||||
|
||||
function handleDownloadUploadProgress(
|
||||
type: "download" | "upload",
|
||||
type: ProcessingType,
|
||||
total: number,
|
||||
current: number
|
||||
) {
|
||||
const [key, status] = getProcessingStatusFromType(type);
|
||||
|
||||
console.log("handleDownloadUploadProgresss", key, status, current, total);
|
||||
if (current === total) {
|
||||
removeStatus(key);
|
||||
} else {
|
||||
updateStatus({
|
||||
key,
|
||||
status: `${status} attachments (${current}/${total})`,
|
||||
status: `${status} attachments`,
|
||||
current,
|
||||
total,
|
||||
progress: 0
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const fileDownloadedEvent = EV.subscribe(
|
||||
EVENTS.fileDownloaded,
|
||||
const fileDownloadEvents = EV.subscribeMulti(
|
||||
[EVENTS.fileDownloaded, EVENTS.fileDownload],
|
||||
({ total, current }: { total: number; current: number }) => {
|
||||
handleDownloadUploadProgress("download", total, current);
|
||||
}
|
||||
},
|
||||
null
|
||||
);
|
||||
|
||||
const fileUploadedEvent = EV.subscribe(
|
||||
EVENTS.fileUploaded,
|
||||
const fileUploadEvents = EV.subscribeMulti(
|
||||
[EVENTS.fileUploaded, EVENTS.fileUpload],
|
||||
({ total, current }: { total: number; current: number }) => {
|
||||
handleDownloadUploadProgress("upload", total, current);
|
||||
},
|
||||
null
|
||||
);
|
||||
|
||||
const fileEncrypted = AppEventManager.subscribe(
|
||||
AppEvents.fileEncrypted,
|
||||
({ total, current }: { total: number; current: number }) => {
|
||||
handleDownloadUploadProgress("encrypt", total, current);
|
||||
}
|
||||
);
|
||||
|
||||
@@ -169,21 +181,36 @@ export default function AppEffects({ setShow }: AppEffectsProps) {
|
||||
if (!key) return;
|
||||
|
||||
const percent = Math.round((loaded / total) * 100);
|
||||
const text = getStatus(key)?.status || `${status} attachment`;
|
||||
const oldStatus = getStatus(key);
|
||||
const text = oldStatus?.status || `${status} attachment`;
|
||||
|
||||
updateStatus({
|
||||
key,
|
||||
status: text,
|
||||
progress: loaded === total ? 100 : percent
|
||||
});
|
||||
if (
|
||||
(!oldStatus ||
|
||||
(oldStatus.total === undefined &&
|
||||
oldStatus.current === undefined) ||
|
||||
oldStatus.total === oldStatus.current) &&
|
||||
loaded === total
|
||||
) {
|
||||
removeStatus(key);
|
||||
} else {
|
||||
updateStatus({
|
||||
...oldStatus,
|
||||
key,
|
||||
status: text,
|
||||
progress: loaded === total ? 100 : percent
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
registerKeyMap();
|
||||
return () => {
|
||||
fileUploadedEvent.unsubscribe();
|
||||
fileDownloadedEvent.unsubscribe();
|
||||
progressEvent.unsubscribe();
|
||||
[
|
||||
...fileDownloadEvents,
|
||||
...fileUploadEvents,
|
||||
progressEvent,
|
||||
fileEncrypted
|
||||
].forEach((e) => e.unsubscribe());
|
||||
// systemTimeInvalidEvent.unsubscribe();
|
||||
};
|
||||
}, []);
|
||||
|
||||
@@ -24,6 +24,7 @@ export const AppEvents = {
|
||||
UPDATE_ATTACHMENT_PROGRESS: "updateAttachmentProgress",
|
||||
UPDATE_STATUS: "updateStatus",
|
||||
REMOVE_STATUS: "removeStatus",
|
||||
fileEncrypted: "file:encrypted",
|
||||
|
||||
checkingForUpdate: "checkingForUpdate",
|
||||
updateAvailable: "updateAvailable",
|
||||
|
||||
@@ -40,7 +40,7 @@ import {
|
||||
showIssueDialog,
|
||||
showUpdateAvailableNotice
|
||||
} from "../../common/dialog-controller";
|
||||
import useStatus from "../../hooks/use-status";
|
||||
import useStatus, { statusToString } from "../../hooks/use-status";
|
||||
import { ScopedThemeProvider } from "../theme-provider";
|
||||
import { checkForUpdate, installUpdate } from "../../utils/updater";
|
||||
import { toTitleCase } from "@notesnook/common";
|
||||
@@ -132,7 +132,8 @@ function StatusBar() {
|
||||
Report an issue
|
||||
</Text>
|
||||
</Button>
|
||||
{statuses?.map(({ key, status, progress, icon: Icon }) => {
|
||||
{statuses?.map((status) => {
|
||||
const { key, icon: Icon } = status;
|
||||
return (
|
||||
<Flex
|
||||
key={key}
|
||||
@@ -141,7 +142,7 @@ function StatusBar() {
|
||||
>
|
||||
{Icon ? <Icon size={12} /> : <Loading size={12} />}
|
||||
<Text variant="subBody" ml={1} sx={{ color: "paragraph" }}>
|
||||
{progress ? `${progress}% ${status}` : status}
|
||||
{statusToString(status)}
|
||||
</Text>
|
||||
</Flex>
|
||||
);
|
||||
|
||||
@@ -24,6 +24,8 @@ import { Icon } from "../components/icons";
|
||||
type Status = {
|
||||
key: string;
|
||||
status: string;
|
||||
total?: number;
|
||||
current?: number;
|
||||
progress?: number;
|
||||
icon?: Icon | null;
|
||||
};
|
||||
@@ -36,13 +38,20 @@ interface IStatusStore {
|
||||
const useStatusStore = create<IStatusStore>((set, get) => ({
|
||||
statuses: {},
|
||||
getStatus: (key: string) => get().statuses[key],
|
||||
updateStatus: ({ key, status, progress, icon }: Status) =>
|
||||
updateStatus: ({ key, status, progress, icon, current, total }: Status) =>
|
||||
set(
|
||||
produce((state) => {
|
||||
if (!key) return;
|
||||
const { statuses } = state;
|
||||
const statusText = status || statuses[key]?.status;
|
||||
statuses[key] = { key, status: statusText, progress, icon };
|
||||
statuses[key] = {
|
||||
current,
|
||||
total,
|
||||
key,
|
||||
status: statusText,
|
||||
progress,
|
||||
icon
|
||||
};
|
||||
})
|
||||
),
|
||||
removeStatus: (key) =>
|
||||
@@ -63,3 +72,12 @@ export default function useStatus() {
|
||||
export const updateStatus = useStatusStore.getState().updateStatus;
|
||||
export const removeStatus = useStatusStore.getState().removeStatus;
|
||||
export const getStatus = useStatusStore.getState().getStatus;
|
||||
|
||||
export function statusToString(status: Status) {
|
||||
const parts: string[] = [];
|
||||
if (status.progress) parts.push(`${status.progress}%`);
|
||||
parts.push(status.status);
|
||||
if (status.total !== undefined && status.current !== undefined)
|
||||
parts.push(`(${status.current}/${status.total})`);
|
||||
return parts.join(" ");
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@ import { AppEventManager, AppEvents } from "../common/app-events";
|
||||
import { StreamableFS } from "@notesnook/streamable-fs";
|
||||
import { NNCrypto } from "./nncrypto";
|
||||
import hosts from "@notesnook/core/dist/utils/constants";
|
||||
import { sendAttachmentsProgressEvent } from "@notesnook/core/dist/common";
|
||||
import { saveAs } from "file-saver";
|
||||
import { showToast } from "../utils/toast";
|
||||
import { db } from "../common/db";
|
||||
@@ -61,7 +60,11 @@ async function writeEncryptedFile(
|
||||
// let offset = 0;
|
||||
// let encrypted = 0;
|
||||
const fileHandle = await streamablefs.createFile(hash, file.size, file.type);
|
||||
sendAttachmentsProgressEvent("encrypt", hash, 1, 0);
|
||||
AppEventManager.publish(AppEvents.fileEncrypted, {
|
||||
hash,
|
||||
total: 1,
|
||||
current: 0
|
||||
});
|
||||
|
||||
const { iv, stream } = await NNCrypto.createEncryptionStream(key);
|
||||
await file
|
||||
@@ -82,7 +85,11 @@ async function writeEncryptedFile(
|
||||
)
|
||||
.pipeTo(fileHandle.writeable);
|
||||
|
||||
sendAttachmentsProgressEvent("encrypt", hash, 1, 1);
|
||||
AppEventManager.publish(AppEvents.fileEncrypted, {
|
||||
hash,
|
||||
total: 1,
|
||||
current: 1
|
||||
});
|
||||
|
||||
return {
|
||||
chunkSize: CHUNK_SIZE,
|
||||
|
||||
@@ -27,9 +27,7 @@ class EventManager {
|
||||
}
|
||||
|
||||
subscribeMulti(names, handler, thisArg) {
|
||||
names.forEach((name) => {
|
||||
this.subscribe(name, handler.bind(thisArg));
|
||||
});
|
||||
return names.map((name) => this.subscribe(name, handler.bind(thisArg)));
|
||||
}
|
||||
|
||||
subscribe(name, handler, once = false) {
|
||||
|
||||
Reference in New Issue
Block a user