diff --git a/dist/index.js b/dist/index.js index 1f22d944..2347b087 100644 --- a/dist/index.js +++ b/dist/index.js @@ -2655,6 +2655,7 @@ dataTransferModal: { transferDataHeadline: "Transfer Data", selectionDescription: "Select the data that you want to transfer.", + dataEntryDescription: "Enter this data on the other device.", /// fromThisDeviceButton: "From this device", toThisDeviceButton: "To this device", @@ -2662,11 +2663,14 @@ generalHeadline: "General", connectionData: "Connection Data", settingsData: "Settings Data", - /// chatsHeadline: "Chats", /// transferChannelHeadline: "Transfer Chanel", - transferKeyHeadline: "Transfer Encryption Key" + transferKeyHeadline: "Transfer Encryption Key", + sendButton: "Send", + /// + sendingFiles: "Sending files...", + filesSentCount: (count) => `Files sent: ${count}` }, storage: { noItemSelected: "No item selected", @@ -4450,6 +4454,13 @@ selectedPaths = new ListState(); transferChannel = new State(""); transferKey = new State(""); + filesSentCount = new State(0); + filePathsSent = new ListState(); + didNotFinishSending = new State(true); + filesSentText = createProxyState( + [this.filesSentCount], + () => translations.dataTransferModal.filesSentCount(this.filesSentCount.value) + ); // guards hasNoPathsSelected = createProxyState( [this.selectedPaths], @@ -4494,6 +4505,21 @@ this.presentedModal.value = 2 /* TransferDataDisplay */; this.getTransferData(); }; + initiateTransfer = () => { + this.presentedModal.value = 3 /* TransferDisplay */; + this.didNotFinishSending.value = true; + this.filesSentCount.value = 0; + this.filePathsSent.clear(); + this.fileTransferModel.sendFiles( + this.selectedPaths.value.values(), + (path) => { + console.log(path); + this.filePathsSent.add(path); + this.filesSentCount.value++; + } + ); + this.didNotFinishSending.value = false; + }; hideModal = () => { this.presentedModal.value = void 0; }; @@ -4504,9 +4530,14 @@ } }; + // src/View/Components/textSpan.tsx + var StringToTextSpan = (string) => { + return /* @__PURE__ */ createElement("span", { class: "ellipsis" }, string); + }; + // src/View/Modals/dataTransferModal.tsx function DataTransferModalWrapper(fileTransferViewModel2) { - return /* @__PURE__ */ createElement("div", null, DirectionSelectionModal(fileTransferViewModel2), FileSelectionModal(fileTransferViewModel2), TransferDataDisplayModal(fileTransferViewModel2)); + return /* @__PURE__ */ createElement("div", null, DirectionSelectionModal(fileTransferViewModel2), FileSelectionModal(fileTransferViewModel2), TransferDataDisplayModal(fileTransferViewModel2), TransferDisplayModal(fileTransferViewModel2)); } function DirectionSelectionModal(fileTransferViewModel2) { const isPresented = createProxyState( @@ -4590,7 +4621,7 @@ [fileTransferViewModel2.presentedModal], () => fileTransferViewModel2.presentedModal.value == 2 /* TransferDataDisplay */ ); - return /* @__PURE__ */ createElement("div", { class: "modal", "toggle:open": isPresented }, /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("main", null, /* @__PURE__ */ createElement("h2", null, translations.dataTransferModal.transferDataHeadline), /* @__PURE__ */ createElement("div", { class: "flex-column gap content-margin-bottom" }, /* @__PURE__ */ createElement("div", { class: "tile" }, /* @__PURE__ */ createElement("span", { class: "icon" }, "forum"), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", { class: "secondary" }, translations.dataTransferModal.transferChannelHeadline), /* @__PURE__ */ createElement( + return /* @__PURE__ */ createElement("div", { class: "modal", "toggle:open": isPresented }, /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("main", null, /* @__PURE__ */ createElement("h2", null, translations.dataTransferModal.transferDataHeadline), /* @__PURE__ */ createElement("span", { class: "secondary" }, translations.dataTransferModal.dataEntryDescription), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement("div", { class: "flex-column gap content-margin-bottom" }, /* @__PURE__ */ createElement("div", { class: "tile" }, /* @__PURE__ */ createElement("span", { class: "icon" }, "forum"), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", { class: "secondary" }, translations.dataTransferModal.transferChannelHeadline), /* @__PURE__ */ createElement( "b", { "subscribe:innerText": fileTransferViewModel2.transferChannel @@ -4602,7 +4633,45 @@ "on:click": fileTransferViewModel2.showFileSelectionModal }, translations.general.backButton - ), /* @__PURE__ */ createElement("button", { class: "primary flex" }, translations.general.continueButton, /* @__PURE__ */ createElement("span", { class: "icon" }, "arrow_forward"))))); + ), /* @__PURE__ */ createElement( + "button", + { + class: "primary flex", + "on:click": fileTransferViewModel2.initiateTransfer + }, + translations.dataTransferModal.sendButton, + /* @__PURE__ */ createElement("span", { class: "icon" }, "arrow_forward") + )))); + } + function TransferDisplayModal(fileTransferViewModel2) { + const isPresented = createProxyState( + [fileTransferViewModel2.presentedModal], + () => fileTransferViewModel2.presentedModal.value == 3 /* TransferDisplay */ + ); + return /* @__PURE__ */ createElement("div", { class: "modal", "toggle:open": isPresented }, /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("main", null, /* @__PURE__ */ createElement("h2", null, translations.dataTransferModal.transferDataHeadline), /* @__PURE__ */ createElement("p", null, translations.dataTransferModal.sendingFiles), /* @__PURE__ */ createElement( + "p", + { + class: "secondary", + "subscribe:innerText": fileTransferViewModel2.filesSentText + } + ), /* @__PURE__ */ createElement( + "div", + { + class: "tile flex-column align-start", + "children:append": [ + fileTransferViewModel2.filePathsSent, + StringToTextSpan + ] + } + )), /* @__PURE__ */ createElement( + "button", + { + "on:click": fileTransferViewModel2.hideModal, + "toggle:disabled": fileTransferViewModel2.didNotFinishSending + }, + translations.general.closeButton, + /* @__PURE__ */ createElement("span", { class: "icon" }, "close") + ))); } // src/Model/Global/fileTransferModel.ts @@ -4645,10 +4714,14 @@ this.storageModel.write(fileData.path, fileData.body); }; // sending - sendFiles = (...directoryPaths) => { + sendFiles = (directoryPaths, callback) => { for (const directoryPath of directoryPaths) { this.storageModel.recurse(directoryPath, (filePath) => { this.sendFile(filePath); + const pathString = StorageModel.pathComponentsToString( + ...filePath + ); + callback(pathString); }); } }; diff --git a/src/Model/Global/fileTransferModel.ts b/src/Model/Global/fileTransferModel.ts index e2829364..77ddfd09 100644 --- a/src/Model/Global/fileTransferModel.ts +++ b/src/Model/Global/fileTransferModel.ts @@ -56,10 +56,17 @@ export default class FileTransferModel { }; // sending - sendFiles = (...directoryPaths: string[][]): void => { + sendFiles = ( + directoryPaths: BuiltinIterator, + callback: (path: string) => void + ): void => { for (const directoryPath of directoryPaths) { this.storageModel.recurse(directoryPath, (filePath: string[]) => { this.sendFile(filePath); + const pathString: string = StorageModel.pathComponentsToString( + ...filePath + ); + callback(pathString); }); } }; diff --git a/src/View/Components/textSpan.tsx b/src/View/Components/textSpan.tsx index fecbd1da..fd944c89 100644 --- a/src/View/Components/textSpan.tsx +++ b/src/View/Components/textSpan.tsx @@ -3,5 +3,5 @@ import * as React from "bloatless-react"; export const StringToTextSpan: React.StateItemConverter = ( string: string ) => { - return {string} + return {string} }; diff --git a/src/View/Modals/dataTransferModal.tsx b/src/View/Modals/dataTransferModal.tsx index ac7fbe12..84fbceb8 100644 --- a/src/View/Modals/dataTransferModal.tsx +++ b/src/View/Modals/dataTransferModal.tsx @@ -6,6 +6,7 @@ import FileTransferViewModel, { } from "../../ViewModel/Global/fileTransferViewModel"; import StorageModel from "../../Model/Global/storageModel"; +import { StringToTextSpan } from "../Components/textSpan"; import { translations } from "../translations"; export function DataTransferModalWrapper( @@ -16,6 +17,7 @@ export function DataTransferModalWrapper( {DirectionSelectionModal(fileTransferViewModel)} {FileSelectionModal(fileTransferViewModel)} {TransferDataDisplayModal(fileTransferViewModel)} + {TransferDisplayModal(fileTransferViewModel)} ); } @@ -176,6 +178,12 @@ function TransferDataDisplayModal(

{translations.dataTransferModal.transferDataHeadline}

+ + {translations.dataTransferModal.dataEntryDescription} + + +
+
forum @@ -206,8 +214,11 @@ function TransferDataDisplayModal( > {translations.general.backButton} -
@@ -215,3 +226,44 @@ function TransferDataDisplayModal(
); } + +function TransferDisplayModal(fileTransferViewModel: FileTransferViewModel) { + const isPresented = React.createProxyState( + [fileTransferViewModel.presentedModal], + () => + fileTransferViewModel.presentedModal.value == + FileTransferModal.TransferDisplay + ); + + return ( + + ); +} diff --git a/src/View/translations.ts b/src/View/translations.ts index 9bde0e58..00356fec 100644 --- a/src/View/translations.ts +++ b/src/View/translations.ts @@ -82,6 +82,7 @@ const englishTranslations = { dataTransferModal: { transferDataHeadline: "Transfer Data", selectionDescription: "Select the data that you want to transfer.", + dataEntryDescription: "Enter this data on the other device.", /// @@ -94,15 +95,20 @@ const englishTranslations = { connectionData: "Connection Data", settingsData: "Settings Data", - - /// - + chatsHeadline: "Chats", /// transferChannelHeadline: "Transfer Chanel", transferKeyHeadline: "Transfer Encryption Key", + + sendButton: "Send", + + /// + + sendingFiles: "Sending files...", + filesSentCount: (count: number) => `Files sent: ${count}` }, storage: { diff --git a/src/ViewModel/Global/fileTransferViewModel.ts b/src/ViewModel/Global/fileTransferViewModel.ts index 71a8fb6f..15a5d43d 100644 --- a/src/ViewModel/Global/fileTransferViewModel.ts +++ b/src/ViewModel/Global/fileTransferViewModel.ts @@ -27,6 +27,15 @@ export default class FileTransferViewModel { transferChannel: React.State = new React.State(""); transferKey: React.State = new React.State(""); + filesSentCount: React.State = new React.State(0); + filePathsSent: React.ListState = new React.ListState(); + didNotFinishSending: React.State = new React.State(true); + filesSentText: React.State = React.createProxyState( + [this.filesSentCount], + () => + translations.dataTransferModal.filesSentCount(this.filesSentCount.value) + ); + // guards hasNoPathsSelected: React.State = React.createProxyState( [this.selectedPaths], @@ -80,6 +89,24 @@ export default class FileTransferViewModel { this.getTransferData(); }; + initiateTransfer = (): void => { + this.presentedModal.value = FileTransferModal.TransferDisplay; + this.didNotFinishSending.value = true; + this.filesSentCount.value = 0; + this.filePathsSent.clear(); + + this.fileTransferModel.sendFiles( + this.selectedPaths.value.values(), + (path: string) => { + console.log(path); + this.filePathsSent.add(path); + this.filesSentCount.value++; + } + ); + + this.didNotFinishSending.value = false; + }; + hideModal = (): void => { this.presentedModal.value = undefined; };