Skip to content

Commit 144a948

Browse files
committed
improve bit Boilerplate docs (#11591)
1 parent 83cbee2 commit 144a948

File tree

17 files changed

+99
-16
lines changed

17 files changed

+99
-16
lines changed

src/Templates/Boilerplate/Bit.Boilerplate/.docs/22- Messaging.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -546,7 +546,20 @@ private async Task ShowNotification()
546546

547547
---
548548

549-
## 7. Dashboard Data Changed Example
549+
## 7. Testing Push Notifications - Understanding the Four Scenarios
550+
551+
When testing push notifications, you must consider **four distinct scenarios** based on the app state when the notification is sent and when the user taps on it:
552+
553+
1. **Scenario 1**: The app was **closed** when the notification was sent, and the app was **still closed** when the user tapped on the notification.
554+
2. **Scenario 2**: The app was **closed** when the notification was sent, but the app was **already open** when the user tapped on the notification.
555+
3. **Scenario 3**: The app was **open** when the notification was sent, but the app was **closed** when the user tapped on the notification.
556+
4. **Scenario 4**: The app was **open** when the notification was sent, and the app was **still open** when the user tapped on the notification.
557+
558+
The codebase includes specialized handling across all platforms to manage these scenarios correctly. The implementation uses different entry points and data extraction methods depending on whether the app is starting up, already running, or being brought back from the background.
559+
560+
---
561+
562+
## 8. Dashboard Data Changed Example
550563

551564
Another common scenario is notifying all authenticated clients when data changes.
552565

src/Templates/Boilerplate/Bit.Boilerplate/.github/copilot-instructions.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ After applying changes, you **MUST** verify the integrity of the application.
128128
Example 1: `OnClick="WrapHandled(MyMethod)"` instead of `OnClick="MyMethod"`.
129129
Example 2: `OnClick="WrapHandled(async () => await MyMethod())"` instead of `OnClick="async () => await MyMethod()"`.
130130
16. **Use OData Query Options**: Leverage `[EnableQuery]` and `ODataQueryOptions` for efficient data filtering and pagination.
131-
17. **Follow Mapperly Conventions**: Use partial static classes and extensions methods with Mapperly for high-performance object mapping.
131+
17. **Follow Mapperly Conventions**: Use **partial static classes and extensions methods** with Mapperly for high-performance object mapping.
132132
18. **Handle Concurrency**: Always use `ConcurrencyStamp` for optimistic concurrency control in update and delete operations.
133133

134134
## Instructions for adding new model/entity to ef-core DbContext / Database

src/Templates/Boilerplate/Bit.Boilerplate/.github/prompts/getting-started.prompt.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1083,6 +1083,12 @@ At the end of Stage 21, ask: **"Do you have any questions about .NET MAUI, nativ
10831083
- Find `PushNotificationService` implementation
10841084
- Show examples of sending push notifications with deep links
10851085
- Explain how to handle notification clicks on the client side
1086+
- **Explain** that in order to test push notifications, the following scenarios must be considered:
1087+
1. The time that push notification was sent, the app was closed already, and when the user tapped on the notification to open the app, the app was still closed.
1088+
2. The time that push notification was sent, the app was closed already, but when the user tapped on the notification, the app was already open.
1089+
3. The time that push notification was sent, the app was open, but the time that user tapped on the notification, the app was closed.
1090+
4. The time that push notification was sent, the app was open, and the time that user tapped on the notification, the app was still open.
1091+
Explain that if some similar codes exists in the codebase, they are used to handle these 4 different scenarios across platforms.
10861092
<!--#endif-->
10871093

10881094
---

src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Common/Prompt.razor

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
@inherits AppComponentBase
22

3+
@* This component gets shown by the PromptService to prompt the user for input. *@
4+
35
<section>
46
<BitStack Gap="0">
57
<BitStack Horizontal AutoHeight Class="header-stack">

src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Layout/AppAiChatPanel.razor.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,8 @@ private async Task StartChannel()
158158
{
159159
channel = Channel.CreateUnbounded<string>(new() { SingleReader = true, SingleWriter = true });
160160

161+
// The following code streams user's input messages to the server and processes the streamed responses.
162+
// It keeps the chat ongoing until CurrentCancellationToken is cancelled.
161163
await foreach (var response in hubConnection.StreamAsync<string>("Chatbot",
162164
new StartChatbotRequest()
163165
{

src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Pages/Identity/SignIn/SignInPanel.razor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ private async Task SocialSignIn(string provider)
211211
try
212212
{
213213
pubSubUnsubscribe?.Invoke();
214-
pubSubUnsubscribe = PubSubService.Subscribe(ClientPubSubMessages.SOCIAL_SIGN_IN, async (uriString) =>
214+
pubSubUnsubscribe = PubSubService.Subscribe(ClientPubSubMessages.SOCIAL_SIGN_IN_CALLBACK, async (uriString) =>
215215
{
216216
// Check out SignInModalService for more details
217217
var uri = uriString!.ToString();

src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Pages/Identity/SignUp/SignUpPage.razor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ private async Task SocialSignUp(string provider)
9090
{
9191
try
9292
{
93-
pubSubUnsubscribe = PubSubService.Subscribe(ClientPubSubMessages.SOCIAL_SIGN_IN, async (uriString) =>
93+
pubSubUnsubscribe = PubSubService.Subscribe(ClientPubSubMessages.SOCIAL_SIGN_IN_CALLBACK, async (uriString) =>
9494
{
9595
// Social sign-in creates a new user automatically, so we only need to navigate to the sign-in page to automatically sign-in the user by provided OTP.
9696
NavigationManager.NavigateTo(uriString!.ToString()!, replace: true);

src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Services/ClientPubSubMessages.cs

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,40 +8,94 @@ public partial class ClientPubSubMessages
88
: SharedPubSubMessages
99
//#endif
1010
{
11+
/// <summary>
12+
/// A publisher that publishes this message wants a snack bar to be shown.
13+
/// </summary>
1114
public const string SHOW_SNACK = nameof(SHOW_SNACK);
15+
16+
/// <summary>
17+
/// A publisher that publishes this message wants a modal to be shown.
18+
/// </summary>
1219
public const string SHOW_MODAL = nameof(SHOW_MODAL);
20+
21+
/// <summary>
22+
/// A publisher that publishes this message wants a modal to be closed.
23+
/// </summary>
1324
public const string CLOSE_MODAL = nameof(CLOSE_MODAL);
1425

26+
/// <summary>
27+
/// This message gets published when the app theme is changed.
28+
/// </summary>
1529
public const string THEME_CHANGED = nameof(THEME_CHANGED);
30+
31+
/// <summary>
32+
/// A publisher that publishes this message wants the navigation panel to be opened.
33+
/// </summary>
1634
public const string OPEN_NAV_PANEL = nameof(OPEN_NAV_PANEL);
35+
36+
/// <summary>
37+
/// A publisher that publishes this message wants the navigation panel to be closed.
38+
/// </summary>
1739
public const string CLOSE_NAV_PANEL = nameof(CLOSE_NAV_PANEL);
40+
41+
/// <summary>
42+
/// When the culture is changed, this message is published.
43+
/// </summary>
1844
public const string CULTURE_CHANGED = nameof(CULTURE_CHANGED);
45+
1946
/// <summary>
2047
/// <inheritdoc cref="Parameters.IsOnline"/>
2148
/// </summary>
2249
public const string IS_ONLINE_CHANGED = nameof(IS_ONLINE_CHANGED);
50+
51+
/// <summary>
52+
/// When the data of the current page is changed, this message is published.
53+
/// </summary>
2354
public const string PAGE_DATA_CHANGED = nameof(PAGE_DATA_CHANGED);
55+
56+
/// <summary>
57+
/// When the route data is updated, this message is published.
58+
/// </summary>
2459
public const string ROUTE_DATA_UPDATED = nameof(ROUTE_DATA_UPDATED);
2560

2661
/// <summary>
2762
/// Supposed to be called using JavaScript to navigate between pages without reloading the app.
2863
/// </summary>
2964
public const string NAVIGATE_TO = nameof(NAVIGATE_TO);
65+
66+
/// <summary>
67+
/// A publisher that publishes this message wants the diagnostic modal to be shown.
68+
/// </summary>
3069
public const string SHOW_DIAGNOSTIC_MODAL = nameof(SHOW_DIAGNOSTIC_MODAL);
3170

3271
//#if (signalR != true)
72+
/// <summary>
73+
/// When the user profile is updated, this message is published.
74+
/// </summary>
3375
public const string PROFILE_UPDATED = nameof(PROFILE_UPDATED);
3476
//#endif
3577

3678
//#if(module == "Sales")
79+
/// <summary>
80+
/// When a user taps on search bar, this message is published to open the AI chat panel with product search prompt.
81+
/// </summary>
3782
public const string SEARCH_PRODUCTS = nameof(SEARCH_PRODUCTS);
3883
//#endif
3984

4085
//#if(ads == true)
86+
/// <summary>
87+
/// When a user has trouble with ads, this message is published to open the AI chat panel with ad help prompt.
88+
/// </summary>
4189
public const string AD_HAVE_TROUBLE = nameof(AD_HAVE_TROUBLE);
4290
//#endif
4391

44-
public const string SOCIAL_SIGN_IN = nameof(SOCIAL_SIGN_IN);
92+
/// <summary>
93+
/// When a user completes social sign-in in a separate window, this message is published to notify the app.
94+
/// </summary>
95+
public const string SOCIAL_SIGN_IN_CALLBACK = nameof(SOCIAL_SIGN_IN_CALLBACK);
4596

97+
/// <summary>
98+
/// A publisher that publishes this message wants to force the app to check for updates and install them.
99+
/// </summary>
46100
public const string FORCE_UPDATE = nameof(FORCE_UPDATE);
47101
}

src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Services/Contracts/ILocalHttpServer.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
namespace Boilerplate.Client.Core.Services.Contracts;
1+
namespace Boilerplate.Client.Core.Services.Contracts;
22

3+
// Checkout Client.web/wwwroot/web-interop-app.html's comments.
34
public interface ILocalHttpServer : IAsyncDisposable
45
{
56
int EnsureStarted();

src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Services/DefaultExternalNavigationService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public async Task NavigateToAsync(string url)
3636
else
3737
{
3838
pubSubUnsubscribe?.Invoke();
39-
pubSubUnsubscribe = pubSubService.Subscribe(ClientPubSubMessages.SOCIAL_SIGN_IN, async _ =>
39+
pubSubUnsubscribe = pubSubService.Subscribe(ClientPubSubMessages.SOCIAL_SIGN_IN_CALLBACK, async _ =>
4040
{
4141
if (lastOpenedWindowId != null)
4242
{

0 commit comments

Comments
 (0)