move name to settings modal
This commit is contained in:
Vendored
+197
-128
@@ -351,9 +351,6 @@
|
|||||||
connectAudioLabel: "connect to server",
|
connectAudioLabel: "connect to server",
|
||||||
disconnectAudioLabel: "disconnect from server",
|
disconnectAudioLabel: "disconnect from server",
|
||||||
manageConnectionsAudioLabel: "manage connections",
|
manageConnectionsAudioLabel: "manage connections",
|
||||||
yourNameLabel: "Your name",
|
|
||||||
yourNamePlaceholder: "Jane Doe",
|
|
||||||
setNameButtonAudioLabel: "set name",
|
|
||||||
settingsButton: "Settings",
|
settingsButton: "Settings",
|
||||||
manageStorageButton: "Manage storage",
|
manageStorageButton: "Manage storage",
|
||||||
transferDataButton: "Transfer or export data",
|
transferDataButton: "Transfer or export data",
|
||||||
@@ -369,6 +366,7 @@
|
|||||||
settings: {
|
settings: {
|
||||||
pages: {
|
pages: {
|
||||||
appearance: "Appearance",
|
appearance: "Appearance",
|
||||||
|
account: "Account",
|
||||||
regional: "Language & Region",
|
regional: "Language & Region",
|
||||||
info: "About CT"
|
info: "About CT"
|
||||||
},
|
},
|
||||||
@@ -379,10 +377,19 @@
|
|||||||
system: "Device theme",
|
system: "Device theme",
|
||||||
black: "Black"
|
black: "Black"
|
||||||
},
|
},
|
||||||
version: "Version",
|
account: {
|
||||||
language: "Language",
|
yourNameLabel: "Your name",
|
||||||
firstDayOfWeekLabel: "First day of week",
|
yourNamePlaceholder: "Jane Doe",
|
||||||
checkUpdatesButton: "Check for updates"
|
setNameButtonAudioLabel: "set name"
|
||||||
|
},
|
||||||
|
regional: {
|
||||||
|
language: "Language",
|
||||||
|
firstDayOfWeekLabel: "First day of week"
|
||||||
|
},
|
||||||
|
about: {
|
||||||
|
version: "Version",
|
||||||
|
checkUpdatesButton: "Check for updates"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
connectionModal: {
|
connectionModal: {
|
||||||
connectionModalHeadline: "Manage Connections",
|
connectionModalHeadline: "Manage Connections",
|
||||||
@@ -600,9 +607,6 @@
|
|||||||
connectAudioLabel: "mit Server verbinden",
|
connectAudioLabel: "mit Server verbinden",
|
||||||
disconnectAudioLabel: "vom Server trennen",
|
disconnectAudioLabel: "vom Server trennen",
|
||||||
manageConnectionsAudioLabel: "Verbindungen verwalten",
|
manageConnectionsAudioLabel: "Verbindungen verwalten",
|
||||||
yourNameLabel: "Dein Name",
|
|
||||||
yourNamePlaceholder: "Max Mustermann",
|
|
||||||
setNameButtonAudioLabel: "Name speichern",
|
|
||||||
settingsButton: "Einstellungen",
|
settingsButton: "Einstellungen",
|
||||||
manageStorageButton: "Daten verwalten",
|
manageStorageButton: "Daten verwalten",
|
||||||
transferDataButton: "Daten \xFCbertragen",
|
transferDataButton: "Daten \xFCbertragen",
|
||||||
@@ -617,6 +621,7 @@
|
|||||||
settings: {
|
settings: {
|
||||||
pages: {
|
pages: {
|
||||||
appearance: "Erscheinungsbild",
|
appearance: "Erscheinungsbild",
|
||||||
|
account: "Konto",
|
||||||
regional: "Sprache & Region",
|
regional: "Sprache & Region",
|
||||||
info: "\xDCber CT"
|
info: "\xDCber CT"
|
||||||
},
|
},
|
||||||
@@ -627,10 +632,19 @@
|
|||||||
system: "Ger\xE4teeinstellung",
|
system: "Ger\xE4teeinstellung",
|
||||||
black: "Schwarz"
|
black: "Schwarz"
|
||||||
},
|
},
|
||||||
version: "Version",
|
account: {
|
||||||
language: "Sprache",
|
yourNameLabel: "Dein Name",
|
||||||
firstDayOfWeekLabel: "Erster Wochentag",
|
yourNamePlaceholder: "Max Mustermann",
|
||||||
checkUpdatesButton: "Nach updates suchen"
|
setNameButtonAudioLabel: "Namen festlegen"
|
||||||
|
},
|
||||||
|
regional: {
|
||||||
|
language: "Sprache",
|
||||||
|
firstDayOfWeekLabel: "Erster Wochentag"
|
||||||
|
},
|
||||||
|
about: {
|
||||||
|
version: "Version",
|
||||||
|
checkUpdatesButton: "Nach Updates suchen"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
connectionModal: {
|
connectionModal: {
|
||||||
connectionModalHeadline: "Verbindungen verwalten",
|
connectionModalHeadline: "Verbindungen verwalten",
|
||||||
@@ -829,9 +843,6 @@
|
|||||||
connectAudioLabel: "conectar al servidor",
|
connectAudioLabel: "conectar al servidor",
|
||||||
disconnectAudioLabel: "desconectar del servidor",
|
disconnectAudioLabel: "desconectar del servidor",
|
||||||
manageConnectionsAudioLabel: "gestionar conexiones",
|
manageConnectionsAudioLabel: "gestionar conexiones",
|
||||||
yourNameLabel: "Tu nombre",
|
|
||||||
yourNamePlaceholder: "Juan P\xE9rez",
|
|
||||||
setNameButtonAudioLabel: "establecer nombre",
|
|
||||||
settingsButton: "Ajustes",
|
settingsButton: "Ajustes",
|
||||||
manageStorageButton: "Gestionar almacenamiento",
|
manageStorageButton: "Gestionar almacenamiento",
|
||||||
transferDataButton: "Enviar o exportar archivos",
|
transferDataButton: "Enviar o exportar archivos",
|
||||||
@@ -846,6 +857,7 @@
|
|||||||
settings: {
|
settings: {
|
||||||
pages: {
|
pages: {
|
||||||
appearance: "Aspecto",
|
appearance: "Aspecto",
|
||||||
|
account: "Cuenta",
|
||||||
regional: "Idioma y Regi\xF3n",
|
regional: "Idioma y Regi\xF3n",
|
||||||
info: "Sobre CT"
|
info: "Sobre CT"
|
||||||
},
|
},
|
||||||
@@ -856,10 +868,19 @@
|
|||||||
system: "Seg\xFAn dispositivo",
|
system: "Seg\xFAn dispositivo",
|
||||||
black: "Negro"
|
black: "Negro"
|
||||||
},
|
},
|
||||||
version: "Versi\xF3n",
|
account: {
|
||||||
language: "Idioma",
|
yourNameLabel: "Tu nombre",
|
||||||
firstDayOfWeekLabel: "Primer d\xEDa de la semana",
|
yourNamePlaceholder: "Juan P\xE9rez",
|
||||||
checkUpdatesButton: "Buscar actualizaciones"
|
setNameButtonAudioLabel: "establecer nombre"
|
||||||
|
},
|
||||||
|
regional: {
|
||||||
|
language: "Idioma",
|
||||||
|
firstDayOfWeekLabel: "Primer d\xEDa de la semana"
|
||||||
|
},
|
||||||
|
about: {
|
||||||
|
version: "Versi\xF3n",
|
||||||
|
checkUpdatesButton: "Buscar actualisaciones"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
connectionModal: {
|
connectionModal: {
|
||||||
connectionModalHeadline: "Gestionar Conexiones",
|
connectionModalHeadline: "Gestionar Conexiones",
|
||||||
@@ -1709,7 +1730,7 @@
|
|||||||
this.printTree = () => {
|
this.printTree = () => {
|
||||||
return stringify(this.storageEntryTree);
|
return stringify(this.storageEntryTree);
|
||||||
};
|
};
|
||||||
// upgrade
|
// upgrade
|
||||||
this.upgrade = () => {
|
this.upgrade = () => {
|
||||||
};
|
};
|
||||||
this.initializeTree();
|
this.initializeTree();
|
||||||
@@ -1862,9 +1883,8 @@
|
|||||||
// src/Model/Global/settingsModel.ts
|
// src/Model/Global/settingsModel.ts
|
||||||
var SettingsModel = class _SettingsModel {
|
var SettingsModel = class _SettingsModel {
|
||||||
// init
|
// init
|
||||||
constructor(storageModel2, contactListModel2) {
|
constructor(storageModel2) {
|
||||||
this.storageModel = storageModel2;
|
this.storageModel = storageModel2;
|
||||||
this.contactListModel = contactListModel2;
|
|
||||||
// data
|
// data
|
||||||
this.username = "";
|
this.username = "";
|
||||||
this.userid = "";
|
this.userid = "";
|
||||||
@@ -1886,7 +1906,6 @@
|
|||||||
this.setName = (newValue) => {
|
this.setName = (newValue) => {
|
||||||
this.username = newValue;
|
this.username = newValue;
|
||||||
this.storeSetting("username", newValue);
|
this.storeSetting("username", newValue);
|
||||||
this.contactListModel.storeContact(this.userid, newValue);
|
|
||||||
};
|
};
|
||||||
this.setFirstDayOfWeek = (newValue) => {
|
this.setFirstDayOfWeek = (newValue) => {
|
||||||
this.firstDayOfWeek = newValue;
|
this.firstDayOfWeek = newValue;
|
||||||
@@ -1976,7 +1995,10 @@
|
|||||||
() => this.usernameInput.value == "" || this.usernameInput.value == this.coreViewModel.settingsModel.username
|
() => this.usernameInput.value == "" || this.usernameInput.value == this.coreViewModel.settingsModel.username
|
||||||
);
|
);
|
||||||
// methods
|
// methods
|
||||||
this.setName = () => {
|
this.setName = (name) => {
|
||||||
|
if (typeof name == "string") {
|
||||||
|
this.usernameInput.value = name;
|
||||||
|
}
|
||||||
this.coreViewModel.settingsModel.setName(this.usernameInput.value);
|
this.coreViewModel.settingsModel.setName(this.usernameInput.value);
|
||||||
this.username.value = this.coreViewModel.settingsModel.username;
|
this.username.value = this.coreViewModel.settingsModel.username;
|
||||||
this.usernameInput.callSubscriptions();
|
this.usernameInput.callSubscriptions();
|
||||||
@@ -2362,6 +2384,58 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// src/ViewModel/Global/contactViewModel.ts
|
||||||
|
var ContactListViewModel = class {
|
||||||
|
// init
|
||||||
|
constructor(contactListModel2, settingsViewModel2) {
|
||||||
|
this.contactListModel = contactListModel2;
|
||||||
|
this.settingsViewModel = settingsViewModel2;
|
||||||
|
// state
|
||||||
|
this.contacts = /* @__PURE__ */ new Map();
|
||||||
|
// main
|
||||||
|
this.updateContact = (id, name) => {
|
||||||
|
if (id == this.settingsViewModel.settingsModel.userid) {
|
||||||
|
this.settingsViewModel.setName(name);
|
||||||
|
}
|
||||||
|
const match = this.contacts.get(id);
|
||||||
|
if (match) {
|
||||||
|
match.name.value = name;
|
||||||
|
return match;
|
||||||
|
}
|
||||||
|
const vm = new ContactViewModel(id, name);
|
||||||
|
this.contacts.set(id, vm);
|
||||||
|
return vm;
|
||||||
|
};
|
||||||
|
this.handleContact = (contact) => {
|
||||||
|
this.updateContact(...contact);
|
||||||
|
};
|
||||||
|
this.unwrapContact = (id, knownName) => {
|
||||||
|
if (this.contacts.has(id))
|
||||||
|
return this.contacts.get(id);
|
||||||
|
return this.updateContact(id, knownName);
|
||||||
|
};
|
||||||
|
// load
|
||||||
|
this.loadData = () => {
|
||||||
|
const contacts = this.contactListModel.loadContacts();
|
||||||
|
for (const contact of contacts) {
|
||||||
|
const vm = new ContactViewModel(...contact);
|
||||||
|
this.contacts.set(vm.id, vm);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this.loadData();
|
||||||
|
this.contactListModel.contactHandlerManager.setHandler("contact-list-view-model", this.handleContact);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var ContactViewModel = class {
|
||||||
|
// init
|
||||||
|
constructor(id, name) {
|
||||||
|
this.id = id;
|
||||||
|
// state
|
||||||
|
this.name = new State("");
|
||||||
|
this.name.value = name;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// src/ViewModel/Global/connectionViewModel.ts
|
// src/ViewModel/Global/connectionViewModel.ts
|
||||||
var ConnectionViewModel = class {
|
var ConnectionViewModel = class {
|
||||||
// init
|
// init
|
||||||
@@ -2952,9 +3026,14 @@
|
|||||||
// messaging
|
// messaging
|
||||||
this.addMessage = async (chatMessage) => {
|
this.addMessage = async (chatMessage) => {
|
||||||
await this.decryptMessage(chatMessage);
|
await this.decryptMessage(chatMessage);
|
||||||
this.contactListModel.storeContact(chatMessage.senderId, chatMessage.senderName);
|
this.contactListModel.storeContact(
|
||||||
|
chatMessage.senderId,
|
||||||
|
chatMessage.senderName
|
||||||
|
);
|
||||||
if (chatMessage.body != "") {
|
if (chatMessage.body != "") {
|
||||||
const messagePath = this.getMessagePath(chatMessage.fileId);
|
const messagePath = this.getMessagePath(
|
||||||
|
chatMessage.fileId
|
||||||
|
);
|
||||||
this.storageModel.writeStringifiable(messagePath, chatMessage);
|
this.storageModel.writeStringifiable(messagePath, chatMessage);
|
||||||
this.chatMessageHandlerManager.trigger(chatMessage);
|
this.chatMessageHandlerManager.trigger(chatMessage);
|
||||||
}
|
}
|
||||||
@@ -5196,23 +5275,6 @@
|
|||||||
"toggle:disabled": connectionViewModel2.cannotConnect
|
"toggle:disabled": connectionViewModel2.cannotConnect
|
||||||
},
|
},
|
||||||
/* @__PURE__ */ createElement("span", { class: "icon" }, "link")
|
/* @__PURE__ */ createElement("span", { class: "icon" }, "link")
|
||||||
)), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement("label", { class: "tile flex-no" }, /* @__PURE__ */ createElement("span", { class: "icon" }, "account_circle"), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, coreViewModel2.translations.homePage.yourNameLabel), /* @__PURE__ */ createElement(
|
|
||||||
"input",
|
|
||||||
{
|
|
||||||
placeholder: coreViewModel2.translations.homePage.yourNamePlaceholder,
|
|
||||||
"bind:value": settingsViewModel2.usernameInput,
|
|
||||||
"on:enter": settingsViewModel2.setName
|
|
||||||
}
|
|
||||||
))), /* @__PURE__ */ createElement("div", { class: "flex-row justify-end" }, /* @__PURE__ */ createElement(
|
|
||||||
"button",
|
|
||||||
{
|
|
||||||
class: "width-50",
|
|
||||||
"on:click": settingsViewModel2.setName,
|
|
||||||
"toggle:disabled": settingsViewModel2.cannotSetName,
|
|
||||||
"aria-label": coreViewModel2.translations.homePage.setNameButtonAudioLabel
|
|
||||||
},
|
|
||||||
coreViewModel2.translations.general.setButton,
|
|
||||||
/* @__PURE__ */ createElement("span", { class: "icon" }, "check")
|
|
||||||
)), /* @__PURE__ */ createElement("hr", null), HomePageButton(
|
)), /* @__PURE__ */ createElement("hr", null), HomePageButton(
|
||||||
settingsViewModel2.showSettingsModal,
|
settingsViewModel2.showSettingsModal,
|
||||||
coreViewModel2.translations.homePage.settingsButton,
|
coreViewModel2.translations.homePage.settingsButton,
|
||||||
@@ -6476,7 +6538,13 @@
|
|||||||
|
|
||||||
// src/View/Components/replyPreview.tsx
|
// src/View/Components/replyPreview.tsx
|
||||||
function ReplyPreview(coreViewModel2, chatMessageViewModel) {
|
function ReplyPreview(coreViewModel2, chatMessageViewModel) {
|
||||||
return /* @__PURE__ */ createElement("div", { class: "reply-preview" }, /* @__PURE__ */ createElement("div", { class: "surface blur" }, /* @__PURE__ */ createElement("span", { class: "secondary", "subscribe:innerText": chatMessageViewModel.contact.name }), /* @__PURE__ */ createElement(
|
return /* @__PURE__ */ createElement("div", { class: "reply-preview" }, /* @__PURE__ */ createElement("div", { class: "surface blur" }, /* @__PURE__ */ createElement(
|
||||||
|
"span",
|
||||||
|
{
|
||||||
|
class: "secondary",
|
||||||
|
"subscribe:innerText": chatMessageViewModel.contact.name
|
||||||
|
}
|
||||||
|
), /* @__PURE__ */ createElement(
|
||||||
"b",
|
"b",
|
||||||
{
|
{
|
||||||
class: "ellipsis",
|
class: "ellipsis",
|
||||||
@@ -7430,12 +7498,17 @@
|
|||||||
coreViewModel2,
|
coreViewModel2,
|
||||||
settingsViewModel2
|
settingsViewModel2
|
||||||
);
|
);
|
||||||
case 1 /* Regional */:
|
case 1 /* Account */:
|
||||||
|
return SettingsAccountPane(
|
||||||
|
coreViewModel2,
|
||||||
|
settingsViewModel2
|
||||||
|
);
|
||||||
|
case 2 /* Regional */:
|
||||||
return SettingsRegionalPane(
|
return SettingsRegionalPane(
|
||||||
coreViewModel2,
|
coreViewModel2,
|
||||||
settingsViewModel2
|
settingsViewModel2
|
||||||
);
|
);
|
||||||
case 2 /* Info */:
|
case 3 /* Info */:
|
||||||
return SettingsInfoPane(coreViewModel2, settingsViewModel2);
|
return SettingsInfoPane(coreViewModel2, settingsViewModel2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7466,12 +7539,17 @@
|
|||||||
), SettingsPaneButton(
|
), SettingsPaneButton(
|
||||||
coreViewModel2,
|
coreViewModel2,
|
||||||
settingsViewModel2,
|
settingsViewModel2,
|
||||||
1 /* Regional */,
|
1 /* Account */,
|
||||||
|
coreViewModel2.translations.settings.pages.account
|
||||||
|
), SettingsPaneButton(
|
||||||
|
coreViewModel2,
|
||||||
|
settingsViewModel2,
|
||||||
|
2 /* Regional */,
|
||||||
coreViewModel2.translations.settings.pages.regional
|
coreViewModel2.translations.settings.pages.regional
|
||||||
), SettingsPaneButton(
|
), SettingsPaneButton(
|
||||||
coreViewModel2,
|
coreViewModel2,
|
||||||
settingsViewModel2,
|
settingsViewModel2,
|
||||||
2 /* Info */,
|
3 /* Info */,
|
||||||
coreViewModel2.translations.settings.pages.info
|
coreViewModel2.translations.settings.pages.info
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@@ -7487,7 +7565,7 @@
|
|||||||
function SettingsInfoPane(coreViewModel2, settingsViewModel2) {
|
function SettingsInfoPane(coreViewModel2, settingsViewModel2) {
|
||||||
return /* @__PURE__ */ createElement("div", { class: "slide-up" }, /* @__PURE__ */ createElement("h2", null, coreViewModel2.translations.homePage.appName), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement("div", { class: "flex-column gap" }, InfoTile(
|
return /* @__PURE__ */ createElement("div", { class: "slide-up" }, /* @__PURE__ */ createElement("h2", null, coreViewModel2.translations.homePage.appName), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement("div", { class: "flex-column gap" }, InfoTile(
|
||||||
"build",
|
"build",
|
||||||
coreViewModel2.translations.settings.version,
|
coreViewModel2.translations.settings.about.version,
|
||||||
settingsViewModel2.coreViewModel.version
|
settingsViewModel2.coreViewModel.version
|
||||||
), /* @__PURE__ */ createElement(
|
), /* @__PURE__ */ createElement(
|
||||||
"button",
|
"button",
|
||||||
@@ -7498,15 +7576,15 @@
|
|||||||
},
|
},
|
||||||
/* @__PURE__ */ createElement("span", { "subscribe:innerText": coreViewModel2.updateText }),
|
/* @__PURE__ */ createElement("span", { "subscribe:innerText": coreViewModel2.updateText }),
|
||||||
/* @__PURE__ */ createElement("span", { class: "icon" }, "update")
|
/* @__PURE__ */ createElement("span", { class: "icon" }, "update")
|
||||||
), /* @__PURE__ */ createElement("button", { class: "standard", "on:click": coreViewModel2.checkUpdates }, coreViewModel2.translations.settings.checkUpdatesButton)));
|
), /* @__PURE__ */ createElement("button", { class: "standard", "on:click": coreViewModel2.checkUpdates }, coreViewModel2.translations.settings.about.checkUpdatesButton)));
|
||||||
}
|
}
|
||||||
function SettingsRegionalPane(coreViewModel2, settingsViewModel2) {
|
function SettingsRegionalPane(coreViewModel2, settingsViewModel2) {
|
||||||
return /* @__PURE__ */ createElement("div", { class: "slide-up" }, /* @__PURE__ */ createElement("h2", null, coreViewModel2.translations.settings.pages.regional), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement("h3", null, coreViewModel2.translations.settings.language), OptionButtonList(
|
return /* @__PURE__ */ createElement("div", { class: "slide-up" }, /* @__PURE__ */ createElement("h2", null, coreViewModel2.translations.settings.pages.regional), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement("h3", null, coreViewModel2.translations.settings.regional.language), OptionButtonList(
|
||||||
new ListState(
|
new ListState(
|
||||||
Object.values(Languages).map((x) => [languageNames[x], x])
|
Object.values(Languages).map((x) => [languageNames[x], x])
|
||||||
),
|
),
|
||||||
settingsViewModel2.language
|
settingsViewModel2.language
|
||||||
), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement("h3", null, coreViewModel2.translations.settings.firstDayOfWeekLabel), OptionButtonList(
|
), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement("h3", null, coreViewModel2.translations.settings.regional.firstDayOfWeekLabel), OptionButtonList(
|
||||||
new ListState(
|
new ListState(
|
||||||
coreViewModel2.translations.regional.weekdays.full.map(
|
coreViewModel2.translations.regional.weekdays.full.map(
|
||||||
(x, i) => [x, i.toString()]
|
(x, i) => [x, i.toString()]
|
||||||
@@ -7515,6 +7593,26 @@
|
|||||||
settingsViewModel2.firstDayOfWeek
|
settingsViewModel2.firstDayOfWeek
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
function SettingsAccountPane(coreViewModel2, settingsViewModel2) {
|
||||||
|
return /* @__PURE__ */ createElement("div", { class: "slide-up" }, /* @__PURE__ */ createElement("h2", null, coreViewModel2.translations.settings.pages.account), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement("label", { class: "tile flex-no" }, /* @__PURE__ */ createElement("span", { class: "icon" }, "account_circle"), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, coreViewModel2.translations.settings.account.yourNameLabel), /* @__PURE__ */ createElement(
|
||||||
|
"input",
|
||||||
|
{
|
||||||
|
placeholder: coreViewModel2.translations.settings.account.yourNamePlaceholder,
|
||||||
|
"bind:value": settingsViewModel2.usernameInput,
|
||||||
|
"on:enter": settingsViewModel2.setName
|
||||||
|
}
|
||||||
|
))), /* @__PURE__ */ createElement("div", { class: "flex-row justify-end width-input" }, /* @__PURE__ */ createElement(
|
||||||
|
"button",
|
||||||
|
{
|
||||||
|
class: "width-50",
|
||||||
|
"on:click": settingsViewModel2.setName,
|
||||||
|
"toggle:disabled": settingsViewModel2.cannotSetName,
|
||||||
|
"aria-label": coreViewModel2.translations.settings.account.setNameButtonAudioLabel
|
||||||
|
},
|
||||||
|
coreViewModel2.translations.general.setButton,
|
||||||
|
/* @__PURE__ */ createElement("span", { class: "icon" }, "check")
|
||||||
|
)));
|
||||||
|
}
|
||||||
function SettingsAppearancePane(coreViewModel2, settingsViewModel2) {
|
function SettingsAppearancePane(coreViewModel2, settingsViewModel2) {
|
||||||
return /* @__PURE__ */ createElement("div", { class: "slide-up" }, /* @__PURE__ */ createElement("h2", null, coreViewModel2.translations.settings.pages.appearance), /* @__PURE__ */ createElement("hr", null), OptionButtonList(
|
return /* @__PURE__ */ createElement("div", { class: "slide-up" }, /* @__PURE__ */ createElement("h2", null, coreViewModel2.translations.settings.pages.appearance), /* @__PURE__ */ createElement("hr", null), OptionButtonList(
|
||||||
new ListState([
|
new ListState([
|
||||||
@@ -8150,6 +8248,37 @@
|
|||||||
body: ""
|
body: ""
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// src/Model/Global/contactListModel.ts
|
||||||
|
var ContactListModel = class {
|
||||||
|
constructor(storageModel2, settingsModel2) {
|
||||||
|
this.storageModel = storageModel2;
|
||||||
|
this.settingsModel = settingsModel2;
|
||||||
|
this.contactHandlerManager = new HandlerManager();
|
||||||
|
this.getContactPath = (contactId) => {
|
||||||
|
return StorageModel.getPath("contacts" /* ContactsModel */, [
|
||||||
|
contactId
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
this.loadContacts = () => {
|
||||||
|
const contactIds = this.storageModel.list([
|
||||||
|
"contacts" /* ContactsModel */
|
||||||
|
]);
|
||||||
|
const contacts = contactIds.map((id) => [
|
||||||
|
id,
|
||||||
|
this.storageModel.read(this.getContactPath(id)) ?? "?"
|
||||||
|
]);
|
||||||
|
contacts.push([this.settingsModel.userid, this.settingsModel.username]);
|
||||||
|
return contacts;
|
||||||
|
};
|
||||||
|
this.storeContact = (id, name) => {
|
||||||
|
this.contactHandlerManager.trigger([id, name]);
|
||||||
|
if (id == this.settingsModel.userid) return;
|
||||||
|
const path = this.getContactPath(id);
|
||||||
|
this.storageModel.write(path, name);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// node_modules/udn-frontend/index.ts
|
// node_modules/udn-frontend/index.ts
|
||||||
var UDNFrontend = class {
|
var UDNFrontend = class {
|
||||||
ws;
|
ws;
|
||||||
@@ -8370,11 +8499,17 @@
|
|||||||
return chatMessages;
|
return chatMessages;
|
||||||
};
|
};
|
||||||
this.addToOutbox = (chatMessage) => {
|
this.addToOutbox = (chatMessage) => {
|
||||||
const messagePath = [...this.getOutboxPath(), chatMessage.fileId];
|
const messagePath = [
|
||||||
|
...this.getOutboxPath(),
|
||||||
|
chatMessage.fileId
|
||||||
|
];
|
||||||
this.storageModel.writeStringifiable(messagePath, chatMessage);
|
this.storageModel.writeStringifiable(messagePath, chatMessage);
|
||||||
};
|
};
|
||||||
this.removeFromOutbox = (chatMessage) => {
|
this.removeFromOutbox = (chatMessage) => {
|
||||||
const messagePath = [...this.getOutboxPath(), chatMessage.fileId];
|
const messagePath = [
|
||||||
|
...this.getOutboxPath(),
|
||||||
|
chatMessage.fileId
|
||||||
|
];
|
||||||
this.storageModel.remove(messagePath);
|
this.storageModel.remove(messagePath);
|
||||||
};
|
};
|
||||||
this.sendMessagesInOutbox = () => {
|
this.sendMessagesInOutbox = () => {
|
||||||
@@ -8564,79 +8699,10 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// src/Model/Global/contactListModel.ts
|
|
||||||
var ContactListModel = class {
|
|
||||||
constructor(storageModel2) {
|
|
||||||
this.storageModel = storageModel2;
|
|
||||||
this.contactHandlerManager = new HandlerManager();
|
|
||||||
this.getContactPath = (contactId) => {
|
|
||||||
return StorageModel.getPath("contacts" /* ContactsModel */, [contactId]);
|
|
||||||
};
|
|
||||||
this.loadContacts = () => {
|
|
||||||
const contactIds = this.storageModel.list(["contacts" /* ContactsModel */]);
|
|
||||||
const contacts = contactIds.map((id) => [id, this.storageModel.read(this.getContactPath(id)) ?? "?"]);
|
|
||||||
return contacts;
|
|
||||||
};
|
|
||||||
this.storeContact = (id, name) => {
|
|
||||||
const path = this.getContactPath(id);
|
|
||||||
this.storageModel.write(path, name);
|
|
||||||
this.contactHandlerManager.trigger([id, name]);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// src/ViewModel/Global/contactViewModel.ts
|
|
||||||
var ContactListViewModel = class {
|
|
||||||
// init
|
|
||||||
constructor(contactListModel2) {
|
|
||||||
this.contactListModel = contactListModel2;
|
|
||||||
// state
|
|
||||||
this.contacts = /* @__PURE__ */ new Map();
|
|
||||||
// main
|
|
||||||
this.updateContact = (id, name) => {
|
|
||||||
const match = this.contacts.get(id);
|
|
||||||
if (match) {
|
|
||||||
match.name.value = name;
|
|
||||||
return match;
|
|
||||||
}
|
|
||||||
const vm = new ContactViewModel(id, name);
|
|
||||||
this.contacts.set(id, vm);
|
|
||||||
return vm;
|
|
||||||
};
|
|
||||||
this.handleContact = (contact) => {
|
|
||||||
this.updateContact(...contact);
|
|
||||||
};
|
|
||||||
this.unwrapContact = (id, knownName) => {
|
|
||||||
if (this.contacts.has(id))
|
|
||||||
return this.contacts.get(id);
|
|
||||||
return this.updateContact(id, knownName);
|
|
||||||
};
|
|
||||||
// load
|
|
||||||
this.loadData = () => {
|
|
||||||
const contacts = this.contactListModel.loadContacts();
|
|
||||||
for (const contact of contacts) {
|
|
||||||
const vm = new ContactViewModel(...contact);
|
|
||||||
this.contacts.set(vm.id, vm);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
this.loadData();
|
|
||||||
this.contactListModel.contactHandlerManager.setHandler("contact-list-view-model", this.handleContact);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
var ContactViewModel = class {
|
|
||||||
// init
|
|
||||||
constructor(id, name) {
|
|
||||||
this.id = id;
|
|
||||||
// state
|
|
||||||
this.name = new State("");
|
|
||||||
this.name.value = name;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// src/index.tsx
|
// src/index.tsx
|
||||||
var storageModel = new StorageModel();
|
var storageModel = new StorageModel();
|
||||||
var contactListModel = new ContactListModel(storageModel);
|
var settingsModel = new SettingsModel(storageModel);
|
||||||
var settingsModel = new SettingsModel(storageModel, contactListModel);
|
var contactListModel = new ContactListModel(storageModel, settingsModel);
|
||||||
var connectionModel = new ConnectionModel(storageModel);
|
var connectionModel = new ConnectionModel(storageModel);
|
||||||
var chatListModel = new ChatListModel(
|
var chatListModel = new ChatListModel(
|
||||||
storageModel,
|
storageModel,
|
||||||
@@ -8653,8 +8719,11 @@
|
|||||||
fileTransferModel
|
fileTransferModel
|
||||||
);
|
);
|
||||||
var storageViewModel = new StorageViewModel(coreViewModel);
|
var storageViewModel = new StorageViewModel(coreViewModel);
|
||||||
var contactListViewModel = new ContactListViewModel(contactListModel);
|
|
||||||
var settingsViewModel = new SettingsViewModel(coreViewModel, settingsModel);
|
var settingsViewModel = new SettingsViewModel(coreViewModel, settingsModel);
|
||||||
|
var contactListViewModel = new ContactListViewModel(
|
||||||
|
contactListModel,
|
||||||
|
settingsViewModel
|
||||||
|
);
|
||||||
var connectionViewModel = new ConnectionViewModel(coreViewModel);
|
var connectionViewModel = new ConnectionViewModel(coreViewModel);
|
||||||
var chatListViewModel = new ChatListViewModel(
|
var chatListViewModel = new ChatListViewModel(
|
||||||
coreViewModel,
|
coreViewModel,
|
||||||
|
|||||||
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
const VERSION = "2610 Beta 14"
|
const VERSION = "2610 Beta 16"
|
||||||
|
|
||||||
function processUrl(event) {
|
function processUrl(event) {
|
||||||
const url = event.request.url;
|
const url = event.request.url;
|
||||||
|
|||||||
Vendored
+1
-1
@@ -1 +1 @@
|
|||||||
2610 Beta 14
|
2610 Beta 16
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ import StorageModel, {
|
|||||||
filePaths,
|
filePaths,
|
||||||
} from "../Global/storageModel";
|
} from "../Global/storageModel";
|
||||||
import SettingsModel from "../Global/settingsModel";
|
import SettingsModel from "../Global/settingsModel";
|
||||||
import ConnectionModel from "../Global/connectionModel";
|
|
||||||
import ContactListModel from "../Global/contactListModel";
|
import ContactListModel from "../Global/contactListModel";
|
||||||
|
import ConnectionModel from "../Global/connectionModel";
|
||||||
|
|
||||||
export default class ChatListModel {
|
export default class ChatListModel {
|
||||||
// data
|
// data
|
||||||
@@ -28,7 +28,7 @@ export default class ChatListModel {
|
|||||||
this.connectionModel,
|
this.connectionModel,
|
||||||
this.settingsModel,
|
this.settingsModel,
|
||||||
this,
|
this,
|
||||||
this.contactListModel,
|
this.contactListModel,
|
||||||
id,
|
id,
|
||||||
);
|
);
|
||||||
chatModel.setName(primaryChannel);
|
chatModel.setName(primaryChannel);
|
||||||
@@ -90,7 +90,7 @@ export default class ChatListModel {
|
|||||||
this.connectionModel,
|
this.connectionModel,
|
||||||
this.settingsModel,
|
this.settingsModel,
|
||||||
this,
|
this,
|
||||||
this.contactListModel,
|
this.contactListModel,
|
||||||
chatId,
|
chatId,
|
||||||
);
|
);
|
||||||
this.addChatModel(chatModel);
|
this.addChatModel(chatModel);
|
||||||
@@ -102,7 +102,7 @@ export default class ChatListModel {
|
|||||||
public storageModel: StorageModel,
|
public storageModel: StorageModel,
|
||||||
public settingsModel: SettingsModel,
|
public settingsModel: SettingsModel,
|
||||||
public connectionModel: ConnectionModel,
|
public connectionModel: ConnectionModel,
|
||||||
public contactListModel: ContactListModel
|
public contactListModel: ContactListModel,
|
||||||
) {
|
) {
|
||||||
this.loadChats();
|
this.loadChats();
|
||||||
|
|
||||||
|
|||||||
+15
-11
@@ -18,10 +18,10 @@ import StorageModel, {
|
|||||||
filePaths,
|
filePaths,
|
||||||
} from "../Global/storageModel";
|
} from "../Global/storageModel";
|
||||||
import SettingsModel from "../Global/settingsModel";
|
import SettingsModel from "../Global/settingsModel";
|
||||||
|
import ContactListModel from "../Global/contactListModel";
|
||||||
import ConnectionModel from "../Global/connectionModel";
|
import ConnectionModel from "../Global/connectionModel";
|
||||||
import FileModel, { FileContent } from "../Files/fileModel";
|
import FileModel, { FileContent } from "../Files/fileModel";
|
||||||
import { Colors } from "../../colors";
|
import { Colors } from "../../colors";
|
||||||
import ContactListModel from "../Global/contactListModel";
|
|
||||||
|
|
||||||
export default class ChatModel {
|
export default class ChatModel {
|
||||||
// models
|
// models
|
||||||
@@ -162,11 +162,16 @@ export default class ChatModel {
|
|||||||
readonly addMessage = async (chatMessage: ChatMessage): Promise<void> => {
|
readonly addMessage = async (chatMessage: ChatMessage): Promise<void> => {
|
||||||
await this.decryptMessage(chatMessage);
|
await this.decryptMessage(chatMessage);
|
||||||
|
|
||||||
this.contactListModel.storeContact(chatMessage.senderId, chatMessage.senderName);
|
this.contactListModel.storeContact(
|
||||||
|
chatMessage.senderId,
|
||||||
|
chatMessage.senderName,
|
||||||
|
);
|
||||||
|
|
||||||
// message
|
// message
|
||||||
if (chatMessage.body != "") {
|
if (chatMessage.body != "") {
|
||||||
const messagePath: string[] = this.getMessagePath(chatMessage.fileId);
|
const messagePath: string[] = this.getMessagePath(
|
||||||
|
chatMessage.fileId,
|
||||||
|
);
|
||||||
this.storageModel.writeStringifiable(messagePath, chatMessage);
|
this.storageModel.writeStringifiable(messagePath, chatMessage);
|
||||||
this.chatMessageHandlerManager.trigger(chatMessage);
|
this.chatMessageHandlerManager.trigger(chatMessage);
|
||||||
}
|
}
|
||||||
@@ -238,7 +243,7 @@ export default class ChatModel {
|
|||||||
const reaction = ChatModel.createMessageReaction(
|
const reaction = ChatModel.createMessageReaction(
|
||||||
messageId,
|
messageId,
|
||||||
senderId,
|
senderId,
|
||||||
senderName,
|
senderName,
|
||||||
content,
|
content,
|
||||||
isDeleting,
|
isDeleting,
|
||||||
);
|
);
|
||||||
@@ -350,7 +355,7 @@ export default class ChatModel {
|
|||||||
public connectionModel: ConnectionModel,
|
public connectionModel: ConnectionModel,
|
||||||
public settingsModel: SettingsModel,
|
public settingsModel: SettingsModel,
|
||||||
public chatListModel: ChatListModel,
|
public chatListModel: ChatListModel,
|
||||||
public contactListModel: ContactListModel,
|
public contactListModel: ContactListModel,
|
||||||
chatId: string,
|
chatId: string,
|
||||||
) {
|
) {
|
||||||
this.id = chatId;
|
this.id = chatId;
|
||||||
@@ -397,10 +402,10 @@ export default class ChatModel {
|
|||||||
inlineReplyId?: string,
|
inlineReplyId?: string,
|
||||||
fileContent?: FileContent<string>,
|
fileContent?: FileContent<string>,
|
||||||
): Promise<ChatMessage> => {
|
): Promise<ChatMessage> => {
|
||||||
const messageFileContent = FileModel.createFileContent(v4(), "message");
|
const messageFileContent = FileModel.createFileContent(v4(), "message");
|
||||||
|
|
||||||
const chatMessage: ChatMessage = {
|
const chatMessage: ChatMessage = {
|
||||||
...messageFileContent,
|
...messageFileContent,
|
||||||
|
|
||||||
channel,
|
channel,
|
||||||
senderName,
|
senderName,
|
||||||
@@ -446,7 +451,7 @@ export default class ChatModel {
|
|||||||
|
|
||||||
messageId,
|
messageId,
|
||||||
senderId,
|
senderId,
|
||||||
senderName,
|
senderName,
|
||||||
content,
|
content,
|
||||||
isDeleting,
|
isDeleting,
|
||||||
};
|
};
|
||||||
@@ -501,8 +506,7 @@ export interface ChatMessage extends FileContent<"message"> {
|
|||||||
stringifiedFile: string;
|
stringifiedFile: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ChatMessageReaction
|
export interface ChatMessageReaction extends FileContent<"reaction"> {
|
||||||
extends FileContent<"reaction"> {
|
|
||||||
readonly messageId: string;
|
readonly messageId: string;
|
||||||
readonly senderId: string;
|
readonly senderId: string;
|
||||||
readonly senderName: string;
|
readonly senderName: string;
|
||||||
@@ -531,7 +535,7 @@ export const ChatInfoReference: ChatInfoFileContent = {
|
|||||||
|
|
||||||
export const ChatMessageReference: ChatMessage = {
|
export const ChatMessageReference: ChatMessage = {
|
||||||
dataVersion: DATA_VERSION,
|
dataVersion: DATA_VERSION,
|
||||||
|
|
||||||
fileId: "",
|
fileId: "",
|
||||||
fileContentId: "",
|
fileContentId: "",
|
||||||
creationDate: "",
|
creationDate: "",
|
||||||
|
|||||||
@@ -149,12 +149,18 @@ export default class ConnectionModel {
|
|||||||
};
|
};
|
||||||
|
|
||||||
readonly addToOutbox = (chatMessage: ChatMessage): void => {
|
readonly addToOutbox = (chatMessage: ChatMessage): void => {
|
||||||
const messagePath: string[] = [...this.getOutboxPath(), chatMessage.fileId];
|
const messagePath: string[] = [
|
||||||
|
...this.getOutboxPath(),
|
||||||
|
chatMessage.fileId,
|
||||||
|
];
|
||||||
this.storageModel.writeStringifiable(messagePath, chatMessage);
|
this.storageModel.writeStringifiable(messagePath, chatMessage);
|
||||||
};
|
};
|
||||||
|
|
||||||
readonly removeFromOutbox = (chatMessage: ChatMessage): void => {
|
readonly removeFromOutbox = (chatMessage: ChatMessage): void => {
|
||||||
const messagePath: string[] = [...this.getOutboxPath(), chatMessage.fileId];
|
const messagePath: string[] = [
|
||||||
|
...this.getOutboxPath(),
|
||||||
|
chatMessage.fileId,
|
||||||
|
];
|
||||||
this.storageModel.remove(messagePath);
|
this.storageModel.remove(messagePath);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,28 +1,38 @@
|
|||||||
import {HandlerManager} from "../Utility/utility";
|
import StorageModel, { StorageModelSubPaths } from "./storageModel";
|
||||||
import SettingsModel from "./settingsModel";
|
import SettingsModel from "./settingsModel";
|
||||||
import StorageModel, {StorageModelSubPaths} from "./storageModel";
|
import { HandlerManager } from "../Utility/utility";
|
||||||
|
|
||||||
export default class ContactListModel {
|
export default class ContactListModel {
|
||||||
contactHandlerManager = new HandlerManager<[string, string]>();
|
contactHandlerManager = new HandlerManager<[string, string]>();
|
||||||
|
|
||||||
private getContactPath = (contactId: string): string[] => {
|
private getContactPath = (contactId: string): string[] => {
|
||||||
return StorageModel.getPath(StorageModelSubPaths.ContactsModel, [contactId]);
|
return StorageModel.getPath(StorageModelSubPaths.ContactsModel, [
|
||||||
}
|
contactId,
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
|
||||||
loadContacts = (): [string, string][] => {
|
loadContacts = (): [string, string][] => {
|
||||||
const contactIds: string[] = this.storageModel.list([StorageModelSubPaths.ContactsModel]);
|
const contactIds: string[] = this.storageModel.list([
|
||||||
const contacts: [string, string][] = contactIds.map(id => [id, this.storageModel.read(this.getContactPath(id)) ?? "?"]);
|
StorageModelSubPaths.ContactsModel,
|
||||||
contacts.push([this.settingsModel.userid, this.settingsModel.username]);
|
]);
|
||||||
return contacts;
|
const contacts: [string, string][] = contactIds.map((id) => [
|
||||||
}
|
id,
|
||||||
|
this.storageModel.read(this.getContactPath(id)) ?? "?",
|
||||||
|
]);
|
||||||
|
contacts.push([this.settingsModel.userid, this.settingsModel.username]);
|
||||||
|
return contacts;
|
||||||
|
};
|
||||||
|
|
||||||
storeContact = (id: string, name: string) => {
|
storeContact = (id: string, name: string) => {
|
||||||
this.contactHandlerManager.trigger([id, name]);
|
this.contactHandlerManager.trigger([id, name]);
|
||||||
|
|
||||||
if (id == this.settingsModel.userid) return;
|
if (id == this.settingsModel.userid) return;
|
||||||
const path = this.getContactPath(id);
|
const path = this.getContactPath(id);
|
||||||
this.storageModel.write(path, name)
|
this.storageModel.write(path, name);
|
||||||
}
|
};
|
||||||
|
|
||||||
constructor(public storageModel: StorageModel, public settingsModel: SettingsModel) {}
|
constructor(
|
||||||
|
public storageModel: StorageModel,
|
||||||
|
public settingsModel: SettingsModel,
|
||||||
|
) {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,93 +28,93 @@ export default class SettingsModel {
|
|||||||
|
|
||||||
readonly setName = (newValue: string): void => {
|
readonly setName = (newValue: string): void => {
|
||||||
this.username = newValue;
|
this.username = newValue;
|
||||||
this.storeSetting("username", newValue);
|
this.storeSetting("username", newValue);
|
||||||
};
|
};
|
||||||
|
|
||||||
readonly setFirstDayOfWeek = (newValue: string): void => {
|
readonly setFirstDayOfWeek = (newValue: string): void => {
|
||||||
this.firstDayOfWeek = newValue;
|
this.firstDayOfWeek = newValue;
|
||||||
this.storeSetting("firstDayOfWeek", newValue);
|
this.storeSetting("firstDayOfWeek", newValue);
|
||||||
};
|
};
|
||||||
|
|
||||||
readonly setLanguage = (newValue: string): void => {
|
readonly setLanguage = (newValue: string): void => {
|
||||||
this.language = newValue;
|
this.language = newValue;
|
||||||
this.storeSetting("language", newValue);
|
this.storeSetting("language", newValue);
|
||||||
};
|
};
|
||||||
|
|
||||||
readonly setTheme = (newValue: string): void => {
|
readonly setTheme = (newValue: string): void => {
|
||||||
this.theme = newValue;
|
this.theme = newValue;
|
||||||
this.storeSetting("theme", newValue);
|
this.storeSetting("theme", newValue);
|
||||||
};
|
};
|
||||||
|
|
||||||
// load
|
// load
|
||||||
private readonly readSetting = (
|
private readonly readSetting = (
|
||||||
pathName: keyof typeof filePaths.settingsModel,
|
pathName: keyof typeof filePaths.settingsModel,
|
||||||
): string | null => {
|
): string | null => {
|
||||||
const path = StorageModel.getPath(
|
const path = StorageModel.getPath(
|
||||||
StorageModelSubPaths.SettingsModel,
|
StorageModelSubPaths.SettingsModel,
|
||||||
filePaths.settingsModel[pathName],
|
filePaths.settingsModel[pathName],
|
||||||
);
|
);
|
||||||
return this.storageModel.read(path);
|
return this.storageModel.read(path);
|
||||||
};
|
};
|
||||||
|
|
||||||
readonly loadId = (): void => {
|
readonly loadId = (): void => {
|
||||||
const content: string | null = this.readSetting("userid");
|
const content: string | null = this.readSetting("userid");
|
||||||
const id = content ?? UUID();
|
const id = content ?? UUID();
|
||||||
if (content) this.userid = content;
|
if (content) this.userid = content;
|
||||||
else this.setId(id);
|
else this.setId(id);
|
||||||
};
|
};
|
||||||
|
|
||||||
readonly loadUsername = (): void => {
|
readonly loadUsername = (): void => {
|
||||||
const content: string | null = this.readSetting("username");
|
const content: string | null = this.readSetting("username");
|
||||||
this.username = content ?? "";
|
this.username = content ?? "";
|
||||||
};
|
};
|
||||||
|
|
||||||
readonly loadFirstDayofWeek = (): void => {
|
readonly loadFirstDayofWeek = (): void => {
|
||||||
const content: string | null = this.readSetting("firstDayOfWeek");
|
const content: string | null = this.readSetting("firstDayOfWeek");
|
||||||
this.firstDayOfWeek = content ?? "0";
|
this.firstDayOfWeek = content ?? "0";
|
||||||
};
|
};
|
||||||
|
|
||||||
readonly loadLanguage = (): void => {
|
readonly loadLanguage = (): void => {
|
||||||
const content: string | null = this.readSetting("language");
|
const content: string | null = this.readSetting("language");
|
||||||
this.language = content ?? SettingsModel.getSystemLanguage();
|
this.language = content ?? SettingsModel.getSystemLanguage();
|
||||||
};
|
};
|
||||||
|
|
||||||
readonly loadTheme = (): void => {
|
readonly loadTheme = (): void => {
|
||||||
const content: string | null = this.readSetting("theme");
|
const content: string | null = this.readSetting("theme");
|
||||||
this.theme = content ?? ThemeSettings.System;
|
this.theme = content ?? ThemeSettings.System;
|
||||||
};
|
};
|
||||||
|
|
||||||
// init
|
// init
|
||||||
constructor(public storageModel: StorageModel) {
|
constructor(public storageModel: StorageModel) {
|
||||||
this.loadId();
|
this.loadId();
|
||||||
this.loadUsername();
|
this.loadUsername();
|
||||||
this.loadFirstDayofWeek();
|
this.loadFirstDayofWeek();
|
||||||
this.loadLanguage();
|
this.loadLanguage();
|
||||||
this.loadTheme();
|
this.loadTheme();
|
||||||
}
|
}
|
||||||
|
|
||||||
static getSystemLanguage(): Languages {
|
static getSystemLanguage(): Languages {
|
||||||
switch (navigator.language.substring(0, 2)) {
|
switch (navigator.language.substring(0, 2)) {
|
||||||
case "de":
|
case "de":
|
||||||
return Languages.German;
|
return Languages.German;
|
||||||
case "es":
|
case "es":
|
||||||
return Languages.Spanish;
|
return Languages.Spanish;
|
||||||
default:
|
default:
|
||||||
return Languages.English;
|
return Languages.English;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum Languages {
|
export enum Languages {
|
||||||
English = "en",
|
English = "en",
|
||||||
German = "de",
|
German = "de",
|
||||||
Spanish = "es",
|
Spanish = "es",
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum ThemeSettings {
|
export enum ThemeSettings {
|
||||||
Dark = "dark",
|
Dark = "dark",
|
||||||
Light = "light",
|
Light = "light",
|
||||||
System = "system",
|
System = "system",
|
||||||
Dynamic = "dynamic",
|
Dynamic = "dynamic",
|
||||||
Black = "black",
|
Black = "black",
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -216,52 +216,52 @@ export default class StorageModel {
|
|||||||
return stringify(this.storageEntryTree);
|
return stringify(this.storageEntryTree);
|
||||||
};
|
};
|
||||||
|
|
||||||
// upgrade
|
// upgrade
|
||||||
readonly upgrade = (): void => {
|
readonly upgrade = (): void => {
|
||||||
// function used to upgrade data versions
|
// function used to upgrade data versions
|
||||||
}
|
};
|
||||||
|
|
||||||
// init
|
// init
|
||||||
constructor() {
|
constructor() {
|
||||||
this.initializeTree();
|
this.initializeTree();
|
||||||
this.upgrade();
|
this.upgrade();
|
||||||
}
|
}
|
||||||
|
|
||||||
// utility
|
// utility
|
||||||
static getFileName = (pathComponents: string[]): string => {
|
static getFileName = (pathComponents: string[]): string => {
|
||||||
return pathComponents[pathComponents.length - 1] || "\\";
|
return pathComponents[pathComponents.length - 1] || "\\";
|
||||||
};
|
};
|
||||||
|
|
||||||
static getFileNameFromString = (pathString: string): string => {
|
static getFileNameFromString = (pathString: string): string => {
|
||||||
const pathComponents: string[] =
|
const pathComponents: string[] =
|
||||||
this.stringToPathComponents(pathString);
|
this.stringToPathComponents(pathString);
|
||||||
return pathComponents[pathComponents.length - 1] || "\\";
|
return pathComponents[pathComponents.length - 1] || "\\";
|
||||||
};
|
};
|
||||||
|
|
||||||
static pathComponentsToString = (...pathComponents: string[]): string => {
|
static pathComponentsToString = (...pathComponents: string[]): string => {
|
||||||
return pathComponents
|
return pathComponents
|
||||||
.filter((x) => x != "")
|
.filter((x) => x != "")
|
||||||
.join(PATH_COMPONENT_SEPARATOR);
|
.join(PATH_COMPONENT_SEPARATOR);
|
||||||
};
|
};
|
||||||
|
|
||||||
static stringToPathComponents = (string: string): string[] => {
|
static stringToPathComponents = (string: string): string[] => {
|
||||||
return string.split(PATH_COMPONENT_SEPARATOR).filter((x) => x != "");
|
return string.split(PATH_COMPONENT_SEPARATOR).filter((x) => x != "");
|
||||||
};
|
};
|
||||||
|
|
||||||
static join = (...items: string[]): string => {
|
static join = (...items: string[]): string => {
|
||||||
let allComponents: string[] = [];
|
let allComponents: string[] = [];
|
||||||
for (const item of items) {
|
for (const item of items) {
|
||||||
const parts = this.stringToPathComponents(item);
|
const parts = this.stringToPathComponents(item);
|
||||||
allComponents.push(...parts);
|
allComponents.push(...parts);
|
||||||
}
|
}
|
||||||
return StorageModel.pathComponentsToString(...allComponents);
|
return StorageModel.pathComponentsToString(...allComponents);
|
||||||
};
|
};
|
||||||
|
|
||||||
static getPath(
|
static getPath(
|
||||||
locationName: StorageModelSubPaths,
|
locationName: StorageModelSubPaths,
|
||||||
filePath: string[],
|
filePath: string[],
|
||||||
): string[] {
|
): string[] {
|
||||||
return [DATA_VERSION, locationName, ...filePath];
|
return [DATA_VERSION, locationName, ...filePath];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -272,52 +272,52 @@ export type StorageEntry = { [key: string]: StorageEntry };
|
|||||||
export enum StorageModelSubPaths {
|
export enum StorageModelSubPaths {
|
||||||
Chat = "chat",
|
Chat = "chat",
|
||||||
|
|
||||||
ConnectionModel = "connection",
|
ConnectionModel = "connection",
|
||||||
NotificationModel = "notifications",
|
NotificationModel = "notifications",
|
||||||
SettingsModel = "settings",
|
SettingsModel = "settings",
|
||||||
ContactsModel = "contacts",
|
ContactsModel = "contacts",
|
||||||
}
|
}
|
||||||
|
|
||||||
export const filePaths = {
|
export const filePaths = {
|
||||||
connectionModel: {
|
connectionModel: {
|
||||||
socketAddress: ["socket-address"],
|
socketAddress: ["socket-address"],
|
||||||
reconnectAddress: ["reconnect-address"],
|
reconnectAddress: ["reconnect-address"],
|
||||||
outbox: ["outbox"],
|
outbox: ["outbox"],
|
||||||
mailboxes: ["mailboxes"],
|
mailboxes: ["mailboxes"],
|
||||||
|
|
||||||
previousAddresses: ["previous-addresses"],
|
previousAddresses: ["previous-addresses"],
|
||||||
},
|
},
|
||||||
|
|
||||||
chat: {
|
chat: {
|
||||||
base: [],
|
base: [],
|
||||||
chatBase: (id: string) => [id],
|
chatBase: (id: string) => [id],
|
||||||
info: (id: string) => [...filePaths.chat.chatBase(id), "info"],
|
info: (id: string) => [...filePaths.chat.chatBase(id), "info"],
|
||||||
color: (id: string) => [...filePaths.chat.chatBase(id), "color"],
|
color: (id: string) => [...filePaths.chat.chatBase(id), "color"],
|
||||||
messages: (id: string) => [...filePaths.chat.chatBase(id), "messages"],
|
messages: (id: string) => [...filePaths.chat.chatBase(id), "messages"],
|
||||||
reactions: (id: string) => [
|
reactions: (id: string) => [
|
||||||
...filePaths.chat.chatBase(id),
|
...filePaths.chat.chatBase(id),
|
||||||
"reactions",
|
"reactions",
|
||||||
],
|
],
|
||||||
previousFilter: (id: string) => [
|
previousFilter: (id: string) => [
|
||||||
...filePaths.chat.chatBase(id),
|
...filePaths.chat.chatBase(id),
|
||||||
"previous-filter",
|
"previous-filter",
|
||||||
],
|
],
|
||||||
lastUsedPage: (id: string) => [
|
lastUsedPage: (id: string) => [
|
||||||
...filePaths.chat.chatBase(id),
|
...filePaths.chat.chatBase(id),
|
||||||
"last-used-page",
|
"last-used-page",
|
||||||
],
|
],
|
||||||
files: (id: string) => [...filePaths.chat.chatBase(id), "files"],
|
files: (id: string) => [...filePaths.chat.chatBase(id), "files"],
|
||||||
},
|
},
|
||||||
|
|
||||||
notificationModel: {
|
notificationModel: {
|
||||||
base: [],
|
base: [],
|
||||||
},
|
},
|
||||||
|
|
||||||
settingsModel: {
|
settingsModel: {
|
||||||
username: ["user-name"],
|
username: ["user-name"],
|
||||||
userid: ["user-id"],
|
userid: ["user-id"],
|
||||||
firstDayOfWeek: ["first-day-of-week"],
|
firstDayOfWeek: ["first-day-of-week"],
|
||||||
language: ["language"],
|
language: ["language"],
|
||||||
theme: ["theme"],
|
theme: ["theme"],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -37,10 +37,10 @@ export function ChatMessage(
|
|||||||
{InlineReply(chatMessageViewModel)}
|
{InlineReply(chatMessageViewModel)}
|
||||||
<div class="main tile">
|
<div class="main tile">
|
||||||
<div class="text-container">
|
<div class="text-container">
|
||||||
<span
|
<span
|
||||||
class="sender-name ellipsis"
|
class="sender-name ellipsis"
|
||||||
subscribe:innerText={chatMessageViewModel.contact.name}
|
subscribe:innerText={chatMessageViewModel.contact.name}
|
||||||
></span>
|
></span>
|
||||||
<span
|
<span
|
||||||
class="body"
|
class="body"
|
||||||
subscribe:innerText={chatMessageViewModel.body}
|
subscribe:innerText={chatMessageViewModel.body}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { ViewController } from "../viewController";
|
import { ViewController } from "../viewController";
|
||||||
import * as React from "../../react";
|
import * as React from "../../react";
|
||||||
|
import { ContactViewModel } from "../../ViewModel/Global/contactViewModel";
|
||||||
import ChatMessageViewModel from "../../ViewModel/Chat/chatMessageViewModel";
|
import ChatMessageViewModel from "../../ViewModel/Chat/chatMessageViewModel";
|
||||||
import {ContactViewModel} from "../../ViewModel/Global/contactViewModel";
|
|
||||||
|
|
||||||
export function InlineReply(chatMessageViewModel: ChatMessageViewModel ) {
|
export function InlineReply(chatMessageViewModel: ChatMessageViewModel) {
|
||||||
const reply = chatMessageViewModel.inlineReply;
|
const reply = chatMessageViewModel.inlineReply;
|
||||||
if (reply == undefined) return <div></div>;
|
if (reply == undefined) return <div></div>;
|
||||||
|
|
||||||
@@ -13,7 +13,7 @@ export function InlineReply(chatMessageViewModel: ChatMessageViewModel ) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div class="inline-reply" on:click={scroll}>
|
<div class="inline-reply" on:click={scroll}>
|
||||||
<span subscribe:innerText={reply.contact.name}></span>
|
<span subscribe:innerText={reply.contact.name}></span>
|
||||||
<b class="ellipsis" subscribe:innerText={reply.body}></b>
|
<b class="ellipsis" subscribe:innerText={reply.body}></b>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -7,24 +7,27 @@ export function ReplyPreview(
|
|||||||
chatMessageViewModel: ChatMessageViewModel,
|
chatMessageViewModel: ChatMessageViewModel,
|
||||||
) {
|
) {
|
||||||
return (
|
return (
|
||||||
<div class="reply-preview">
|
<div class="reply-preview">
|
||||||
<div class="surface blur">
|
<div class="surface blur">
|
||||||
<span class="secondary" subscribe:innerText={chatMessageViewModel.contact.name}></span>
|
<span
|
||||||
<b
|
class="secondary"
|
||||||
class="ellipsis"
|
subscribe:innerText={chatMessageViewModel.contact.name}
|
||||||
subscribe:innerText={chatMessageViewModel.body}
|
></span>
|
||||||
></b>
|
<b
|
||||||
</div>
|
class="ellipsis"
|
||||||
<button
|
subscribe:innerText={chatMessageViewModel.body}
|
||||||
class="standard square blur"
|
></b>
|
||||||
on:click={chatMessageViewModel.cancelReply}
|
</div>
|
||||||
aria-label={
|
<button
|
||||||
coreViewModel.translations.chatPage.message
|
class="standard square blur"
|
||||||
.cancelReplyAudioLabel
|
on:click={chatMessageViewModel.cancelReply}
|
||||||
}
|
aria-label={
|
||||||
>
|
coreViewModel.translations.chatPage.message
|
||||||
<span class="icon">close</span>
|
.cancelReplyAudioLabel
|
||||||
</button>
|
}
|
||||||
</div>
|
>
|
||||||
|
<span class="icon">close</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,11 @@ export function SettingsModal(
|
|||||||
coreViewModel,
|
coreViewModel,
|
||||||
settingsViewModel,
|
settingsViewModel,
|
||||||
);
|
);
|
||||||
|
case SettingsModalPages.Account:
|
||||||
|
return SettingsAccountPane(
|
||||||
|
coreViewModel,
|
||||||
|
settingsViewModel,
|
||||||
|
);
|
||||||
case SettingsModalPages.Regional:
|
case SettingsModalPages.Regional:
|
||||||
return SettingsRegionalPane(
|
return SettingsRegionalPane(
|
||||||
coreViewModel,
|
coreViewModel,
|
||||||
@@ -79,6 +84,12 @@ function SettingsLeftPane(
|
|||||||
SettingsModalPages.Appearance,
|
SettingsModalPages.Appearance,
|
||||||
coreViewModel.translations.settings.pages.appearance,
|
coreViewModel.translations.settings.pages.appearance,
|
||||||
)}
|
)}
|
||||||
|
{SettingsPaneButton(
|
||||||
|
coreViewModel,
|
||||||
|
settingsViewModel,
|
||||||
|
SettingsModalPages.Account,
|
||||||
|
coreViewModel.translations.settings.pages.account,
|
||||||
|
)}
|
||||||
{SettingsPaneButton(
|
{SettingsPaneButton(
|
||||||
coreViewModel,
|
coreViewModel,
|
||||||
settingsViewModel,
|
settingsViewModel,
|
||||||
@@ -121,7 +132,7 @@ function SettingsInfoPane(
|
|||||||
<div class="flex-column gap">
|
<div class="flex-column gap">
|
||||||
{InfoTile(
|
{InfoTile(
|
||||||
"build",
|
"build",
|
||||||
coreViewModel.translations.settings.version,
|
coreViewModel.translations.settings.about.version,
|
||||||
settingsViewModel.coreViewModel.version,
|
settingsViewModel.coreViewModel.version,
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@@ -135,7 +146,10 @@ function SettingsInfoPane(
|
|||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button class="standard" on:click={coreViewModel.checkUpdates}>
|
<button class="standard" on:click={coreViewModel.checkUpdates}>
|
||||||
{coreViewModel.translations.settings.checkUpdatesButton}
|
{
|
||||||
|
coreViewModel.translations.settings.about
|
||||||
|
.checkUpdatesButton
|
||||||
|
}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -151,7 +165,7 @@ function SettingsRegionalPane(
|
|||||||
<h2>{coreViewModel.translations.settings.pages.regional}</h2>
|
<h2>{coreViewModel.translations.settings.pages.regional}</h2>
|
||||||
|
|
||||||
<hr></hr>
|
<hr></hr>
|
||||||
<h3>{coreViewModel.translations.settings.language}</h3>
|
<h3>{coreViewModel.translations.settings.regional.language}</h3>
|
||||||
{OptionButtonList(
|
{OptionButtonList(
|
||||||
new React.ListState<[string, string]>(
|
new React.ListState<[string, string]>(
|
||||||
Object.values(Languages).map((x) => [languageNames[x], x]),
|
Object.values(Languages).map((x) => [languageNames[x], x]),
|
||||||
@@ -160,7 +174,12 @@ function SettingsRegionalPane(
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
<hr></hr>
|
<hr></hr>
|
||||||
<h3>{coreViewModel.translations.settings.firstDayOfWeekLabel}</h3>
|
<h3>
|
||||||
|
{
|
||||||
|
coreViewModel.translations.settings.regional
|
||||||
|
.firstDayOfWeekLabel
|
||||||
|
}
|
||||||
|
</h3>
|
||||||
{OptionButtonList(
|
{OptionButtonList(
|
||||||
new React.ListState<[string, string]>(
|
new React.ListState<[string, string]>(
|
||||||
coreViewModel.translations.regional.weekdays.full.map(
|
coreViewModel.translations.regional.weekdays.full.map(
|
||||||
@@ -173,6 +192,51 @@ function SettingsRegionalPane(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function SettingsAccountPane(
|
||||||
|
coreViewModel: CoreViewModel,
|
||||||
|
settingsViewModel: SettingsViewModel,
|
||||||
|
) {
|
||||||
|
return (
|
||||||
|
<div class="slide-up">
|
||||||
|
<h2>{coreViewModel.translations.settings.pages.account}</h2>
|
||||||
|
<hr></hr>
|
||||||
|
<label class="tile flex-no">
|
||||||
|
<span class="icon">account_circle</span>
|
||||||
|
<div>
|
||||||
|
<span>
|
||||||
|
{
|
||||||
|
coreViewModel.translations.settings.account
|
||||||
|
.yourNameLabel
|
||||||
|
}
|
||||||
|
</span>
|
||||||
|
<input
|
||||||
|
placeholder={
|
||||||
|
coreViewModel.translations.settings.account
|
||||||
|
.yourNamePlaceholder
|
||||||
|
}
|
||||||
|
bind:value={settingsViewModel.usernameInput}
|
||||||
|
on:enter={settingsViewModel.setName}
|
||||||
|
></input>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
<div class="flex-row justify-end width-input">
|
||||||
|
<button
|
||||||
|
class="width-50"
|
||||||
|
on:click={settingsViewModel.setName}
|
||||||
|
toggle:disabled={settingsViewModel.cannotSetName}
|
||||||
|
aria-label={
|
||||||
|
coreViewModel.translations.settings.account
|
||||||
|
.setNameButtonAudioLabel
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{coreViewModel.translations.general.setButton}
|
||||||
|
<span class="icon">check</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function SettingsAppearancePane(
|
function SettingsAppearancePane(
|
||||||
coreViewModel: CoreViewModel,
|
coreViewModel: CoreViewModel,
|
||||||
settingsViewModel: SettingsViewModel,
|
settingsViewModel: SettingsViewModel,
|
||||||
|
|||||||
@@ -87,39 +87,6 @@ export function HomePage(
|
|||||||
|
|
||||||
<hr></hr>
|
<hr></hr>
|
||||||
|
|
||||||
<label class="tile flex-no">
|
|
||||||
<span class="icon">account_circle</span>
|
|
||||||
<div>
|
|
||||||
<span>
|
|
||||||
{coreViewModel.translations.homePage.yourNameLabel}
|
|
||||||
</span>
|
|
||||||
<input
|
|
||||||
placeholder={
|
|
||||||
coreViewModel.translations.homePage
|
|
||||||
.yourNamePlaceholder
|
|
||||||
}
|
|
||||||
bind:value={settingsViewModel.usernameInput}
|
|
||||||
on:enter={settingsViewModel.setName}
|
|
||||||
></input>
|
|
||||||
</div>
|
|
||||||
</label>
|
|
||||||
<div class="flex-row justify-end">
|
|
||||||
<button
|
|
||||||
class="width-50"
|
|
||||||
on:click={settingsViewModel.setName}
|
|
||||||
toggle:disabled={settingsViewModel.cannotSetName}
|
|
||||||
aria-label={
|
|
||||||
coreViewModel.translations.homePage
|
|
||||||
.setNameButtonAudioLabel
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{coreViewModel.translations.general.setButton}
|
|
||||||
<span class="icon">check</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<hr></hr>
|
|
||||||
|
|
||||||
{HomePageButton(
|
{HomePageButton(
|
||||||
settingsViewModel.showSettingsModal,
|
settingsViewModel.showSettingsModal,
|
||||||
coreViewModel.translations.homePage.settingsButton,
|
coreViewModel.translations.homePage.settingsButton,
|
||||||
|
|||||||
+42
-33
@@ -65,10 +65,6 @@ const englishTranslations = {
|
|||||||
disconnectAudioLabel: "disconnect from server",
|
disconnectAudioLabel: "disconnect from server",
|
||||||
manageConnectionsAudioLabel: "manage connections",
|
manageConnectionsAudioLabel: "manage connections",
|
||||||
|
|
||||||
yourNameLabel: "Your name",
|
|
||||||
yourNamePlaceholder: "Jane Doe",
|
|
||||||
setNameButtonAudioLabel: "set name",
|
|
||||||
|
|
||||||
settingsButton: "Settings",
|
settingsButton: "Settings",
|
||||||
manageStorageButton: "Manage storage",
|
manageStorageButton: "Manage storage",
|
||||||
transferDataButton: "Transfer or export data",
|
transferDataButton: "Transfer or export data",
|
||||||
@@ -90,6 +86,7 @@ const englishTranslations = {
|
|||||||
settings: {
|
settings: {
|
||||||
pages: {
|
pages: {
|
||||||
appearance: "Appearance",
|
appearance: "Appearance",
|
||||||
|
account: "Account",
|
||||||
regional: "Language & Region",
|
regional: "Language & Region",
|
||||||
info: "About CT",
|
info: "About CT",
|
||||||
},
|
},
|
||||||
@@ -100,13 +97,19 @@ const englishTranslations = {
|
|||||||
system: "Device theme",
|
system: "Device theme",
|
||||||
black: "Black",
|
black: "Black",
|
||||||
},
|
},
|
||||||
|
account: {
|
||||||
version: "Version",
|
yourNameLabel: "Your name",
|
||||||
language: "Language",
|
yourNamePlaceholder: "Jane Doe",
|
||||||
|
setNameButtonAudioLabel: "set name",
|
||||||
firstDayOfWeekLabel: "First day of week",
|
},
|
||||||
|
regional: {
|
||||||
checkUpdatesButton: "Check for updates",
|
language: "Language",
|
||||||
|
firstDayOfWeekLabel: "First day of week",
|
||||||
|
},
|
||||||
|
about: {
|
||||||
|
version: "Version",
|
||||||
|
checkUpdatesButton: "Check for updates",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
connectionModal: {
|
connectionModal: {
|
||||||
@@ -414,10 +417,6 @@ export const allTranslations: {
|
|||||||
disconnectAudioLabel: "vom Server trennen",
|
disconnectAudioLabel: "vom Server trennen",
|
||||||
manageConnectionsAudioLabel: "Verbindungen verwalten",
|
manageConnectionsAudioLabel: "Verbindungen verwalten",
|
||||||
|
|
||||||
yourNameLabel: "Dein Name",
|
|
||||||
yourNamePlaceholder: "Max Mustermann",
|
|
||||||
setNameButtonAudioLabel: "Name speichern",
|
|
||||||
|
|
||||||
settingsButton: "Einstellungen",
|
settingsButton: "Einstellungen",
|
||||||
manageStorageButton: "Daten verwalten",
|
manageStorageButton: "Daten verwalten",
|
||||||
transferDataButton: "Daten übertragen",
|
transferDataButton: "Daten übertragen",
|
||||||
@@ -437,6 +436,7 @@ export const allTranslations: {
|
|||||||
settings: {
|
settings: {
|
||||||
pages: {
|
pages: {
|
||||||
appearance: "Erscheinungsbild",
|
appearance: "Erscheinungsbild",
|
||||||
|
account: "Konto",
|
||||||
regional: "Sprache & Region",
|
regional: "Sprache & Region",
|
||||||
info: "Über CT",
|
info: "Über CT",
|
||||||
},
|
},
|
||||||
@@ -447,13 +447,19 @@ export const allTranslations: {
|
|||||||
system: "Geräteeinstellung",
|
system: "Geräteeinstellung",
|
||||||
black: "Schwarz",
|
black: "Schwarz",
|
||||||
},
|
},
|
||||||
|
account: {
|
||||||
version: "Version",
|
yourNameLabel: "Dein Name",
|
||||||
language: "Sprache",
|
yourNamePlaceholder: "Max Mustermann",
|
||||||
|
setNameButtonAudioLabel: "Namen festlegen",
|
||||||
firstDayOfWeekLabel: "Erster Wochentag",
|
},
|
||||||
|
regional: {
|
||||||
checkUpdatesButton: "Nach updates suchen",
|
language: "Sprache",
|
||||||
|
firstDayOfWeekLabel: "Erster Wochentag",
|
||||||
|
},
|
||||||
|
about: {
|
||||||
|
version: "Version",
|
||||||
|
checkUpdatesButton: "Nach Updates suchen",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
connectionModal: {
|
connectionModal: {
|
||||||
@@ -729,10 +735,6 @@ export const allTranslations: {
|
|||||||
disconnectAudioLabel: "desconectar del servidor",
|
disconnectAudioLabel: "desconectar del servidor",
|
||||||
manageConnectionsAudioLabel: "gestionar conexiones",
|
manageConnectionsAudioLabel: "gestionar conexiones",
|
||||||
|
|
||||||
yourNameLabel: "Tu nombre",
|
|
||||||
yourNamePlaceholder: "Juan Pérez",
|
|
||||||
setNameButtonAudioLabel: "establecer nombre",
|
|
||||||
|
|
||||||
settingsButton: "Ajustes",
|
settingsButton: "Ajustes",
|
||||||
manageStorageButton: "Gestionar almacenamiento",
|
manageStorageButton: "Gestionar almacenamiento",
|
||||||
transferDataButton: "Enviar o exportar archivos",
|
transferDataButton: "Enviar o exportar archivos",
|
||||||
@@ -752,6 +754,7 @@ export const allTranslations: {
|
|||||||
settings: {
|
settings: {
|
||||||
pages: {
|
pages: {
|
||||||
appearance: "Aspecto",
|
appearance: "Aspecto",
|
||||||
|
account: "Cuenta",
|
||||||
regional: "Idioma y Región",
|
regional: "Idioma y Región",
|
||||||
info: "Sobre CT",
|
info: "Sobre CT",
|
||||||
},
|
},
|
||||||
@@ -762,13 +765,19 @@ export const allTranslations: {
|
|||||||
system: "Según dispositivo",
|
system: "Según dispositivo",
|
||||||
black: "Negro",
|
black: "Negro",
|
||||||
},
|
},
|
||||||
|
account: {
|
||||||
version: "Versión",
|
yourNameLabel: "Tu nombre",
|
||||||
language: "Idioma",
|
yourNamePlaceholder: "Juan Pérez",
|
||||||
|
setNameButtonAudioLabel: "establecer nombre",
|
||||||
firstDayOfWeekLabel: "Primer día de la semana",
|
},
|
||||||
|
regional: {
|
||||||
checkUpdatesButton: "Buscar actualizaciones",
|
language: "Idioma",
|
||||||
|
firstDayOfWeekLabel: "Primer día de la semana",
|
||||||
|
},
|
||||||
|
about: {
|
||||||
|
version: "Versión",
|
||||||
|
checkUpdatesButton: "Buscar actualisaciones",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
connectionModal: {
|
connectionModal: {
|
||||||
connectionModalHeadline: "Gestionar Conexiones",
|
connectionModalHeadline: "Gestionar Conexiones",
|
||||||
|
|||||||
@@ -2,11 +2,11 @@ import ChatViewModel from "./chatViewModel";
|
|||||||
import SettingsViewModel from "../Global/settingsViewModel";
|
import SettingsViewModel from "../Global/settingsViewModel";
|
||||||
import NotificationViewModel from "../Global/notificationViewModel";
|
import NotificationViewModel from "../Global/notificationViewModel";
|
||||||
import CoreViewModel from "../Global/coreViewModel";
|
import CoreViewModel from "../Global/coreViewModel";
|
||||||
|
import ContactListViewModel from "../Global/contactViewModel";
|
||||||
import ConnectionViewModel from "../Global/connectionViewModel";
|
import ConnectionViewModel from "../Global/connectionViewModel";
|
||||||
import * as React from "../../react";
|
import * as React from "../../react";
|
||||||
import { IndexManager } from "../../Model/Utility/utility";
|
import { IndexManager } from "../../Model/Utility/utility";
|
||||||
import ChatModel from "../../Model/Chat/chatModel";
|
import ChatModel from "../../Model/Chat/chatModel";
|
||||||
import ContactListViewModel from "../Global/contactViewModel";
|
|
||||||
|
|
||||||
export default class ChatListViewModel {
|
export default class ChatListViewModel {
|
||||||
notificationViewModel: NotificationViewModel;
|
notificationViewModel: NotificationViewModel;
|
||||||
@@ -62,7 +62,7 @@ export default class ChatListViewModel {
|
|||||||
this.notificationViewModel,
|
this.notificationViewModel,
|
||||||
this.connectionViewModel,
|
this.connectionViewModel,
|
||||||
this,
|
this,
|
||||||
this.contactListViewModel,
|
this.contactListViewModel,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -99,7 +99,7 @@ export default class ChatListViewModel {
|
|||||||
public readonly coreViewModel: CoreViewModel,
|
public readonly coreViewModel: CoreViewModel,
|
||||||
public readonly settingsViewModel: SettingsViewModel,
|
public readonly settingsViewModel: SettingsViewModel,
|
||||||
public readonly connectionViewModel: ConnectionViewModel,
|
public readonly connectionViewModel: ConnectionViewModel,
|
||||||
public readonly contactListViewModel: ContactListViewModel,
|
public readonly contactListViewModel: ContactListViewModel,
|
||||||
) {
|
) {
|
||||||
this.notificationViewModel = new NotificationViewModel(this);
|
this.notificationViewModel = new NotificationViewModel(this);
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import MessagePageViewModel from "../Pages/messagePageViewModel";
|
import MessagePageViewModel from "../Pages/messagePageViewModel";
|
||||||
import CoreViewModel from "../Global/coreViewModel";
|
import CoreViewModel from "../Global/coreViewModel";
|
||||||
|
import { ContactViewModel } from "../Global/contactViewModel";
|
||||||
import * as React from "../../react";
|
import * as React from "../../react";
|
||||||
import {
|
import {
|
||||||
ChatMessage,
|
ChatMessage,
|
||||||
@@ -7,7 +8,6 @@ import {
|
|||||||
ChatMessageStatuses,
|
ChatMessageStatuses,
|
||||||
ReactionSymbols,
|
ReactionSymbols,
|
||||||
} from "../../Model/Chat/chatModel";
|
} from "../../Model/Chat/chatModel";
|
||||||
import {ContactViewModel} from "../Global/contactViewModel";
|
|
||||||
|
|
||||||
export default class ChatMessageViewModel {
|
export default class ChatMessageViewModel {
|
||||||
// data
|
// data
|
||||||
@@ -203,7 +203,7 @@ export default class ChatMessageViewModel {
|
|||||||
public readonly coreViewModel: CoreViewModel,
|
public readonly coreViewModel: CoreViewModel,
|
||||||
public readonly messagePageViewModel: MessagePageViewModel,
|
public readonly messagePageViewModel: MessagePageViewModel,
|
||||||
chatMessage: ChatMessage,
|
chatMessage: ChatMessage,
|
||||||
public contact: ContactViewModel,
|
public contact: ContactViewModel,
|
||||||
sentByUser: boolean,
|
sentByUser: boolean,
|
||||||
) {
|
) {
|
||||||
this.chatMessage = chatMessage;
|
this.chatMessage = chatMessage;
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import CalendarPageViewModel, {
|
|||||||
import SettingsViewModel from "../Global/settingsViewModel";
|
import SettingsViewModel from "../Global/settingsViewModel";
|
||||||
import NotificationViewModel from "../Global/notificationViewModel";
|
import NotificationViewModel from "../Global/notificationViewModel";
|
||||||
import CoreViewModel, { Context, ContextHost } from "../Global/coreViewModel";
|
import CoreViewModel, { Context, ContextHost } from "../Global/coreViewModel";
|
||||||
|
import ContactListViewModel from "../Global/contactViewModel";
|
||||||
import ConnectionViewModel from "../Global/connectionViewModel";
|
import ConnectionViewModel from "../Global/connectionViewModel";
|
||||||
import * as React from "../../react";
|
import * as React from "../../react";
|
||||||
import { Colors } from "../../colors";
|
import { Colors } from "../../colors";
|
||||||
@@ -21,7 +22,6 @@ import ChatModel, {
|
|||||||
ChatMessage,
|
ChatMessage,
|
||||||
ChatMessageReaction,
|
ChatMessageReaction,
|
||||||
} from "../../Model/Chat/chatModel";
|
} from "../../Model/Chat/chatModel";
|
||||||
import ContactListViewModel from "../Global/contactViewModel";
|
|
||||||
|
|
||||||
export default class ChatViewModel extends ContextHost<ChatPageTypes> {
|
export default class ChatViewModel extends ContextHost<ChatPageTypes> {
|
||||||
calendarViewModel: CalendarPageViewModel;
|
calendarViewModel: CalendarPageViewModel;
|
||||||
@@ -150,7 +150,7 @@ export default class ChatViewModel extends ContextHost<ChatPageTypes> {
|
|||||||
public readonly notificationViewModel: NotificationViewModel,
|
public readonly notificationViewModel: NotificationViewModel,
|
||||||
public readonly connectionViewModel: ConnectionViewModel,
|
public readonly connectionViewModel: ConnectionViewModel,
|
||||||
public readonly chatListViewModel: ChatListViewModel,
|
public readonly chatListViewModel: ChatListViewModel,
|
||||||
public readonly contactListViewModel: ContactListViewModel,
|
public readonly contactListViewModel: ContactListViewModel,
|
||||||
) {
|
) {
|
||||||
super("chat", coreViewModel);
|
super("chat", coreViewModel);
|
||||||
|
|
||||||
@@ -169,7 +169,7 @@ export default class ChatViewModel extends ContextHost<ChatPageTypes> {
|
|||||||
this.messagePageViewModel = new MessagePageViewModel(
|
this.messagePageViewModel = new MessagePageViewModel(
|
||||||
this.coreViewModel,
|
this.coreViewModel,
|
||||||
this,
|
this,
|
||||||
this.contactListViewModel,
|
this.contactListViewModel,
|
||||||
);
|
);
|
||||||
this.settingsPageViewModel = new SettingsPageViewModel(
|
this.settingsPageViewModel = new SettingsPageViewModel(
|
||||||
this.coreViewModel,
|
this.coreViewModel,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import ContactListModel from "../../Model/Global/contactListModel";
|
|
||||||
import * as React from "../../react";
|
|
||||||
import SettingsViewModel from "./settingsViewModel";
|
import SettingsViewModel from "./settingsViewModel";
|
||||||
|
import * as React from "../../react";
|
||||||
|
import ContactListModel from "../../Model/Global/contactListModel";
|
||||||
|
|
||||||
export default class ContactListViewModel {
|
export default class ContactListViewModel {
|
||||||
// state
|
// state
|
||||||
@@ -8,43 +8,49 @@ export default class ContactListViewModel {
|
|||||||
|
|
||||||
// main
|
// main
|
||||||
updateContact = (id: string, name: string): ContactViewModel => {
|
updateContact = (id: string, name: string): ContactViewModel => {
|
||||||
if (id == this.settingsViewModel.settingsModel.userid) {
|
if (id == this.settingsViewModel.settingsModel.userid) {
|
||||||
this.settingsViewModel.setName(name);
|
this.settingsViewModel.setName(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
const match = this.contacts.get(id);
|
const match = this.contacts.get(id);
|
||||||
if (match) {
|
if (match) {
|
||||||
match.name.value = name;
|
match.name.value = name;
|
||||||
return match;
|
return match;
|
||||||
}
|
}
|
||||||
const vm = new ContactViewModel(id, name);
|
const vm = new ContactViewModel(id, name);
|
||||||
this.contacts.set(id, vm);
|
this.contacts.set(id, vm);
|
||||||
return vm;
|
return vm;
|
||||||
}
|
};
|
||||||
|
|
||||||
handleContact = (contact: [string, string]): void => {
|
handleContact = (contact: [string, string]): void => {
|
||||||
this.updateContact(...contact);
|
this.updateContact(...contact);
|
||||||
}
|
};
|
||||||
|
|
||||||
unwrapContact = (id: string, knownName: string): ContactViewModel => {
|
unwrapContact = (id: string, knownName: string): ContactViewModel => {
|
||||||
if (this.contacts.has(id))
|
if (this.contacts.has(id)) return this.contacts.get(id)!;
|
||||||
return this.contacts.get(id)!
|
return this.updateContact(id, knownName);
|
||||||
return this.updateContact(id, knownName);
|
};
|
||||||
}
|
|
||||||
|
|
||||||
// load
|
// load
|
||||||
loadData = (): void => {
|
loadData = (): void => {
|
||||||
const contacts: [string, string][] = this.contactListModel.loadContacts();
|
const contacts: [string, string][] =
|
||||||
for (const contact of contacts) {
|
this.contactListModel.loadContacts();
|
||||||
const vm = new ContactViewModel(...contact);
|
for (const contact of contacts) {
|
||||||
this.contacts.set(vm.id, vm);
|
const vm = new ContactViewModel(...contact);
|
||||||
}
|
this.contacts.set(vm.id, vm);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// init
|
// init
|
||||||
constructor(public contactListModel: ContactListModel, public settingsViewModel: SettingsViewModel) {
|
constructor(
|
||||||
this.loadData();
|
public contactListModel: ContactListModel,
|
||||||
this.contactListModel.contactHandlerManager.setHandler("contact-list-view-model", this.handleContact);
|
public settingsViewModel: SettingsViewModel,
|
||||||
|
) {
|
||||||
|
this.loadData();
|
||||||
|
this.contactListModel.contactHandlerManager.setHandler(
|
||||||
|
"contact-list-view-model",
|
||||||
|
this.handleContact,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,7 +59,10 @@ export class ContactViewModel {
|
|||||||
name: React.State<string> = new React.State("");
|
name: React.State<string> = new React.State("");
|
||||||
|
|
||||||
// init
|
// init
|
||||||
constructor(public id: string, name: string) {
|
constructor(
|
||||||
this.name.value = name;
|
public id: string,
|
||||||
|
name: string,
|
||||||
|
) {
|
||||||
|
this.name.value = name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
import CoreViewModel, { Context } from "./coreViewModel";
|
import CoreViewModel, { Context } from "./coreViewModel";
|
||||||
import * as React from "../../react";
|
import * as React from "../../react";
|
||||||
import { CommonKeys } from "../../View/keystrokes";
|
import { CommonKeys } from "../../View/keystrokes";
|
||||||
import SettingsModel, { Languages, ThemeSettings } from "../../Model/Global/settingsModel";
|
import SettingsModel, {
|
||||||
|
Languages,
|
||||||
|
ThemeSettings,
|
||||||
|
} from "../../Model/Global/settingsModel";
|
||||||
|
|
||||||
export default class SettingsViewModel extends Context {
|
export default class SettingsViewModel extends Context {
|
||||||
// state
|
// state
|
||||||
@@ -31,154 +34,158 @@ export default class SettingsViewModel extends Context {
|
|||||||
|
|
||||||
// methods
|
// methods
|
||||||
setName = (name?: string): void => {
|
setName = (name?: string): void => {
|
||||||
if (typeof name == "string") {
|
if (typeof name == "string") {
|
||||||
this.usernameInput.value = name;
|
this.usernameInput.value = name;
|
||||||
}
|
}
|
||||||
this.coreViewModel.settingsModel.setName(this.usernameInput.value);
|
this.coreViewModel.settingsModel.setName(this.usernameInput.value);
|
||||||
this.username.value = this.coreViewModel.settingsModel.username;
|
this.username.value = this.coreViewModel.settingsModel.username;
|
||||||
this.usernameInput.callSubscriptions();
|
this.usernameInput.callSubscriptions();
|
||||||
};
|
};
|
||||||
|
|
||||||
setFirstDayofWeek = (): void => {
|
setFirstDayofWeek = (): void => {
|
||||||
this.coreViewModel.settingsModel.setFirstDayOfWeek(
|
this.coreViewModel.settingsModel.setFirstDayOfWeek(
|
||||||
this.firstDayOfWeek.value,
|
this.firstDayOfWeek.value,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
showSettingsModal = (): void => {
|
showSettingsModal = (): void => {
|
||||||
this.coreViewModel.context = this;
|
this.coreViewModel.context = this;
|
||||||
this.isShowingSettingsModal.value = true;
|
this.isShowingSettingsModal.value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
showModalPage = (page: SettingsModalPages): void => {
|
showModalPage = (page: SettingsModalPages): void => {
|
||||||
this.selectedModalPage.value = page;
|
this.selectedModalPage.value = page;
|
||||||
};
|
};
|
||||||
|
|
||||||
// view
|
// view
|
||||||
applyTheme = (): void => {
|
applyTheme = (): void => {
|
||||||
let theme: string = this.theme.value;
|
let theme: string = this.theme.value;
|
||||||
|
|
||||||
if (theme == ThemeSettings.System)
|
if (theme == ThemeSettings.System)
|
||||||
theme = SettingsViewModel.getSystemTheme();
|
theme = SettingsViewModel.getSystemTheme();
|
||||||
|
|
||||||
switch (theme) {
|
switch (theme) {
|
||||||
case ThemeSettings.Dynamic:
|
case ThemeSettings.Dynamic:
|
||||||
const scene = this.selectDynamicScene();
|
const scene = this.selectDynamicScene();
|
||||||
this.setScene(scene);
|
this.setScene(scene);
|
||||||
break;
|
break;
|
||||||
case ThemeSettings.Dark:
|
case ThemeSettings.Dark:
|
||||||
this.setScene(DynamicSceneNight);
|
this.setScene(DynamicSceneNight);
|
||||||
break;
|
break;
|
||||||
case ThemeSettings.Black:
|
case ThemeSettings.Black:
|
||||||
this.setScene(DynamicSceneBlack);
|
this.setScene(DynamicSceneBlack);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
this.setScene(DynamicSceneDay);
|
this.setScene(DynamicSceneDay);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
selectDynamicScene = (): DynamicScene => {
|
selectDynamicScene = (): DynamicScene => {
|
||||||
let hour = new Date().getHours();
|
let hour = new Date().getHours();
|
||||||
|
|
||||||
if (hour >= 21 || hour <= 6) {
|
if (hour >= 21 || hour <= 6) {
|
||||||
return DynamicSceneNight;
|
return DynamicSceneNight;
|
||||||
} else if (hour > 6 && hour < 10) {
|
} else if (hour > 6 && hour < 10) {
|
||||||
return DynamicSceneSunrise;
|
return DynamicSceneSunrise;
|
||||||
} else if (hour < 14) {
|
} else if (hour < 14) {
|
||||||
return DynamicSceneDay;
|
return DynamicSceneDay;
|
||||||
} else if (hour < 17) {
|
} else if (hour < 17) {
|
||||||
return DynamicSceneAfternoon;
|
return DynamicSceneAfternoon;
|
||||||
} else {
|
} else {
|
||||||
return DynamicSceneSunset;
|
return DynamicSceneSunset;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
setScene = (scene: DynamicScene): void => {
|
setScene = (scene: DynamicScene): void => {
|
||||||
document.body.style.setProperty(
|
document.body.style.setProperty(
|
||||||
"--backdrop-grass-filter",
|
"--backdrop-grass-filter",
|
||||||
`brightness(${scene.brightness})`,
|
`brightness(${scene.brightness})`,
|
||||||
);
|
);
|
||||||
|
|
||||||
function setSkyColor(
|
function setSkyColor(
|
||||||
tone: 1 | 2,
|
tone: 1 | 2,
|
||||||
hue: number,
|
hue: number,
|
||||||
saturation: number,
|
saturation: number,
|
||||||
luma: number,
|
luma: number,
|
||||||
) {
|
) {
|
||||||
document.body.style.setProperty(
|
document.body.style.setProperty(
|
||||||
`--sky-${tone}`,
|
`--sky-${tone}`,
|
||||||
`hsl(${hue}, ${saturation}%, ${luma}%)`,
|
`hsl(${hue}, ${saturation}%, ${luma}%)`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
setSkyColor(1, scene.hue1, scene.saturation, scene.luma);
|
setSkyColor(1, scene.hue1, scene.saturation, scene.luma);
|
||||||
setSkyColor(2, scene.hue2, scene.saturation - 10, scene.luma - 10);
|
setSkyColor(2, scene.hue2, scene.saturation - 10, scene.luma - 10);
|
||||||
|
|
||||||
document.body.setAttribute("theme", scene.baseTheme);
|
document.body.setAttribute("theme", scene.baseTheme);
|
||||||
};
|
};
|
||||||
|
|
||||||
// exit
|
// exit
|
||||||
close = (): void => {
|
close = (): void => {
|
||||||
this.coreViewModel.closeContext(this.contextId);
|
this.coreViewModel.closeContext(this.contextId);
|
||||||
};
|
};
|
||||||
|
|
||||||
handleContextClose = (): void => {
|
handleContextClose = (): void => {
|
||||||
this.isShowingSettingsModal.value = false;
|
this.isShowingSettingsModal.value = false;
|
||||||
if (this.requiresReload.value == true) {
|
if (this.requiresReload.value == true) {
|
||||||
window.location.reload();
|
window.location.reload();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// init
|
// init
|
||||||
constructor(public readonly coreViewModel: CoreViewModel, public readonly settingsModel: SettingsModel) {
|
constructor(
|
||||||
super("settings");
|
public readonly coreViewModel: CoreViewModel,
|
||||||
|
public readonly settingsModel: SettingsModel,
|
||||||
|
) {
|
||||||
|
super("settings");
|
||||||
|
|
||||||
this.username.value = coreViewModel.settingsModel.username;
|
this.username.value = coreViewModel.settingsModel.username;
|
||||||
this.usernameInput.value = coreViewModel.settingsModel.username;
|
this.usernameInput.value = coreViewModel.settingsModel.username;
|
||||||
this.firstDayOfWeek.value = coreViewModel.settingsModel.firstDayOfWeek;
|
this.firstDayOfWeek.value = coreViewModel.settingsModel.firstDayOfWeek;
|
||||||
this.language.value = coreViewModel.settingsModel.language;
|
this.language.value = coreViewModel.settingsModel.language;
|
||||||
this.theme.value = coreViewModel.settingsModel.theme;
|
this.theme.value = coreViewModel.settingsModel.theme;
|
||||||
|
|
||||||
// subscriptions
|
// subscriptions
|
||||||
this.firstDayOfWeek.subscribe(this.setFirstDayofWeek);
|
this.firstDayOfWeek.subscribe(this.setFirstDayofWeek);
|
||||||
this.language.subscribeSilent((newValue) => {
|
this.language.subscribeSilent((newValue) => {
|
||||||
this.coreViewModel.settingsModel.setLanguage(newValue);
|
this.coreViewModel.settingsModel.setLanguage(newValue);
|
||||||
this.requiresReload.value = true;
|
this.requiresReload.value = true;
|
||||||
});
|
});
|
||||||
this.theme.subscribeSilent((newValue) => {
|
this.theme.subscribeSilent((newValue) => {
|
||||||
this.coreViewModel.settingsModel.setTheme(newValue);
|
this.coreViewModel.settingsModel.setTheme(newValue);
|
||||||
});
|
});
|
||||||
|
|
||||||
// set theme
|
// set theme
|
||||||
this.theme.subscribe(() => {
|
this.theme.subscribe(() => {
|
||||||
this.applyTheme();
|
this.applyTheme();
|
||||||
});
|
});
|
||||||
SettingsViewModel.generateThemeMedia().addEventListener("change", () =>
|
SettingsViewModel.generateThemeMedia().addEventListener("change", () =>
|
||||||
this.applyTheme(),
|
this.applyTheme(),
|
||||||
);
|
);
|
||||||
const seconds = new Date().getSeconds();
|
const seconds = new Date().getSeconds();
|
||||||
const secondsUntilNewMinute = 60 - seconds;
|
const secondsUntilNewMinute = 60 - seconds;
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
setInterval(this.applyTheme, 1000 * 60);
|
setInterval(this.applyTheme, 1000 * 60);
|
||||||
}, secondsUntilNewMinute);
|
}, secondsUntilNewMinute);
|
||||||
|
|
||||||
// keystrokes
|
// keystrokes
|
||||||
this.registerKeyStroke(CommonKeys.CloseOrCancel, this.close);
|
this.registerKeyStroke(CommonKeys.CloseOrCancel, this.close);
|
||||||
}
|
}
|
||||||
|
|
||||||
static generateThemeMedia(): MediaQueryList {
|
static generateThemeMedia(): MediaQueryList {
|
||||||
return window.matchMedia("(prefers-color-scheme: dark)");
|
return window.matchMedia("(prefers-color-scheme: dark)");
|
||||||
}
|
}
|
||||||
|
|
||||||
static getSystemTheme(): string {
|
static getSystemTheme(): string {
|
||||||
const media = SettingsViewModel.generateThemeMedia();
|
const media = SettingsViewModel.generateThemeMedia();
|
||||||
return media.matches == true ? ThemeSettings.Dark : ThemeSettings.Light;
|
return media.matches == true ? ThemeSettings.Dark : ThemeSettings.Light;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum SettingsModalPages {
|
export enum SettingsModalPages {
|
||||||
Appearance,
|
Appearance,
|
||||||
Regional,
|
Account,
|
||||||
Info,
|
Regional,
|
||||||
|
Info,
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DynamicScene {
|
export interface DynamicScene {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import SearchViewModel from "../Utility/searchViewModel";
|
import SearchViewModel from "../Utility/searchViewModel";
|
||||||
import CoreViewModel, { Context } from "../Global/coreViewModel";
|
import CoreViewModel, { Context } from "../Global/coreViewModel";
|
||||||
|
import ContactListViewModel from "../Global/contactViewModel";
|
||||||
import ChatViewModel, { ChatPageTypes } from "../Chat/chatViewModel";
|
import ChatViewModel, { ChatPageTypes } from "../Chat/chatViewModel";
|
||||||
import ChatMessageViewModel from "../Chat/chatMessageViewModel";
|
import ChatMessageViewModel from "../Chat/chatMessageViewModel";
|
||||||
import * as React from "../../react";
|
import * as React from "../../react";
|
||||||
@@ -9,7 +10,6 @@ import {
|
|||||||
ChatMessageReaction,
|
ChatMessageReaction,
|
||||||
ReactionSymbols,
|
ReactionSymbols,
|
||||||
} from "../../Model/Chat/chatModel";
|
} from "../../Model/Chat/chatModel";
|
||||||
import ContactListViewModel from "../Global/contactViewModel";
|
|
||||||
|
|
||||||
export default class MessagePageViewModel extends Context {
|
export default class MessagePageViewModel extends Context {
|
||||||
// state
|
// state
|
||||||
@@ -107,138 +107,141 @@ export default class MessagePageViewModel extends Context {
|
|||||||
|
|
||||||
// view
|
// view
|
||||||
showChatMessage = (chatMessage: ChatMessage): void => {
|
showChatMessage = (chatMessage: ChatMessage): void => {
|
||||||
const contact = this.contactListViewModel.unwrapContact(chatMessage.senderId, chatMessage.senderName);
|
const contact = this.contactListViewModel.unwrapContact(
|
||||||
const chatMessageViewModel = new ChatMessageViewModel(
|
chatMessage.senderId,
|
||||||
this.coreViewModel,
|
chatMessage.senderName,
|
||||||
this,
|
);
|
||||||
chatMessage,
|
const chatMessageViewModel = new ChatMessageViewModel(
|
||||||
contact,
|
this.coreViewModel,
|
||||||
chatMessage.senderId ==
|
this,
|
||||||
this.chatViewModel.settingsViewModel.settingsModel.userid
|
chatMessage,
|
||||||
);
|
contact,
|
||||||
|
chatMessage.senderId ==
|
||||||
|
this.chatViewModel.settingsViewModel.settingsModel.userid,
|
||||||
|
);
|
||||||
|
|
||||||
const existingChatMessageViewModel: ChatMessageViewModel | undefined =
|
const existingChatMessageViewModel: ChatMessageViewModel | undefined =
|
||||||
this.chatMessageViewModels.value.get(chatMessage.fileId);
|
this.chatMessageViewModels.value.get(chatMessage.fileId);
|
||||||
if (existingChatMessageViewModel != undefined) {
|
if (existingChatMessageViewModel != undefined) {
|
||||||
existingChatMessageViewModel.body.value = chatMessage.body;
|
existingChatMessageViewModel.body.value = chatMessage.body;
|
||||||
existingChatMessageViewModel.status.value = chatMessage.status;
|
existingChatMessageViewModel.status.value = chatMessage.status;
|
||||||
} else {
|
} else {
|
||||||
this.chatMessageViewModels.set(
|
this.chatMessageViewModels.set(
|
||||||
chatMessage.fileId,
|
chatMessage.fileId,
|
||||||
chatMessageViewModel,
|
chatMessageViewModel,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
handleReaction = (reaction: ChatMessageReaction): void => {
|
handleReaction = (reaction: ChatMessageReaction): void => {
|
||||||
const messageViewModel: ChatMessageViewModel | undefined =
|
const messageViewModel: ChatMessageViewModel | undefined =
|
||||||
this.chatMessageViewModels.value.get(reaction.messageId);
|
this.chatMessageViewModels.value.get(reaction.messageId);
|
||||||
if (messageViewModel == undefined) return;
|
if (messageViewModel == undefined) return;
|
||||||
messageViewModel.handleReaction(reaction);
|
messageViewModel.handleReaction(reaction);
|
||||||
};
|
};
|
||||||
|
|
||||||
showFilterModal = (): void => {
|
showFilterModal = (): void => {
|
||||||
this.isFilterModalOpen.value = true;
|
this.isFilterModalOpen.value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
hideFilterModal = (): void => {
|
hideFilterModal = (): void => {
|
||||||
this.isFilterModalOpen.value = false;
|
this.isFilterModalOpen.value = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
revokeReactionFilter = (persist: boolean = true): void => {
|
revokeReactionFilter = (persist: boolean = true): void => {
|
||||||
this.reactionFilter.value = undefined;
|
this.reactionFilter.value = undefined;
|
||||||
if (persist) this.chatViewModel.chatModel.storeFilter("");
|
if (persist) this.chatViewModel.chatModel.storeFilter("");
|
||||||
};
|
};
|
||||||
|
|
||||||
setReactionFilter = (content: ReactionSymbols): void => {
|
setReactionFilter = (content: ReactionSymbols): void => {
|
||||||
this.reactionFilter.value = content;
|
this.reactionFilter.value = content;
|
||||||
this.chatViewModel.chatModel.storeFilter(content);
|
this.chatViewModel.chatModel.storeFilter(content);
|
||||||
};
|
};
|
||||||
|
|
||||||
resetFilter = (): void => {
|
resetFilter = (): void => {
|
||||||
this.revokeReactionFilter();
|
this.revokeReactionFilter();
|
||||||
this.searchViewModel.search("");
|
this.searchViewModel.search("");
|
||||||
};
|
};
|
||||||
|
|
||||||
setReplyView = (message: ChatMessageViewModel): void => {
|
setReplyView = (message: ChatMessageViewModel): void => {
|
||||||
this.replyViewSelectedMessage.value = message;
|
this.replyViewSelectedMessage.value = message;
|
||||||
this.revokeReactionFilter(false);
|
this.revokeReactionFilter(false);
|
||||||
this.setReply(message, false);
|
this.setReply(message, false);
|
||||||
};
|
};
|
||||||
|
|
||||||
resetReplyView = (): void => {
|
resetReplyView = (): void => {
|
||||||
this.replyViewSelectedMessage.value = undefined;
|
this.replyViewSelectedMessage.value = undefined;
|
||||||
this.resetReply(false);
|
this.resetReply(false);
|
||||||
this.restoreFilter();
|
this.restoreFilter();
|
||||||
};
|
};
|
||||||
|
|
||||||
setFocus = (): void => {
|
setFocus = (): void => {
|
||||||
this.focusSetter.callSubscriptions();
|
this.focusSetter.callSubscriptions();
|
||||||
};
|
};
|
||||||
|
|
||||||
// load
|
// load
|
||||||
loadData = (): void => {
|
loadData = (): void => {
|
||||||
this.chatMessageViewModels.clear();
|
this.chatMessageViewModels.clear();
|
||||||
for (const chatMessage of this.chatViewModel.chatModel.messages) {
|
for (const chatMessage of this.chatViewModel.chatModel.messages) {
|
||||||
this.showChatMessage(chatMessage);
|
this.showChatMessage(chatMessage);
|
||||||
}
|
}
|
||||||
for (const reaction of this.chatViewModel.chatModel.reactions) {
|
for (const reaction of this.chatViewModel.chatModel.reactions) {
|
||||||
this.handleReaction(reaction);
|
this.handleReaction(reaction);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
restoreFilter = (): void => {
|
restoreFilter = (): void => {
|
||||||
const previousFilter = this.chatViewModel.chatModel.getFilter() as any;
|
const previousFilter = this.chatViewModel.chatModel.getFilter() as any;
|
||||||
if (Object.values(ReactionSymbols).includes(previousFilter))
|
if (Object.values(ReactionSymbols).includes(previousFilter))
|
||||||
this.setReactionFilter(previousFilter);
|
this.setReactionFilter(previousFilter);
|
||||||
};
|
};
|
||||||
|
|
||||||
// init
|
// init
|
||||||
constructor(
|
constructor(
|
||||||
public readonly coreViewModel: CoreViewModel,
|
public readonly coreViewModel: CoreViewModel,
|
||||||
public readonly chatViewModel: ChatViewModel,
|
public readonly chatViewModel: ChatViewModel,
|
||||||
public readonly contactListViewModel: ContactListViewModel,
|
public readonly contactListViewModel: ContactListViewModel,
|
||||||
) {
|
) {
|
||||||
super("message-page");
|
super("message-page");
|
||||||
this.restoreFilter();
|
this.restoreFilter();
|
||||||
|
|
||||||
// states
|
// states
|
||||||
this.cannotSendMessage = React.createProxyState(
|
this.cannotSendMessage = React.createProxyState(
|
||||||
[
|
[
|
||||||
this.chatViewModel.settingsViewModel.username,
|
this.chatViewModel.settingsViewModel.username,
|
||||||
this.composingMessage,
|
this.composingMessage,
|
||||||
],
|
],
|
||||||
() =>
|
() =>
|
||||||
this.chatViewModel.settingsViewModel.username.value == "" ||
|
this.chatViewModel.settingsViewModel.username.value == "" ||
|
||||||
this.composingMessage.value == "",
|
this.composingMessage.value == "",
|
||||||
);
|
);
|
||||||
|
|
||||||
this.searchViewModel = new SearchViewModel(
|
this.searchViewModel = new SearchViewModel(
|
||||||
this.chatMessageViewModels,
|
this.chatMessageViewModels,
|
||||||
this.filteredMessageViewModels,
|
this.filteredMessageViewModels,
|
||||||
(chatMessageViewModel) => [chatMessageViewModel.body.value],
|
(chatMessageViewModel) => [chatMessageViewModel.body.value],
|
||||||
new React.ListState(),
|
new React.ListState(),
|
||||||
);
|
);
|
||||||
|
|
||||||
this.isFilterActive = React.createProxyState(
|
this.isFilterActive = React.createProxyState(
|
||||||
[this.searchViewModel.appliedQuery, this.reactionFilter],
|
[this.searchViewModel.appliedQuery, this.reactionFilter],
|
||||||
() =>
|
() =>
|
||||||
this.searchViewModel.appliedQuery.value != "" ||
|
this.searchViewModel.appliedQuery.value != "" ||
|
||||||
this.reactionFilter.value != undefined,
|
this.reactionFilter.value != undefined,
|
||||||
);
|
);
|
||||||
|
|
||||||
// keystrokes
|
// keystrokes
|
||||||
this.registerKeyStroke(CommonKeys.Filter, this.showFilterModal);
|
this.registerKeyStroke(CommonKeys.Filter, this.showFilterModal);
|
||||||
this.registerKeyStroke(CommonKeys.CloseOrCancel, () => {
|
this.registerKeyStroke(CommonKeys.CloseOrCancel, () => {
|
||||||
if (this.isFilterModalOpen.value == true) {
|
if (this.isFilterModalOpen.value == true) {
|
||||||
this.hideFilterModal();
|
this.hideFilterModal();
|
||||||
} else {
|
} else {
|
||||||
this.replyingMessage.value = undefined;
|
this.replyingMessage.value = undefined;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.registerKeyStroke(CommonKeys.Reset, this.resetFilter);
|
this.registerKeyStroke(CommonKeys.Reset, this.resetFilter);
|
||||||
this.registerKeyStroke(CommonKeys.Create, this.setFocus);
|
this.registerKeyStroke(CommonKeys.Create, this.setFocus);
|
||||||
|
|
||||||
this.chatViewModel.registerContext(ChatPageTypes.Messages, this);
|
this.chatViewModel.registerContext(ChatPageTypes.Messages, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-3
@@ -7,6 +7,7 @@ import StorageViewModel from "./ViewModel/Global/storageViewModel";
|
|||||||
import SettingsViewModel from "./ViewModel/Global/settingsViewModel";
|
import SettingsViewModel from "./ViewModel/Global/settingsViewModel";
|
||||||
import FileTransferViewModel from "./ViewModel/Global/fileTransferViewModel";
|
import FileTransferViewModel from "./ViewModel/Global/fileTransferViewModel";
|
||||||
import CoreViewModel from "./ViewModel/Global/coreViewModel";
|
import CoreViewModel from "./ViewModel/Global/coreViewModel";
|
||||||
|
import ContactListViewModel from "./ViewModel/Global/contactViewModel";
|
||||||
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 { HomePage } from "./View/homePage";
|
import { HomePage } from "./View/homePage";
|
||||||
@@ -18,10 +19,9 @@ import { ConnectionModal } from "./View/Modals/connectionModal";
|
|||||||
import StorageModel from "./Model/Global/storageModel";
|
import StorageModel from "./Model/Global/storageModel";
|
||||||
import SettingsModel from "./Model/Global/settingsModel";
|
import SettingsModel from "./Model/Global/settingsModel";
|
||||||
import FileTransferModel from "./Model/Global/fileTransferModel";
|
import FileTransferModel from "./Model/Global/fileTransferModel";
|
||||||
|
import ContactListModel from "./Model/Global/contactListModel";
|
||||||
import ConnectionModel from "./Model/Global/connectionModel";
|
import ConnectionModel from "./Model/Global/connectionModel";
|
||||||
import ChatListModel from "./Model/Chat/chatListModel";
|
import ChatListModel from "./Model/Chat/chatListModel";
|
||||||
import ContactListModel from "./Model/Global/contactListModel";
|
|
||||||
import ContactListViewModel from "./ViewModel/Global/contactViewModel";
|
|
||||||
|
|
||||||
// models
|
// models
|
||||||
const storageModel = new StorageModel();
|
const storageModel = new StorageModel();
|
||||||
@@ -47,7 +47,10 @@ const coreViewModel = new CoreViewModel(
|
|||||||
|
|
||||||
const storageViewModel = new StorageViewModel(coreViewModel);
|
const storageViewModel = new StorageViewModel(coreViewModel);
|
||||||
const settingsViewModel = new SettingsViewModel(coreViewModel, settingsModel);
|
const settingsViewModel = new SettingsViewModel(coreViewModel, settingsModel);
|
||||||
const contactListViewModel = new ContactListViewModel(contactListModel, settingsViewModel);
|
const contactListViewModel = new ContactListViewModel(
|
||||||
|
contactListModel,
|
||||||
|
settingsViewModel,
|
||||||
|
);
|
||||||
const connectionViewModel = new ConnectionViewModel(coreViewModel);
|
const connectionViewModel = new ConnectionViewModel(coreViewModel);
|
||||||
const chatListViewModel = new ChatListViewModel(
|
const chatListViewModel = new ChatListViewModel(
|
||||||
coreViewModel,
|
coreViewModel,
|
||||||
|
|||||||
Reference in New Issue
Block a user