diff --git a/.cursor/rules/pr-conventions.mdc b/.cursor/rules/pr-conventions.mdc
new file mode 100644
index 00000000..cd953b17
--- /dev/null
+++ b/.cursor/rules/pr-conventions.mdc
@@ -0,0 +1,32 @@
+---
+description: Conventions for pull request titles and body content
+alwaysApply: true
+---
+
+# Pull Request Conventions
+
+## PR Title
+
+Use semantic/conventional commit prefixes in PR titles:
+
+- `fix:` for bug fixes
+- `feat:` for new features
+- `chore:` for maintenance tasks (deps, CI, tooling)
+- `refactor:` for code restructuring without behavior changes
+- `docs:` for documentation-only changes
+- `test:` for test-only changes
+
+Example: `fix: resolve notification grouping on Android 14`
+
+## PR Body
+
+Follow the repo's PR template at `.github/pull_request_template.md`. Every PR body must include:
+
+1. **One Line Summary** (required)
+2. **Motivation** (required) explaining why the change is being made
+3. **Scope** (recommended) describing what is and isn't affected
+4. **Testing** section with manual and/or unit testing details
+5. **Affected code checklist** with relevant items checked
+6. **Checklist** sections confirmed
+
+Remove the instructional header block (between `` and ``) before submitting.
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 00000000..65156fae
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,21 @@
+name: Run Checks
+permissions:
+ contents: read
+on:
+ pull_request:
+ branches:
+ - "**"
+
+jobs:
+ test:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v5
+
+ - name: Install CSharpier
+ run: dotnet tool install -g csharpier
+
+ - name: Check formatting
+ run: csharpier check .
diff --git a/OneSignalSDK.DotNet.Android.Core.Binding/OneSignalSDK.DotNet.Android.Core.Binding.csproj b/OneSignalSDK.DotNet.Android.Core.Binding/OneSignalSDK.DotNet.Android.Core.Binding.csproj
index df2cc30f..e0272fee 100644
--- a/OneSignalSDK.DotNet.Android.Core.Binding/OneSignalSDK.DotNet.Android.Core.Binding.csproj
+++ b/OneSignalSDK.DotNet.Android.Core.Binding/OneSignalSDK.DotNet.Android.Core.Binding.csproj
@@ -11,7 +11,9 @@
Resources
Assets
OneSignalSDK.DotNet.Android.Core.Binding
- 28.0.3
+ 28.0.3
class-parse
@@ -57,4 +59,4 @@
-
\ No newline at end of file
+
diff --git a/OneSignalSDK.DotNet.Android.Core.Binding/Transforms/EnumFields.xml b/OneSignalSDK.DotNet.Android.Core.Binding/Transforms/EnumFields.xml
index e9af0eeb..e5ec0a0c 100755
--- a/OneSignalSDK.DotNet.Android.Core.Binding/Transforms/EnumFields.xml
+++ b/OneSignalSDK.DotNet.Android.Core.Binding/Transforms/EnumFields.xml
@@ -1,5 +1,5 @@
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
-
-
-
+
+
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
diff --git a/examples/demo/Controls/LogView.xaml.cs b/examples/demo/Controls/LogView.xaml.cs
index 2c1a66d1..4908173e 100644
--- a/examples/demo/Controls/LogView.xaml.cs
+++ b/examples/demo/Controls/LogView.xaml.cs
@@ -1,5 +1,5 @@
-using MauiIcons.Material;
using MauiIcons.Core;
+using MauiIcons.Material;
using OneSignalDemo.Services;
namespace OneSignalDemo.Controls;
@@ -43,7 +43,7 @@ private void RebuildLogList()
FontSize = 11,
FontFamily = "DroidSansMono",
VerticalOptions = LayoutOptions.Center,
- AutomationId = $"log_entry_{i}_timestamp"
+ AutomationId = $"log_entry_{i}_timestamp",
};
var level = new Label
{
@@ -54,7 +54,7 @@ private void RebuildLogList()
FontAttributes = FontAttributes.Bold,
VerticalOptions = LayoutOptions.Center,
Margin = new Thickness(4, 0),
- AutomationId = $"log_entry_{i}_level"
+ AutomationId = $"log_entry_{i}_level",
};
var msg = new Label
{
@@ -63,7 +63,7 @@ private void RebuildLogList()
FontSize = 11,
FontFamily = "DroidSansMono",
VerticalOptions = LayoutOptions.Center,
- AutomationId = $"log_entry_{i}_message"
+ AutomationId = $"log_entry_{i}_message",
};
row.Children.Add(ts);
diff --git a/examples/demo/Controls/MultiPairDialogHelper.cs b/examples/demo/Controls/MultiPairDialogHelper.cs
index 78945a25..2c77804a 100644
--- a/examples/demo/Controls/MultiPairDialogHelper.cs
+++ b/examples/demo/Controls/MultiPairDialogHelper.cs
@@ -163,13 +163,21 @@ IEnumerable keys
var row = new HorizontalStackLayout { Spacing = 8 };
row.Children.Add(cb);
row.Children.Add(
- new Label { Text = key, VerticalOptions = LayoutOptions.Center, FontSize = 14 }
+ new Label
+ {
+ Text = key,
+ VerticalOptions = LayoutOptions.Center,
+ FontSize = 14,
+ }
);
itemsLayout.Children.Add(row);
}
var cancelButton = DialogInputHelper.ActionButton("Cancel", "multi_select_cancel_button");
- var removeButton = DialogInputHelper.ActionButtonDisabled("Remove (0)", "multi_select_remove_button");
+ var removeButton = DialogInputHelper.ActionButtonDisabled(
+ "Remove (0)",
+ "multi_select_remove_button"
+ );
void UpdateButton()
{
@@ -185,10 +193,7 @@ void UpdateButton()
removeButton.Clicked += async (s, e) =>
{
- var selected = checkboxes
- .Where(c => c.Box.IsChecked)
- .Select(c => c.Key)
- .ToList();
+ var selected = checkboxes.Where(c => c.Box.IsChecked).Select(c => c.Key).ToList();
await parentPage.ClosePopupAsync(selected);
};
@@ -217,7 +222,10 @@ void UpdateButton()
},
};
- var result = await parentPage.ShowPopupAsync>(content, DialogInputHelper.DialogOptions);
+ var result = await parentPage.ShowPopupAsync>(
+ content,
+ DialogInputHelper.DialogOptions
+ );
return result?.Result;
}
}
diff --git a/examples/demo/Controls/Sections/AliasesSection.xaml b/examples/demo/Controls/Sections/AliasesSection.xaml
index 9383bee8..89c9d5bb 100644
--- a/examples/demo/Controls/Sections/AliasesSection.xaml
+++ b/examples/demo/Controls/Sections/AliasesSection.xaml
@@ -1,29 +1,52 @@
+ xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
+ xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
+ xmlns:mi="http://www.aathifmahir.com/dotnet/2022/maui/icons"
+ x:Class="OneSignalDemo.Controls.Sections.AliasesSection"
+>
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
diff --git a/examples/demo/Controls/Sections/AliasesSection.xaml.cs b/examples/demo/Controls/Sections/AliasesSection.xaml.cs
index 91673aea..177135ce 100644
--- a/examples/demo/Controls/Sections/AliasesSection.xaml.cs
+++ b/examples/demo/Controls/Sections/AliasesSection.xaml.cs
@@ -43,31 +43,27 @@ private void RebuildList()
{
if (!first)
{
- AliasListContainer.Children.Add(new BoxView
- {
- HeightRequest = 1,
- Color = Color.FromArgb("#E8EAED"),
- Margin = new Thickness(12, 0)
- });
+ AliasListContainer.Children.Add(
+ new BoxView
+ {
+ HeightRequest = 1,
+ Color = Color.FromArgb("#E8EAED"),
+ Margin = new Thickness(12, 0),
+ }
+ );
}
first = false;
- var row = new VerticalStackLayout
- {
- Padding = new Thickness(12, 4),
- Spacing = 2
- };
- row.Children.Add(new Label
- {
- Text = alias.Key,
- FontSize = 14,
- });
- row.Children.Add(new Label
- {
- Text = alias.Value,
- FontSize = 12,
- TextColor = Color.FromArgb("#757575")
- });
+ var row = new VerticalStackLayout { Padding = new Thickness(12, 4), Spacing = 2 };
+ row.Children.Add(new Label { Text = alias.Key, FontSize = 14 });
+ row.Children.Add(
+ new Label
+ {
+ Text = alias.Value,
+ FontSize = 12,
+ TextColor = Color.FromArgb("#757575"),
+ }
+ );
AliasListContainer.Children.Add(row);
}
@@ -75,13 +71,24 @@ private void RebuildList()
private async void OnAddClicked(object? sender, EventArgs e)
{
- if (_parentPage == null || _viewModel == null) return;
+ if (_parentPage == null || _viewModel == null)
+ return;
var form = await DialogInputHelper.ShowPairInput(
_parentPage,
"Add Alias",
- new DialogInputField { Key = "label", Placeholder = "Label", AutomationId = "alias_label_input" },
- new DialogInputField { Key = "id", Placeholder = "ID", AutomationId = "alias_id_input" },
+ new DialogInputField
+ {
+ Key = "label",
+ Placeholder = "Label",
+ AutomationId = "alias_label_input",
+ },
+ new DialogInputField
+ {
+ Key = "id",
+ Placeholder = "ID",
+ AutomationId = "alias_id_input",
+ },
"Add"
);
@@ -100,17 +107,24 @@ private async void OnAddClicked(object? sender, EventArgs e)
private async void OnAddMultipleClicked(object? sender, EventArgs e)
{
- if (_parentPage == null || _viewModel == null) return;
+ if (_parentPage == null || _viewModel == null)
+ return;
var pairs = await ShowMultiPairDialog("Add Multiple Aliases", "Label", "ID");
- if (pairs == null || pairs.Count == 0) return;
+ if (pairs == null || pairs.Count == 0)
+ return;
_viewModel.AddAliases(pairs);
await Toast.Make($"{pairs.Count} alias(es) added", ToastDuration.Short).Show();
}
- private async Task?> ShowMultiPairDialog(string title, string keyLabel, string valueLabel)
+ private async Task?> ShowMultiPairDialog(
+ string title,
+ string keyLabel,
+ string valueLabel
+ )
{
- if (_parentPage == null) return null;
+ if (_parentPage == null)
+ return null;
return await MultiPairDialogHelper.Show(_parentPage, title, keyLabel, valueLabel);
}
diff --git a/examples/demo/Controls/Sections/AppSection.xaml b/examples/demo/Controls/Sections/AppSection.xaml
index 4cb58825..d3b9326e 100644
--- a/examples/demo/Controls/Sections/AppSection.xaml
+++ b/examples/demo/Controls/Sections/AppSection.xaml
@@ -1,72 +1,108 @@
+ xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
+ xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
+ x:Class="OneSignalDemo.Controls.Sections.AppSection"
+ x:Name="root"
+>
+
+
+
-
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/demo/Controls/Sections/AppSection.xaml.cs b/examples/demo/Controls/Sections/AppSection.xaml.cs
index add89567..73dc711b 100644
--- a/examples/demo/Controls/Sections/AppSection.xaml.cs
+++ b/examples/demo/Controls/Sections/AppSection.xaml.cs
@@ -51,14 +51,16 @@ private void UpdatePrivacyConsentVisibility(bool consentRequired)
private void OnConsentRequiredToggled(object? sender, ToggledEventArgs e)
{
- if (_suppressToggle) return;
+ if (_suppressToggle)
+ return;
_viewModel?.SetConsentRequired(e.Value);
UpdatePrivacyConsentVisibility(e.Value);
}
private void OnPrivacyConsentToggled(object? sender, ToggledEventArgs e)
{
- if (_suppressToggle) return;
+ if (_suppressToggle)
+ return;
_viewModel?.SetConsentGiven(e.Value);
}
diff --git a/examples/demo/Controls/Sections/EmailsSection.xaml b/examples/demo/Controls/Sections/EmailsSection.xaml
index 7c99db40..23b468cb 100644
--- a/examples/demo/Controls/Sections/EmailsSection.xaml
+++ b/examples/demo/Controls/Sections/EmailsSection.xaml
@@ -1,27 +1,46 @@
+ xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
+ xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
+ xmlns:mi="http://www.aathifmahir.com/dotnet/2022/maui/icons"
+ x:Class="OneSignalDemo.Controls.Sections.EmailsSection"
+>
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
diff --git a/examples/demo/Controls/Sections/EmailsSection.xaml.cs b/examples/demo/Controls/Sections/EmailsSection.xaml.cs
index 20d2f677..dc867d7b 100644
--- a/examples/demo/Controls/Sections/EmailsSection.xaml.cs
+++ b/examples/demo/Controls/Sections/EmailsSection.xaml.cs
@@ -1,5 +1,5 @@
-using OneSignalDemo.ViewModels;
using OneSignalDemo.Controls;
+using OneSignalDemo.ViewModels;
namespace OneSignalDemo.Controls.Sections;
@@ -36,15 +36,23 @@ private void RebuildList()
return;
}
- var displayList = (!_expanded && list.Count > CollapseThreshold)
- ? list.Take(CollapseThreshold).ToList()
- : list.ToList();
+ var displayList =
+ (!_expanded && list.Count > CollapseThreshold)
+ ? list.Take(CollapseThreshold).ToList()
+ : list.ToList();
bool first = true;
foreach (var email in displayList)
{
if (!first)
- EmailListContainer.Children.Add(new BoxView { HeightRequest = 1, Color = Color.FromArgb("#E8EAED"), Margin = new Thickness(12, 0) });
+ EmailListContainer.Children.Add(
+ new BoxView
+ {
+ HeightRequest = 1,
+ Color = Color.FromArgb("#E8EAED"),
+ Margin = new Thickness(12, 0),
+ }
+ );
first = false;
var captured = email;
@@ -54,16 +62,18 @@ private void RebuildList()
ColumnDefinitions =
{
new ColumnDefinition { Width = GridLength.Star },
- new ColumnDefinition { Width = GridLength.Auto }
- }
+ new ColumnDefinition { Width = GridLength.Auto },
+ },
};
- row.Children.Add(new Label
- {
- Text = email,
- FontSize = 14,
- VerticalOptions = LayoutOptions.Center
- });
+ row.Children.Add(
+ new Label
+ {
+ Text = email,
+ FontSize = 14,
+ VerticalOptions = LayoutOptions.Center,
+ }
+ );
var deleteBtn = new Button
{
@@ -72,7 +82,7 @@ private void RebuildList()
TextColor = Color.FromArgb("#E54B4D"),
Padding = new Thickness(8, 0),
FontSize = 18,
- HeightRequest = 40
+ HeightRequest = 40,
};
deleteBtn.Clicked += (s, e) => _viewModel?.RemoveEmail(captured);
Grid.SetColumn(deleteBtn, 1);
@@ -90,19 +100,26 @@ private void RebuildList()
TextColor = Color.FromArgb("#E54B4D"),
FontAttributes = FontAttributes.Bold,
Padding = new Thickness(12, 4),
- FontSize = 14
+ FontSize = 14,
};
- moreLabel.GestureRecognizers.Add(new TapGestureRecognizer
- {
- Command = new Command(() => { _expanded = true; RebuildList(); })
- });
+ moreLabel.GestureRecognizers.Add(
+ new TapGestureRecognizer
+ {
+ Command = new Command(() =>
+ {
+ _expanded = true;
+ RebuildList();
+ }),
+ }
+ );
EmailListContainer.Children.Add(moreLabel);
}
}
private async void OnAddEmailClicked(object? sender, EventArgs e)
{
- if (_parentPage == null || _viewModel == null) return;
+ if (_parentPage == null || _viewModel == null)
+ return;
var email = await DialogInputHelper.ShowSingleInput(
_parentPage,
@@ -112,7 +129,8 @@ private async void OnAddEmailClicked(object? sender, EventArgs e)
"email_input"
);
- if (string.IsNullOrEmpty(email)) return;
+ if (string.IsNullOrEmpty(email))
+ return;
_viewModel.AddEmail(email);
}
diff --git a/examples/demo/Controls/Sections/InAppSection.xaml b/examples/demo/Controls/Sections/InAppSection.xaml
index 4d115647..455267a8 100644
--- a/examples/demo/Controls/Sections/InAppSection.xaml
+++ b/examples/demo/Controls/Sections/InAppSection.xaml
@@ -1,31 +1,43 @@
+ xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
+ xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
+ xmlns:mi="http://www.aathifmahir.com/dotnet/2022/maui/icons"
+ x:Class="OneSignalDemo.Controls.Sections.InAppSection"
+>
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/demo/Controls/Sections/InAppSection.xaml.cs b/examples/demo/Controls/Sections/InAppSection.xaml.cs
index 2bd524e3..816b592a 100644
--- a/examples/demo/Controls/Sections/InAppSection.xaml.cs
+++ b/examples/demo/Controls/Sections/InAppSection.xaml.cs
@@ -34,7 +34,8 @@ public void Initialize(AppViewModel viewModel)
private void OnIamPausedToggled(object? sender, ToggledEventArgs e)
{
- if (_suppressToggle) return;
+ if (_suppressToggle)
+ return;
_viewModel?.SetIamPaused(e.Value);
}
diff --git a/examples/demo/Controls/Sections/LocationSection.xaml b/examples/demo/Controls/Sections/LocationSection.xaml
index 2f961f4a..0a7618cb 100644
--- a/examples/demo/Controls/Sections/LocationSection.xaml
+++ b/examples/demo/Controls/Sections/LocationSection.xaml
@@ -1,33 +1,53 @@
+ xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
+ xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
+ xmlns:mi="http://www.aathifmahir.com/dotnet/2022/maui/icons"
+ x:Class="OneSignalDemo.Controls.Sections.LocationSection"
+>
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
diff --git a/examples/demo/Controls/Sections/LocationSection.xaml.cs b/examples/demo/Controls/Sections/LocationSection.xaml.cs
index cf71e949..f83c2670 100644
--- a/examples/demo/Controls/Sections/LocationSection.xaml.cs
+++ b/examples/demo/Controls/Sections/LocationSection.xaml.cs
@@ -34,7 +34,8 @@ public void Initialize(AppViewModel viewModel)
private void OnLocationSharedToggled(object? sender, ToggledEventArgs e)
{
- if (_suppressToggle) return;
+ if (_suppressToggle)
+ return;
_viewModel?.SetLocationSharedValue(e.Value);
}
diff --git a/examples/demo/Controls/Sections/OutcomesSection.xaml b/examples/demo/Controls/Sections/OutcomesSection.xaml
index 67b8295a..a1a8d4ee 100644
--- a/examples/demo/Controls/Sections/OutcomesSection.xaml
+++ b/examples/demo/Controls/Sections/OutcomesSection.xaml
@@ -1,20 +1,34 @@
+ xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
+ xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
+ xmlns:mi="http://www.aathifmahir.com/dotnet/2022/maui/icons"
+ x:Class="OneSignalDemo.Controls.Sections.OutcomesSection"
+>
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
diff --git a/examples/demo/Controls/Sections/OutcomesSection.xaml.cs b/examples/demo/Controls/Sections/OutcomesSection.xaml.cs
index fb32742d..aa3198c6 100644
--- a/examples/demo/Controls/Sections/OutcomesSection.xaml.cs
+++ b/examples/demo/Controls/Sections/OutcomesSection.xaml.cs
@@ -27,20 +27,47 @@ public void Initialize(AppViewModel viewModel, Page parentPage)
private async void OnSendOutcomeClicked(object? sender, EventArgs e)
{
- if (_parentPage == null || _viewModel == null) return;
+ if (_parentPage == null || _viewModel == null)
+ return;
const string group = "outcome_type";
- var radioNormal = new RadioButton { Content = "Normal Outcome", GroupName = group, IsChecked = true };
+ var radioNormal = new RadioButton
+ {
+ Content = "Normal Outcome",
+ GroupName = group,
+ IsChecked = true,
+ };
var radioUnique = new RadioButton { Content = "Unique Outcome", GroupName = group };
var radioWithValue = new RadioButton { Content = "Outcome with Value", GroupName = group };
- var nameEntry = new Entry { Placeholder = "Outcome name", AutomationId = "outcome_name_input" };
- var valueEntry = new Entry { Placeholder = "Value (float)", Keyboard = Keyboard.Numeric, AutomationId = "outcome_value_input" };
- var valueContainer = new VerticalStackLayout { IsVisible = false, Children = { valueEntry } };
+ var nameEntry = new Entry
+ {
+ Placeholder = "Outcome name",
+ AutomationId = "outcome_name_input",
+ };
+ var valueEntry = new Entry
+ {
+ Placeholder = "Value (float)",
+ Keyboard = Keyboard.Numeric,
+ AutomationId = "outcome_value_input",
+ };
+ var valueContainer = new VerticalStackLayout
+ {
+ IsVisible = false,
+ Children = { valueEntry },
+ };
radioWithValue.CheckedChanged += (s, e2) => valueContainer.IsVisible = e2.Value;
- radioNormal.CheckedChanged += (s, e2) => { if (e2.Value) valueContainer.IsVisible = false; };
- radioUnique.CheckedChanged += (s, e2) => { if (e2.Value) valueContainer.IsVisible = false; };
+ radioNormal.CheckedChanged += (s, e2) =>
+ {
+ if (e2.Value)
+ valueContainer.IsVisible = false;
+ };
+ radioUnique.CheckedChanged += (s, e2) =>
+ {
+ if (e2.Value)
+ valueContainer.IsVisible = false;
+ };
var cancelButton = DialogInputHelper.ActionButton("Cancel");
var sendButton = DialogInputHelper.ActionButton("Send");
@@ -52,9 +79,10 @@ private async void OnSendOutcomeClicked(object? sender, EventArgs e)
cancelButton.Clicked += async (s, e2) => await _parentPage.ClosePopupAsync();
sendButton.Clicked += async (s, e2) =>
{
- outcomeType = radioWithValue.IsChecked ? "Outcome with Value"
- : radioUnique.IsChecked ? "Unique Outcome"
- : "Normal Outcome";
+ outcomeType =
+ radioWithValue.IsChecked ? "Outcome with Value"
+ : radioUnique.IsChecked ? "Unique Outcome"
+ : "Normal Outcome";
name = nameEntry.Text?.Trim();
valueStr = valueEntry.Text?.Trim();
await _parentPage.ClosePopupAsync();
@@ -72,7 +100,7 @@ private async void OnSendOutcomeClicked(object? sender, EventArgs e)
new VerticalStackLayout
{
Spacing = 4,
- Children = { radioNormal, radioUnique, radioWithValue }
+ Children = { radioNormal, radioUnique, radioWithValue },
},
nameEntry,
valueContainer,
diff --git a/examples/demo/Controls/Sections/PushSection.xaml b/examples/demo/Controls/Sections/PushSection.xaml
index 4b3ba5a4..d33f4854 100644
--- a/examples/demo/Controls/Sections/PushSection.xaml
+++ b/examples/demo/Controls/Sections/PushSection.xaml
@@ -1,43 +1,80 @@
+ xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
+ xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
+ xmlns:mi="http://www.aathifmahir.com/dotnet/2022/maui/icons"
+ x:Class="OneSignalDemo.Controls.Sections.PushSection"
+ x:Name="root"
+>
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
diff --git a/examples/demo/Controls/Sections/PushSection.xaml.cs b/examples/demo/Controls/Sections/PushSection.xaml.cs
index 1e4e6649..5c76cd0e 100644
--- a/examples/demo/Controls/Sections/PushSection.xaml.cs
+++ b/examples/demo/Controls/Sections/PushSection.xaml.cs
@@ -22,9 +22,12 @@ public void Initialize(AppViewModel viewModel)
viewModel.PropertyChanged += (s, e) =>
{
- if (e.PropertyName is nameof(AppViewModel.PushSubscriptionId)
- or nameof(AppViewModel.IsPushEnabled)
- or nameof(AppViewModel.HasNotificationPermission))
+ if (
+ e.PropertyName
+ is nameof(AppViewModel.PushSubscriptionId)
+ or nameof(AppViewModel.IsPushEnabled)
+ or nameof(AppViewModel.HasNotificationPermission)
+ )
{
Refresh();
}
@@ -33,7 +36,8 @@ or nameof(AppViewModel.HasNotificationPermission))
private void Refresh()
{
- if (_viewModel == null) return;
+ if (_viewModel == null)
+ return;
PushIdLabel.Text = _viewModel.PushSubscriptionId;
_suppressToggle = true;
@@ -46,7 +50,8 @@ private void Refresh()
private void OnPushEnabledToggled(object? sender, ToggledEventArgs e)
{
- if (_suppressToggle) return;
+ if (_suppressToggle)
+ return;
_viewModel?.SetPushEnabled(e.Value);
}
@@ -55,6 +60,7 @@ private void OnPushEnabledToggled(object? sender, ToggledEventArgs e)
private async void OnPromptPushClicked(object? sender, EventArgs e)
{
PromptPushRequested?.Invoke(this, e);
- if (_viewModel != null) await _viewModel.PromptPushAsync();
+ if (_viewModel != null)
+ await _viewModel.PromptPushAsync();
}
}
diff --git a/examples/demo/Controls/Sections/SendIamSection.xaml b/examples/demo/Controls/Sections/SendIamSection.xaml
index 88430f3e..93e636d5 100644
--- a/examples/demo/Controls/Sections/SendIamSection.xaml
+++ b/examples/demo/Controls/Sections/SendIamSection.xaml
@@ -1,73 +1,131 @@
+ xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
+ xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
+ xmlns:mi="http://www.aathifmahir.com/dotnet/2022/maui/icons"
+ x:Class="OneSignalDemo.Controls.Sections.SendIamSection"
+>
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/demo/Controls/Sections/SendIamSection.xaml.cs b/examples/demo/Controls/Sections/SendIamSection.xaml.cs
index 4ee5a216..c5ffcc51 100644
--- a/examples/demo/Controls/Sections/SendIamSection.xaml.cs
+++ b/examples/demo/Controls/Sections/SendIamSection.xaml.cs
@@ -1,7 +1,7 @@
-using OneSignalDemo.Models;
-using OneSignalDemo.ViewModels;
using CommunityToolkit.Maui.Alerts;
using CommunityToolkit.Maui.Core;
+using OneSignalDemo.Models;
+using OneSignalDemo.ViewModels;
namespace OneSignalDemo.Controls.Sections;
@@ -23,16 +23,25 @@ public void Initialize(AppViewModel viewModel, Page parentPage)
_parentPage = parentPage;
}
- private async void OnTopBannerTapped(object? sender, TappedEventArgs e) => await SendIam(InAppMessageType.TopBanner);
- private async void OnBottomBannerTapped(object? sender, TappedEventArgs e) => await SendIam(InAppMessageType.BottomBanner);
- private async void OnCenterModalTapped(object? sender, TappedEventArgs e) => await SendIam(InAppMessageType.CenterModal);
- private async void OnFullScreenTapped(object? sender, TappedEventArgs e) => await SendIam(InAppMessageType.FullScreen);
+ private async void OnTopBannerTapped(object? sender, TappedEventArgs e) =>
+ await SendIam(InAppMessageType.TopBanner);
+
+ private async void OnBottomBannerTapped(object? sender, TappedEventArgs e) =>
+ await SendIam(InAppMessageType.BottomBanner);
+
+ private async void OnCenterModalTapped(object? sender, TappedEventArgs e) =>
+ await SendIam(InAppMessageType.CenterModal);
+
+ private async void OnFullScreenTapped(object? sender, TappedEventArgs e) =>
+ await SendIam(InAppMessageType.FullScreen);
private async Task SendIam(InAppMessageType type)
{
_viewModel?.SendInAppMessage(type);
if (_parentPage != null)
- await Toast.Make($"Sent In-App Message: {type.GetDisplayName()}", ToastDuration.Short).Show();
+ await Toast
+ .Make($"Sent In-App Message: {type.GetDisplayName()}", ToastDuration.Short)
+ .Show();
}
private void OnInfoTapped(object? sender, EventArgs e) => InfoTapped?.Invoke(this, e);
diff --git a/examples/demo/Controls/Sections/SendPushSection.xaml b/examples/demo/Controls/Sections/SendPushSection.xaml
index ac841887..36741168 100644
--- a/examples/demo/Controls/Sections/SendPushSection.xaml
+++ b/examples/demo/Controls/Sections/SendPushSection.xaml
@@ -1,24 +1,46 @@
+ xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
+ xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
+ xmlns:mi="http://www.aathifmahir.com/dotnet/2022/maui/icons"
+ x:Class="OneSignalDemo.Controls.Sections.SendPushSection"
+>
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
diff --git a/examples/demo/Controls/Sections/SendPushSection.xaml.cs b/examples/demo/Controls/Sections/SendPushSection.xaml.cs
index c123d259..8ac653d2 100644
--- a/examples/demo/Controls/Sections/SendPushSection.xaml.cs
+++ b/examples/demo/Controls/Sections/SendPushSection.xaml.cs
@@ -22,13 +22,15 @@ public void Initialize(AppViewModel viewModel)
private async void OnSimpleClicked(object? sender, EventArgs e)
{
- if (_viewModel == null) return;
+ if (_viewModel == null)
+ return;
await _viewModel.SendNotificationAsync(NotificationType.Simple);
}
private async void OnWithImageClicked(object? sender, EventArgs e)
{
- if (_viewModel == null) return;
+ if (_viewModel == null)
+ return;
await _viewModel.SendNotificationAsync(NotificationType.WithImage);
}
diff --git a/examples/demo/Controls/Sections/SmsSection.xaml b/examples/demo/Controls/Sections/SmsSection.xaml
index dcb9d3ab..e830ad4f 100644
--- a/examples/demo/Controls/Sections/SmsSection.xaml
+++ b/examples/demo/Controls/Sections/SmsSection.xaml
@@ -1,27 +1,46 @@
+ xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
+ xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
+ xmlns:mi="http://www.aathifmahir.com/dotnet/2022/maui/icons"
+ x:Class="OneSignalDemo.Controls.Sections.SmsSection"
+>
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
diff --git a/examples/demo/Controls/Sections/SmsSection.xaml.cs b/examples/demo/Controls/Sections/SmsSection.xaml.cs
index 1e9fbfdf..0102fba8 100644
--- a/examples/demo/Controls/Sections/SmsSection.xaml.cs
+++ b/examples/demo/Controls/Sections/SmsSection.xaml.cs
@@ -1,5 +1,5 @@
-using OneSignalDemo.ViewModels;
using OneSignalDemo.Controls;
+using OneSignalDemo.ViewModels;
namespace OneSignalDemo.Controls.Sections;
@@ -36,15 +36,23 @@ private void RebuildList()
return;
}
- var displayList = (!_expanded && list.Count > CollapseThreshold)
- ? list.Take(CollapseThreshold).ToList()
- : list.ToList();
+ var displayList =
+ (!_expanded && list.Count > CollapseThreshold)
+ ? list.Take(CollapseThreshold).ToList()
+ : list.ToList();
bool first = true;
foreach (var sms in displayList)
{
if (!first)
- SmsListContainer.Children.Add(new BoxView { HeightRequest = 1, Color = Color.FromArgb("#E8EAED"), Margin = new Thickness(12, 0) });
+ SmsListContainer.Children.Add(
+ new BoxView
+ {
+ HeightRequest = 1,
+ Color = Color.FromArgb("#E8EAED"),
+ Margin = new Thickness(12, 0),
+ }
+ );
first = false;
var captured = sms;
@@ -54,11 +62,18 @@ private void RebuildList()
ColumnDefinitions =
{
new ColumnDefinition { Width = GridLength.Star },
- new ColumnDefinition { Width = GridLength.Auto }
- }
+ new ColumnDefinition { Width = GridLength.Auto },
+ },
};
- row.Children.Add(new Label { Text = sms, FontSize = 14, VerticalOptions = LayoutOptions.Center });
+ row.Children.Add(
+ new Label
+ {
+ Text = sms,
+ FontSize = 14,
+ VerticalOptions = LayoutOptions.Center,
+ }
+ );
var deleteBtn = new Button
{
@@ -67,7 +82,7 @@ private void RebuildList()
TextColor = Color.FromArgb("#E54B4D"),
Padding = new Thickness(8, 0),
FontSize = 18,
- HeightRequest = 40
+ HeightRequest = 40,
};
deleteBtn.Clicked += (s, e) => _viewModel?.RemoveSms(captured);
Grid.SetColumn(deleteBtn, 1);
@@ -85,19 +100,26 @@ private void RebuildList()
TextColor = Color.FromArgb("#E54B4D"),
FontAttributes = FontAttributes.Bold,
Padding = new Thickness(12, 4),
- FontSize = 14
+ FontSize = 14,
};
- moreLabel.GestureRecognizers.Add(new TapGestureRecognizer
- {
- Command = new Command(() => { _expanded = true; RebuildList(); })
- });
+ moreLabel.GestureRecognizers.Add(
+ new TapGestureRecognizer
+ {
+ Command = new Command(() =>
+ {
+ _expanded = true;
+ RebuildList();
+ }),
+ }
+ );
SmsListContainer.Children.Add(moreLabel);
}
}
private async void OnAddSmsClicked(object? sender, EventArgs e)
{
- if (_parentPage == null || _viewModel == null) return;
+ if (_parentPage == null || _viewModel == null)
+ return;
var sms = await DialogInputHelper.ShowSingleInput(
_parentPage,
@@ -108,7 +130,8 @@ private async void OnAddSmsClicked(object? sender, EventArgs e)
keyboard: Keyboard.Telephone
);
- if (string.IsNullOrEmpty(sms)) return;
+ if (string.IsNullOrEmpty(sms))
+ return;
_viewModel.AddSms(sms);
}
diff --git a/examples/demo/Controls/Sections/TagsSection.xaml b/examples/demo/Controls/Sections/TagsSection.xaml
index 48ce141e..1d0e5c95 100644
--- a/examples/demo/Controls/Sections/TagsSection.xaml
+++ b/examples/demo/Controls/Sections/TagsSection.xaml
@@ -1,31 +1,60 @@
+ xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
+ xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
+ xmlns:mi="http://www.aathifmahir.com/dotnet/2022/maui/icons"
+ x:Class="OneSignalDemo.Controls.Sections.TagsSection"
+>
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
diff --git a/examples/demo/Controls/Sections/TagsSection.xaml.cs b/examples/demo/Controls/Sections/TagsSection.xaml.cs
index 9a2d92e4..098242fc 100644
--- a/examples/demo/Controls/Sections/TagsSection.xaml.cs
+++ b/examples/demo/Controls/Sections/TagsSection.xaml.cs
@@ -1,5 +1,5 @@
-using OneSignalDemo.ViewModels;
using OneSignalDemo.Controls;
+using OneSignalDemo.ViewModels;
namespace OneSignalDemo.Controls.Sections;
@@ -40,7 +40,14 @@ private void RebuildList()
foreach (var tag in list)
{
if (!first)
- TagListContainer.Children.Add(new BoxView { HeightRequest = 1, Color = Color.FromArgb("#E8EAED"), Margin = new Thickness(12, 0) });
+ TagListContainer.Children.Add(
+ new BoxView
+ {
+ HeightRequest = 1,
+ Color = Color.FromArgb("#E8EAED"),
+ Margin = new Thickness(12, 0),
+ }
+ );
first = false;
var captured = tag;
@@ -50,22 +57,20 @@ private void RebuildList()
ColumnDefinitions =
{
new ColumnDefinition { Width = GridLength.Star },
- new ColumnDefinition { Width = GridLength.Auto }
- }
+ new ColumnDefinition { Width = GridLength.Auto },
+ },
};
var textStack = new VerticalStackLayout { Spacing = 2 };
- textStack.Children.Add(new Label
- {
- Text = tag.Key,
- FontSize = 14,
- });
- textStack.Children.Add(new Label
- {
- Text = tag.Value,
- FontSize = 12,
- TextColor = Color.FromArgb("#757575")
- });
+ textStack.Children.Add(new Label { Text = tag.Key, FontSize = 14 });
+ textStack.Children.Add(
+ new Label
+ {
+ Text = tag.Value,
+ FontSize = 12,
+ TextColor = Color.FromArgb("#757575"),
+ }
+ );
row.Children.Add(textStack);
var deleteBtn = new Button
@@ -76,7 +81,7 @@ private void RebuildList()
Padding = new Thickness(8, 0),
FontSize = 18,
HeightRequest = 40,
- VerticalOptions = LayoutOptions.Center
+ VerticalOptions = LayoutOptions.Center,
};
deleteBtn.Clicked += (s, e) => _viewModel?.RemoveTag(captured.Key);
Grid.SetColumn(deleteBtn, 1);
@@ -88,13 +93,24 @@ private void RebuildList()
private async void OnAddClicked(object? sender, EventArgs e)
{
- if (_parentPage == null || _viewModel == null) return;
+ if (_parentPage == null || _viewModel == null)
+ return;
var form = await DialogInputHelper.ShowPairInput(
_parentPage,
"Add Tag",
- new DialogInputField { Key = "key", Placeholder = "Key", AutomationId = "tag_key_input" },
- new DialogInputField { Key = "value", Placeholder = "Value", AutomationId = "tag_value_input" },
+ new DialogInputField
+ {
+ Key = "key",
+ Placeholder = "Key",
+ AutomationId = "tag_key_input",
+ },
+ new DialogInputField
+ {
+ Key = "value",
+ Placeholder = "Value",
+ AutomationId = "tag_value_input",
+ },
"Add"
);
@@ -111,18 +127,31 @@ private async void OnAddClicked(object? sender, EventArgs e)
private async void OnAddMultipleClicked(object? sender, EventArgs e)
{
- if (_parentPage == null || _viewModel == null) return;
- var pairs = await MultiPairDialogHelper.Show(_parentPage, "Add Multiple Tags", "Key", "Value");
- if (pairs == null || pairs.Count == 0) return;
+ if (_parentPage == null || _viewModel == null)
+ return;
+ var pairs = await MultiPairDialogHelper.Show(
+ _parentPage,
+ "Add Multiple Tags",
+ "Key",
+ "Value"
+ );
+ if (pairs == null || pairs.Count == 0)
+ return;
_viewModel.AddTags(pairs);
}
private async void OnRemoveSelectedClicked(object? sender, EventArgs e)
{
- if (_parentPage == null || _viewModel == null) return;
+ if (_parentPage == null || _viewModel == null)
+ return;
var keys = _viewModel.TagsList.Select(t => t.Key).ToList();
- var selected = await MultiPairDialogHelper.ShowMultiSelect(_parentPage, "Remove Tags", keys);
- if (selected == null || selected.Count == 0) return;
+ var selected = await MultiPairDialogHelper.ShowMultiSelect(
+ _parentPage,
+ "Remove Tags",
+ keys
+ );
+ if (selected == null || selected.Count == 0)
+ return;
_viewModel.RemoveSelectedTags(selected);
}
diff --git a/examples/demo/Controls/Sections/TrackEventSection.xaml b/examples/demo/Controls/Sections/TrackEventSection.xaml
index fc467843..f4166467 100644
--- a/examples/demo/Controls/Sections/TrackEventSection.xaml
+++ b/examples/demo/Controls/Sections/TrackEventSection.xaml
@@ -1,20 +1,34 @@
+ xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
+ xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
+ xmlns:mi="http://www.aathifmahir.com/dotnet/2022/maui/icons"
+ x:Class="OneSignalDemo.Controls.Sections.TrackEventSection"
+>
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
diff --git a/examples/demo/Controls/Sections/TrackEventSection.xaml.cs b/examples/demo/Controls/Sections/TrackEventSection.xaml.cs
index b3b14ddc..17dfcc9d 100644
--- a/examples/demo/Controls/Sections/TrackEventSection.xaml.cs
+++ b/examples/demo/Controls/Sections/TrackEventSection.xaml.cs
@@ -28,16 +28,21 @@ public void Initialize(AppViewModel viewModel, Page parentPage)
private async void OnTrackEventClicked(object? sender, EventArgs e)
{
- if (_parentPage == null || _viewModel == null) return;
+ if (_parentPage == null || _viewModel == null)
+ return;
var result = await ShowTrackEventPopup(_parentPage);
- if (result == null) return;
+ if (result == null)
+ return;
_viewModel.TrackEvent(result.Value.name, result.Value.properties);
await Toast.Make($"Event tracked: {result.Value.name}", ToastDuration.Short).Show();
}
- private static async Task<(string name, Dictionary? properties)?> ShowTrackEventPopup(Page parentPage)
+ private static async Task<(
+ string name,
+ Dictionary? properties
+ )?> ShowTrackEventPopup(Page parentPage)
{
var nameEntry = new Entry
{
@@ -67,7 +72,8 @@ private async void OnTrackEventClicked(object? sender, EventArgs e)
confirmButton.Clicked += async (s, ev) =>
{
var name = nameEntry.Text?.Trim() ?? string.Empty;
- if (string.IsNullOrEmpty(name)) return;
+ if (string.IsNullOrEmpty(name))
+ return;
var propsText = propsEntry.Text?.Trim() ?? string.Empty;
Dictionary? properties = null;
@@ -111,12 +117,7 @@ private async void OnTrackEventClicked(object? sender, EventArgs e)
new VerticalStackLayout
{
Spacing = 8,
- Children =
- {
- nameEntry,
- propsEntry,
- errorLabel,
- }
+ Children = { nameEntry, propsEntry, errorLabel },
},
new HorizontalStackLayout
{
@@ -128,7 +129,10 @@ private async void OnTrackEventClicked(object? sender, EventArgs e)
},
};
- await parentPage.ShowPopupAsync<(string, Dictionary?)?>(card, DialogInputHelper.DialogOptions);
+ await parentPage.ShowPopupAsync<(string, Dictionary?)?>(
+ card,
+ DialogInputHelper.DialogOptions
+ );
return popupResult;
}
diff --git a/examples/demo/Controls/Sections/TriggersSection.xaml b/examples/demo/Controls/Sections/TriggersSection.xaml
index e9d2db59..5923e82a 100644
--- a/examples/demo/Controls/Sections/TriggersSection.xaml
+++ b/examples/demo/Controls/Sections/TriggersSection.xaml
@@ -1,33 +1,68 @@
+ xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
+ xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
+ xmlns:mi="http://www.aathifmahir.com/dotnet/2022/maui/icons"
+ x:Class="OneSignalDemo.Controls.Sections.TriggersSection"
+>
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
diff --git a/examples/demo/Controls/Sections/TriggersSection.xaml.cs b/examples/demo/Controls/Sections/TriggersSection.xaml.cs
index 5f65f306..decfbc29 100644
--- a/examples/demo/Controls/Sections/TriggersSection.xaml.cs
+++ b/examples/demo/Controls/Sections/TriggersSection.xaml.cs
@@ -1,5 +1,5 @@
-using OneSignalDemo.ViewModels;
using OneSignalDemo.Controls;
+using OneSignalDemo.ViewModels;
namespace OneSignalDemo.Controls.Sections;
@@ -42,7 +42,14 @@ private void RebuildList()
foreach (var trigger in list!)
{
if (!first)
- TriggerListContainer.Children.Add(new BoxView { HeightRequest = 1, Color = Color.FromArgb("#E8EAED"), Margin = new Thickness(12, 0) });
+ TriggerListContainer.Children.Add(
+ new BoxView
+ {
+ HeightRequest = 1,
+ Color = Color.FromArgb("#E8EAED"),
+ Margin = new Thickness(12, 0),
+ }
+ );
first = false;
var captured = trigger;
@@ -52,13 +59,20 @@ private void RebuildList()
ColumnDefinitions =
{
new ColumnDefinition { Width = GridLength.Star },
- new ColumnDefinition { Width = GridLength.Auto }
- }
+ new ColumnDefinition { Width = GridLength.Auto },
+ },
};
var textStack = new VerticalStackLayout { Spacing = 2 };
textStack.Children.Add(new Label { Text = trigger.Key, FontSize = 14 });
- textStack.Children.Add(new Label { Text = trigger.Value, FontSize = 12, TextColor = Color.FromArgb("#757575") });
+ textStack.Children.Add(
+ new Label
+ {
+ Text = trigger.Value,
+ FontSize = 12,
+ TextColor = Color.FromArgb("#757575"),
+ }
+ );
row.Children.Add(textStack);
var deleteBtn = new Button
@@ -69,7 +83,7 @@ private void RebuildList()
Padding = new Thickness(8, 0),
FontSize = 18,
HeightRequest = 40,
- VerticalOptions = LayoutOptions.Center
+ VerticalOptions = LayoutOptions.Center,
};
deleteBtn.Clicked += (s, e) => _viewModel?.RemoveTrigger(captured.Key);
Grid.SetColumn(deleteBtn, 1);
@@ -81,13 +95,24 @@ private void RebuildList()
private async void OnAddClicked(object? sender, EventArgs e)
{
- if (_parentPage == null || _viewModel == null) return;
+ if (_parentPage == null || _viewModel == null)
+ return;
var form = await DialogInputHelper.ShowPairInput(
_parentPage,
"Add Trigger",
- new DialogInputField { Key = "key", Placeholder = "Key", AutomationId = "trigger_key_input" },
- new DialogInputField { Key = "value", Placeholder = "Value", AutomationId = "trigger_value_input" },
+ new DialogInputField
+ {
+ Key = "key",
+ Placeholder = "Key",
+ AutomationId = "trigger_key_input",
+ },
+ new DialogInputField
+ {
+ Key = "value",
+ Placeholder = "Value",
+ AutomationId = "trigger_value_input",
+ },
"Add"
);
@@ -104,18 +129,31 @@ private async void OnAddClicked(object? sender, EventArgs e)
private async void OnAddMultipleClicked(object? sender, EventArgs e)
{
- if (_parentPage == null || _viewModel == null) return;
- var pairs = await MultiPairDialogHelper.Show(_parentPage, "Add Multiple Triggers", "Key", "Value");
- if (pairs == null || pairs.Count == 0) return;
+ if (_parentPage == null || _viewModel == null)
+ return;
+ var pairs = await MultiPairDialogHelper.Show(
+ _parentPage,
+ "Add Multiple Triggers",
+ "Key",
+ "Value"
+ );
+ if (pairs == null || pairs.Count == 0)
+ return;
_viewModel.AddTriggers(pairs);
}
private async void OnRemoveSelectedClicked(object? sender, EventArgs e)
{
- if (_parentPage == null || _viewModel == null) return;
+ if (_parentPage == null || _viewModel == null)
+ return;
var keys = _viewModel.TriggersList.Select(t => t.Key).ToList();
- var selected = await MultiPairDialogHelper.ShowMultiSelect(_parentPage, "Remove Triggers", keys);
- if (selected == null || selected.Count == 0) return;
+ var selected = await MultiPairDialogHelper.ShowMultiSelect(
+ _parentPage,
+ "Remove Triggers",
+ keys
+ );
+ if (selected == null || selected.Count == 0)
+ return;
_viewModel.RemoveSelectedTriggers(selected);
}
diff --git a/examples/demo/Controls/Sections/UserSection.xaml b/examples/demo/Controls/Sections/UserSection.xaml
index 4fcc8805..31dd1137 100644
--- a/examples/demo/Controls/Sections/UserSection.xaml
+++ b/examples/demo/Controls/Sections/UserSection.xaml
@@ -1,39 +1,70 @@
+ xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
+ xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
+ x:Class="OneSignalDemo.Controls.Sections.UserSection"
+ x:Name="root"
+>
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
diff --git a/examples/demo/Controls/TooltipDialogHelper.cs b/examples/demo/Controls/TooltipDialogHelper.cs
index 4b747f7c..e6983e45 100644
--- a/examples/demo/Controls/TooltipDialogHelper.cs
+++ b/examples/demo/Controls/TooltipDialogHelper.cs
@@ -12,30 +12,36 @@ public static async Task Show(Page parentPage, TooltipData tooltip)
okButton.Clicked += async (s, e) => await parentPage.ClosePopupAsync();
var contentStack = new VerticalStackLayout { Spacing = 8 };
- contentStack.Children.Add(new Label
- {
- Text = tooltip.Description,
- FontSize = 14,
- TextColor = Color.FromArgb("#5F6368"),
- });
+ contentStack.Children.Add(
+ new Label
+ {
+ Text = tooltip.Description,
+ FontSize = 14,
+ TextColor = Color.FromArgb("#5F6368"),
+ }
+ );
if (tooltip.Options is { Count: > 0 })
{
foreach (var option in tooltip.Options)
{
- contentStack.Children.Add(new Label
- {
- Text = option.Name,
- FontSize = 14,
- FontAttributes = FontAttributes.Bold,
- });
- contentStack.Children.Add(new Label
- {
- Text = option.Description,
- FontSize = 13,
- TextColor = Color.FromArgb("#5F6368"),
- Margin = new Thickness(0, 0, 0, 4),
- });
+ contentStack.Children.Add(
+ new Label
+ {
+ Text = option.Name,
+ FontSize = 14,
+ FontAttributes = FontAttributes.Bold,
+ }
+ );
+ contentStack.Children.Add(
+ new Label
+ {
+ Text = option.Description,
+ FontSize = 13,
+ TextColor = Color.FromArgb("#5F6368"),
+ Margin = new Thickness(0, 0, 0, 4),
+ }
+ );
}
}
diff --git a/examples/demo/MauiProgram.cs b/examples/demo/MauiProgram.cs
index 3e5bd8fd..bc938b4f 100644
--- a/examples/demo/MauiProgram.cs
+++ b/examples/demo/MauiProgram.cs
@@ -81,19 +81,17 @@ public static MauiApp CreateMauiApp()
OneSignal.Initialize(prefs.AppId);
// Register observers
- OneSignal.InAppMessages.WillDisplay +=
- (s, e) => LogManager.Instance.D("IAM", $"WillDisplay");
- OneSignal.InAppMessages.DidDisplay +=
- (s, e) => LogManager.Instance.D("IAM", $"DidDisplay");
- OneSignal.InAppMessages.WillDismiss +=
- (s, e) => LogManager.Instance.D("IAM", $"WillDismiss");
- OneSignal.InAppMessages.DidDismiss +=
- (s, e) => LogManager.Instance.D("IAM", $"DidDismiss");
+ OneSignal.InAppMessages.WillDisplay += (s, e) =>
+ LogManager.Instance.D("IAM", $"WillDisplay");
+ OneSignal.InAppMessages.DidDisplay += (s, e) => LogManager.Instance.D("IAM", $"DidDisplay");
+ OneSignal.InAppMessages.WillDismiss += (s, e) =>
+ LogManager.Instance.D("IAM", $"WillDismiss");
+ OneSignal.InAppMessages.DidDismiss += (s, e) => LogManager.Instance.D("IAM", $"DidDismiss");
OneSignal.InAppMessages.Clicked += (s, e) => LogManager.Instance.D("IAM", $"Clicked");
- OneSignal.Notifications.Clicked +=
- (s, e) => LogManager.Instance.D("Notifications", "Clicked");
- OneSignal.Notifications.WillDisplay +=
- (s, e) => LogManager.Instance.D("Notifications", "WillDisplay");
+ OneSignal.Notifications.Clicked += (s, e) =>
+ LogManager.Instance.D("Notifications", "Clicked");
+ OneSignal.Notifications.WillDisplay += (s, e) =>
+ LogManager.Instance.D("Notifications", "WillDisplay");
// Restore SDK state from prefs (after Initialize)
OneSignal.InAppMessages.Paused = prefs.IamPaused;
diff --git a/examples/demo/Models/InAppMessageType.cs b/examples/demo/Models/InAppMessageType.cs
index 49af63be..8a69bbd7 100644
--- a/examples/demo/Models/InAppMessageType.cs
+++ b/examples/demo/Models/InAppMessageType.cs
@@ -5,26 +5,28 @@ public enum InAppMessageType
TopBanner,
BottomBanner,
CenterModal,
- FullScreen
+ FullScreen,
}
public static class InAppMessageTypeExtensions
{
- public static string GetTriggerValue(this InAppMessageType type) => type switch
- {
- InAppMessageType.TopBanner => "top_banner",
- InAppMessageType.BottomBanner => "bottom_banner",
- InAppMessageType.CenterModal => "center_modal",
- InAppMessageType.FullScreen => "full_screen",
- _ => "top_banner"
- };
+ public static string GetTriggerValue(this InAppMessageType type) =>
+ type switch
+ {
+ InAppMessageType.TopBanner => "top_banner",
+ InAppMessageType.BottomBanner => "bottom_banner",
+ InAppMessageType.CenterModal => "center_modal",
+ InAppMessageType.FullScreen => "full_screen",
+ _ => "top_banner",
+ };
- public static string GetDisplayName(this InAppMessageType type) => type switch
- {
- InAppMessageType.TopBanner => "Top Banner",
- InAppMessageType.BottomBanner => "Bottom Banner",
- InAppMessageType.CenterModal => "Center Modal",
- InAppMessageType.FullScreen => "Full Screen",
- _ => "Top Banner"
- };
+ public static string GetDisplayName(this InAppMessageType type) =>
+ type switch
+ {
+ InAppMessageType.TopBanner => "Top Banner",
+ InAppMessageType.BottomBanner => "Bottom Banner",
+ InAppMessageType.CenterModal => "Center Modal",
+ InAppMessageType.FullScreen => "Full Screen",
+ _ => "Top Banner",
+ };
}
diff --git a/examples/demo/Models/NotificationType.cs b/examples/demo/Models/NotificationType.cs
index c69d6eae..92cd562d 100644
--- a/examples/demo/Models/NotificationType.cs
+++ b/examples/demo/Models/NotificationType.cs
@@ -4,5 +4,5 @@ public enum NotificationType
{
Simple,
WithImage,
- Custom
+ Custom,
}
diff --git a/examples/demo/Models/UserData.cs b/examples/demo/Models/UserData.cs
index 05ee2621..72eac719 100644
--- a/examples/demo/Models/UserData.cs
+++ b/examples/demo/Models/UserData.cs
@@ -15,7 +15,8 @@ public UserData(
Dictionary tags,
List emails,
List smsNumbers,
- string? externalId)
+ string? externalId
+ )
{
Aliases = aliases;
Tags = tags;
@@ -33,17 +34,24 @@ public UserData(
{
foreach (var prop in identity.EnumerateObject())
{
- if (prop.Name is "external_id" or "onesignal_id") continue;
+ if (prop.Name is "external_id" or "onesignal_id")
+ continue;
aliases[prop.Name] = prop.Value.GetString() ?? "";
}
}
string? externalId = null;
- if (json.TryGetProperty("identity", out var id2) && id2.TryGetProperty("external_id", out var extId))
+ if (
+ json.TryGetProperty("identity", out var id2)
+ && id2.TryGetProperty("external_id", out var extId)
+ )
externalId = extId.GetString();
var tags = new Dictionary();
- if (json.TryGetProperty("properties", out var props) && props.TryGetProperty("tags", out var tagsEl))
+ if (
+ json.TryGetProperty("properties", out var props)
+ && props.TryGetProperty("tags", out var tagsEl)
+ )
{
foreach (var prop in tagsEl.EnumerateObject())
tags[prop.Name] = prop.Value.GetString() ?? "";
@@ -55,13 +63,19 @@ public UserData(
{
foreach (var sub in subs.EnumerateArray())
{
- if (!sub.TryGetProperty("type", out var typeEl)) continue;
+ if (!sub.TryGetProperty("type", out var typeEl))
+ continue;
var subType = typeEl.GetString();
- var token = sub.TryGetProperty("token", out var tokenEl) ? tokenEl.GetString() : null;
- if (string.IsNullOrEmpty(token)) continue;
+ var token = sub.TryGetProperty("token", out var tokenEl)
+ ? tokenEl.GetString()
+ : null;
+ if (string.IsNullOrEmpty(token))
+ continue;
- if (subType == "Email") emails.Add(token);
- else if (subType == "SMS") smsNumbers.Add(token);
+ if (subType == "Email")
+ emails.Add(token);
+ else if (subType == "SMS")
+ smsNumbers.Add(token);
}
}
diff --git a/examples/demo/NotificationServiceExtension/NotificationService.cs b/examples/demo/NotificationServiceExtension/NotificationService.cs
index 49f7e7b9..73032a3e 100644
--- a/examples/demo/NotificationServiceExtension/NotificationService.cs
+++ b/examples/demo/NotificationServiceExtension/NotificationService.cs
@@ -12,23 +12,32 @@ public class NotificationService : UNNotificationServiceExtension
UNMutableNotificationContent? BestAttemptContent { get; set; }
UNNotificationRequest? ReceivedRequest { get; set; }
- protected NotificationService(IntPtr handle) : base(handle)
- {
- }
+ protected NotificationService(IntPtr handle)
+ : base(handle) { }
- public override void DidReceiveNotificationRequest(UNNotificationRequest request, Action contentHandler)
+ public override void DidReceiveNotificationRequest(
+ UNNotificationRequest request,
+ Action contentHandler
+ )
{
ReceivedRequest = request;
ContentHandler = contentHandler;
BestAttemptContent = (UNMutableNotificationContent)request.Content.MutableCopy();
- NotificationServiceExtension.DidReceiveNotificationExtensionRequest(request, BestAttemptContent, contentHandler);
+ NotificationServiceExtension.DidReceiveNotificationExtensionRequest(
+ request,
+ BestAttemptContent,
+ contentHandler
+ );
}
public override void TimeWillExpire()
{
if (ReceivedRequest != null && BestAttemptContent != null)
- NotificationServiceExtension.ServiceExtensionTimeWillExpireRequest(ReceivedRequest, BestAttemptContent);
+ NotificationServiceExtension.ServiceExtensionTimeWillExpireRequest(
+ ReceivedRequest,
+ BestAttemptContent
+ );
ContentHandler?.Invoke(BestAttemptContent ?? new UNMutableNotificationContent());
}
diff --git a/examples/demo/Pages/MainPage.xaml b/examples/demo/Pages/MainPage.xaml
index cc6c80d1..d2c18d46 100644
--- a/examples/demo/Pages/MainPage.xaml
+++ b/examples/demo/Pages/MainPage.xaml
@@ -1,55 +1,60 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
+ xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
+ xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
+ xmlns:controls="clr-namespace:OneSignalDemo.Controls"
+ xmlns:sections="clr-namespace:OneSignalDemo.Controls.Sections"
+ x:Class="OneSignalDemo.Pages.MainPage"
+ Title="DotNet"
+ BackgroundColor="{StaticResource OsLightBackground}"
+>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/demo/Pages/MainPage.xaml.cs b/examples/demo/Pages/MainPage.xaml.cs
index 3fc87279..dda04e4c 100644
--- a/examples/demo/Pages/MainPage.xaml.cs
+++ b/examples/demo/Pages/MainPage.xaml.cs
@@ -1,7 +1,7 @@
+using OneSignalDemo.Controls;
using OneSignalDemo.Models;
using OneSignalDemo.Services;
using OneSignalDemo.ViewModels;
-using OneSignalDemo.Controls;
namespace OneSignalDemo.Pages;
@@ -70,7 +70,8 @@ public MainPage(AppViewModel viewModel)
protected override async void OnAppearing()
{
base.OnAppearing();
- if (_initialLoadDone) return;
+ if (_initialLoadDone)
+ return;
_initialLoadDone = true;
await _viewModel.LoadInitialStateAsync();
await _viewModel.PromptPushAsync();
@@ -122,7 +123,11 @@ private async void OnCustomNotificationRequested(object? sender, EventArgs e)
"custom_notif_send_button"
);
- if (form == null || !form.TryGetValue("title", out var title) || string.IsNullOrEmpty(title))
+ if (
+ form == null
+ || !form.TryGetValue("title", out var title)
+ || string.IsNullOrEmpty(title)
+ )
return;
form.TryGetValue("body", out var body);
@@ -132,7 +137,8 @@ private async void OnCustomNotificationRequested(object? sender, EventArgs e)
private async void ShowTooltip(string key)
{
var tooltip = TooltipHelper.Instance.GetTooltip(key);
- if (tooltip == null) return;
+ if (tooltip == null)
+ return;
await TooltipDialogHelper.Show(this, tooltip);
}
diff --git a/examples/demo/Pages/SecondaryPage.xaml b/examples/demo/Pages/SecondaryPage.xaml
index bbeba76d..d02c9641 100644
--- a/examples/demo/Pages/SecondaryPage.xaml
+++ b/examples/demo/Pages/SecondaryPage.xaml
@@ -1,17 +1,19 @@
-
-
-
-
+ xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
+ xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
+ x:Class="OneSignalDemo.Pages.SecondaryPage"
+ Title="Secondary Activity"
+ BackgroundColor="{StaticResource LightBackground}"
+>
+
+
+
diff --git a/examples/demo/Platforms/Android/AndroidManifest.xml b/examples/demo/Platforms/Android/AndroidManifest.xml
index 4b428815..e4aadb9f 100644
--- a/examples/demo/Platforms/Android/AndroidManifest.xml
+++ b/examples/demo/Platforms/Android/AndroidManifest.xml
@@ -1,12 +1,19 @@
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
diff --git a/examples/demo/Platforms/Android/MainActivity.cs b/examples/demo/Platforms/Android/MainActivity.cs
index aae4fdb7..0c1c9d48 100644
--- a/examples/demo/Platforms/Android/MainActivity.cs
+++ b/examples/demo/Platforms/Android/MainActivity.cs
@@ -5,9 +5,14 @@
namespace OneSignalDemo;
-[Activity(Theme = "@style/Maui.SplashTheme", MainLauncher = true,
- ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode |
- ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)]
-public class MainActivity : MauiAppCompatActivity
-{
-}
+[Activity(
+ Theme = "@style/Maui.SplashTheme",
+ MainLauncher = true,
+ ConfigurationChanges = ConfigChanges.ScreenSize
+ | ConfigChanges.Orientation
+ | ConfigChanges.UiMode
+ | ConfigChanges.ScreenLayout
+ | ConfigChanges.SmallestScreenSize
+ | ConfigChanges.Density
+)]
+public class MainActivity : MauiAppCompatActivity { }
diff --git a/examples/demo/Platforms/Android/MainApplication.cs b/examples/demo/Platforms/Android/MainApplication.cs
index 39527260..78501708 100644
--- a/examples/demo/Platforms/Android/MainApplication.cs
+++ b/examples/demo/Platforms/Android/MainApplication.cs
@@ -9,9 +9,7 @@ namespace OneSignalDemo;
public class MainApplication : MauiApplication
{
public MainApplication(IntPtr handle, JniHandleOwnership ownership)
- : base(handle, ownership)
- {
- }
+ : base(handle, ownership) { }
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
}
diff --git a/examples/demo/Repositories/OneSignalRepository.cs b/examples/demo/Repositories/OneSignalRepository.cs
index 2cc1127e..9e58b330 100644
--- a/examples/demo/Repositories/OneSignalRepository.cs
+++ b/examples/demo/Repositories/OneSignalRepository.cs
@@ -1,6 +1,6 @@
-using OneSignalSDK.DotNet;
using OneSignalDemo.Models;
using OneSignalDemo.Services;
+using OneSignalSDK.DotNet;
namespace OneSignalDemo.Repositories;
@@ -15,38 +15,57 @@ public OneSignalRepository(OneSignalApiService apiService)
// User
public void LoginUser(string externalUserId) => OneSignal.Login(externalUserId);
+
public void LogoutUser() => OneSignal.Logout();
// Aliases
public void AddAlias(string label, string id) => OneSignal.User.AddAlias(label, id);
- public void AddAliases(IDictionary aliases) => OneSignal.User.AddAliases(aliases);
+
+ public void AddAliases(IDictionary aliases) =>
+ OneSignal.User.AddAliases(aliases);
// Email
public void AddEmail(string email) => OneSignal.User.AddEmail(email);
+
public void RemoveEmail(string email) => OneSignal.User.RemoveEmail(email);
// SMS
public void AddSms(string smsNumber) => OneSignal.User.AddSms(smsNumber);
+
public void RemoveSms(string smsNumber) => OneSignal.User.RemoveSms(smsNumber);
// Tags
public void AddTag(string key, string value) => OneSignal.User.AddTag(key, value);
+
public void AddTags(IDictionary tags) => OneSignal.User.AddTags(tags);
+
public void RemoveTag(string key) => OneSignal.User.RemoveTag(key);
+
public void RemoveTags(IEnumerable keys) => OneSignal.User.RemoveTags(keys.ToArray());
+
public IDictionary GetTags() => OneSignal.User.GetTags();
// Triggers
- public void AddTrigger(string key, string value) => OneSignal.InAppMessages.AddTrigger(key, value);
- public void AddTriggers(IDictionary triggers) => OneSignal.InAppMessages.AddTriggers(triggers);
+ public void AddTrigger(string key, string value) =>
+ OneSignal.InAppMessages.AddTrigger(key, value);
+
+ public void AddTriggers(IDictionary triggers) =>
+ OneSignal.InAppMessages.AddTriggers(triggers);
+
public void RemoveTrigger(string key) => OneSignal.InAppMessages.RemoveTrigger(key);
- public void RemoveTriggers(IEnumerable keys) => OneSignal.InAppMessages.RemoveTriggers(keys.ToArray());
+
+ public void RemoveTriggers(IEnumerable keys) =>
+ OneSignal.InAppMessages.RemoveTriggers(keys.ToArray());
+
public void ClearTriggers() => OneSignal.InAppMessages.ClearTriggers();
// Outcomes
public void SendOutcome(string name) => OneSignal.Session.AddOutcome(name);
+
public void SendUniqueOutcome(string name) => OneSignal.Session.AddUniqueOutcome(name);
- public void SendOutcomeWithValue(string name, float value) => OneSignal.Session.AddOutcomeWithValue(name, value);
+
+ public void SendOutcomeWithValue(string name, float value) =>
+ OneSignal.Session.AddOutcomeWithValue(name, value);
// Track Event
public void TrackEvent(string name, IDictionary? properties) =>
@@ -54,44 +73,55 @@ public void TrackEvent(string name, IDictionary? properties) =>
// Push subscription
public string? GetPushSubscriptionId() => OneSignal.User.PushSubscription.Id;
+
public bool IsPushOptedIn() => OneSignal.User.PushSubscription.OptedIn;
+
public void OptInPush() => OneSignal.User.PushSubscription.OptIn();
+
public void OptOutPush() => OneSignal.User.PushSubscription.OptOut();
// Notifications
public bool HasPermission() => OneSignal.Notifications.Permission;
+
public Task RequestPermissionAsync(bool fallbackToSettings) =>
OneSignal.Notifications.RequestPermissionAsync(fallbackToSettings);
// In-App Messages
public void SetInAppMessagesPaused(bool paused) => OneSignal.InAppMessages.Paused = paused;
+
public bool IsInAppMessagesPaused() => OneSignal.InAppMessages.Paused;
// Location
public void SetLocationShared(bool shared) => OneSignal.Location.IsShared = shared;
+
public bool IsLocationShared() => OneSignal.Location.IsShared;
+
public void RequestLocationPermission() => OneSignal.Location.RequestPermission();
// Privacy consent
public void SetConsentRequired(bool required) => OneSignal.ConsentRequired = required;
+
public void SetConsentGiven(bool granted) => OneSignal.ConsentGiven = granted;
// User IDs
public string? GetExternalId() => OneSignal.User.ExternalId;
+
public string? GetOnesignalId() => OneSignal.User.OneSignalId;
// Notifications (API)
public Task SendNotificationAsync(NotificationType type)
{
var id = GetPushSubscriptionId();
- if (string.IsNullOrEmpty(id)) return Task.FromResult(false);
+ if (string.IsNullOrEmpty(id))
+ return Task.FromResult(false);
return _apiService.SendNotificationAsync(type, id);
}
public Task SendCustomNotificationAsync(string title, string body)
{
var id = GetPushSubscriptionId();
- if (string.IsNullOrEmpty(id)) return Task.FromResult(false);
+ if (string.IsNullOrEmpty(id))
+ return Task.FromResult(false);
return _apiService.SendCustomNotificationAsync(title, body, id);
}
diff --git a/examples/demo/Resources/Styles/Colors.xaml b/examples/demo/Resources/Styles/Colors.xaml
index 629665b1..32256b08 100644
--- a/examples/demo/Resources/Styles/Colors.xaml
+++ b/examples/demo/Resources/Styles/Colors.xaml
@@ -1,32 +1,31 @@
-
- #E54B4D
- #34A853
- #616161
- #757575
- #9E9E9E
- #F8F9FA
- #FFFFFF
- #1A000000
- #E8EAED
- #FFF8E1
- #1A1B1E
- #82AAFF
- #C3E88D
- #FFCB6B
- #FF5370
- #676E7B
-
-
- #E54B4D
- #34A853
- #F8F9FA
- #FFFFFF
- #E8EAED
- #FFF8E1
- #1A1B1E
+ xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
+ xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
+>
+ #E54B4D
+ #34A853
+ #616161
+ #757575
+ #9E9E9E
+ #F8F9FA
+ #FFFFFF
+ #1A000000
+ #E8EAED
+ #FFF8E1
+ #1A1B1E
+ #82AAFF
+ #C3E88D
+ #FFCB6B
+ #FF5370
+ #676E7B
+
+ #E54B4D
+ #34A853
+ #F8F9FA
+ #FFFFFF
+ #E8EAED
+ #FFF8E1
+ #1A1B1E
diff --git a/examples/demo/Resources/Styles/Styles.xaml b/examples/demo/Resources/Styles/Styles.xaml
index 241fb193..9dc7a609 100644
--- a/examples/demo/Resources/Styles/Styles.xaml
+++ b/examples/demo/Resources/Styles/Styles.xaml
@@ -1,82 +1,81 @@
+ xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
+ xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
+>
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
-
-
-
+
+
diff --git a/examples/demo/Services/LogManager.cs b/examples/demo/Services/LogManager.cs
index 76f7924f..4cb355f9 100644
--- a/examples/demo/Services/LogManager.cs
+++ b/examples/demo/Services/LogManager.cs
@@ -40,8 +40,11 @@ public class LogManager : INotifyPropertyChanged
private LogManager() { }
public void D(string tag, string message) => AddLog("D", tag, message);
+
public void I(string tag, string message) => AddLog("I", tag, message);
+
public void W(string tag, string message) => AddLog("W", tag, message);
+
public void E(string tag, string message) => AddLog("E", tag, message);
private void AddLog(string level, string tag, string message)
diff --git a/examples/demo/Services/OneSignalApiService.cs b/examples/demo/Services/OneSignalApiService.cs
index d17df7fc..9a3305e9 100644
--- a/examples/demo/Services/OneSignalApiService.cs
+++ b/examples/demo/Services/OneSignalApiService.cs
@@ -9,13 +9,15 @@ public class OneSignalApiService
private string _appId = "";
public void SetAppId(string appId) => _appId = appId;
+
public string GetAppId() => _appId;
public async Task SendNotificationAsync(NotificationType type, string subscriptionId)
{
try
{
- string title, body;
+ string title,
+ body;
Dictionary? extra = null;
switch (type)
@@ -29,12 +31,14 @@ public async Task SendNotificationAsync(NotificationType type, string subs
body = "This notification includes an image";
extra = new Dictionary
{
- ["big_picture"] = "https://media.onesignal.com/automated_push_templates/ratings_template.png",
+ ["big_picture"] =
+ "https://media.onesignal.com/automated_push_templates/ratings_template.png",
["ios_attachments"] = new Dictionary
{
- ["image"] = "https://media.onesignal.com/automated_push_templates/ratings_template.png"
+ ["image"] =
+ "https://media.onesignal.com/automated_push_templates/ratings_template.png",
},
- ["mutable_content"] = true
+ ["mutable_content"] = true,
};
break;
default:
@@ -49,7 +53,11 @@ public async Task SendNotificationAsync(NotificationType type, string subs
}
}
- public async Task SendCustomNotificationAsync(string title, string body, string subscriptionId)
+ public async Task SendCustomNotificationAsync(
+ string title,
+ string body,
+ string subscriptionId
+ )
{
try
{
@@ -61,7 +69,12 @@ public async Task SendCustomNotificationAsync(string title, string body, s
}
}
- private async Task SendAsync(string title, string body, string subscriptionId, Dictionary? extra)
+ private async Task SendAsync(
+ string title,
+ string body,
+ string subscriptionId,
+ Dictionary? extra
+ )
{
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("Accept", "application/vnd.onesignal.v1+json");
@@ -71,7 +84,7 @@ private async Task SendAsync(string title, string body, string subscriptio
["app_id"] = _appId,
["headings"] = new Dictionary { ["en"] = title },
["contents"] = new Dictionary { ["en"] = body },
- ["include_subscription_ids"] = new[] { subscriptionId }
+ ["include_subscription_ids"] = new[] { subscriptionId },
};
if (extra != null)
@@ -82,7 +95,10 @@ private async Task SendAsync(string title, string body, string subscriptio
var json = JsonSerializer.Serialize(payload);
var content = new StringContent(json, Encoding.UTF8, "application/json");
- var response = await client.PostAsync("https://onesignal.com/api/v1/notifications", content);
+ var response = await client.PostAsync(
+ "https://onesignal.com/api/v1/notifications",
+ content
+ );
return response.IsSuccessStatusCode;
}
@@ -91,9 +107,11 @@ private async Task SendAsync(string title, string body, string subscriptio
try
{
using var client = new HttpClient();
- var url = $"https://api.onesignal.com/apps/{_appId}/users/by/onesignal_id/{onesignalId}";
+ var url =
+ $"https://api.onesignal.com/apps/{_appId}/users/by/onesignal_id/{onesignalId}";
var response = await client.GetAsync(url);
- if (!response.IsSuccessStatusCode) return null;
+ if (!response.IsSuccessStatusCode)
+ return null;
var json = await response.Content.ReadAsStringAsync();
var doc = JsonDocument.Parse(json);
diff --git a/examples/demo/Services/PreferencesService.cs b/examples/demo/Services/PreferencesService.cs
index 02bebaba..52c6d2e5 100644
--- a/examples/demo/Services/PreferencesService.cs
+++ b/examples/demo/Services/PreferencesService.cs
@@ -36,8 +36,10 @@ public string? ExternalUserId
get => Preferences.Get(KeyExternalUserId, (string?)null);
set
{
- if (value == null) Preferences.Remove(KeyExternalUserId);
- else Preferences.Set(KeyExternalUserId, value);
+ if (value == null)
+ Preferences.Remove(KeyExternalUserId);
+ else
+ Preferences.Set(KeyExternalUserId, value);
}
}
diff --git a/examples/demo/Services/TooltipHelper.cs b/examples/demo/Services/TooltipHelper.cs
index 042ef757..b045d4be 100644
--- a/examples/demo/Services/TooltipHelper.cs
+++ b/examples/demo/Services/TooltipHelper.cs
@@ -3,6 +3,7 @@
namespace OneSignalDemo.Services;
public record TooltipOption(string Name, string Description);
+
public record TooltipData(string Title, string Description, List? Options);
public class TooltipHelper
@@ -20,7 +21,8 @@ private TooltipHelper() { }
public async Task InitAsync()
{
- if (_initialized) return;
+ if (_initialized)
+ return;
try
{
using var client = new HttpClient();
@@ -36,13 +38,18 @@ public async Task InitAsync()
var desc = el.TryGetProperty("description", out var d) ? d.GetString() ?? "" : "";
List? options = null;
- if (el.TryGetProperty("options", out var opts) && opts.ValueKind == JsonValueKind.Array)
+ if (
+ el.TryGetProperty("options", out var opts)
+ && opts.ValueKind == JsonValueKind.Array
+ )
{
options = new List();
foreach (var opt in opts.EnumerateArray())
{
var name = opt.TryGetProperty("name", out var n) ? n.GetString() ?? "" : "";
- var optDesc = opt.TryGetProperty("description", out var od) ? od.GetString() ?? "" : "";
+ var optDesc = opt.TryGetProperty("description", out var od)
+ ? od.GetString() ?? ""
+ : "";
options.Add(new TooltipOption(name, optDesc));
}
}
diff --git a/examples/demo/ViewModels/AppViewModel.cs b/examples/demo/ViewModels/AppViewModel.cs
index fac4a6b1..afafdb47 100644
--- a/examples/demo/ViewModels/AppViewModel.cs
+++ b/examples/demo/ViewModels/AppViewModel.cs
@@ -1,12 +1,12 @@
using System.Collections.ObjectModel;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
-using OneSignalSDK.DotNet;
-using OneSignalSDK.DotNet.Core.User;
-using OneSignalSDK.DotNet.Core.User.Subscriptions;
using OneSignalDemo.Models;
using OneSignalDemo.Repositories;
using OneSignalDemo.Services;
+using OneSignalSDK.DotNet;
+using OneSignalSDK.DotNet.Core.User;
+using OneSignalSDK.DotNet.Core.User.Subscriptions;
namespace OneSignalDemo.ViewModels;
@@ -16,27 +16,48 @@ public partial class AppViewModel : ObservableObject
private readonly PreferencesService _prefs;
// App section
- [ObservableProperty] private string _appId = "";
- [ObservableProperty] private bool _consentRequired;
- [ObservableProperty] private bool _privacyConsentGiven;
- [ObservableProperty] private string _userStatus = "Anonymous";
- [ObservableProperty] private string _externalIdDisplay = "–";
- [ObservableProperty] private bool _isLoggedIn;
- [ObservableProperty] private string _loginButtonText = "LOGIN USER";
+ [ObservableProperty]
+ private string _appId = "";
+
+ [ObservableProperty]
+ private bool _consentRequired;
+
+ [ObservableProperty]
+ private bool _privacyConsentGiven;
+
+ [ObservableProperty]
+ private string _userStatus = "Anonymous";
+
+ [ObservableProperty]
+ private string _externalIdDisplay = "–";
+
+ [ObservableProperty]
+ private bool _isLoggedIn;
+
+ [ObservableProperty]
+ private string _loginButtonText = "LOGIN USER";
// Push section
- [ObservableProperty] private string _pushSubscriptionId = "";
- [ObservableProperty] private bool _isPushEnabled;
- [ObservableProperty] private bool _hasNotificationPermission;
+ [ObservableProperty]
+ private string _pushSubscriptionId = "";
+
+ [ObservableProperty]
+ private bool _isPushEnabled;
+
+ [ObservableProperty]
+ private bool _hasNotificationPermission;
// IAM section
- [ObservableProperty] private bool _inAppMessagesPaused;
+ [ObservableProperty]
+ private bool _inAppMessagesPaused;
// Location section
- [ObservableProperty] private bool _locationShared;
+ [ObservableProperty]
+ private bool _locationShared;
// Loading
- [ObservableProperty] private bool _isLoading;
+ [ObservableProperty]
+ private bool _isLoading;
// Lists
public ObservableCollection> AliasesList { get; } = new();
@@ -109,7 +130,8 @@ private void UpdateUserStatus(string? externalId)
[RelayCommand]
public async Task LoginUserAsync(string externalUserId)
{
- if (string.IsNullOrWhiteSpace(externalUserId)) return;
+ if (string.IsNullOrWhiteSpace(externalUserId))
+ return;
IsLoading = true;
ClearUserData();
_repository.LoginUser(externalUserId);
@@ -153,7 +175,8 @@ public void AddAlias(KeyValuePair pair)
public void AddAliases(IDictionary aliases)
{
_repository.AddAliases(aliases);
- foreach (var kv in aliases) UpsertAlias(kv.Key, kv.Value);
+ foreach (var kv in aliases)
+ UpsertAlias(kv.Key, kv.Value);
LogManager.Instance.I("AppVM", $"{aliases.Count} alias(es) added");
}
@@ -176,7 +199,8 @@ private void UpsertAlias(string key, string value)
public void AddEmail(string email)
{
_repository.AddEmail(email);
- if (!EmailsList.Contains(email)) EmailsList.Add(email);
+ if (!EmailsList.Contains(email))
+ EmailsList.Add(email);
LogManager.Instance.I("AppVM", $"Email added: {email}");
}
@@ -193,7 +217,8 @@ public void RemoveEmail(string email)
public void AddSms(string sms)
{
_repository.AddSms(sms);
- if (!SmsNumbersList.Contains(sms)) SmsNumbersList.Add(sms);
+ if (!SmsNumbersList.Contains(sms))
+ SmsNumbersList.Add(sms);
LogManager.Instance.I("AppVM", $"SMS added: {sms}");
}
@@ -218,7 +243,8 @@ public void AddTag(KeyValuePair pair)
public void AddTags(IDictionary tags)
{
_repository.AddTags(tags);
- foreach (var kv in tags) UpsertTag(kv.Key, kv.Value);
+ foreach (var kv in tags)
+ UpsertTag(kv.Key, kv.Value);
LogManager.Instance.I("AppVM", $"{tags.Count} tag(s) added");
}
@@ -227,7 +253,8 @@ public void RemoveTag(string key)
{
_repository.RemoveTag(key);
var item = TagsList.FirstOrDefault(t => t.Key == key);
- if (item.Key != null) TagsList.Remove(item);
+ if (item.Key != null)
+ TagsList.Remove(item);
LogManager.Instance.I("AppVM", $"Tag removed: {key}");
}
@@ -239,7 +266,8 @@ public void RemoveSelectedTags(IEnumerable keys)
foreach (var key in keyList)
{
var item = TagsList.FirstOrDefault(t => t.Key == key);
- if (item.Key != null) TagsList.Remove(item);
+ if (item.Key != null)
+ TagsList.Remove(item);
}
LogManager.Instance.I("AppVM", $"{keyList.Count} tag(s) removed");
}
@@ -271,7 +299,8 @@ public void AddTrigger(KeyValuePair pair)
public void AddTriggers(IDictionary triggers)
{
_repository.AddTriggers(triggers);
- foreach (var kv in triggers) UpsertTrigger(kv.Key, kv.Value);
+ foreach (var kv in triggers)
+ UpsertTrigger(kv.Key, kv.Value);
LogManager.Instance.I("AppVM", $"{triggers.Count} trigger(s) added");
}
@@ -280,7 +309,8 @@ public void RemoveTrigger(string key)
{
_repository.RemoveTrigger(key);
var item = TriggersList.FirstOrDefault(t => t.Key == key);
- if (item.Key != null) TriggersList.Remove(item);
+ if (item.Key != null)
+ TriggersList.Remove(item);
LogManager.Instance.I("AppVM", $"Trigger removed: {key}");
}
@@ -292,7 +322,8 @@ public void RemoveSelectedTriggers(IEnumerable keys)
foreach (var key in keyList)
{
var item = TriggersList.FirstOrDefault(t => t.Key == key);
- if (item.Key != null) TriggersList.Remove(item);
+ if (item.Key != null)
+ TriggersList.Remove(item);
}
LogManager.Instance.I("AppVM", $"{keyList.Count} trigger(s) removed");
}
@@ -352,13 +383,19 @@ public void TrackEvent(string name, IDictionary? properties = nu
public async Task SendNotificationAsync(NotificationType type)
{
var success = await _repository.SendNotificationAsync(type);
- LogManager.Instance.I("AppVM", success ? $"Notification sent: {type}" : "Failed to send notification");
+ LogManager.Instance.I(
+ "AppVM",
+ success ? $"Notification sent: {type}" : "Failed to send notification"
+ );
}
public async Task SendCustomNotificationAsync(string title, string body)
{
var success = await _repository.SendCustomNotificationAsync(title, body);
- LogManager.Instance.I("AppVM", success ? $"Notification sent: {title}" : "Failed to send notification");
+ LogManager.Instance.I(
+ "AppVM",
+ success ? $"Notification sent: {title}" : "Failed to send notification"
+ );
}
// IAM
@@ -367,7 +404,10 @@ public void SetIamPaused(bool paused)
_repository.SetInAppMessagesPaused(paused);
_prefs.IamPaused = paused;
InAppMessagesPaused = paused;
- LogManager.Instance.I("AppVM", paused ? "In-App Messages paused" : "In-App Messages resumed");
+ LogManager.Instance.I(
+ "AppVM",
+ paused ? "In-App Messages paused" : "In-App Messages resumed"
+ );
}
public void SendInAppMessage(InAppMessageType type)
@@ -384,7 +424,10 @@ public void SetLocationSharedValue(bool shared)
_repository.SetLocationShared(shared);
_prefs.LocationShared = shared;
LocationShared = shared;
- LogManager.Instance.I("AppVM", shared ? "Location sharing enabled" : "Location sharing disabled");
+ LogManager.Instance.I(
+ "AppVM",
+ shared ? "Location sharing enabled" : "Location sharing disabled"
+ );
}
[RelayCommand]
@@ -412,8 +455,10 @@ public void SetConsentGiven(bool granted)
// Toggle push
public void SetPushEnabled(bool enabled)
{
- if (enabled) _repository.OptInPush();
- else _repository.OptOutPush();
+ if (enabled)
+ _repository.OptInPush();
+ else
+ _repository.OptOutPush();
IsPushEnabled = enabled;
LogManager.Instance.I("AppVM", enabled ? "Push enabled" : "Push disabled");
}
@@ -425,11 +470,17 @@ private void OnPushSubscriptionChanged(object? sender, PushSubscriptionChangedEv
{
PushSubscriptionId = _repository.GetPushSubscriptionId() ?? "";
IsPushEnabled = _repository.IsPushOptedIn();
- LogManager.Instance.D("AppVM", $"Push subscription changed: id={PushSubscriptionId}, optedIn={IsPushEnabled}");
+ LogManager.Instance.D(
+ "AppVM",
+ $"Push subscription changed: id={PushSubscriptionId}, optedIn={IsPushEnabled}"
+ );
});
}
- private void OnPermissionChanged(object? sender, OneSignalSDK.DotNet.Core.Notifications.NotificationPermissionChangedEventArgs args)
+ private void OnPermissionChanged(
+ object? sender,
+ OneSignalSDK.DotNet.Core.Notifications.NotificationPermissionChangedEventArgs args
+ )
{
MainThread.BeginInvokeOnMainThread(() =>
{
@@ -438,7 +489,10 @@ private void OnPermissionChanged(object? sender, OneSignalSDK.DotNet.Core.Notifi
});
}
- private void OnUserChanged(object? sender, OneSignalSDK.DotNet.Core.User.UserStateChangedEventArgs args)
+ private void OnUserChanged(
+ object? sender,
+ OneSignalSDK.DotNet.Core.User.UserStateChangedEventArgs args
+ )
{
MainThread.BeginInvokeOnMainThread(async () =>
{
diff --git a/examples/demo/demo.csproj b/examples/demo/demo.csproj
index 699bf346..1ffc4e41 100644
--- a/examples/demo/demo.csproj
+++ b/examples/demo/demo.csproj
@@ -1,5 +1,4 @@
-
net10.0-android;net10.0-ios
Exe
@@ -14,8 +13,14 @@
1
1.0
- 14.2
- 26.0
+ 14.2
+ 26.0
@@ -30,7 +35,6 @@
-
@@ -46,7 +50,10 @@
-
+
@@ -64,5 +71,4 @@
true
-