Skip to content

[BEEEP] [PS-940] Support for dark theme selection while using Default (System) theme#1959

Merged
mpbw2 merged 2 commits intomasterfrom
feature-autodarkthemeselect
Jun 21, 2022
Merged

[BEEEP] [PS-940] Support for dark theme selection while using Default (System) theme#1959
mpbw2 merged 2 commits intomasterfrom
feature-autodarkthemeselect

Conversation

@mpbw2
Copy link
Contributor

@mpbw2 mpbw2 commented Jun 17, 2022

Type of change

  • Bug fix
  • New feature development
  • Tech debt (refactoring, code cleanup, dependency upgrades, etc)
  • Build/deploy pipeline (DevOps)
  • Other

Objective

Now you can select which dark theme to use when using the Default (System) (automatic light/dark) theme. (Previously only the "Dark" theme was used).

When Default (System) is the selected theme, a new Default Dark Theme option appears immediately below the Theme option. It defaults to "Dark" but allows "Black" and "Nord" to be selected as well. When the device/OS is in dark mode, the selected dark theme becomes active. This section is only visible while the Default (System) theme is selected.

Code changes

  • OptionsPage.xaml/cs/ViewModel: Added the UI & selection control logic for the Options screen within Settings
  • ThemeManager.cs: Added autoDarkTheme arg & logic
  • StateService.cs: Added get/save methods for AutoDarkTheme
  • Constants.cs: Added AutoDarkThemeKey for storage

Screenshots

System/OS in light mode with Default (System) theme & custom default dark themes selected:

01

System/OS in dark mode with Default (System) theme & custom default dark themes selected:

02

Light & dark themes selected, Default Dark Theme section not visible

03

Before you submit

  • I have checked for formatting errors (dotnet tool run dotnet-format --check) (required)
  • I have added unit tests where it makes sense to do so (encouraged but not required)
  • This change requires a documentation update (notify the documentation team)
  • This change has particular deployment requirements (notify the DevOps team)

@mpbw2 mpbw2 requested review from a team, andrebispo5, fedemkr and vvolkgang June 17, 2022 19:00
@mpbw2 mpbw2 changed the title [BEEEP] Support for dark theme selection while using Default (System) theme [BEEEP] [PS-940] Support for dark theme selection while using Default (System) theme Jun 17, 2022
_vm = BindingContext as OptionsPageViewModel;
_vm.Page = this;
_themePicker.ItemDisplayBinding = new Binding("Value");
_autoDarkThemePicker.ItemDisplayBinding = new Binding("Value");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe I'm unaware of some issue but wouldn't it be possible to put the binding on the xaml page? (as well as the others)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tbh I'm not sure - I'm following the established pattern since we're going to rebuild Settings at some point anyway and I didn't want to create new issues before then.

else
{
_themePicker.On<iOS>().SetUpdateMode(UpdateMode.WhenFinished);
_autoDarkThemePicker.On<iOS>().SetUpdateMode(UpdateMode.WhenFinished);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The On<iOS> here is redundant to put it on the else (given that we only have Android and iOS as platforms).
We could just remove the else and let the code be there as is, or remove the On<iOS>. (I'd just remove the else). BTW, this can also be done on xaml if we'd want to here the how to.
Maybe we should look into all the places where it's used; but we could just add a custom control CustomPicker or something like that, that we can use to set this update mode by default and just use it like that. I see that there are a lot of places where this is being set up. Also, we could you the CustomPickerRenderer of iOS to set this up as well globally. But we need to be careful maybe there are some specific places where we don't want update mode when finished.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment here (following existing pattern for safety/sanity until we rebuild Settings)

Comment on lines +62 to +67
AutoDarkThemeOptions = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("dark", AppResources.Dark),
new KeyValuePair<string, string>("black", AppResources.Black),
new KeyValuePair<string, string>("nord", "Nord"),
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should use Tuple instead of KeyValuePair here you have a gist with performance comparison. There are some caveats regarding allocation where KeyValuePair is better but in this case we don't care much given that there are just a few items.
It doesn't matter much with these few items but I also think it's more readable with Tuples.
What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

KeyValuePair seems more appropriate to me here since that's what the values are, vs Tuple which doesn't suggest a relation among the values. If the data set was larger maybe it would be worth the change, but as is I don't see the benefit.

additionalPropertyNames: new[] { nameof(ShowAutoDarkThemeOptions) })
)
{
var task = SaveThemeAsync();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here there's no need to assign the returned Task to a variable. And I've checked there's no try catch on SaveThemeAsync so if any exceptions are raised are going to be swollen by the Task. So either we add the try catch or just call fire and forget here: SaveThemeAsync().FireAndForget() (just be careful if it switches to a background thread and maybe when calling it and there are things on SaveThemeAsync that may need to be marshalled to the Main thread, so test it a few times just in case)

DisableFavicon = (await _stateService.GetDisableFaviconAsync()).GetValueOrDefault();
var theme = await _stateService.GetThemeAsync();
ThemeSelectedIndex = ThemeOptions.FindIndex(k => k.Key == theme);
var autoDarkTheme = await _stateService.GetAutoDarkThemeAsync() ?? "dark";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd really like if theme strings (like "dark", "nord", and so on) would be consts (or an Enum even better) in ThemeManager that can be referenced. So that there is less chance of misspelling and if for some reason we change any of them it's easier to replace.
Maybe not for this PR, but we should keep this in mind.
What do you think?

Comment on lines +233 to +234
var autoDarkTheme = AutoDarkThemeOptions[AutoDarkThemeSelectedIndex].Key;
await _stateService.SetAutoDarkThemeAsync(autoDarkTheme);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we inline these?

await _stateService.SetAutoDarkThemeAsync(AutoDarkThemeOptions[AutoDarkThemeSelectedIndex].Key);

Or is it too long?

Comment on lines +1544 to +1546
<data name="AutoDarkTheme" xml:space="preserve">
<value>Default Dark Theme</value>
</data>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO, resource strings keys should be the same (when not too long) as the value to be easier to read in the code without the need to go to the resx file to check what is the value. So here I'd use DefaultDarkTheme as the key.
Furthermore if for some reason in the future we have a value "Auto Dark Theme" we couldn't use the key as it'd be used here.

Comment on lines +1547 to +1549
<data name="AutoDarkThemeDescription" xml:space="preserve">
<value>Choose the dark theme to use when using Default (System) theme while your device's dark mode is enabled</value>
</data>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even though, here I think it's ok to have a key like this, if we change the above this should change to DefaultDarkThemeDescription

@mpbw2 mpbw2 requested a review from fedemkr June 21, 2022 18:38
@mpbw2 mpbw2 merged commit 109aeb4 into master Jun 21, 2022
@mpbw2 mpbw2 deleted the feature-autodarkthemeselect branch June 21, 2022 18:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants