Files
CT/src/View/Modals/settingsModal.tsx
T

194 lines
6.2 KiB
TypeScript
Raw Normal View History

2026-04-08 20:39:12 +00:00
import * as React from "bloatless-react";
import { languageNames } from "../translations";
2026-04-08 21:03:36 +00:00
import SettingsViewModel, {
SettingsModalPages,
} from "../../ViewModel/Global/settingsViewModel";
2026-04-11 20:30:35 +00:00
import { SplitModal } from "./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";
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
2026-04-09 18:09:26 +00:00
import { Languages, ThemeSettings } from "../../Model/Global/settingsModel";
import { OptionButtonList } from "../Components/optionButtonList";
import { stringify } from "../../Model/Utility/utility";
2026-04-10 19:00:59 +00:00
import { PlaceholderView } from "../Components/placeholderView";
import { NavigationButton } from "../Components/navigationButton";
2026-04-08 20:39:12 +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) {
2026-04-10 19:00:59 +00:00
case undefined: {
return PlaceholderView(
coreViewModel.translations.general.noPageSelected,
);
}
2026-04-09 15:45:19 +00:00
case SettingsModalPages.Appearance:
2026-04-09 18:09:26 +00:00
return SettingsAppearancePane(
coreViewModel,
settingsViewModel,
);
2026-04-09 15:45:19 +00:00
case SettingsModalPages.Regional:
return SettingsRegionalPane(
coreViewModel,
settingsViewModel,
);
2026-04-09 15:45:19 +00:00
case SettingsModalPages.Info:
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-10 19:00:59 +00:00
coreViewModel,
new React.State(
SettingsLeftPane(coreViewModel, settingsViewModel),
),
2026-04-09 08:35:14 +00:00
detailView,
2026-04-09 21:45:56 +00:00
true,
2026-04-08 21:14:37 +00:00
settingsViewModel.selectedModalPage,
2026-04-08 21:03:36 +00:00
)}
</main>
2026-04-08 20:39:12 +00:00
<button on:click={settingsViewModel.hideSettingsModal}>
{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
function SettingsLeftPane(
coreViewModel: CoreViewModel,
settingsViewModel: SettingsViewModel,
) {
2026-04-08 21:03:36 +00:00
return (
2026-04-10 19:00:59 +00:00
<div class="flex-column gap slide-up">
<h2>{coreViewModel.translations.homePage.settingsButton}</h2>
2026-04-08 21:03:36 +00:00
{SettingsPaneButton(
coreViewModel,
2026-04-08 21:03:36 +00:00
settingsViewModel,
SettingsModalPages.Appearance,
coreViewModel.translations.settings.pages.appearance,
2026-04-08 21:03:36 +00:00
)}
{SettingsPaneButton(
coreViewModel,
2026-04-08 21:03:36 +00:00
settingsViewModel,
SettingsModalPages.Regional,
coreViewModel.translations.settings.pages.regional,
2026-04-08 21:03:36 +00:00
)}
2026-04-08 21:14:37 +00:00
{SettingsPaneButton(
coreViewModel,
2026-04-08 21:14:37 +00:00
settingsViewModel,
SettingsModalPages.Info,
coreViewModel.translations.settings.pages.info,
2026-04-08 21:14:37 +00:00
)}
2026-04-08 21:03:36 +00:00
</div>
);
}
function SettingsPaneButton(
coreViewModel: CoreViewModel,
2026-04-08 21:03:36 +00:00
settingsViewModel: SettingsViewModel,
page: SettingsModalPages,
label: string,
) {
return NavigationButton(
coreViewModel,
label,
settingsViewModel.selectedModalPage,
page,
2026-04-10 19:24:58 +00:00
true,
2026-04-08 21:03:36 +00:00
);
}
2026-04-09 15:45:19 +00:00
function SettingsInfoPane(
coreViewModel: CoreViewModel,
settingsViewModel: SettingsViewModel,
) {
2026-04-09 15:45:19 +00:00
return (
<div class="slide-up">
<h2>{coreViewModel.translations.homePage.appName}</h2>
2026-04-09 15:45:19 +00:00
<hr></hr>
<div class="flex-column gap">
{InfoTile(
"build",
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
function SettingsRegionalPane(
coreViewModel: CoreViewModel,
settingsViewModel: SettingsViewModel,
) {
2026-04-09 15:49:19 +00:00
return (
<div class="slide-up">
<h2>{coreViewModel.translations.settings.pages.regional}</h2>
2026-04-09 21:45:56 +00:00
2026-04-09 15:49:19 +00:00
<hr></hr>
2026-04-09 21:45:56 +00:00
<h3>{coreViewModel.translations.settings.language}</h3>
{OptionButtonList(
new React.ListState<[string, string]>(
2026-04-10 18:17:16 +00:00
Object.values(Languages).map((x) => [languageNames[x], x]),
2026-04-09 21:45:56 +00:00
),
settingsViewModel.language,
)}
<hr></hr>
<h3>{coreViewModel.translations.settings.firstDayOfWeekLabel}</h3>
{OptionButtonList(
new React.ListState<[string, string]>(
coreViewModel.translations.regional.weekdays.full.map(
(x, i) => [x, i.toString()],
),
),
settingsViewModel.firstDayOfWeek,
)}
2026-04-09 15:49:19 +00:00
</div>
);
}
2026-04-09 18:09:26 +00:00
function SettingsAppearancePane(
coreViewModel: CoreViewModel,
settingsViewModel: SettingsViewModel,
) {
return (
<div class="slide-up">
<h2>{coreViewModel.translations.settings.pages.appearance}</h2>
<hr></hr>
{OptionButtonList(
new React.ListState<[string, ThemeSettings]>([
[
coreViewModel.translations.settings.themes.dark,
ThemeSettings.Dark,
],
[
coreViewModel.translations.settings.themes.light,
ThemeSettings.Light,
],
[
coreViewModel.translations.settings.themes.system,
ThemeSettings.System,
],
]),
settingsViewModel.theme,
)}
</div>
);
}