2026-10-11 13:05:07 +03:00
|
|
|
import '../../l10n/strings.dart';
|
2026-10-11 14:54:43 +03:00
|
|
|
import '../../l10n/locales.dart';
|
2026-10-11 13:05:07 +03:00
|
|
|
import '../../mews/document.dart';
|
2026-10-11 14:24:06 +03:00
|
|
|
import '../fonts.dart';
|
2026-10-11 13:05:07 +03:00
|
|
|
import '../controllers/reader_settings_controller.dart'
|
|
|
|
|
show ReaderSettingsController;
|
|
|
|
|
import 'mews_urls.dart';
|
|
|
|
|
import 'page_blocks.dart';
|
|
|
|
|
|
|
|
|
|
/// Message ids for the values the controller accepts. Kept literal so every
|
|
|
|
|
/// id in the locale file can be found by searching for it.
|
|
|
|
|
const _themeLabels = {
|
|
|
|
|
'light': 'settings-theme-light',
|
|
|
|
|
'dark': 'settings-theme-dark',
|
|
|
|
|
'system': 'settings-theme-system',
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const _variantLabels = {
|
|
|
|
|
'site': 'settings-variant-site',
|
2026-10-11 22:32:44 +03:00
|
|
|
'host': 'settings-variant-host',
|
2026-10-11 13:05:07 +03:00
|
|
|
'warm': 'settings-variant-warm',
|
|
|
|
|
'cool': 'settings-variant-cool',
|
|
|
|
|
'green': 'settings-variant-green',
|
|
|
|
|
'mono': 'settings-variant-mono',
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Future<MewsPage> buildSettingsPage(
|
|
|
|
|
Uri url, {
|
|
|
|
|
required ReaderSettingsController settings,
|
|
|
|
|
required Strings strings,
|
|
|
|
|
}) async {
|
|
|
|
|
final title = strings.t('settings-page-title');
|
|
|
|
|
final scale = settings.fontScale.value;
|
|
|
|
|
|
|
|
|
|
return internalPage(
|
|
|
|
|
url: url,
|
|
|
|
|
title: title,
|
2026-10-11 14:54:43 +03:00
|
|
|
strings: strings,
|
2026-10-11 13:05:07 +03:00
|
|
|
body: [
|
|
|
|
|
...chrome(title: title, current: url, strings: strings),
|
|
|
|
|
HeadingBlock(2, [MewsText(strings.t('settings-font-heading'))]),
|
|
|
|
|
choiceRow([
|
2026-10-11 14:24:06 +03:00
|
|
|
for (final font in readerFonts)
|
2026-10-11 13:05:07 +03:00
|
|
|
(
|
|
|
|
|
href: MewsUrls.action('set-font', {'value': font.family}),
|
|
|
|
|
label: strings.t(font.labelId),
|
|
|
|
|
current: font.family == settings.font.value,
|
|
|
|
|
),
|
|
|
|
|
]),
|
|
|
|
|
// Text size steps between the controller's bounds, with the current
|
|
|
|
|
// value between the two steps.
|
|
|
|
|
HeadingBlock(2, [MewsText(strings.t('settings-size-heading'))]),
|
|
|
|
|
itemList([
|
|
|
|
|
if (scale > ReaderSettingsController.minScale)
|
|
|
|
|
MewsListItem([
|
|
|
|
|
ParagraphBlock([
|
|
|
|
|
MewsLink(MewsUrls.action('set-size', {'step': 'down'}),
|
|
|
|
|
[MewsText(strings.t('settings-size-decrease'))]),
|
|
|
|
|
]),
|
|
|
|
|
]),
|
|
|
|
|
MewsListItem([
|
|
|
|
|
ParagraphBlock([
|
|
|
|
|
MewsEmphasis(EmphasisStyle.strong, [
|
|
|
|
|
MewsText(strings.t('settings-size-value',
|
|
|
|
|
{'percent': (scale * 100).round()})),
|
|
|
|
|
]),
|
|
|
|
|
]),
|
|
|
|
|
]),
|
|
|
|
|
if (scale < ReaderSettingsController.maxScale)
|
|
|
|
|
MewsListItem([
|
|
|
|
|
ParagraphBlock([
|
|
|
|
|
MewsLink(MewsUrls.action('set-size', {'step': 'up'}),
|
|
|
|
|
[MewsText(strings.t('settings-size-increase'))]),
|
|
|
|
|
]),
|
|
|
|
|
]),
|
|
|
|
|
]),
|
|
|
|
|
HeadingBlock(2, [MewsText(strings.t('settings-theme-heading'))]),
|
|
|
|
|
choiceRow([
|
|
|
|
|
for (final mode in ReaderSettingsController.themeModes)
|
|
|
|
|
(
|
|
|
|
|
href: MewsUrls.action('set-theme', {'value': mode}),
|
|
|
|
|
label: strings.t(_themeLabels[mode]!),
|
|
|
|
|
current: mode == settings.themeMode.value,
|
|
|
|
|
),
|
|
|
|
|
]),
|
2026-10-11 14:54:43 +03:00
|
|
|
// The language a reader wants may not be the one they can currently
|
|
|
|
|
// read, so each is named in its own words.
|
|
|
|
|
HeadingBlock(2, [MewsText(strings.t('settings-language-heading'))]),
|
|
|
|
|
choiceRow([
|
|
|
|
|
(
|
|
|
|
|
href: MewsUrls.action('set-language', {'value': systemLanguage}),
|
|
|
|
|
label: strings.t('settings-language-system'),
|
|
|
|
|
current: settings.language.value == systemLanguage,
|
|
|
|
|
),
|
|
|
|
|
for (final locale in appLocales)
|
|
|
|
|
(
|
|
|
|
|
href: MewsUrls.action('set-language', {'value': locale.tag}),
|
|
|
|
|
label: strings.t(locale.labelId),
|
|
|
|
|
current: locale.tag == settings.language.value,
|
|
|
|
|
),
|
|
|
|
|
]),
|
2026-10-11 13:05:07 +03:00
|
|
|
HeadingBlock(2, [MewsText(strings.t('settings-variant-heading'))]),
|
|
|
|
|
choiceRow([
|
|
|
|
|
for (final variant in ReaderSettingsController.variants)
|
|
|
|
|
(
|
|
|
|
|
href: MewsUrls.action('set-colors', {'value': variant}),
|
|
|
|
|
label: strings.t(_variantLabels[variant]!),
|
|
|
|
|
current: variant == settings.variant.value,
|
|
|
|
|
),
|
|
|
|
|
]),
|
2026-10-11 22:07:25 +03:00
|
|
|
// Identities are their own page: a certificate is added from a file,
|
|
|
|
|
// which has no place among the presentation choices.
|
|
|
|
|
HeadingBlock(2, [MewsText(strings.t('settings-identities-heading'))]),
|
|
|
|
|
itemList([
|
|
|
|
|
MewsListItem([
|
|
|
|
|
ParagraphBlock([
|
|
|
|
|
MewsLink(MewsUrls.certificates, [
|
|
|
|
|
MewsText(strings.t('certificates-title')),
|
|
|
|
|
]),
|
|
|
|
|
]),
|
|
|
|
|
]),
|
|
|
|
|
]),
|
2026-10-11 13:05:07 +03:00
|
|
|
],
|
|
|
|
|
);
|
|
|
|
|
}
|