add progress bar to data transfer
This commit is contained in:
Vendored
+63
-53
@@ -436,9 +436,8 @@
|
|||||||
sendButton: "Send",
|
sendButton: "Send",
|
||||||
sendAgainButton: "Send again",
|
sendAgainButton: "Send again",
|
||||||
///
|
///
|
||||||
filesSentCount: (count) => `Files sent: ${count}.`,
|
filesSentProgress: (progress, total) => `Sent ${progress} of ${total} files`,
|
||||||
allFilesSent: "Done.",
|
filesReceivedProgress: (progress, total) => `Received ${progress} of ${total} files`,
|
||||||
filesReceivedCount: (count) => `Files processed: ${count}.`,
|
|
||||||
//
|
//
|
||||||
exportKey: "Encryption key",
|
exportKey: "Encryption key",
|
||||||
exportKeyConfirmation: "Confirm",
|
exportKeyConfirmation: "Confirm",
|
||||||
@@ -702,9 +701,8 @@
|
|||||||
transferKeyHeadline: "Schl\xFCssel",
|
transferKeyHeadline: "Schl\xFCssel",
|
||||||
sendButton: "Senden",
|
sendButton: "Senden",
|
||||||
sendAgainButton: "Erneut senden",
|
sendAgainButton: "Erneut senden",
|
||||||
filesSentCount: (count) => `Dateien gesendet: ${count}.`,
|
filesSentProgress: (progress, total) => `${progress} von ${total} Dateien gesendet`,
|
||||||
allFilesSent: "Fertig.",
|
filesReceivedProgress: (progress, total) => `${progress} von ${total} Dateien empfangen`,
|
||||||
filesReceivedCount: (count) => `Dateien empfangen: ${count}.`,
|
|
||||||
exportKey: "Schl\xFCssel",
|
exportKey: "Schl\xFCssel",
|
||||||
exportKeyConfirmation: "Schl\xFCssel best\xE4tigen",
|
exportKeyConfirmation: "Schl\xFCssel best\xE4tigen",
|
||||||
downloadFileButton: "Herunterladen",
|
downloadFileButton: "Herunterladen",
|
||||||
@@ -954,9 +952,8 @@
|
|||||||
transferKeyHeadline: "Clave de encriptaci\xF3n de transferencia",
|
transferKeyHeadline: "Clave de encriptaci\xF3n de transferencia",
|
||||||
sendButton: "Enviar",
|
sendButton: "Enviar",
|
||||||
sendAgainButton: "Enviar otra vez",
|
sendAgainButton: "Enviar otra vez",
|
||||||
filesSentCount: (count) => `Archivos enviados: ${count}.`,
|
filesSentProgress: (progress, total) => `${progress} de ${total} enviados`,
|
||||||
allFilesSent: "Hecho.",
|
filesReceivedProgress: (progress, total) => `${progress} de ${total} recibidos`,
|
||||||
filesReceivedCount: (count) => `Archivos recibidos: ${count}.`,
|
|
||||||
exportKey: "Clave de encriptaci\xF3n",
|
exportKey: "Clave de encriptaci\xF3n",
|
||||||
exportKeyConfirmation: "Confirmar clave",
|
exportKeyConfirmation: "Confirmar clave",
|
||||||
downloadFileButton: "Descargar",
|
downloadFileButton: "Descargar",
|
||||||
@@ -2290,27 +2287,13 @@
|
|||||||
this.receivingTransferChannel = new State("");
|
this.receivingTransferChannel = new State("");
|
||||||
this.receivingTransferKey = new State("");
|
this.receivingTransferKey = new State("");
|
||||||
this.filePathsSent = new ListState();
|
this.filePathsSent = new ListState();
|
||||||
this.filesSentCount = createProxyState(
|
this.fileTransferTotal = new State(0);
|
||||||
[this.filePathsSent],
|
this.fileTransferProgress = new State(0);
|
||||||
() => this.filePathsSent.value.size
|
|
||||||
);
|
|
||||||
this.filesSentText = createProxyState(
|
|
||||||
[this.filesSentCount],
|
|
||||||
() => this.coreViewModel.translations.dataTransferModal.filesSentCount(
|
|
||||||
this.filesSentCount.value
|
|
||||||
)
|
|
||||||
);
|
|
||||||
this.filePathsReceived = new ListState();
|
this.filePathsReceived = new ListState();
|
||||||
this.filesReceivedCount = createProxyState(
|
this.filesReceivedCount = createProxyState(
|
||||||
[this.filePathsReceived],
|
[this.filePathsReceived],
|
||||||
() => this.filePathsReceived.value.size
|
() => this.filePathsReceived.value.size
|
||||||
);
|
);
|
||||||
this.filesReceivedText = createProxyState(
|
|
||||||
[this.filesReceivedCount],
|
|
||||||
() => this.coreViewModel.translations.dataTransferModal.filesReceivedCount(
|
|
||||||
this.filesReceivedCount.value
|
|
||||||
)
|
|
||||||
);
|
|
||||||
this.exportKey = new State("");
|
this.exportKey = new State("");
|
||||||
this.exportKeyConfirmation = new State("");
|
this.exportKeyConfirmation = new State("");
|
||||||
this.importedFile = new State(void 0);
|
this.importedFile = new State(void 0);
|
||||||
@@ -2322,7 +2305,6 @@
|
|||||||
[this.selectedPaths],
|
[this.selectedPaths],
|
||||||
() => this.selectedPaths.value.size == 0
|
() => this.selectedPaths.value.size == 0
|
||||||
);
|
);
|
||||||
this.didNotFinishSending = new State(true);
|
|
||||||
this.cannotPrepareToReceive = createProxyState(
|
this.cannotPrepareToReceive = createProxyState(
|
||||||
[this.receivingTransferChannel, this.receivingTransferKey],
|
[this.receivingTransferChannel, this.receivingTransferKey],
|
||||||
() => this.receivingTransferChannel.value == "" || this.receivingTransferKey.value == ""
|
() => this.receivingTransferChannel.value == "" || this.receivingTransferKey.value == ""
|
||||||
@@ -2346,6 +2328,7 @@
|
|||||||
// handlers
|
// handlers
|
||||||
this.handleReceivedFile = (path) => {
|
this.handleReceivedFile = (path) => {
|
||||||
this.filePathsReceived.add(path);
|
this.filePathsReceived.add(path);
|
||||||
|
this.fileTransferProgress.value = this.filePathsReceived.value.size;
|
||||||
};
|
};
|
||||||
// methods
|
// methods
|
||||||
this.getOptions = () => {
|
this.getOptions = () => {
|
||||||
@@ -2454,7 +2437,6 @@
|
|||||||
};
|
};
|
||||||
this.initiateTransfer = () => {
|
this.initiateTransfer = () => {
|
||||||
this.presentedModal.value = 3 /* TransferDisplay */;
|
this.presentedModal.value = 3 /* TransferDisplay */;
|
||||||
this.didNotFinishSending.value = true;
|
|
||||||
this.filePathsSent.clear();
|
this.filePathsSent.clear();
|
||||||
this.coreViewModel.fileTransferModel.sendFiles(
|
this.coreViewModel.fileTransferModel.sendFiles(
|
||||||
this.selectedPaths.value.values(),
|
this.selectedPaths.value.values(),
|
||||||
@@ -2462,7 +2444,6 @@
|
|||||||
this.filePathsSent.add(path);
|
this.filePathsSent.add(path);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
this.didNotFinishSending.value = false;
|
|
||||||
};
|
};
|
||||||
this.showTransferDataInputModal = () => {
|
this.showTransferDataInputModal = () => {
|
||||||
this.presentedModal.value = 4 /* TransferDataInput */;
|
this.presentedModal.value = 4 /* TransferDataInput */;
|
||||||
@@ -2496,6 +2477,10 @@
|
|||||||
this.handleContextClose = () => {
|
this.handleContextClose = () => {
|
||||||
this.presentedModal.value = void 0;
|
this.presentedModal.value = void 0;
|
||||||
};
|
};
|
||||||
|
this.coreViewModel.fileTransferModel.transferSizeHandlerManager.setHandler(
|
||||||
|
"file-transfer-view-model",
|
||||||
|
(count) => this.fileTransferTotal.value = count
|
||||||
|
);
|
||||||
this.coreViewModel.fileTransferModel.fileHandlerManager.setHandler(
|
this.coreViewModel.fileTransferModel.fileHandlerManager.setHandler(
|
||||||
"file-transfer-view-model",
|
"file-transfer-view-model",
|
||||||
this.handleReceivedFile
|
this.handleReceivedFile
|
||||||
@@ -4742,7 +4727,6 @@
|
|||||||
};
|
};
|
||||||
this.randomizeKey = () => {
|
this.randomizeKey = () => {
|
||||||
this.encryptionKeyInput.value = random(24);
|
this.encryptionKeyInput.value = random(24);
|
||||||
this.setEncryptionKey();
|
|
||||||
};
|
};
|
||||||
this.applyColor = () => {
|
this.applyColor = () => {
|
||||||
this.chatViewModel.setColor(this.color.value);
|
this.chatViewModel.setColor(this.color.value);
|
||||||
@@ -8165,6 +8149,21 @@
|
|||||||
return /* @__PURE__ */ createElement("span", { class: "ellipsis" }, string);
|
return /* @__PURE__ */ createElement("span", { class: "ellipsis" }, string);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// src/View/Components/progressBar.tsx
|
||||||
|
function ProgressBar(valueLabel, value, maximum) {
|
||||||
|
const style = createProxyState(
|
||||||
|
[value, maximum],
|
||||||
|
() => `width: ${100 * (value.value / maximum.value)}%`
|
||||||
|
);
|
||||||
|
return /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("div", { class: "width-100 surface-alt", style: "height: 18px" }, /* @__PURE__ */ createElement(
|
||||||
|
"div",
|
||||||
|
{
|
||||||
|
class: "height-100 background-primary",
|
||||||
|
"set:style": style
|
||||||
|
}
|
||||||
|
)), /* @__PURE__ */ createElement("span", { class: "secondary", "subscribe:innerText": valueLabel }));
|
||||||
|
}
|
||||||
|
|
||||||
// src/View/Modals/dataTransferModal.tsx
|
// src/View/Modals/dataTransferModal.tsx
|
||||||
function DataTransferModalWrapper(coreViewModel2, connectionViewModel2, fileTransferViewModel2) {
|
function DataTransferModalWrapper(coreViewModel2, connectionViewModel2, fileTransferViewModel2) {
|
||||||
return /* @__PURE__ */ createElement("div", null, DirectionSelectionModal(
|
return /* @__PURE__ */ createElement("div", null, DirectionSelectionModal(
|
||||||
@@ -8320,20 +8319,8 @@
|
|||||||
[fileTransferViewModel2.presentedModal],
|
[fileTransferViewModel2.presentedModal],
|
||||||
() => fileTransferViewModel2.presentedModal.value == 3 /* TransferDisplay */
|
() => 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, coreViewModel2.translations.dataTransferModal.transferDataHeadline), /* @__PURE__ */ createElement(
|
const progressLabel = createProxyState([fileTransferViewModel2.fileTransferProgress, fileTransferViewModel2.fileTransferTotal], () => coreViewModel2.translations.dataTransferModal.filesSentProgress(fileTransferViewModel2.fileTransferProgress.value, fileTransferViewModel2.fileTransferTotal.value));
|
||||||
"p",
|
return /* @__PURE__ */ createElement("div", { class: "modal", "toggle:open": isPresented }, /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("main", null, /* @__PURE__ */ createElement("h2", null, coreViewModel2.translations.dataTransferModal.transferDataHeadline), ProgressBar(progressLabel, fileTransferViewModel2.fileTransferProgress, fileTransferViewModel2.fileTransferTotal), /* @__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" }, coreViewModel2.translations.dataTransferModal.transferChannelHeadline), /* @__PURE__ */ createElement(
|
||||||
{
|
|
||||||
class: "secondary",
|
|
||||||
"subscribe:innerText": fileTransferViewModel2.filesSentText
|
|
||||||
}
|
|
||||||
), /* @__PURE__ */ createElement(
|
|
||||||
"p",
|
|
||||||
{
|
|
||||||
class: "secondary",
|
|
||||||
"toggle:hidden": fileTransferViewModel2.didNotFinishSending
|
|
||||||
},
|
|
||||||
coreViewModel2.translations.dataTransferModal.allFilesSent
|
|
||||||
), /* @__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" }, coreViewModel2.translations.dataTransferModal.transferChannelHeadline), /* @__PURE__ */ createElement(
|
|
||||||
"b",
|
"b",
|
||||||
{
|
{
|
||||||
"subscribe:innerText": fileTransferViewModel2.transferChannel
|
"subscribe:innerText": fileTransferViewModel2.transferChannel
|
||||||
@@ -8364,8 +8351,7 @@
|
|||||||
"button",
|
"button",
|
||||||
{
|
{
|
||||||
class: "flex",
|
class: "flex",
|
||||||
"on:click": fileTransferViewModel2.close,
|
"on:click": fileTransferViewModel2.close
|
||||||
"toggle:disabled": fileTransferViewModel2.didNotFinishSending
|
|
||||||
},
|
},
|
||||||
coreViewModel2.translations.general.closeButton,
|
coreViewModel2.translations.general.closeButton,
|
||||||
/* @__PURE__ */ createElement("span", { class: "icon" }, "close")
|
/* @__PURE__ */ createElement("span", { class: "icon" }, "close")
|
||||||
@@ -8413,13 +8399,8 @@
|
|||||||
[fileTransferViewModel2.presentedModal],
|
[fileTransferViewModel2.presentedModal],
|
||||||
() => fileTransferViewModel2.presentedModal.value == 5 /* ReceptionDisplay */
|
() => fileTransferViewModel2.presentedModal.value == 5 /* ReceptionDisplay */
|
||||||
);
|
);
|
||||||
return /* @__PURE__ */ createElement("div", { class: "modal", "toggle:open": isPresented }, /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("main", null, /* @__PURE__ */ createElement("h2", null, coreViewModel2.translations.dataTransferModal.receiveHeadline), /* @__PURE__ */ createElement(
|
const progressLabel = createProxyState([fileTransferViewModel2.fileTransferProgress, fileTransferViewModel2.fileTransferTotal], () => coreViewModel2.translations.dataTransferModal.filesReceivedProgress(fileTransferViewModel2.fileTransferProgress.value, fileTransferViewModel2.fileTransferTotal.value));
|
||||||
"p",
|
return /* @__PURE__ */ createElement("div", { class: "modal", "toggle:open": isPresented }, /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("main", null, /* @__PURE__ */ createElement("h2", null, coreViewModel2.translations.dataTransferModal.receiveHeadline), ProgressBar(progressLabel, fileTransferViewModel2.fileTransferProgress, fileTransferViewModel2.fileTransferTotal), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement(
|
||||||
{
|
|
||||||
class: "secondary",
|
|
||||||
"subscribe:innerText": fileTransferViewModel2.filesReceivedText
|
|
||||||
}
|
|
||||||
), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement(
|
|
||||||
"div",
|
"div",
|
||||||
{
|
{
|
||||||
class: "tile flex-column align-start",
|
class: "tile flex-column align-start",
|
||||||
@@ -8641,6 +8622,7 @@
|
|||||||
this.direction = 0 /* Send */;
|
this.direction = 0 /* Send */;
|
||||||
// handler managers
|
// handler managers
|
||||||
this.fileHandlerManager = new HandlerManager();
|
this.fileHandlerManager = new HandlerManager();
|
||||||
|
this.transferSizeHandlerManager = new HandlerManager();
|
||||||
this.readyToSendHandlerManager = new HandlerManager();
|
this.readyToSendHandlerManager = new HandlerManager();
|
||||||
// general
|
// general
|
||||||
this.generateTransferData = () => {
|
this.generateTransferData = () => {
|
||||||
@@ -8700,6 +8682,11 @@
|
|||||||
};
|
};
|
||||||
this.handleDecryptedFile = (data) => {
|
this.handleDecryptedFile = (data) => {
|
||||||
const parsed = parse(data);
|
const parsed = parse(data);
|
||||||
|
if (!parsed.type) return;
|
||||||
|
if (parsed.type == "transfer-size" && typeof parsed.count == "number") {
|
||||||
|
this.transferSizeHandlerManager.trigger(parsed.count);
|
||||||
|
return;
|
||||||
|
}
|
||||||
const isFileData = checkMatchesObjectStructure(
|
const isFileData = checkMatchesObjectStructure(
|
||||||
parsed,
|
parsed,
|
||||||
FileDataReference
|
FileDataReference
|
||||||
@@ -8714,15 +8701,21 @@
|
|||||||
};
|
};
|
||||||
// sending
|
// sending
|
||||||
this.sendFiles = (directoryPaths, fileCallback) => {
|
this.sendFiles = (directoryPaths, fileCallback) => {
|
||||||
|
const filesToSend = /* @__PURE__ */ new Set();
|
||||||
for (const directoryPath of directoryPaths) {
|
for (const directoryPath of directoryPaths) {
|
||||||
this.storageModel.recurse(directoryPath, (filePath) => {
|
this.storageModel.recurse(directoryPath, (filePath) => {
|
||||||
const stringifiedFileData = this.prepareFileForSending(filePath);
|
const stringifiedFileData = this.prepareFileForSending(filePath);
|
||||||
|
filesToSend.add([stringifiedFileData, filePath]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.sendTransferSize(filesToSend.size);
|
||||||
|
for (const file of filesToSend) {
|
||||||
|
const [stringifiedFileData, filePath] = file;
|
||||||
this.sendFile(stringifiedFileData);
|
this.sendFile(stringifiedFileData);
|
||||||
const pathString = StorageModel.pathComponentsToString(
|
const pathString = StorageModel.pathComponentsToString(
|
||||||
...filePath
|
...filePath
|
||||||
);
|
);
|
||||||
fileCallback(pathString);
|
fileCallback(pathString);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
this.generateBackup = async (directoryPaths, passphrase) => {
|
this.generateBackup = async (directoryPaths, passphrase) => {
|
||||||
@@ -8739,10 +8732,26 @@
|
|||||||
const blob = new Blob([encrypted], { type: "text/plain" });
|
const blob = new Blob([encrypted], { type: "text/plain" });
|
||||||
return blob;
|
return blob;
|
||||||
};
|
};
|
||||||
|
this.sendTransferSize = async (count) => {
|
||||||
|
if (!this.transferData) return;
|
||||||
|
const data = {
|
||||||
|
type: "transfer-size",
|
||||||
|
count
|
||||||
|
};
|
||||||
|
const encryptedData = await encryptString(
|
||||||
|
stringify(data),
|
||||||
|
this.transferData.key
|
||||||
|
);
|
||||||
|
this.connectionModel.sendPlainMessage(
|
||||||
|
this.transferData.channel,
|
||||||
|
encryptedData
|
||||||
|
);
|
||||||
|
};
|
||||||
this.prepareFileForSending = (filePath) => {
|
this.prepareFileForSending = (filePath) => {
|
||||||
const fileContent = this.storageModel.read(filePath);
|
const fileContent = this.storageModel.read(filePath);
|
||||||
if (fileContent == null) return "";
|
if (fileContent == null) return "";
|
||||||
const fileData = {
|
const fileData = {
|
||||||
|
type: "file-data",
|
||||||
path: filePath,
|
path: filePath,
|
||||||
body: fileContent
|
body: fileContent
|
||||||
};
|
};
|
||||||
@@ -8771,6 +8780,7 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
var FileDataReference = {
|
var FileDataReference = {
|
||||||
|
type: "file-data",
|
||||||
path: [""],
|
path: [""],
|
||||||
body: ""
|
body: ""
|
||||||
};
|
};
|
||||||
|
|||||||
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
const VERSION = "2610 Beta 21.12"
|
const VERSION = "2610 Beta 21.13"
|
||||||
|
|
||||||
function processUrl(event) {
|
function processUrl(event) {
|
||||||
const url = event.request.url;
|
const url = event.request.url;
|
||||||
|
|||||||
Vendored
+1
-1
@@ -1 +1 @@
|
|||||||
2610 Beta 21.12
|
2610 Beta 21.13
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ export default class FileTransferModel {
|
|||||||
|
|
||||||
// handler managers
|
// handler managers
|
||||||
readonly fileHandlerManager = new HandlerManager<string>();
|
readonly fileHandlerManager = new HandlerManager<string>();
|
||||||
|
readonly transferSizeHandlerManager = new HandlerManager<number>();
|
||||||
readonly readyToSendHandlerManager = new HandlerManager<boolean>();
|
readonly readyToSendHandlerManager = new HandlerManager<boolean>();
|
||||||
|
|
||||||
// general
|
// general
|
||||||
@@ -105,6 +106,12 @@ export default class FileTransferModel {
|
|||||||
readonly handleDecryptedFile = (data: string): void => {
|
readonly handleDecryptedFile = (data: string): void => {
|
||||||
const parsed: any = parse(data);
|
const parsed: any = parse(data);
|
||||||
|
|
||||||
|
if (!parsed.type) return;
|
||||||
|
if (parsed.type == "transfer-size" && typeof parsed.count == "number") {
|
||||||
|
this.transferSizeHandlerManager.trigger(parsed.count);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const isFileData: boolean = checkMatchesObjectStructure(
|
const isFileData: boolean = checkMatchesObjectStructure(
|
||||||
parsed,
|
parsed,
|
||||||
FileDataReference,
|
FileDataReference,
|
||||||
@@ -126,16 +133,22 @@ export default class FileTransferModel {
|
|||||||
directoryPaths: IteratorObject<string[]>,
|
directoryPaths: IteratorObject<string[]>,
|
||||||
fileCallback: (path: string) => void,
|
fileCallback: (path: string) => void,
|
||||||
): void => {
|
): void => {
|
||||||
|
const filesToSend = new Set<[string, string[]]>();
|
||||||
for (const directoryPath of directoryPaths) {
|
for (const directoryPath of directoryPaths) {
|
||||||
this.storageModel.recurse(directoryPath, (filePath: string[]) => {
|
this.storageModel.recurse(directoryPath, (filePath: string[]) => {
|
||||||
const stringifiedFileData =
|
const stringifiedFileData =
|
||||||
this.prepareFileForSending(filePath);
|
this.prepareFileForSending(filePath);
|
||||||
|
filesToSend.add([stringifiedFileData, filePath]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.sendTransferSize(filesToSend.size);
|
||||||
|
for (const file of filesToSend) {
|
||||||
|
const [stringifiedFileData, filePath] = file;
|
||||||
this.sendFile(stringifiedFileData);
|
this.sendFile(stringifiedFileData);
|
||||||
const pathString: string = StorageModel.pathComponentsToString(
|
const pathString: string = StorageModel.pathComponentsToString(
|
||||||
...filePath,
|
...filePath,
|
||||||
);
|
);
|
||||||
fileCallback(pathString);
|
fileCallback(pathString);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -158,11 +171,30 @@ export default class FileTransferModel {
|
|||||||
return blob;
|
return blob;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
readonly sendTransferSize = async (count: number): Promise<void> => {
|
||||||
|
if (!this.transferData) return;
|
||||||
|
|
||||||
|
const data: TransferSize = {
|
||||||
|
type: "transfer-size",
|
||||||
|
count,
|
||||||
|
};
|
||||||
|
|
||||||
|
const encryptedData: string = await encryptString(
|
||||||
|
stringify(data),
|
||||||
|
this.transferData.key,
|
||||||
|
);
|
||||||
|
this.connectionModel.sendPlainMessage(
|
||||||
|
this.transferData.channel,
|
||||||
|
encryptedData,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
readonly prepareFileForSending = (filePath: string[]): string => {
|
readonly prepareFileForSending = (filePath: string[]): string => {
|
||||||
const fileContent: string | null = this.storageModel.read(filePath);
|
const fileContent: string | null = this.storageModel.read(filePath);
|
||||||
if (fileContent == null) return "";
|
if (fileContent == null) return "";
|
||||||
|
|
||||||
const fileData: FileData = {
|
const fileData: FileData = {
|
||||||
|
type: "file-data",
|
||||||
path: filePath,
|
path: filePath,
|
||||||
body: fileContent,
|
body: fileContent,
|
||||||
};
|
};
|
||||||
@@ -200,11 +232,18 @@ export interface TransferData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface FileData {
|
export interface FileData {
|
||||||
|
type: "file-data";
|
||||||
path: string[];
|
path: string[];
|
||||||
body: string;
|
body: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface TransferSize {
|
||||||
|
type: "transfer-size";
|
||||||
|
count: number;
|
||||||
|
}
|
||||||
|
|
||||||
export const FileDataReference: FileData = {
|
export const FileDataReference: FileData = {
|
||||||
|
type: "file-data",
|
||||||
path: [""],
|
path: [""],
|
||||||
body: "",
|
body: "",
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ const ENCRYPTION_ALG = "AES-GCM";
|
|||||||
|
|
||||||
// random
|
// random
|
||||||
export function random(length: number): string {
|
export function random(length: number): string {
|
||||||
return cryptoRandomString({length})
|
return cryptoRandomString({ length });
|
||||||
}
|
}
|
||||||
|
|
||||||
// encrypt
|
// encrypt
|
||||||
|
|||||||
@@ -140,11 +140,12 @@ export function SettingsPage(
|
|||||||
<div class="flex-row width-input">
|
<div class="flex-row width-input">
|
||||||
<button
|
<button
|
||||||
class="width-50"
|
class="width-50"
|
||||||
on:click={
|
on:click={settingsPageViewModel.randomizeKey}
|
||||||
settingsPageViewModel.randomizeKey
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
{coreViewModel.translations.chatPage.settings.randomizeKey}
|
{
|
||||||
|
coreViewModel.translations.chatPage.settings
|
||||||
|
.randomizeKey
|
||||||
|
}
|
||||||
<span class="icon">shuffle</span>
|
<span class="icon">shuffle</span>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
|||||||
@@ -65,10 +65,10 @@ export function TaskPage(
|
|||||||
class="no-outline"
|
class="no-outline"
|
||||||
bind:value={taskPageViewModel.boardQuery}
|
bind:value={taskPageViewModel.boardQuery}
|
||||||
on:enter={taskPageViewModel.createBoard}
|
on:enter={taskPageViewModel.createBoard}
|
||||||
placeholder={
|
placeholder={coreViewModel.translations.general.filterOrCreateLabel(
|
||||||
coreViewModel.translations.general
|
coreViewModel.translations.chatPage.task
|
||||||
.filterOrCreateLabel(coreViewModel.translations.chatPage.task.typeBoard)
|
.typeBoard,
|
||||||
}
|
)}
|
||||||
></input>
|
></input>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
import * as React from "../../react";
|
||||||
|
|
||||||
|
export function ProgressBar(
|
||||||
|
valueLabel: React.State<string>,
|
||||||
|
value: React.State<number>,
|
||||||
|
maximum: React.State<number>,
|
||||||
|
) {
|
||||||
|
const style = React.createProxyState(
|
||||||
|
[value, maximum],
|
||||||
|
() => `width: ${100 * (value.value / maximum.value)}%`,
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div class="width-100 surface-alt" style="height: 18px">
|
||||||
|
<div
|
||||||
|
class="height-100 background-primary"
|
||||||
|
set:style={style}
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
<span class="secondary" subscribe:innerText={valueLabel}></span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import { ViewController } from "../viewController";
|
import { ViewController } from "../viewController";
|
||||||
import { CommonKeys, getKeySymbol } from "../keystrokes";
|
import { CommonKeys, getKeySymbol } from "../keystrokes";
|
||||||
import { StringToTextSpan } from "../Components/textSpan";
|
import { StringToTextSpan } from "../Components/textSpan";
|
||||||
|
import { ProgressBar } from "../Components/progressBar";
|
||||||
import * as React from "../../react";
|
import * as React from "../../react";
|
||||||
import FileTransferViewModel, {
|
import FileTransferViewModel, {
|
||||||
FileTransferModals,
|
FileTransferModals,
|
||||||
@@ -370,6 +371,18 @@ function TransferDisplayModal(
|
|||||||
FileTransferModals.TransferDisplay,
|
FileTransferModals.TransferDisplay,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const progressLabel = React.createProxyState(
|
||||||
|
[
|
||||||
|
fileTransferViewModel.fileTransferProgress,
|
||||||
|
fileTransferViewModel.fileTransferTotal,
|
||||||
|
],
|
||||||
|
() =>
|
||||||
|
coreViewModel.translations.dataTransferModal.filesSentProgress(
|
||||||
|
fileTransferViewModel.fileTransferProgress.value,
|
||||||
|
fileTransferViewModel.fileTransferTotal.value,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class="modal" toggle:open={isPresented}>
|
<div class="modal" toggle:open={isPresented}>
|
||||||
<div>
|
<div>
|
||||||
@@ -381,24 +394,11 @@ function TransferDisplayModal(
|
|||||||
}
|
}
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<p
|
{ProgressBar(
|
||||||
class="secondary"
|
progressLabel,
|
||||||
subscribe:innerText={
|
fileTransferViewModel.fileTransferProgress,
|
||||||
fileTransferViewModel.filesSentText
|
fileTransferViewModel.fileTransferTotal,
|
||||||
}
|
)}
|
||||||
></p>
|
|
||||||
|
|
||||||
<p
|
|
||||||
class="secondary"
|
|
||||||
toggle:hidden={
|
|
||||||
fileTransferViewModel.didNotFinishSending
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{
|
|
||||||
coreViewModel.translations.dataTransferModal
|
|
||||||
.allFilesSent
|
|
||||||
}
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<hr></hr>
|
<hr></hr>
|
||||||
|
|
||||||
@@ -460,13 +460,7 @@ function TransferDisplayModal(
|
|||||||
}
|
}
|
||||||
<span class="icon">restart_alt</span>
|
<span class="icon">restart_alt</span>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button class="flex" on:click={fileTransferViewModel.close}>
|
||||||
class="flex"
|
|
||||||
on:click={fileTransferViewModel.close}
|
|
||||||
toggle:disabled={
|
|
||||||
fileTransferViewModel.didNotFinishSending
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{coreViewModel.translations.general.closeButton}
|
{coreViewModel.translations.general.closeButton}
|
||||||
<span class="icon">close</span>
|
<span class="icon">close</span>
|
||||||
</button>
|
</button>
|
||||||
@@ -588,6 +582,18 @@ function DataReceptionModal(
|
|||||||
FileTransferModals.ReceptionDisplay,
|
FileTransferModals.ReceptionDisplay,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const progressLabel = React.createProxyState(
|
||||||
|
[
|
||||||
|
fileTransferViewModel.fileTransferProgress,
|
||||||
|
fileTransferViewModel.fileTransferTotal,
|
||||||
|
],
|
||||||
|
() =>
|
||||||
|
coreViewModel.translations.dataTransferModal.filesReceivedProgress(
|
||||||
|
fileTransferViewModel.fileTransferProgress.value,
|
||||||
|
fileTransferViewModel.fileTransferTotal.value,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class="modal" toggle:open={isPresented}>
|
<div class="modal" toggle:open={isPresented}>
|
||||||
<div>
|
<div>
|
||||||
@@ -599,12 +605,11 @@ function DataReceptionModal(
|
|||||||
}
|
}
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<p
|
{ProgressBar(
|
||||||
class="secondary"
|
progressLabel,
|
||||||
subscribe:innerText={
|
fileTransferViewModel.fileTransferProgress,
|
||||||
fileTransferViewModel.filesReceivedText
|
fileTransferViewModel.fileTransferTotal,
|
||||||
}
|
)}
|
||||||
></p>
|
|
||||||
|
|
||||||
<hr></hr>
|
<hr></hr>
|
||||||
|
|
||||||
|
|||||||
+21
-12
@@ -1,5 +1,6 @@
|
|||||||
import "./homePage.css";
|
import "./homePage.css";
|
||||||
import { StringToOption } from "./Components/option";
|
import { StringToOption } from "./Components/option";
|
||||||
|
import { NewItemEntry } from "./Components/newItemEntry";
|
||||||
import { HomePageButton } from "./Components/homePageButton";
|
import { HomePageButton } from "./Components/homePageButton";
|
||||||
import { ChatViewModelToChatEntry } from "./Components/chatEntry";
|
import { ChatViewModelToChatEntry } from "./Components/chatEntry";
|
||||||
import * as React from "../react";
|
import * as React from "../react";
|
||||||
@@ -9,7 +10,6 @@ import FileTransferViewModel from "../ViewModel/Global/fileTransferViewModel";
|
|||||||
import CoreViewModel from "../ViewModel/Global/coreViewModel";
|
import CoreViewModel from "../ViewModel/Global/coreViewModel";
|
||||||
import ConnectionViewModel from "../ViewModel/Global/connectionViewModel";
|
import ConnectionViewModel from "../ViewModel/Global/connectionViewModel";
|
||||||
import ChatListViewModel from "../ViewModel/Chat/chatListViewModel";
|
import ChatListViewModel from "../ViewModel/Chat/chatListViewModel";
|
||||||
import {NewItemEntry} from "./Components/newItemEntry";
|
|
||||||
|
|
||||||
export function HomePage(
|
export function HomePage(
|
||||||
coreViewModel: CoreViewModel,
|
coreViewModel: CoreViewModel,
|
||||||
@@ -19,9 +19,18 @@ export function HomePage(
|
|||||||
fileTransferViewModel: FileTransferViewModel,
|
fileTransferViewModel: FileTransferViewModel,
|
||||||
chatListViewModel: ChatListViewModel,
|
chatListViewModel: ChatListViewModel,
|
||||||
) {
|
) {
|
||||||
const greeting = React.createProxyState([settingsViewModel.username], ()=>coreViewModel.translations.homePage.greeting(settingsViewModel.username.value));
|
const greeting = React.createProxyState([settingsViewModel.username], () =>
|
||||||
|
coreViewModel.translations.homePage.greeting(
|
||||||
|
settingsViewModel.username.value,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
const isChatPlaceholderHidden = React.createProxyState([chatListViewModel.chatMatches, chatListViewModel.chatQuery], ()=>chatListViewModel.chatMatches.value.size > 0 || chatListViewModel.chatQuery.value != "");
|
const isChatPlaceholderHidden = React.createProxyState(
|
||||||
|
[chatListViewModel.chatMatches, chatListViewModel.chatQuery],
|
||||||
|
() =>
|
||||||
|
chatListViewModel.chatMatches.value.size > 0 ||
|
||||||
|
chatListViewModel.chatQuery.value != "",
|
||||||
|
);
|
||||||
|
|
||||||
// sections
|
// sections
|
||||||
const overviewSection = (
|
const overviewSection = (
|
||||||
@@ -128,10 +137,9 @@ export function HomePage(
|
|||||||
<div id="chat-section">
|
<div id="chat-section">
|
||||||
<div class="flex-row width-input">
|
<div class="flex-row width-input">
|
||||||
<input
|
<input
|
||||||
placeholder={
|
placeholder={coreViewModel.translations.general.filterOrCreateLabel(
|
||||||
coreViewModel.translations.general
|
coreViewModel.translations.homePage.typeChat,
|
||||||
.filterOrCreateLabel(coreViewModel.translations.homePage.typeChat)
|
)}
|
||||||
}
|
|
||||||
bind:value={chatListViewModel.chatQuery}
|
bind:value={chatListViewModel.chatQuery}
|
||||||
on:enter={chatListViewModel.createChat}
|
on:enter={chatListViewModel.createChat}
|
||||||
></input>
|
></input>
|
||||||
@@ -139,12 +147,13 @@ export function HomePage(
|
|||||||
|
|
||||||
<hr></hr>
|
<hr></hr>
|
||||||
|
|
||||||
{NewItemEntry(coreViewModel, chatListViewModel.chatQuery, chatListViewModel.createChat)}
|
{NewItemEntry(
|
||||||
|
coreViewModel,
|
||||||
|
chatListViewModel.chatQuery,
|
||||||
|
chatListViewModel.createChat,
|
||||||
|
)}
|
||||||
|
|
||||||
<span
|
<span class="secondary" toggle:hidden={isChatPlaceholderHidden}>
|
||||||
class="secondary"
|
|
||||||
toggle:hidden={isChatPlaceholderHidden}
|
|
||||||
>
|
|
||||||
{coreViewModel.translations.homePage.noChatsPlaceholder}
|
{coreViewModel.translations.homePage.noChatsPlaceholder}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
|
|||||||
+14
-13
@@ -181,10 +181,10 @@ const englishTranslations = {
|
|||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
filesSentCount: (count: number) => `Files sent: ${count}.`,
|
filesSentProgress: (progress: number, total: number) =>
|
||||||
allFilesSent: "Done.",
|
`Sent ${progress} of ${total} files`,
|
||||||
|
filesReceivedProgress: (progress: number, total: number) =>
|
||||||
filesReceivedCount: (count: number) => `Files processed: ${count}.`,
|
`Received ${progress} of ${total} files`,
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
@@ -402,7 +402,8 @@ export const allTranslations: {
|
|||||||
saveButton: "Speichern",
|
saveButton: "Speichern",
|
||||||
setButton: "OK",
|
setButton: "OK",
|
||||||
|
|
||||||
filterOrCreateLabel: (type: string) => `${type} suchen oder erstellen`,
|
filterOrCreateLabel: (type: string) =>
|
||||||
|
`${type} suchen oder erstellen`,
|
||||||
createLabel: (query: string) => `"${query}" erstellen`,
|
createLabel: (query: string) => `"${query}" erstellen`,
|
||||||
|
|
||||||
reloadAppButton: "Neu laden",
|
reloadAppButton: "Neu laden",
|
||||||
@@ -550,10 +551,10 @@ export const allTranslations: {
|
|||||||
sendButton: "Senden",
|
sendButton: "Senden",
|
||||||
sendAgainButton: "Erneut senden",
|
sendAgainButton: "Erneut senden",
|
||||||
|
|
||||||
filesSentCount: (count) => `Dateien gesendet: ${count}.`,
|
filesSentProgress: (progress: number, total: number) =>
|
||||||
allFilesSent: "Fertig.",
|
`${progress} von ${total} Dateien gesendet`,
|
||||||
|
filesReceivedProgress: (progress: number, total: number) =>
|
||||||
filesReceivedCount: (count) => `Dateien empfangen: ${count}.`,
|
`${progress} von ${total} Dateien empfangen`,
|
||||||
|
|
||||||
exportKey: "Schlüssel",
|
exportKey: "Schlüssel",
|
||||||
exportKeyConfirmation: "Schlüssel bestätigen",
|
exportKeyConfirmation: "Schlüssel bestätigen",
|
||||||
@@ -894,10 +895,10 @@ export const allTranslations: {
|
|||||||
sendButton: "Enviar",
|
sendButton: "Enviar",
|
||||||
sendAgainButton: "Enviar otra vez",
|
sendAgainButton: "Enviar otra vez",
|
||||||
|
|
||||||
filesSentCount: (count) => `Archivos enviados: ${count}.`,
|
filesSentProgress: (progress: number, total: number) =>
|
||||||
allFilesSent: "Hecho.",
|
`${progress} de ${total} enviados`,
|
||||||
|
filesReceivedProgress: (progress: number, total: number) =>
|
||||||
filesReceivedCount: (count) => `Archivos recibidos: ${count}.`,
|
`${progress} de ${total} recibidos`,
|
||||||
|
|
||||||
exportKey: "Clave de encriptación",
|
exportKey: "Clave de encriptación",
|
||||||
exportKeyConfirmation: "Confirmar clave",
|
exportKeyConfirmation: "Confirmar clave",
|
||||||
|
|||||||
@@ -35,9 +35,7 @@ export default class ChatListViewModel {
|
|||||||
// methods
|
// methods
|
||||||
createChat = (): void => {
|
createChat = (): void => {
|
||||||
const chatModel: ChatModel =
|
const chatModel: ChatModel =
|
||||||
this.coreViewModel.chatListModel.createChat(
|
this.coreViewModel.chatListModel.createChat(this.chatQuery.value);
|
||||||
this.chatQuery.value,
|
|
||||||
);
|
|
||||||
this.chatQuery.value = "";
|
this.chatQuery.value = "";
|
||||||
|
|
||||||
const chatViewModel: ChatViewModel =
|
const chatViewModel: ChatViewModel =
|
||||||
@@ -109,7 +107,12 @@ export default class ChatListViewModel {
|
|||||||
|
|
||||||
this.loadChats();
|
this.loadChats();
|
||||||
|
|
||||||
implementFilter(this.chatViewModels, this.chatMatches, this.chatQuery, chat => chat.chatModel.info.name)
|
implementFilter(
|
||||||
|
this.chatViewModels,
|
||||||
|
this.chatMatches,
|
||||||
|
this.chatQuery,
|
||||||
|
(chat) => chat.chatModel.info.name,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// utility
|
// utility
|
||||||
|
|||||||
@@ -57,14 +57,15 @@ export default class CoreViewModel {
|
|||||||
while (this.contexts.length > 0) {
|
while (this.contexts.length > 0) {
|
||||||
const currentContext: Context | undefined = this.context;
|
const currentContext: Context | undefined = this.context;
|
||||||
if (!currentContext) break;
|
if (!currentContext) break;
|
||||||
const response = currentContext.handleContextClose(fromHistoryEvent);
|
const response =
|
||||||
|
currentContext.handleContextClose(fromHistoryEvent);
|
||||||
if (response == false) break;
|
if (response == false) break;
|
||||||
this.contextStack.delete(currentContext.contextId);
|
this.contextStack.delete(currentContext.contextId);
|
||||||
if (response == true) {
|
if (response == true) {
|
||||||
exitNext = true;
|
exitNext = true;
|
||||||
continue;
|
continue;
|
||||||
} else if (exitNext == true) {
|
} else if (exitNext == true) {
|
||||||
break
|
break;
|
||||||
} else if (currentContext.contextId == contextId) {
|
} else if (currentContext.contextId == contextId) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import ChatModel from "../../Model/Chat/chatModel";
|
|||||||
|
|
||||||
export default class FileTransferViewModel extends Context {
|
export default class FileTransferViewModel extends Context {
|
||||||
// state
|
// state
|
||||||
exitReception: () => void | undefined = undefined;
|
exitReception: (() => void) | undefined = undefined;
|
||||||
|
|
||||||
presentedModal: React.State<FileTransferModals | undefined> =
|
presentedModal: React.State<FileTransferModals | undefined> =
|
||||||
new React.State<any>(undefined);
|
new React.State<any>(undefined);
|
||||||
@@ -29,30 +29,14 @@ export default class FileTransferViewModel extends Context {
|
|||||||
receivingTransferKey: React.State<string> = new React.State("");
|
receivingTransferKey: React.State<string> = new React.State("");
|
||||||
|
|
||||||
filePathsSent: React.ListState<string> = new React.ListState();
|
filePathsSent: React.ListState<string> = new React.ListState();
|
||||||
filesSentCount: React.State<number> = React.createProxyState(
|
|
||||||
[this.filePathsSent],
|
|
||||||
() => this.filePathsSent.value.size,
|
|
||||||
);
|
|
||||||
filesSentText: React.State<string> = React.createProxyState(
|
|
||||||
[this.filesSentCount],
|
|
||||||
() =>
|
|
||||||
this.coreViewModel.translations.dataTransferModal.filesSentCount(
|
|
||||||
this.filesSentCount.value,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
|
fileTransferTotal: React.State<number> = new React.State(0);
|
||||||
|
fileTransferProgress: React.State<number> = new React.State(0);
|
||||||
filePathsReceived: React.ListState<string> = new React.ListState();
|
filePathsReceived: React.ListState<string> = new React.ListState();
|
||||||
filesReceivedCount: React.State<number> = React.createProxyState(
|
filesReceivedCount: React.State<number> = React.createProxyState(
|
||||||
[this.filePathsReceived],
|
[this.filePathsReceived],
|
||||||
() => this.filePathsReceived.value.size,
|
() => this.filePathsReceived.value.size,
|
||||||
);
|
);
|
||||||
filesReceivedText: React.State<string> = React.createProxyState(
|
|
||||||
[this.filesReceivedCount],
|
|
||||||
() =>
|
|
||||||
this.coreViewModel.translations.dataTransferModal.filesReceivedCount(
|
|
||||||
this.filesReceivedCount.value,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
exportKey: React.State<string> = new React.State("");
|
exportKey: React.State<string> = new React.State("");
|
||||||
exportKeyConfirmation: React.State<string> = new React.State("");
|
exportKeyConfirmation: React.State<string> = new React.State("");
|
||||||
@@ -69,7 +53,6 @@ export default class FileTransferViewModel extends Context {
|
|||||||
[this.selectedPaths],
|
[this.selectedPaths],
|
||||||
() => this.selectedPaths.value.size == 0,
|
() => this.selectedPaths.value.size == 0,
|
||||||
);
|
);
|
||||||
didNotFinishSending: React.State<boolean> = new React.State(true);
|
|
||||||
cannotPrepareToReceive: React.State<boolean> = React.createProxyState(
|
cannotPrepareToReceive: React.State<boolean> = React.createProxyState(
|
||||||
[this.receivingTransferChannel, this.receivingTransferKey],
|
[this.receivingTransferChannel, this.receivingTransferKey],
|
||||||
() =>
|
() =>
|
||||||
@@ -99,6 +82,7 @@ export default class FileTransferViewModel extends Context {
|
|||||||
// handlers
|
// handlers
|
||||||
handleReceivedFile = (path: string): void => {
|
handleReceivedFile = (path: string): void => {
|
||||||
this.filePathsReceived.add(path);
|
this.filePathsReceived.add(path);
|
||||||
|
this.fileTransferProgress.value = this.filePathsReceived.value.size;
|
||||||
};
|
};
|
||||||
|
|
||||||
// methods
|
// methods
|
||||||
@@ -229,7 +213,6 @@ export default class FileTransferViewModel extends Context {
|
|||||||
|
|
||||||
initiateTransfer = (): void => {
|
initiateTransfer = (): void => {
|
||||||
this.presentedModal.value = FileTransferModals.TransferDisplay;
|
this.presentedModal.value = FileTransferModals.TransferDisplay;
|
||||||
this.didNotFinishSending.value = true;
|
|
||||||
this.filePathsSent.clear();
|
this.filePathsSent.clear();
|
||||||
|
|
||||||
this.coreViewModel.fileTransferModel.sendFiles(
|
this.coreViewModel.fileTransferModel.sendFiles(
|
||||||
@@ -238,8 +221,6 @@ export default class FileTransferViewModel extends Context {
|
|||||||
this.filePathsSent.add(path);
|
this.filePathsSent.add(path);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
this.didNotFinishSending.value = false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
showTransferDataInputModal = (): void => {
|
showTransferDataInputModal = (): void => {
|
||||||
@@ -287,6 +268,11 @@ export default class FileTransferViewModel extends Context {
|
|||||||
constructor(public readonly coreViewModel: CoreViewModel) {
|
constructor(public readonly coreViewModel: CoreViewModel) {
|
||||||
super("file-transfer");
|
super("file-transfer");
|
||||||
|
|
||||||
|
this.coreViewModel.fileTransferModel.transferSizeHandlerManager.setHandler(
|
||||||
|
"file-transfer-view-model",
|
||||||
|
(count) => (this.fileTransferTotal.value = count),
|
||||||
|
);
|
||||||
|
|
||||||
this.coreViewModel.fileTransferModel.fileHandlerManager.setHandler(
|
this.coreViewModel.fileTransferModel.fileHandlerManager.setHandler(
|
||||||
"file-transfer-view-model",
|
"file-transfer-view-model",
|
||||||
this.handleReceivedFile,
|
this.handleReceivedFile,
|
||||||
|
|||||||
@@ -204,7 +204,7 @@ export default class BoardViewModel extends TaskContainingPageViewModel {
|
|||||||
|
|
||||||
resetPinchZoom = (): void => {
|
resetPinchZoom = (): void => {
|
||||||
this.pinchToZoomData.value = { x: 0, y: 0, zoom: 1 };
|
this.pinchToZoomData.value = { x: 0, y: 0, zoom: 1 };
|
||||||
}
|
};
|
||||||
|
|
||||||
// load
|
// load
|
||||||
preloadData = (): void => {
|
preloadData = (): void => {
|
||||||
@@ -318,7 +318,7 @@ export default class BoardViewModel extends TaskContainingPageViewModel {
|
|||||||
|
|
||||||
this.searchViewModel.appliedQuery.subscribeSilent(() => {
|
this.searchViewModel.appliedQuery.subscribeSilent(() => {
|
||||||
this.resetPinchZoom();
|
this.resetPinchZoom();
|
||||||
})
|
});
|
||||||
|
|
||||||
// handlers
|
// handlers
|
||||||
boardsAndTasksModel.taskHandlerManager.setHandler(
|
boardsAndTasksModel.taskHandlerManager.setHandler(
|
||||||
|
|||||||
@@ -224,7 +224,7 @@ export default class CalendarPageViewModel extends TaskContainingPageViewModel {
|
|||||||
handleContextClose = (fromHistoryEvent: boolean): void | boolean => {
|
handleContextClose = (fromHistoryEvent: boolean): void | boolean => {
|
||||||
if (!fromHistoryEvent) return;
|
if (!fromHistoryEvent) return;
|
||||||
return true;
|
return true;
|
||||||
}
|
};
|
||||||
|
|
||||||
// init
|
// init
|
||||||
constructor(
|
constructor(
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
import * as React from "../../react";
|
|
||||||
|
|
||||||
import StorageViewModel from "../Global/storageViewModel";
|
import StorageViewModel from "../Global/storageViewModel";
|
||||||
import SettingsViewModel from "../Global/settingsViewModel";
|
import SettingsViewModel from "../Global/settingsViewModel";
|
||||||
import FileTransferViewModel from "../Global/fileTransferViewModel";
|
import FileTransferViewModel from "../Global/fileTransferViewModel";
|
||||||
import CoreViewModel, { Context } from "../Global/coreViewModel";
|
import CoreViewModel, { Context } from "../Global/coreViewModel";
|
||||||
import ConnectionViewModel from "../Global/connectionViewModel";
|
import ConnectionViewModel from "../Global/connectionViewModel";
|
||||||
|
import * as React from "../../react";
|
||||||
import { CommonKeys } from "../../View/keystrokes";
|
import { CommonKeys } from "../../View/keystrokes";
|
||||||
|
|
||||||
export default class HomeViewModel extends Context {
|
export default class HomeViewModel extends Context {
|
||||||
|
|||||||
@@ -197,14 +197,14 @@ export default class MessagePageViewModel extends Context {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// context
|
// context
|
||||||
handleContextClose = (fromHistoryEvent: boolean):boolean=> {
|
handleContextClose = (fromHistoryEvent: boolean): boolean | void => {
|
||||||
if (fromHistoryEvent) {
|
if (fromHistoryEvent) {
|
||||||
if (this.replyViewSelectedMessage.value == undefined) return true;
|
if (this.replyViewSelectedMessage.value == undefined) return true;
|
||||||
|
|
||||||
this.resetReplyView();
|
this.resetReplyView();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
// init
|
// init
|
||||||
constructor(
|
constructor(
|
||||||
|
|||||||
@@ -76,8 +76,7 @@ export default class SettingsPageViewModel extends Context {
|
|||||||
|
|
||||||
randomizeKey = (): void => {
|
randomizeKey = (): void => {
|
||||||
this.encryptionKeyInput.value = random(24);
|
this.encryptionKeyInput.value = random(24);
|
||||||
this.setEncryptionKey();
|
};
|
||||||
}
|
|
||||||
|
|
||||||
applyColor = (): void => {
|
applyColor = (): void => {
|
||||||
this.chatViewModel.setColor(this.color.value);
|
this.chatViewModel.setColor(this.color.value);
|
||||||
@@ -125,7 +124,7 @@ export default class SettingsPageViewModel extends Context {
|
|||||||
handleContextClose = (fromHistoryEvent: boolean): void | boolean => {
|
handleContextClose = (fromHistoryEvent: boolean): void | boolean => {
|
||||||
if (!fromHistoryEvent) return;
|
if (!fromHistoryEvent) return;
|
||||||
return true;
|
return true;
|
||||||
}
|
};
|
||||||
|
|
||||||
// init
|
// init
|
||||||
constructor(
|
constructor(
|
||||||
|
|||||||
@@ -170,7 +170,7 @@ export default class TaskPageViewModel extends ContextHost<string> {
|
|||||||
handleContextClose = (fromHistoryEvent: boolean): void | boolean => {
|
handleContextClose = (fromHistoryEvent: boolean): void | boolean => {
|
||||||
if (!fromHistoryEvent) return;
|
if (!fromHistoryEvent) return;
|
||||||
return true;
|
return true;
|
||||||
}
|
};
|
||||||
|
|
||||||
// init
|
// init
|
||||||
constructor(
|
constructor(
|
||||||
|
|||||||
+2
-2
@@ -30,7 +30,7 @@ main {
|
|||||||
z-index: -1;
|
z-index: -1;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
|
|
||||||
opacity: .3;
|
opacity: 0.3;
|
||||||
}
|
}
|
||||||
|
|
||||||
#background-wrapper > div > div {
|
#background-wrapper > div > div {
|
||||||
@@ -143,6 +143,6 @@ body[theme="dark"] #background-wrapper #grass-2 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
body[keystroke-active] [ctkeystroke]::after {
|
body[keystroke-active] [ctkeystroke]::after {
|
||||||
opacity: .7;
|
opacity: 0.7;
|
||||||
transform: translateY(0px);
|
transform: translateY(0px);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user