2026-04-08 20:39:12 +00:00
|
|
|
import * as React from "bloatless-react";
|
|
|
|
|
|
2026-04-09 16:48:22 +00:00
|
|
|
import { Languages } from "../translations";
|
2026-04-08 21:03:36 +00:00
|
|
|
import SettingsViewModel, {
|
|
|
|
|
SettingsModalPages,
|
|
|
|
|
} from "../../ViewModel/Global/settingsViewModel";
|
|
|
|
|
import { SplitModal } from "../Components/splitModal";
|
2026-04-09 15:45:19 +00:00
|
|
|
import { InfoTile } from "../Components/infoTile";
|
2026-04-09 15:49:19 +00:00
|
|
|
import { Option } from "../Components/option";
|
2026-04-09 16:48:22 +00:00
|
|
|
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
|
2026-04-08 20:39:12 +00:00
|
|
|
|
2026-04-09 16:48:22 +00:00
|
|
|
export function SettingsModal(
|
|
|
|
|
coreViewModel: CoreViewModel,
|
|
|
|
|
settingsViewModel: SettingsViewModel,
|
|
|
|
|
) {
|
2026-04-09 15:45:19 +00:00
|
|
|
const detailView = React.createProxyState(
|
|
|
|
|
[settingsViewModel.selectedModalPage],
|
|
|
|
|
() => {
|
|
|
|
|
switch (settingsViewModel.selectedModalPage.value) {
|
|
|
|
|
case SettingsModalPages.Appearance:
|
|
|
|
|
return <div>Appearance</div>;
|
|
|
|
|
case SettingsModalPages.Regional:
|
2026-04-09 16:48:22 +00:00
|
|
|
return SettingsRegionalPane(
|
|
|
|
|
coreViewModel,
|
|
|
|
|
settingsViewModel,
|
|
|
|
|
);
|
2026-04-09 15:45:19 +00:00
|
|
|
case SettingsModalPages.Info:
|
2026-04-09 16:48:22 +00:00
|
|
|
return SettingsInfoPane(coreViewModel, settingsViewModel);
|
2026-04-09 15:45:19 +00:00
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
);
|
2026-04-09 08:35:14 +00:00
|
|
|
|
2026-04-08 20:39:12 +00:00
|
|
|
return (
|
2026-04-08 21:03:36 +00:00
|
|
|
<div
|
|
|
|
|
class="modal"
|
|
|
|
|
toggle:open={settingsViewModel.isShowingSettingsModal}
|
|
|
|
|
>
|
2026-04-08 21:14:37 +00:00
|
|
|
<div>
|
2026-04-08 21:03:36 +00:00
|
|
|
<main class="padding-0">
|
|
|
|
|
{SplitModal(
|
2026-04-09 16:48:22 +00:00
|
|
|
new React.State(
|
|
|
|
|
SettingsLeftPane(coreViewModel, settingsViewModel),
|
|
|
|
|
),
|
2026-04-09 08:35:14 +00:00
|
|
|
detailView,
|
2026-04-08 21:03:36 +00:00
|
|
|
new React.State(""),
|
2026-04-08 21:14:37 +00:00
|
|
|
false,
|
|
|
|
|
settingsViewModel.selectedModalPage,
|
2026-04-08 21:03:36 +00:00
|
|
|
)}
|
|
|
|
|
</main>
|
2026-04-08 20:39:12 +00:00
|
|
|
<button on:click={settingsViewModel.hideSettingsModal}>
|
2026-04-09 16:48:22 +00:00
|
|
|
{coreViewModel.translations.general.closeButton}
|
2026-04-08 20:39:12 +00:00
|
|
|
<span class="icon">close</span>
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|
2026-04-08 21:03:36 +00:00
|
|
|
|
2026-04-09 16:48:22 +00:00
|
|
|
function SettingsLeftPane(
|
|
|
|
|
coreViewModel: CoreViewModel,
|
|
|
|
|
settingsViewModel: SettingsViewModel,
|
|
|
|
|
) {
|
2026-04-08 21:03:36 +00:00
|
|
|
return (
|
2026-04-08 21:14:37 +00:00
|
|
|
<div class="flex-column gap">
|
2026-04-08 21:03:36 +00:00
|
|
|
{SettingsPaneButton(
|
|
|
|
|
settingsViewModel,
|
|
|
|
|
SettingsModalPages.Appearance,
|
2026-04-09 16:48:22 +00:00
|
|
|
coreViewModel.translations.settings.pages.appearance,
|
2026-04-08 21:03:36 +00:00
|
|
|
)}
|
|
|
|
|
{SettingsPaneButton(
|
|
|
|
|
settingsViewModel,
|
|
|
|
|
SettingsModalPages.Regional,
|
2026-04-09 16:48:22 +00:00
|
|
|
coreViewModel.translations.settings.pages.regional,
|
2026-04-08 21:03:36 +00:00
|
|
|
)}
|
2026-04-08 21:14:37 +00:00
|
|
|
{SettingsPaneButton(
|
|
|
|
|
settingsViewModel,
|
|
|
|
|
SettingsModalPages.Info,
|
2026-04-09 16:48:22 +00:00
|
|
|
coreViewModel.translations.settings.pages.info,
|
2026-04-08 21:14:37 +00:00
|
|
|
)}
|
2026-04-08 21:03:36 +00:00
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function SettingsPaneButton(
|
|
|
|
|
settingsViewModel: SettingsViewModel,
|
|
|
|
|
page: SettingsModalPages,
|
|
|
|
|
label: string,
|
|
|
|
|
) {
|
|
|
|
|
const isSelected = React.createProxyState(
|
|
|
|
|
[settingsViewModel.selectedModalPage],
|
|
|
|
|
() => settingsViewModel.selectedModalPage.value == page,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<button
|
|
|
|
|
toggle:selected={isSelected}
|
|
|
|
|
on:click={() => settingsViewModel.showModalPage(page)}
|
|
|
|
|
>
|
|
|
|
|
{label}
|
|
|
|
|
</button>
|
|
|
|
|
);
|
|
|
|
|
}
|
2026-04-09 15:45:19 +00:00
|
|
|
|
2026-04-09 16:48:22 +00:00
|
|
|
function SettingsInfoPane(
|
|
|
|
|
coreViewModel: CoreViewModel,
|
|
|
|
|
settingsViewModel: SettingsViewModel,
|
|
|
|
|
) {
|
2026-04-09 15:45:19 +00:00
|
|
|
return (
|
|
|
|
|
<div class="slide-up">
|
2026-04-09 16:48:22 +00:00
|
|
|
<h2>{coreViewModel.translations.homePage.appName}</h2>
|
2026-04-09 15:45:19 +00:00
|
|
|
<hr></hr>
|
|
|
|
|
<div class="flex-column gap">
|
|
|
|
|
{InfoTile(
|
|
|
|
|
"build",
|
2026-04-09 16:48:22 +00:00
|
|
|
coreViewModel.translations.settings.version,
|
2026-04-09 15:45:19 +00:00
|
|
|
settingsViewModel.coreViewModel.BUILD,
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|
2026-04-09 15:49:19 +00:00
|
|
|
|
2026-04-09 16:48:22 +00:00
|
|
|
function SettingsRegionalPane(
|
|
|
|
|
coreViewModel: CoreViewModel,
|
|
|
|
|
settingsViewModel: SettingsViewModel,
|
|
|
|
|
) {
|
2026-04-09 15:49:19 +00:00
|
|
|
return (
|
|
|
|
|
<div class="slide-up">
|
2026-04-09 16:48:22 +00:00
|
|
|
<h2>{coreViewModel.translations.settings.pages.regional}</h2>
|
2026-04-09 15:49:19 +00:00
|
|
|
<hr></hr>
|
|
|
|
|
<label class="tile flex-no">
|
|
|
|
|
<span class="icon">calendar_month</span>
|
|
|
|
|
<div>
|
2026-04-09 16:48:22 +00:00
|
|
|
<span>
|
|
|
|
|
{
|
|
|
|
|
coreViewModel.translations.settings
|
|
|
|
|
.firstDayOfWeekLabel
|
|
|
|
|
}
|
|
|
|
|
</span>
|
|
|
|
|
<select bind:value={settingsViewModel.firstDayOfWeek}>
|
|
|
|
|
{...coreViewModel.translations.regional.weekdays.full.map(
|
2026-04-09 15:49:19 +00:00
|
|
|
(weekdayName, i) =>
|
|
|
|
|
Option(
|
|
|
|
|
weekdayName,
|
|
|
|
|
i.toString(),
|
|
|
|
|
i.toString() ==
|
2026-04-09 16:48:22 +00:00
|
|
|
settingsViewModel.firstDayOfWeek.value,
|
2026-04-09 15:49:19 +00:00
|
|
|
),
|
|
|
|
|
)}
|
|
|
|
|
</select>
|
|
|
|
|
<span class="icon">arrow_drop_down</span>
|
|
|
|
|
</div>
|
|
|
|
|
</label>
|
2026-04-09 16:48:22 +00:00
|
|
|
<label class="tile flex-no">
|
|
|
|
|
<span class="icon">language</span>
|
|
|
|
|
<div>
|
|
|
|
|
<span>{coreViewModel.translations.settings.language}</span>
|
|
|
|
|
<select bind:value={settingsViewModel.language}>
|
|
|
|
|
{...[...Object.values(Languages)].map((language, i) =>
|
|
|
|
|
Option(
|
|
|
|
|
language,
|
|
|
|
|
i.toString(),
|
|
|
|
|
i.toString() ==
|
|
|
|
|
settingsViewModel.language.value,
|
|
|
|
|
),
|
|
|
|
|
)}
|
|
|
|
|
</select>
|
|
|
|
|
<span class="icon">arrow_drop_down</span>
|
|
|
|
|
</div>
|
|
|
|
|
</label>
|
2026-04-09 15:49:19 +00:00
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|