Skip to content

Commit 5e2c77b

Browse files
committed
- improved shutdown/resume handling on mobiles
- fixed switching between external and internal screens on Android - improved new version notification
1 parent cbc1cd9 commit 5e2c77b

File tree

7 files changed

+215
-64
lines changed

7 files changed

+215
-64
lines changed

Spixi/App.xaml.cs

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@ public static App Instance(bool force_redraw = false)
2323
}
2424
public static bool isInForeground { get; set; } = false;
2525

26-
Node node = null;
27-
2826
public static Window appWindow { get; private set; } = null;
2927

3028
public static string startingScreen = ""; // Which screen to start on
@@ -122,9 +120,9 @@ public App()
122120

123121
UIHelpers.reloadAllPages();
124122
};
125-
123+
126124
// Start Ixian code
127-
node = new Node();
125+
_ = new Node();
128126

129127
// Attempt to load a pre-existing wallet
130128
bool wallet_found = Node.checkForExistingWallet();
@@ -171,7 +169,6 @@ public App()
171169
else
172170
{
173171
// Already started before
174-
node = Node.Instance;
175172
}
176173
}
177174

@@ -223,11 +220,6 @@ protected override Window CreateWindow(IActivationState activationState)
223220
window.Title = "Spixi IM";
224221
if (appWindow == null)
225222
{
226-
window.Destroying += (s, e) =>
227-
{
228-
Shutdown();
229-
};
230-
231223
window.Resumed += (s, e) =>
232224
{
233225
if (Config.enablePushNotifications && IxianHandler.wallets.Count > 0)
@@ -240,12 +232,19 @@ protected override Window CreateWindow(IActivationState activationState)
240232
return window;
241233
}
242234

243-
public static void Shutdown()
235+
public static async Task Shutdown()
244236
{
245-
IxianHandler.shutdown();
246-
while (IxianHandler.status != NodeStatus.stopped)
237+
try
247238
{
248-
Thread.Sleep(10);
239+
IxianHandler.shutdown();
240+
while (IxianHandler.status != NodeStatus.stopped)
241+
{
242+
await Task.Delay(10);
243+
}
244+
}
245+
catch (Exception ex)
246+
{
247+
Logging.error("Exception during Shutdown: {0}", ex);
249248
}
250249
}
251250

@@ -276,4 +275,30 @@ private static void CurrentDomainOnUnhandledException(object sender, UnhandledEx
276275
}
277276
}
278277

278+
public static void EnsureNodeRunning()
279+
{
280+
try
281+
{
282+
if (Instance == null)
283+
{
284+
Logging.info("EnsureNodeRunning: Node.Instance is null, creating new Node");
285+
_ = new Node();
286+
}
287+
else if (IxianHandler.status == NodeStatus.stopped)
288+
{
289+
Logging.info("EnsureNodeRunning: Node exists but is stopped");
290+
//preStart();
291+
//start();
292+
}
293+
else
294+
{
295+
Logging.info("EnsureNodeRunning: Node is already running");
296+
}
297+
}
298+
catch (Exception ex)
299+
{
300+
Logging.error("EnsureNodeRunning exception: {0}", ex);
301+
}
302+
}
303+
279304
}

Spixi/MauiProgram.cs

Lines changed: 86 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,106 @@
1-
using CommunityToolkit.Maui;
1+
#if ANDROID
2+
using Android.App;
3+
using Android.OS;
4+
#endif
5+
6+
using CommunityToolkit.Maui;
7+
using IXICore.Meta;
28
using Microsoft.Maui.Controls.Compatibility.Hosting;
3-
using Microsoft.Maui.Handlers;
9+
using Microsoft.Maui.LifecycleEvents;
410

511
namespace Spixi;
612

