Merged PR 10778666: Recall | Show error dialog if launching from snapshot has failed

## What
Per Figma design, we can show an error dialog with messages for the failures happens during snapshot launch.

## Notes
- Fixed a crash about taking a snapshot when Calculator hasn't initialized a standard calculator.
- Simplified the restore path.

## Screenshot
![image.png](https://dev.azure.com/microsoft/d1a24475-535d-4c83-988a-9491e6dbc858/_apis/git/repositories/6255259e-4ead-4d8d-b165-55eeacc5ca48/pullRequests/10778666/attachments/image.png)

Related work items: #50858262
This commit is contained in:
Tian Liao ☕ 2024-05-20 02:53:49 +00:00
commit 32597416d0
4 changed files with 40 additions and 38 deletions

View file

@ -710,8 +710,9 @@ Windows::Data::Json::JsonObject ^ ApplicationViewModel::SaveApplicationSnapshot(
ApplicationSnapshot applicationSnapshot; ApplicationSnapshot applicationSnapshot;
applicationSnapshot.SnapshotVersion = SnapshotHelper::SnapshotVersion; applicationSnapshot.SnapshotVersion = SnapshotHelper::SnapshotVersion;
applicationSnapshot.Mode = static_cast<int>(Mode); applicationSnapshot.Mode = static_cast<int>(Mode);
if (NavCategory::IsCalculatorViewMode(m_mode) && m_CalculatorViewModel != nullptr) if (m_CalculatorViewModel != nullptr && m_mode == ViewMode::Standard)
{ {
// Standard calculator is the only supported mode so far.
applicationSnapshot.StandardCalc = m_CalculatorViewModel->GetStandardCalculatorSnapshot(); applicationSnapshot.StandardCalc = m_CalculatorViewModel->GetStandardCalculatorSnapshot();
} }
return SnapshotHelper::SaveSnapshotToJson(applicationSnapshot); return SnapshotHelper::SaveSnapshotToJson(applicationSnapshot);

View file

@ -1786,7 +1786,7 @@ void StandardCalculatorViewModel::SetBitshiftRadioButtonCheckedAnnouncement(Plat
StandardCalculatorSnapshot StandardCalculatorViewModel::GetStandardCalculatorSnapshot() const StandardCalculatorSnapshot StandardCalculatorViewModel::GetStandardCalculatorSnapshot() const
{ {
StandardCalculatorSnapshot snapshot; StandardCalculatorSnapshot snapshot;
auto historyItems = m_standardCalculatorManager.GetHistoryItems(); auto& historyItems = m_standardCalculatorManager.GetHistoryItems();
if (!historyItems.empty()) if (!historyItems.empty())
{ {
snapshot.CalcManager.HistoryItems = std::move(historyItems); snapshot.CalcManager.HistoryItems = std::move(historyItems);

View file

@ -1773,7 +1773,7 @@
<value>J</value> <value>J</value>
<comment>An abbreviation for a measurement unit of energy</comment> <comment>An abbreviation for a measurement unit of energy</comment>
</data> </data>
<data name="UnitAbbreviation_Kilowatthour" xml:space="preserve"> <data name="UnitAbbreviation_Kilowatthour" xml:space="preserve">
<value>kWh</value> <value>kWh</value>
<comment>An abbreviation for a measurement unit of electricity consumption</comment> <comment>An abbreviation for a measurement unit of electricity consumption</comment>
</data> </data>
@ -2145,7 +2145,7 @@
<value>Joules</value> <value>Joules</value>
<comment>A measurement unit for energy. (Please choose the most appropriate plural form to fit any number between 0 and 999,999,999,999,999)</comment> <comment>A measurement unit for energy. (Please choose the most appropriate plural form to fit any number between 0 and 999,999,999,999,999)</comment>
</data> </data>
<data name="UnitName_Kilowatthour" xml:space="preserve"> <data name="UnitName_Kilowatthour" xml:space="preserve">
<value>Kilowatt-hours</value> <value>Kilowatt-hours</value>
<comment>A measurement unit for electricity consumption. (Please choose the most appropriate plural form to fit any number between 0 and 999,999,999,999,999)</comment> <comment>A measurement unit for electricity consumption. (Please choose the most appropriate plural form to fit any number between 0 and 999,999,999,999,999)</comment>
</data> </data>
@ -4754,4 +4754,12 @@
<value>Open the context menu for available actions</value> <value>Open the context menu for available actions</value>
<comment>Screen reader prompt for the context menu of the expression box</comment> <comment>Screen reader prompt for the context menu of the expression box</comment>
</data> </data>
</root> <data name="ErrorButtonOk" xml:space="preserve">
<value>OK</value>
<comment>The text of OK button to dismiss an error dialog.</comment>
</data>
<data name="SnapshotRestoreError" xml:space="preserve">
<value>Couldn't restore this snapshot.</value>
<comment>The error message to notify user that restoring from snapshot has failed.</comment>
</data>
</root>

View file

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Threading.Tasks;
using Windows.ApplicationModel.UserActivities; using Windows.ApplicationModel.UserActivities;
using Windows.Data.Json; using Windows.Data.Json;
@ -21,9 +22,11 @@ using CalculatorApp.ViewModel;
using CalculatorApp.ViewModel.Common; using CalculatorApp.ViewModel.Common;
using CalculatorApp.ViewModel.Common.Automation; using CalculatorApp.ViewModel.Common.Automation;
using wuxc = Windows.UI.Xaml.Controls;
namespace CalculatorApp namespace CalculatorApp
{ {
public sealed partial class MainPage : Windows.UI.Xaml.Controls.Page public sealed partial class MainPage : wuxc.Page
{ {
public static readonly DependencyProperty NavViewCategoriesSourceProperty = public static readonly DependencyProperty NavViewCategoriesSourceProperty =
DependencyProperty.Register(nameof(NavViewCategoriesSource), typeof(List<object>), typeof(MainPage), new PropertyMetadata(default)); DependencyProperty.Register(nameof(NavViewCategoriesSource), typeof(List<object>), typeof(MainPage), new PropertyMetadata(default));
@ -165,42 +168,19 @@ namespace CalculatorApp
{ {
var channel = UserActivityChannel.GetDefault(); var channel = UserActivityChannel.GetDefault();
var activity = await channel.GetOrCreateUserActivityAsync(snapshotArgs.ActivityId); var activity = await channel.GetOrCreateUserActivityAsync(snapshotArgs.ActivityId);
if (!snapshotArgs.VerifyIncomingActivity(activity))
// Work around for bug https://microsoft.visualstudio.com/DefaultCollection/OS/_workitems/edit/48931227
// where ContentInfo can't be directly accessed.
if (snapshotArgs.VerifyIncomingActivity(activity) &&
JsonObject.TryParse(activity.ToJson(), out var activityJson) &&
activityJson.ContainsKey("contentInfo") &&
Model.TryRestoreFromSnapshot(activityJson.GetNamedObject("contentInfo")))
{ {
// something's going wrong with the activity SelectNavigationItemByModel();
// TODO: show error dialog
return;
} }
else else
{ {
if (JsonObject.TryParse(activity.ToJson(), out var activityJson)) await ShowSnapshotLaunchErrorAsync();
{
try
{
// Work around for bug https://microsoft.visualstudio.com/DefaultCollection/OS/_workitems/edit/48931227 where ContentInfo can't be directly accessed.
var contentJson = activityJson.GetNamedObject("contentInfo");
if (Model.TryRestoreFromSnapshot(contentJson))
{
SelectNavigationItemByModel();
}
else
{
// TODO: show error dialog
return;
}
}
catch (Exception ex)
{
// TODO: show error dialog
return;
}
}
else
{
// data corrupted
// TODO: show error dialog
return;
}
} }
}); });
Model.Initialize(initialMode); Model.Initialize(initialMode);
@ -681,6 +661,19 @@ namespace CalculatorApp
CloseSettingsPopup(); CloseSettingsPopup();
} }
private async Task ShowSnapshotLaunchErrorAsync()
{
var resProvider = AppResourceProvider.GetInstance();
var dialog = new wuxc.ContentDialog
{
Title = resProvider.GetResourceString("AppName"),
Content = new wuxc.TextBlock { Text = resProvider.GetResourceString("SnapshotRestoreError") },
CloseButtonText = resProvider.GetResourceString("ErrorButtonOk"),
DefaultButton = wuxc.ContentDialogButton.Close
};
await dialog.ShowAsync();
}
private Calculator m_calculator; private Calculator m_calculator;
private GraphingCalculator m_graphingCalculator; private GraphingCalculator m_graphingCalculator;
private UnitConverter m_converter; private UnitConverter m_converter;