add settingsViewModel, implement name and first weekday
This commit is contained in:
Vendored
+133
-3
@@ -163,6 +163,45 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
// node_modules/bloatless-react/index.ts
|
// node_modules/bloatless-react/index.ts
|
||||||
|
var State = class {
|
||||||
|
_value;
|
||||||
|
_bindings = /* @__PURE__ */ new Set();
|
||||||
|
// init
|
||||||
|
constructor(initialValue) {
|
||||||
|
this._value = initialValue;
|
||||||
|
}
|
||||||
|
// value
|
||||||
|
get value() {
|
||||||
|
return this._value;
|
||||||
|
}
|
||||||
|
set value(newValue) {
|
||||||
|
if (this._value == newValue) return;
|
||||||
|
this._value = newValue;
|
||||||
|
this.callSubscriptions();
|
||||||
|
}
|
||||||
|
// subscriptions
|
||||||
|
callSubscriptions() {
|
||||||
|
this._bindings.forEach((fn) => fn(this._value));
|
||||||
|
}
|
||||||
|
subscribe(fn) {
|
||||||
|
this._bindings.add(fn);
|
||||||
|
fn(this._value);
|
||||||
|
}
|
||||||
|
subscribeSilent(fn) {
|
||||||
|
this._bindings.add(fn);
|
||||||
|
}
|
||||||
|
// stringify
|
||||||
|
toString() {
|
||||||
|
return JSON.stringify(this._value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
function createProxyState(statesToSubscibe, fn) {
|
||||||
|
const proxyState = new State(fn());
|
||||||
|
statesToSubscibe.forEach(
|
||||||
|
(state) => state.subscribe(() => proxyState.value = fn())
|
||||||
|
);
|
||||||
|
return proxyState;
|
||||||
|
}
|
||||||
function createElement(tagName, attributes = {}, ...children) {
|
function createElement(tagName, attributes = {}, ...children) {
|
||||||
const element = document.createElement(tagName);
|
const element = document.createElement(tagName);
|
||||||
if (attributes != null)
|
if (attributes != null)
|
||||||
@@ -263,6 +302,11 @@
|
|||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// src/View/Components/option.tsx
|
||||||
|
function Option(text, value, selectedOnCreate) {
|
||||||
|
return /* @__PURE__ */ createElement("option", { value, "toggle:selected": selectedOnCreate }, text);
|
||||||
|
}
|
||||||
|
|
||||||
// src/View/translations.ts
|
// src/View/translations.ts
|
||||||
var englishTranslations = {
|
var englishTranslations = {
|
||||||
general: {
|
general: {
|
||||||
@@ -326,7 +370,7 @@
|
|||||||
var translations = allTranslations[language] || allTranslations.en;
|
var translations = allTranslations[language] || allTranslations.en;
|
||||||
|
|
||||||
// src/View/homePage.tsx
|
// src/View/homePage.tsx
|
||||||
function HomePage() {
|
function HomePage(settingsViewModel2) {
|
||||||
const overviewSection = /* @__PURE__ */ createElement("div", { id: "overview-section" }, /* @__PURE__ */ createElement("h2", null, translations.homePage.overviewHeadline), /* @__PURE__ */ createElement("label", { class: "tile flex-no" }, /* @__PURE__ */ createElement("span", { class: "icon" }, "cell_tower"), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, translations.homePage.serverAddress), /* @__PURE__ */ createElement("input", null))), /* @__PURE__ */ createElement("div", { class: "flex-row" }, /* @__PURE__ */ createElement(
|
const overviewSection = /* @__PURE__ */ createElement("div", { id: "overview-section" }, /* @__PURE__ */ createElement("h2", null, translations.homePage.overviewHeadline), /* @__PURE__ */ createElement("label", { class: "tile flex-no" }, /* @__PURE__ */ createElement("span", { class: "icon" }, "cell_tower"), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, translations.homePage.serverAddress), /* @__PURE__ */ createElement("input", null))), /* @__PURE__ */ createElement("div", { class: "flex-row" }, /* @__PURE__ */ createElement(
|
||||||
"button",
|
"button",
|
||||||
{
|
{
|
||||||
@@ -348,7 +392,28 @@
|
|||||||
"aria-label": translations.homePage.connectAudioLabel
|
"aria-label": translations.homePage.connectAudioLabel
|
||||||
},
|
},
|
||||||
/* @__PURE__ */ createElement("span", { class: "icon" }, "link")
|
/* @__PURE__ */ createElement("span", { class: "icon" }, "link")
|
||||||
)), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement("div", { class: "tile flex-no" }, /* @__PURE__ */ createElement("span", { class: "icon" }, "inbox"), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("b", null, translations.homePage.mailboxHeadline), /* @__PURE__ */ createElement("span", { class: "error" }, translations.homePage.mailboxDisabled))), /* @__PURE__ */ createElement("div", { class: "tile flex-no" }, /* @__PURE__ */ createElement("span", { class: "icon" }, "outbox"), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("b", null, translations.homePage.outboxHeadline), /* @__PURE__ */ createElement("span", { class: "success" }, translations.homePage.outboxAllItemsSent))), /* @__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, translations.homePage.yourNameLabel), /* @__PURE__ */ createElement("input", null))), /* @__PURE__ */ createElement("div", { class: "flex-row justify-end" }, /* @__PURE__ */ createElement("button", { class: "width-50" }, translations.homePage.setNameButton, /* @__PURE__ */ createElement("span", { class: "icon" }, "check"))), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement("label", { class: "tile flex-no" }, /* @__PURE__ */ createElement("span", { class: "icon" }, "calendar_month"), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, translations.homePage.firstDayOfWeekLabel), /* @__PURE__ */ createElement("select", null))), /* @__PURE__ */ createElement("div", { class: "mobile-only" }, /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement("div", { class: "flex-row justify-end" }, /* @__PURE__ */ createElement("button", { class: "ghost width-50", "on:click": scrollToChat }, translations.homePage.scrollToChatButton, /* @__PURE__ */ createElement("span", { class: "icon" }, "arrow_forward")))));
|
)), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement("div", { class: "tile flex-no" }, /* @__PURE__ */ createElement("span", { class: "icon" }, "inbox"), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("b", null, translations.homePage.mailboxHeadline), /* @__PURE__ */ createElement("span", { class: "error" }, translations.homePage.mailboxDisabled))), /* @__PURE__ */ createElement("div", { class: "tile flex-no" }, /* @__PURE__ */ createElement("span", { class: "icon" }, "outbox"), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("b", null, translations.homePage.outboxHeadline), /* @__PURE__ */ createElement("span", { class: "success" }, translations.homePage.outboxAllItemsSent))), /* @__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, translations.homePage.yourNameLabel), /* @__PURE__ */ createElement(
|
||||||
|
"input",
|
||||||
|
{
|
||||||
|
"bind:value": settingsViewModel2.nameInput,
|
||||||
|
"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
|
||||||
|
},
|
||||||
|
translations.homePage.setNameButton,
|
||||||
|
/* @__PURE__ */ createElement("span", { class: "icon" }, "check")
|
||||||
|
)), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement("label", { class: "tile flex-no" }, /* @__PURE__ */ createElement("span", { class: "icon" }, "calendar_month"), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, translations.homePage.firstDayOfWeekLabel), /* @__PURE__ */ createElement("select", { "bind:value": settingsViewModel2.firstDayOfWeekInput }, ...translations.regional.weekdays.full.map(
|
||||||
|
(weekdayName, i) => Option(
|
||||||
|
weekdayName,
|
||||||
|
i.toString(),
|
||||||
|
i == settingsViewModel2.firstDayOfWeekInput.value
|
||||||
|
)
|
||||||
|
)), /* @__PURE__ */ createElement("span", { class: "icon" }, "arrow_drop_down"))), /* @__PURE__ */ createElement("div", { class: "mobile-only" }, /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement("div", { class: "flex-row justify-end" }, /* @__PURE__ */ createElement("button", { class: "ghost width-50", "on:click": scrollToChat }, translations.homePage.scrollToChatButton, /* @__PURE__ */ createElement("span", { class: "icon" }, "arrow_forward")))));
|
||||||
const chatSection = /* @__PURE__ */ createElement("div", { id: "chat-section" }, /* @__PURE__ */ createElement("h2", null, translations.homePage.chatsHeadline), /* @__PURE__ */ createElement("div", { class: "flex-row width-input" }, /* @__PURE__ */ createElement(
|
const chatSection = /* @__PURE__ */ createElement("div", { id: "chat-section" }, /* @__PURE__ */ createElement("h2", null, translations.homePage.chatsHeadline), /* @__PURE__ */ createElement("div", { class: "flex-row width-input" }, /* @__PURE__ */ createElement(
|
||||||
"input",
|
"input",
|
||||||
{
|
{
|
||||||
@@ -457,13 +522,78 @@
|
|||||||
chatOutbox: (id) => `${DATA_VERSION}/chat/${id}/outbox`
|
chatOutbox: (id) => `${DATA_VERSION}/chat/${id}/outbox`
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// src/Model/settingsModel.ts
|
||||||
|
var SettingsModel = class {
|
||||||
|
storageModel;
|
||||||
|
username;
|
||||||
|
firstDayOfWeek;
|
||||||
|
// set
|
||||||
|
setName(newValue) {
|
||||||
|
this.username = newValue;
|
||||||
|
const path = storageKeys.username;
|
||||||
|
this.storageModel.store(path, newValue);
|
||||||
|
}
|
||||||
|
setFirstDayOfWeek(newValue) {
|
||||||
|
this.firstDayOfWeek = newValue;
|
||||||
|
const path = storageKeys.firstDayOfWeek;
|
||||||
|
this.storageModel.storeStringifiable(path, newValue);
|
||||||
|
}
|
||||||
|
// restore
|
||||||
|
restoreUsername() {
|
||||||
|
const path = storageKeys.username;
|
||||||
|
const content = this.storageModel.restore(path);
|
||||||
|
this.username = content ?? "";
|
||||||
|
}
|
||||||
|
restoreFirstDayofWeek() {
|
||||||
|
const path = storageKeys.firstDayOfWeek;
|
||||||
|
const content = this.storageModel.restoreStringifiable(path);
|
||||||
|
this.firstDayOfWeek = content ?? 0;
|
||||||
|
}
|
||||||
|
// init
|
||||||
|
constructor(storageModel2) {
|
||||||
|
this.storageModel = storageModel2;
|
||||||
|
this.restoreUsername();
|
||||||
|
this.restoreFirstDayofWeek();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// src/ViewModel/settingsViewModel.ts
|
||||||
|
var SettingsViewModel = class {
|
||||||
|
settingsModel;
|
||||||
|
// state
|
||||||
|
nameInput = new State("");
|
||||||
|
firstDayOfWeekInput = new State(0);
|
||||||
|
// toggles
|
||||||
|
cannotSetName = createProxyState(
|
||||||
|
[this.nameInput],
|
||||||
|
() => this.nameInput.value == "" || this.nameInput.value == this.settingsModel.username
|
||||||
|
);
|
||||||
|
// set
|
||||||
|
setName = () => {
|
||||||
|
this.settingsModel.setName(this.nameInput.value);
|
||||||
|
this.nameInput.callSubscriptions();
|
||||||
|
};
|
||||||
|
setFirstDayofWeek = () => {
|
||||||
|
this.settingsModel.setFirstDayOfWeek(this.firstDayOfWeekInput.value);
|
||||||
|
};
|
||||||
|
// init
|
||||||
|
constructor(settingsModel2) {
|
||||||
|
this.settingsModel = settingsModel2;
|
||||||
|
this.nameInput.value = settingsModel2.username;
|
||||||
|
this.firstDayOfWeekInput.value = settingsModel2.firstDayOfWeek;
|
||||||
|
this.firstDayOfWeekInput.subscribe(this.setFirstDayofWeek);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// src/index.tsx
|
// src/index.tsx
|
||||||
var storageModel = new StorageModel();
|
var storageModel = new StorageModel();
|
||||||
|
var settingsModel = new SettingsModel(storageModel);
|
||||||
var connectionModel = new ConnectionModel({
|
var connectionModel = new ConnectionModel({
|
||||||
connectionChangeHandler() {
|
connectionChangeHandler() {
|
||||||
},
|
},
|
||||||
messageHandler(data) {
|
messageHandler(data) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
document.querySelector("main").append(HomePage());
|
var settingsViewModel = new SettingsViewModel(settingsModel);
|
||||||
|
document.querySelector("main").append(HomePage(settingsViewModel));
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -25,13 +25,13 @@ export default class SettingsModel {
|
|||||||
restoreUsername(): void {
|
restoreUsername(): void {
|
||||||
const path = storageKeys.username;
|
const path = storageKeys.username;
|
||||||
const content = this.storageModel.restore(path);
|
const content = this.storageModel.restore(path);
|
||||||
this.username == content ?? "";
|
this.username = content ?? "";
|
||||||
}
|
}
|
||||||
|
|
||||||
restoreFirstDayofWeek(): void {
|
restoreFirstDayofWeek(): void {
|
||||||
const path = storageKeys.firstDayOfWeek;
|
const path = storageKeys.firstDayOfWeek;
|
||||||
const content = this.storageModel.restoreStringifiable(path);
|
const content = this.storageModel.restoreStringifiable(path);
|
||||||
this.firstDayOfWeek == content ?? 0;
|
this.firstDayOfWeek = content ?? 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// init
|
// init
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
import * as React from "bloatless-react";
|
||||||
|
|
||||||
|
export function Option(text: string, value: string, selectedOnCreate: boolean) {
|
||||||
|
return (
|
||||||
|
<option value={value} toggle:selected={selectedOnCreate}>
|
||||||
|
{text}
|
||||||
|
</option>
|
||||||
|
);
|
||||||
|
}
|
||||||
+23
-7
@@ -2,9 +2,11 @@ import "./homePage.css";
|
|||||||
|
|
||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
|
||||||
|
import { Option } from "./Components/option";
|
||||||
|
import SettingsViewModel from "../ViewModel/settingsViewModel";
|
||||||
import { translations } from "./translations";
|
import { translations } from "./translations";
|
||||||
|
|
||||||
export function HomePage() {
|
export function HomePage(settingsViewModel: SettingsViewModel) {
|
||||||
// sections
|
// sections
|
||||||
const overviewSection = (
|
const overviewSection = (
|
||||||
<div id="overview-section">
|
<div id="overview-section">
|
||||||
@@ -45,9 +47,7 @@ export function HomePage() {
|
|||||||
<span class="icon">inbox</span>
|
<span class="icon">inbox</span>
|
||||||
<div>
|
<div>
|
||||||
<b>{translations.homePage.mailboxHeadline}</b>
|
<b>{translations.homePage.mailboxHeadline}</b>
|
||||||
<span class="error">
|
<span class="error">{translations.homePage.mailboxDisabled}</span>
|
||||||
{translations.homePage.mailboxDisabled}
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -67,11 +67,18 @@ export function HomePage() {
|
|||||||
<span class="icon">account_circle</span>
|
<span class="icon">account_circle</span>
|
||||||
<div>
|
<div>
|
||||||
<span>{translations.homePage.yourNameLabel}</span>
|
<span>{translations.homePage.yourNameLabel}</span>
|
||||||
<input></input>
|
<input
|
||||||
|
bind:value={settingsViewModel.nameInput}
|
||||||
|
on:enter={settingsViewModel.setName}
|
||||||
|
></input>
|
||||||
</div>
|
</div>
|
||||||
</label>
|
</label>
|
||||||
<div class="flex-row justify-end">
|
<div class="flex-row justify-end">
|
||||||
<button class="width-50">
|
<button
|
||||||
|
class="width-50"
|
||||||
|
on:click={settingsViewModel.setName}
|
||||||
|
toggle:disabled={settingsViewModel.cannotSetName}
|
||||||
|
>
|
||||||
{translations.homePage.setNameButton}
|
{translations.homePage.setNameButton}
|
||||||
<span class="icon">check</span>
|
<span class="icon">check</span>
|
||||||
</button>
|
</button>
|
||||||
@@ -83,7 +90,16 @@ export function HomePage() {
|
|||||||
<span class="icon">calendar_month</span>
|
<span class="icon">calendar_month</span>
|
||||||
<div>
|
<div>
|
||||||
<span>{translations.homePage.firstDayOfWeekLabel}</span>
|
<span>{translations.homePage.firstDayOfWeekLabel}</span>
|
||||||
<select></select>
|
<select bind:value={settingsViewModel.firstDayOfWeekInput}>
|
||||||
|
{...translations.regional.weekdays.full.map((weekdayName, i) =>
|
||||||
|
Option(
|
||||||
|
weekdayName,
|
||||||
|
i.toString(),
|
||||||
|
i == settingsViewModel.firstDayOfWeekInput.value
|
||||||
|
)
|
||||||
|
)}
|
||||||
|
</select>
|
||||||
|
<span class="icon">arrow_drop_down</span>
|
||||||
</div>
|
</div>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
import * as React from "bloatless-react";
|
||||||
|
|
||||||
|
import SettingsModel from "../Model/settingsModel";
|
||||||
|
|
||||||
|
export default class SettingsViewModel {
|
||||||
|
settingsModel: SettingsModel;
|
||||||
|
|
||||||
|
// state
|
||||||
|
nameInput: React.State<string> = new React.State("");
|
||||||
|
firstDayOfWeekInput: React.State<number> = new React.State(0);
|
||||||
|
|
||||||
|
// toggles
|
||||||
|
cannotSetName = React.createProxyState(
|
||||||
|
[this.nameInput],
|
||||||
|
() =>
|
||||||
|
this.nameInput.value == "" ||
|
||||||
|
this.nameInput.value == this.settingsModel.username
|
||||||
|
);
|
||||||
|
|
||||||
|
// set
|
||||||
|
setName = (): void => {
|
||||||
|
this.settingsModel.setName(this.nameInput.value);
|
||||||
|
this.nameInput.callSubscriptions();
|
||||||
|
};
|
||||||
|
|
||||||
|
setFirstDayofWeek = (): void => {
|
||||||
|
this.settingsModel.setFirstDayOfWeek(this.firstDayOfWeekInput.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
// init
|
||||||
|
constructor(settingsModel: SettingsModel) {
|
||||||
|
this.settingsModel = settingsModel;
|
||||||
|
|
||||||
|
this.nameInput.value = settingsModel.username;
|
||||||
|
this.firstDayOfWeekInput.value = settingsModel.firstDayOfWeek;
|
||||||
|
|
||||||
|
// subscriptions
|
||||||
|
this.firstDayOfWeekInput.subscribe(this.setFirstDayofWeek);
|
||||||
|
}
|
||||||
|
}
|
||||||
+7
-3
@@ -1,16 +1,20 @@
|
|||||||
import ConnectionModel from "./Model/connectionModel";
|
import ConnectionModel from "./Model/connectionModel";
|
||||||
import { HomePage } from "./View/homePage";
|
import { HomePage } from "./View/homePage";
|
||||||
import { MainPage } from "./View/mainPage";
|
import { MainPage } from "./View/mainPage";
|
||||||
|
import SettingsModel from "./Model/settingsModel";
|
||||||
|
import SettingsViewModel from "./ViewModel/settingsViewModel";
|
||||||
import StorageModel from "./Model/storageModel";
|
import StorageModel from "./Model/storageModel";
|
||||||
|
|
||||||
// models
|
// models
|
||||||
const storageModel = new StorageModel();
|
const storageModel = new StorageModel();
|
||||||
|
const settingsModel = new SettingsModel(storageModel);
|
||||||
const connectionModel = new ConnectionModel({
|
const connectionModel = new ConnectionModel({
|
||||||
connectionChangeHandler() {},
|
connectionChangeHandler() {},
|
||||||
messageHandler(data) {},
|
messageHandler(data) {},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// viewModels
|
||||||
|
const settingsViewModel = new SettingsViewModel(settingsModel);
|
||||||
|
|
||||||
// view
|
// view
|
||||||
document
|
document.querySelector("main")!.append(HomePage(settingsViewModel));
|
||||||
.querySelector("main")!
|
|
||||||
.append(HomePage());
|
|
||||||
|
|||||||
Reference in New Issue
Block a user