713
public static class MauiProgram
814
{
9-
public static MauiApp CreateMauiApp()
10-
{
11-
var builder = MauiApp.CreateBuilder();
12-
builder
13-
.UseMauiApp<App>()
15+
public static MauiApp CreateMauiApp()
16+
{
17+
var builder = MauiApp.CreateBuilder();
18+
builder
19+
.UseMauiApp<App>()
1420
.UseMauiCompatibility()
1521
.UseMauiCommunityToolkit()
1622
.ConfigureFonts(fonts =>
17-
{
18-
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
19-
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
20-
})
23+
{
24+
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
25+
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
26+
})
2127
.ConfigureMauiHandlers((handlers) =>
2228
{
2329
#if ANDROID
2430
//handlers.AddHandler(typeof(WebView), typeof(Spixi.Platforms.Android.Renderers.MyWebViewHandler));
25-
handlers.AddCompatibilityRenderer(typeof(WebView), typeof(Spixi.Platforms.Android.Renderers.SpixiWebviewRenderer2));
31+
handlers.AddCompatibilityRenderer(typeof(WebView), typeof(Spixi.Platforms.Android.Renderers.SpixiWebviewRenderer2));
2632
#endif
33+
2734
#if IOS
2835
handlers.AddHandler(typeof(WebView), typeof(Spixi.Platforms.iOS.iOSWebViewHandler));
36+
#endif
37+
})
38+
.ConfigureLifecycleEvents(events =>
39+
{
40+
#if ANDROID
41+
events.AddAndroid(android =>
42+
{
43+
// Shutdown logic
44+
android.OnDestroy(async (activity) =>
45+
{
46+
if (!activity.IsChangingConfigurations)
47+
{
48+
Logging.info("Android OnDestroy real exit, shutting down Node");
49+
await App.Shutdown();
50+
}
51+
else
52+
{
53+
Logging.info("Android OnDestroy ignored due to IsChangingConfigurations=true");
54+
}
55+
});
56+
57+
// Restart logic when activity comes back to foreground
58+
android.OnResume((activity) =>
59+
{
60+
Logging.info("Android OnResume - ensuring Node is running");
61+
App.isInForeground = true;
62+
App.EnsureNodeRunning();
63+
});
64+
});
65+
#endif
66+
67+
#if IOS
68+
events.AddiOS(ios =>
69+
{
70+
ios.WillTerminate(async (app) =>
71+
{
72+
Logging.info("iOS WillTerminate shutting down Node");
73+
await App.Shutdown();
74+
});
75+
76+
ios.OnActivated((app) =>
77+
{
78+
Logging.info("iOS OnActivated ensuring Node is running");
79+
App.isInForeground = true;
80+
App.EnsureNodeRunning();
81+
});
82+
});
83+
#endif
84+
85+
#if WINDOWS
86+
events.AddWindows(windows =>
87+
{
88+
windows.OnClosed(async (window, args) =>
89+
{
90+
Logging.info("Windows OnWindowClosed - shutting down Node");
91+
await App.Shutdown();
92+
});
93+
94+
windows.OnWindowCreated((window) =>
95+
{
96+
Logging.info("Windows OnWindowCreated - ensuring Node is running");
97+
App.isInForeground = true;
98+
App.EnsureNodeRunning();
99+
});
100+
});
29101
#endif
30102
});
31103

32-
return builder.Build();
33-
}
104+
return builder.Build();
105+
}
34106
}

Spixi/Meta/Config.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public class Config
3333
public static readonly int packetDataSize = 102400; // 100 Kb per packet for file transfers
3434
public static readonly long packetRequestTimeout = 60; // Time in seconds to re-request packets
3535

36-
public static readonly string version = "spixi-0.9.9"; // Spixi version
36+
public static readonly string version = "spixi-0.9.10-dev"; // Spixi version
3737

3838
public static readonly string checkVersionUrl = "https://resources.ixian.io/spixi-update.txt";
3939
public static readonly int checkVersionSeconds = 1 * 60 * 60; // 1 hour

Spixi/Meta/Node.cs

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,10 @@ public Node()
6868
networkClientManagerStatic = new NetworkClientManagerStatic(Config.maxRelaySectorNodesToConnectTo);
6969
NetworkClientManager.init(networkClientManagerStatic);
7070

