diff --git a/examples/demo/Assets/Resources/Theme.uss b/examples/demo/Assets/Resources/Theme.uss index ba6b937c..56ee5ba5 100644 --- a/examples/demo/Assets/Resources/Theme.uss +++ b/examples/demo/Assets/Resources/Theme.uss @@ -493,6 +493,35 @@ color: #34A853; } +.language-dropdown-icon { + font-size: 18px; + color: var(--os-grey-600); + margin-left: 4px; +} + +.language-option-list { + max-height: 360px; +} + +.language-option { + flex-direction: row; + align-items: center; + min-height: 44px; +} + +.language-option-label { + flex-grow: 1; +} + +.language-option--selected .language-option-label { + color: var(--os-primary); +} + +.language-option-check { + font-size: 18px; + color: var(--os-primary); +} + .guidance-banner { background-color: var(--os-warning-background); } diff --git a/examples/demo/Assets/Scripts/Services/PreferencesService.cs b/examples/demo/Assets/Scripts/Services/PreferencesService.cs index bf77bfc4..dbf7409d 100644 --- a/examples/demo/Assets/Scripts/Services/PreferencesService.cs +++ b/examples/demo/Assets/Scripts/Services/PreferencesService.cs @@ -9,6 +9,7 @@ public class PreferencesService private const string KeyExternalUserId = "external_user_id"; private const string KeyLocationShared = "location_shared"; private const string KeyIamPaused = "iam_paused"; + private const string KeyLanguage = "language"; public bool ConsentRequired { @@ -40,6 +41,12 @@ public bool IamPaused set => SetBool(KeyIamPaused, value); } + public string Language + { + get => GetString(KeyLanguage, ""); + set => SetString(KeyLanguage, value); + } + private bool GetBool(string key, bool defaultValue) => PlayerPrefs.GetInt(key, defaultValue ? 1 : 0) == 1; diff --git a/examples/demo/Assets/Scripts/UI/Dialogs/LanguagePickerDialog.cs b/examples/demo/Assets/Scripts/UI/Dialogs/LanguagePickerDialog.cs new file mode 100644 index 00000000..138591ed --- /dev/null +++ b/examples/demo/Assets/Scripts/UI/Dialogs/LanguagePickerDialog.cs @@ -0,0 +1,78 @@ +using System; +using System.Collections.Generic; +using OneSignalDemo.Services; +using UnityEngine.UIElements; + +namespace OneSignalDemo.UI.Dialogs +{ + public class LanguagePickerDialog : DialogBase + { + private readonly IReadOnlyList> _options; + private readonly string _selectedCode; + private readonly Action _onSelected; + + /// Display name to language code pairs. + public LanguagePickerDialog( + IReadOnlyList> options, + string selectedCode, + Action onSelected + ) + { + _options = options; + _selectedCode = selectedCode ?? ""; + _onSelected = onSelected; + } + + protected override void BuildContent(VisualElement container) + { + var title = new Label("Language"); + title.AddToClassList("dialog-title"); + title.AddToClassList("text-dialog-title"); + container.Add(title); + + var list = new ScrollView(ScrollViewMode.Vertical); + list.name = "language_option_list"; + list.AddToClassList("language-option-list"); + + foreach (var option in _options) + { + var code = option.Value; + var row = new VisualElement(); + row.name = $"language_option_{(code.Length == 0 ? "default" : code)}"; + row.AddToClassList("language-option"); + + var label = new Label(option.Key); + label.AddToClassList("language-option-label"); + label.AddToClassList("text-card-label"); + row.Add(label); + + if (code == _selectedCode) + { + row.AddToClassList("language-option--selected"); + var check = new Label(MaterialIcons.Check); + check.AddToClassList("material-icon"); + check.AddToClassList("language-option-check"); + row.Add(check); + } + + void Select() => OnSelected(code); + row.AddManipulator(new Clickable(Select)); + AccessibilityBridge.RegisterE2ETapTarget(row, () => true, Select); + list.Add(row); + } + + container.Add(list); + + var actions = new VisualElement(); + actions.AddToClassList("dialog-actions"); + actions.Add(CreateCancelButton()); + container.Add(actions); + } + + private void OnSelected(string code) + { + _onSelected?.Invoke(code); + Dismiss(); + } + } +} diff --git a/examples/demo/Assets/Scripts/UI/Dialogs/LanguagePickerDialog.cs.meta b/examples/demo/Assets/Scripts/UI/Dialogs/LanguagePickerDialog.cs.meta new file mode 100644 index 00000000..c6d9e76b --- /dev/null +++ b/examples/demo/Assets/Scripts/UI/Dialogs/LanguagePickerDialog.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: e571aa67f2c84f85b3910f12b251117f diff --git a/examples/demo/Assets/Scripts/UI/MaterialIcons.cs b/examples/demo/Assets/Scripts/UI/MaterialIcons.cs index ff4bfc36..7186b5e2 100644 --- a/examples/demo/Assets/Scripts/UI/MaterialIcons.cs +++ b/examples/demo/Assets/Scripts/UI/MaterialIcons.cs @@ -16,5 +16,6 @@ public static class MaterialIcons public const string Fullscreen = "\uE5D0"; public const string ExpandMore = "\uE5CF"; public const string ExpandLess = "\uE5CE"; + public const string Check = "\uE5CA"; } } diff --git a/examples/demo/Assets/Scripts/UI/Sections/PushSectionController.cs b/examples/demo/Assets/Scripts/UI/Sections/PushSectionController.cs index d9f314d0..a68d7254 100644 --- a/examples/demo/Assets/Scripts/UI/Sections/PushSectionController.cs +++ b/examples/demo/Assets/Scripts/UI/Sections/PushSectionController.cs @@ -10,6 +10,7 @@ public class PushSectionController private readonly AppViewModel _viewModel; private readonly VisualElement _root; private Label _pushIdLabel; + private Label _statusLabel; private SwitchToggle _enabledToggle; private Button _promptButton; @@ -43,8 +44,18 @@ private VisualElement BuildSection() card.Add(SectionBuilder.CreateDivider()); + var statusRow = SectionBuilder.CreateInlineKeyValue( + "Status", + FormatStatus(_viewModel.IsPushSubscribed), + "push_subscription_status" + ); + _statusLabel = statusRow.Q