71+
// Prepare the stream processor
72+
StreamCapabilities caps = StreamCapabilities.Incoming | StreamCapabilities.Outgoing | StreamCapabilities.IPN | StreamCapabilities.Apps;
73+
streamProcessor = new StreamProcessor(new SpixiPendingMessageProcessor(Config.spixiUserFolder, Config.enablePushNotifications), caps);
74+
7175
// Init TIV
7276
tiv = new TransactionInclusion(new SpixiTransactionInclusionCallbacks(), false);
7377

@@ -81,13 +85,21 @@ public Node()
8185

8286
FriendList.init(Config.spixiUserFolder);
8387

84-
Logging.info("Node init done");
88+
UpdateVerify.init(Config.checkVersionUrl, Config.checkVersionSeconds);
89+
90+
OfflinePushMessages.init(Config.pushServiceUrl, streamProcessor);
8591

8692
string backup_file_name = Path.Combine(Config.spixiUserFolder, "spixi.account.backup.ixi");
8793
if (File.Exists(backup_file_name))
8894
{
8995
File.Delete(backup_file_name);
9096
}
97+
98+
InventoryCache.init(new InventoryCacheClient(tiv));
99+
100+
RelaySectors.init(CoreConfig.relaySectorLevels, null);
101+
102+
Logging.info("Node init done");
91103
}
92104

93105
static public void preStart()
@@ -96,12 +108,6 @@ static public void preStart()
96108
IxianHandler.localStorage.start();
97109

98110
FriendList.loadContacts();
99-
100-
// Prepare the stream processor
101-
StreamCapabilities caps = StreamCapabilities.Incoming | StreamCapabilities.Outgoing | StreamCapabilities.IPN | StreamCapabilities.Apps;
102-
streamProcessor = new StreamProcessor(new SpixiPendingMessageProcessor(Config.spixiUserFolder, Config.enablePushNotifications), caps);
103-
104-
OfflinePushMessages.init(Config.pushServiceUrl, streamProcessor);
105111
}
106112

107113
static public void start()
@@ -114,7 +120,6 @@ static public void start()
114120

115121
running = true;
116122

117-
UpdateVerify.init(Config.checkVersionUrl, Config.checkVersionSeconds);
118123
UpdateVerify.start();
119124

120125
ulong block_height = 0;
@@ -147,9 +152,7 @@ static public void start()
147152
// Start the network queue
148153
NetworkQueue.start();
149154

150-
InventoryCache.init(new InventoryCacheClient(tiv));
151-
152-
RelaySectors.init(CoreConfig.relaySectorLevels, null);
155+
streamProcessor.start();
153156

154157
// Start the keepalive thread
155158
PresenceList.startKeepAlive();
@@ -387,7 +390,7 @@ static public void stop()
387390
running = false;
388391

389392
// Stop the stream processor
390-
streamProcessor.uninitialize();
393+
streamProcessor.stop();
391394

392395
IxianHandler.localStorage.stop();
393396

Spixi/Pages/Chat/SingleChatPage.xaml.cs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,10 @@ private void onLoad()
495495
}
496496

497497
UIHelpers.refreshAppRequests = true;
498+
warningDisplayed = false;
499+
unreadIndicatorDisplayed = false;
500+
setNickname = "";
501+
setOnlineStatus = false;
498502

499503
// Execute timer-related functionality immediately
500504
updateScreen();
@@ -508,8 +512,15 @@ private void onLoad()
508512
}
509513
}
510514

511-
webView.FadeTo(1, 150);
512-
webView.Focus();
515+
try
516+
{
517+
webView.FadeTo(1, 150);
518+
webView.Focus();
519+
}
520+
catch (Exception ex)
521+
{
522+
Logging.warn("Exception: " + ex);
523+
}
513524

514525
Task.Run(() =>
515526
{

0 commit comments

Comments
 (0)