@capgo/capacitor-updater 7.42.9 → 7.45.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Package.swift +5 -2
- package/README.md +250 -77
- package/android/build.gradle +3 -3
- package/android/src/main/java/ee/forgr/capacitor_updater/CapacitorUpdaterPlugin.java +682 -213
- package/android/src/main/java/ee/forgr/capacitor_updater/CapgoUpdater.java +222 -35
- package/android/src/main/java/ee/forgr/capacitor_updater/DelayUpdateUtils.java +49 -13
- package/android/src/main/java/ee/forgr/capacitor_updater/DownloadService.java +38 -13
- package/android/src/main/java/ee/forgr/capacitor_updater/InternalUtils.java +13 -0
- package/android/src/main/java/ee/forgr/capacitor_updater/ShakeMenu.java +476 -2
- package/dist/docs.json +402 -10
- package/dist/esm/definitions.d.ts +183 -22
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/web.d.ts +3 -2
- package/dist/esm/web.js +6 -4
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +6 -4
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +6 -4
- package/dist/plugin.js.map +1 -1
- package/ios/Sources/CapacitorUpdaterPlugin/CapacitorUpdaterPlugin.swift +653 -140
- package/ios/Sources/CapacitorUpdaterPlugin/CapgoUpdater.swift +213 -50
- package/ios/Sources/CapacitorUpdaterPlugin/DelayUpdateUtils.swift +37 -16
- package/ios/Sources/CapacitorUpdaterPlugin/InternalUtils.swift +2 -0
- package/ios/Sources/CapacitorUpdaterPlugin/ShakeMenu.swift +347 -2
- package/package.json +12 -8
|
@@ -10,8 +10,19 @@ import android.app.Activity;
|
|
|
10
10
|
import android.app.AlertDialog;
|
|
11
11
|
import android.content.DialogInterface;
|
|
12
12
|
import android.hardware.SensorManager;
|
|
13
|
+
import android.text.Editable;
|
|
14
|
+
import android.text.TextWatcher;
|
|
15
|
+
import android.widget.ArrayAdapter;
|
|
16
|
+
import android.widget.EditText;
|
|
17
|
+
import android.widget.LinearLayout;
|
|
18
|
+
import android.widget.ListView;
|
|
19
|
+
import android.widget.ProgressBar;
|
|
13
20
|
import com.getcapacitor.Bridge;
|
|
14
21
|
import com.getcapacitor.BridgeActivity;
|
|
22
|
+
import java.util.ArrayList;
|
|
23
|
+
import java.util.List;
|
|
24
|
+
import java.util.Map;
|
|
25
|
+
import org.json.JSONArray;
|
|
15
26
|
|
|
16
27
|
public class ShakeMenu implements ShakeDetector.Listener {
|
|
17
28
|
|
|
@@ -54,10 +65,16 @@ public class ShakeMenu implements ShakeDetector.Listener {
|
|
|
54
65
|
}
|
|
55
66
|
|
|
56
67
|
isShowing = true;
|
|
57
|
-
|
|
68
|
+
|
|
69
|
+
// Check if channel selector mode is enabled
|
|
70
|
+
if (plugin.shakeChannelSelectorEnabled) {
|
|
71
|
+
showChannelSelector();
|
|
72
|
+
} else {
|
|
73
|
+
showDefaultMenu();
|
|
74
|
+
}
|
|
58
75
|
}
|
|
59
76
|
|
|
60
|
-
private void
|
|
77
|
+
private void showDefaultMenu() {
|
|
61
78
|
activity.runOnUiThread(() -> {
|
|
62
79
|
try {
|
|
63
80
|
String appName = activity.getPackageManager().getApplicationLabel(activity.getApplicationInfo()).toString();
|
|
@@ -166,4 +183,461 @@ public class ShakeMenu implements ShakeDetector.Listener {
|
|
|
166
183
|
}
|
|
167
184
|
});
|
|
168
185
|
}
|
|
186
|
+
|
|
187
|
+
private void showChannelSelector() {
|
|
188
|
+
activity.runOnUiThread(() -> {
|
|
189
|
+
try {
|
|
190
|
+
// Show loading dialog
|
|
191
|
+
AlertDialog.Builder loadingBuilder = new AlertDialog.Builder(activity);
|
|
192
|
+
loadingBuilder.setTitle("Loading Channels...");
|
|
193
|
+
loadingBuilder.setCancelable(true);
|
|
194
|
+
|
|
195
|
+
ProgressBar progressBar = new ProgressBar(activity);
|
|
196
|
+
progressBar.setIndeterminate(true);
|
|
197
|
+
int padding = dpToPx(20);
|
|
198
|
+
progressBar.setPadding(padding, padding, padding, padding);
|
|
199
|
+
loadingBuilder.setView(progressBar);
|
|
200
|
+
|
|
201
|
+
final boolean[] didCancel = { false };
|
|
202
|
+
|
|
203
|
+
loadingBuilder.setNegativeButton("Cancel", (dialog, which) -> {
|
|
204
|
+
didCancel[0] = true;
|
|
205
|
+
dialog.dismiss();
|
|
206
|
+
isShowing = false;
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
AlertDialog loadingDialog = loadingBuilder.create();
|
|
210
|
+
loadingDialog.setOnCancelListener((d) -> {
|
|
211
|
+
didCancel[0] = true;
|
|
212
|
+
isShowing = false;
|
|
213
|
+
});
|
|
214
|
+
loadingDialog.setOnDismissListener((d) -> {
|
|
215
|
+
if (didCancel[0]) {
|
|
216
|
+
isShowing = false;
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
loadingDialog.show();
|
|
220
|
+
|
|
221
|
+
// Fetch channels in background
|
|
222
|
+
new Thread(() -> {
|
|
223
|
+
final CapgoUpdater updater = plugin.implementation;
|
|
224
|
+
updater.listChannels((res) -> {
|
|
225
|
+
activity.runOnUiThread(() -> {
|
|
226
|
+
loadingDialog.dismiss();
|
|
227
|
+
|
|
228
|
+
if (didCancel[0]) {
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
if (res == null) {
|
|
233
|
+
showError("Failed to load channels: unknown error");
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
Object errorObj = res.get("error");
|
|
238
|
+
if (errorObj != null) {
|
|
239
|
+
Object messageObj = res.get("message");
|
|
240
|
+
String message = messageObj != null ? messageObj.toString() : errorObj.toString();
|
|
241
|
+
showError("Failed to load channels: " + message);
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
Object channelsObj = res.get("channels");
|
|
246
|
+
if (!(channelsObj instanceof List)) {
|
|
247
|
+
showError("No channels available for self-assignment");
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
List<?> channelsRaw = (List<?>) channelsObj;
|
|
252
|
+
List<Map<String, Object>> channels = toChannelList(channelsRaw);
|
|
253
|
+
|
|
254
|
+
if (channels.isEmpty()) {
|
|
255
|
+
showError("No channels available for self-assignment");
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
presentChannelPicker(channels);
|
|
260
|
+
});
|
|
261
|
+
});
|
|
262
|
+
})
|
|
263
|
+
.start();
|
|
264
|
+
} catch (Exception e) {
|
|
265
|
+
logger.error("Error showing channel selector: " + e.getMessage());
|
|
266
|
+
isShowing = false;
|
|
267
|
+
}
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
private List<Map<String, Object>> toChannelList(List<?> channelsRaw) {
|
|
272
|
+
List<Map<String, Object>> channels = new ArrayList<>();
|
|
273
|
+
for (Object item : channelsRaw) {
|
|
274
|
+
if (!(item instanceof Map<?, ?> rawMap)) {
|
|
275
|
+
continue;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
Map<String, Object> channel = new java.util.HashMap<>();
|
|
279
|
+
for (Map.Entry<?, ?> entry : rawMap.entrySet()) {
|
|
280
|
+
if (entry.getKey() instanceof String key) {
|
|
281
|
+
channel.put(key, entry.getValue());
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
if (!channel.isEmpty()) {
|
|
286
|
+
channels.add(channel);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
return channels;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
private void presentChannelPicker(List<Map<String, Object>> channels) {
|
|
293
|
+
try {
|
|
294
|
+
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
|
|
295
|
+
builder.setTitle("Select Channel");
|
|
296
|
+
|
|
297
|
+
// Create custom layout with search and channel list
|
|
298
|
+
LinearLayout layout = new LinearLayout(activity);
|
|
299
|
+
layout.setOrientation(LinearLayout.VERTICAL);
|
|
300
|
+
int padding = dpToPx(16);
|
|
301
|
+
layout.setPadding(padding, padding, padding, padding);
|
|
302
|
+
|
|
303
|
+
// Search field
|
|
304
|
+
EditText searchField = new EditText(activity);
|
|
305
|
+
searchField.setHint("Search channels...");
|
|
306
|
+
searchField.setSingleLine(true);
|
|
307
|
+
layout.addView(searchField);
|
|
308
|
+
|
|
309
|
+
// Create list of channel names
|
|
310
|
+
List<String> allChannelNames = new ArrayList<>();
|
|
311
|
+
for (Map<String, Object> channel : channels) {
|
|
312
|
+
Object nameObj = channel.get("name");
|
|
313
|
+
if (nameObj instanceof String) {
|
|
314
|
+
allChannelNames.add((String) nameObj);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// Displayed channels (first 5 by default)
|
|
319
|
+
final List<String> displayedChannels = new ArrayList<>();
|
|
320
|
+
displayedChannels.addAll(allChannelNames.subList(0, Math.min(5, allChannelNames.size())));
|
|
321
|
+
|
|
322
|
+
final ArrayAdapter<String> adapter = new ArrayAdapter<>(activity, android.R.layout.simple_list_item_1, displayedChannels);
|
|
323
|
+
|
|
324
|
+
ListView listView = new ListView(activity);
|
|
325
|
+
listView.setAdapter(adapter);
|
|
326
|
+
|
|
327
|
+
// Set fixed height for list (about 5 items)
|
|
328
|
+
LinearLayout.LayoutParams listParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, dpToPx(250));
|
|
329
|
+
listView.setLayoutParams(listParams);
|
|
330
|
+
layout.addView(listView);
|
|
331
|
+
|
|
332
|
+
builder.setView(layout);
|
|
333
|
+
builder.setNegativeButton("Cancel", (dialog, which) -> {
|
|
334
|
+
dialog.dismiss();
|
|
335
|
+
isShowing = false;
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
AlertDialog dialog = builder.create();
|
|
339
|
+
dialog.setOnDismissListener((d) -> isShowing = false);
|
|
340
|
+
|
|
341
|
+
// Search filter
|
|
342
|
+
searchField.addTextChangedListener(
|
|
343
|
+
new TextWatcher() {
|
|
344
|
+
@Override
|
|
345
|
+
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
|
|
346
|
+
|
|
347
|
+
@Override
|
|
348
|
+
public void onTextChanged(CharSequence s, int start, int before, int count) {}
|
|
349
|
+
|
|
350
|
+
@Override
|
|
351
|
+
public void afterTextChanged(Editable s) {
|
|
352
|
+
String query = s.toString().toLowerCase();
|
|
353
|
+
displayedChannels.clear();
|
|
354
|
+
|
|
355
|
+
int count = 0;
|
|
356
|
+
for (String name : allChannelNames) {
|
|
357
|
+
if (name.toLowerCase().contains(query)) {
|
|
358
|
+
displayedChannels.add(name);
|
|
359
|
+
count++;
|
|
360
|
+
if (count >= 5) break;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
adapter.notifyDataSetChanged();
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
);
|
|
368
|
+
|
|
369
|
+
// Channel selection
|
|
370
|
+
listView.setOnItemClickListener((parent, view, position, id) -> {
|
|
371
|
+
String selectedChannel = displayedChannels.get(position);
|
|
372
|
+
dialog.dismiss();
|
|
373
|
+
selectChannel(selectedChannel);
|
|
374
|
+
});
|
|
375
|
+
|
|
376
|
+
dialog.show();
|
|
377
|
+
} catch (Exception e) {
|
|
378
|
+
logger.error("Error presenting channel picker: " + e.getMessage());
|
|
379
|
+
isShowing = false;
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
private void selectChannel(String channelName) {
|
|
384
|
+
activity.runOnUiThread(() -> {
|
|
385
|
+
try {
|
|
386
|
+
// Show progress dialog
|
|
387
|
+
AlertDialog.Builder progressBuilder = new AlertDialog.Builder(activity);
|
|
388
|
+
progressBuilder.setTitle("Switching to " + channelName);
|
|
389
|
+
progressBuilder.setMessage("Setting channel...");
|
|
390
|
+
progressBuilder.setCancelable(false);
|
|
391
|
+
|
|
392
|
+
ProgressBar progressBar = new ProgressBar(activity);
|
|
393
|
+
progressBar.setIndeterminate(true);
|
|
394
|
+
int padding = dpToPx(20);
|
|
395
|
+
progressBar.setPadding(padding, padding, padding, padding);
|
|
396
|
+
progressBuilder.setView(progressBar);
|
|
397
|
+
|
|
398
|
+
AlertDialog progressDialog = progressBuilder.create();
|
|
399
|
+
progressDialog.show();
|
|
400
|
+
|
|
401
|
+
new Thread(() -> {
|
|
402
|
+
final CapgoUpdater updater = plugin.implementation;
|
|
403
|
+
final Bridge bridge = activity.getBridge();
|
|
404
|
+
|
|
405
|
+
// Set the channel - respect plugin's allowSetDefaultChannel config
|
|
406
|
+
updater.setChannel(
|
|
407
|
+
channelName,
|
|
408
|
+
updater.editor,
|
|
409
|
+
"CapacitorUpdater.defaultChannel",
|
|
410
|
+
plugin.allowSetDefaultChannel,
|
|
411
|
+
(setRes) -> {
|
|
412
|
+
if (setRes == null) {
|
|
413
|
+
activity.runOnUiThread(() -> {
|
|
414
|
+
progressDialog.dismiss();
|
|
415
|
+
showError("Failed to set channel: unknown error");
|
|
416
|
+
});
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
Object errorObj = setRes.get("error");
|
|
421
|
+
if (errorObj != null) {
|
|
422
|
+
Object messageObj = setRes.get("message");
|
|
423
|
+
String message = messageObj != null ? messageObj.toString() : errorObj.toString();
|
|
424
|
+
activity.runOnUiThread(() -> {
|
|
425
|
+
progressDialog.dismiss();
|
|
426
|
+
showError("Failed to set channel: " + message);
|
|
427
|
+
});
|
|
428
|
+
return;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
// Update progress message
|
|
432
|
+
activity.runOnUiThread(() -> progressDialog.setMessage("Checking for updates..."));
|
|
433
|
+
|
|
434
|
+
// Check for updates
|
|
435
|
+
String updateUrlStr = plugin.getUpdateUrl();
|
|
436
|
+
if (updateUrlStr == null || updateUrlStr.isEmpty()) {
|
|
437
|
+
updateUrlStr = "https://plugin.capgo.app/updates";
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
final String finalUpdateUrlStr = updateUrlStr;
|
|
441
|
+
updater.getLatest(finalUpdateUrlStr, channelName, (latestRes) -> {
|
|
442
|
+
if (latestRes == null) {
|
|
443
|
+
activity.runOnUiThread(() -> {
|
|
444
|
+
progressDialog.dismiss();
|
|
445
|
+
showSuccess("Channel set to " + channelName + ". Could not check for updates.");
|
|
446
|
+
});
|
|
447
|
+
return;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
String latestError = getString(latestRes, "error");
|
|
451
|
+
String latestKind = getString(latestRes, "kind");
|
|
452
|
+
String latestMessage = getString(latestRes, "message");
|
|
453
|
+
|
|
454
|
+
String detail = latestMessage != null && !latestMessage.isEmpty()
|
|
455
|
+
? latestMessage
|
|
456
|
+
: latestError != null && !latestError.isEmpty()
|
|
457
|
+
? latestError
|
|
458
|
+
: latestKind != null && !latestKind.isEmpty()
|
|
459
|
+
? latestKind
|
|
460
|
+
: "server did not provide a message";
|
|
461
|
+
|
|
462
|
+
// Handle update errors first (before "no new version" check)
|
|
463
|
+
if (
|
|
464
|
+
"failed".equals(latestKind) ||
|
|
465
|
+
(latestError != null &&
|
|
466
|
+
!latestError.isEmpty() &&
|
|
467
|
+
!"up_to_date".equals(latestKind) &&
|
|
468
|
+
!"blocked".equals(latestKind))
|
|
469
|
+
) {
|
|
470
|
+
activity.runOnUiThread(() -> {
|
|
471
|
+
progressDialog.dismiss();
|
|
472
|
+
showError("Channel set to " + channelName + ". Update check failed: " + detail);
|
|
473
|
+
});
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
if ("blocked".equals(latestKind)) {
|
|
478
|
+
activity.runOnUiThread(() -> {
|
|
479
|
+
progressDialog.dismiss();
|
|
480
|
+
showError("Channel set to " + channelName + ". Update check blocked: " + detail);
|
|
481
|
+
});
|
|
482
|
+
return;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
String latestUrl = getString(latestRes, "url");
|
|
486
|
+
|
|
487
|
+
// Check if there's an actual update available
|
|
488
|
+
if ("up_to_date".equals(latestKind) || latestUrl == null || latestUrl.isEmpty()) {
|
|
489
|
+
activity.runOnUiThread(() -> {
|
|
490
|
+
progressDialog.dismiss();
|
|
491
|
+
showSuccess("Channel set to " + channelName + ". Already on latest version.");
|
|
492
|
+
});
|
|
493
|
+
return;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
String version = getString(latestRes, "version");
|
|
497
|
+
if (version == null || version.isEmpty()) {
|
|
498
|
+
activity.runOnUiThread(() -> {
|
|
499
|
+
progressDialog.dismiss();
|
|
500
|
+
showError("Channel set to " + channelName + ". Update check failed: missing version.");
|
|
501
|
+
});
|
|
502
|
+
return;
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
// Update message
|
|
506
|
+
final String versionForUi = version;
|
|
507
|
+
activity.runOnUiThread(() -> progressDialog.setMessage("Downloading update " + versionForUi + "..."));
|
|
508
|
+
|
|
509
|
+
String sessionKey = getString(latestRes, "sessionKey");
|
|
510
|
+
String checksum = getString(latestRes, "checksum");
|
|
511
|
+
Object manifestObj = latestRes.get("manifest");
|
|
512
|
+
|
|
513
|
+
// Download the update
|
|
514
|
+
try {
|
|
515
|
+
BundleInfo bundle;
|
|
516
|
+
if (manifestObj != null) {
|
|
517
|
+
JSONArray manifestArray = null;
|
|
518
|
+
if (manifestObj instanceof JSONArray) {
|
|
519
|
+
manifestArray = (JSONArray) manifestObj;
|
|
520
|
+
} else if (manifestObj instanceof List) {
|
|
521
|
+
manifestArray = new JSONArray((List<?>) manifestObj);
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
if (manifestArray == null) {
|
|
525
|
+
throw new IllegalArgumentException("Invalid manifest format");
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
bundle = updater.downloadManifest(
|
|
529
|
+
latestUrl,
|
|
530
|
+
versionForUi,
|
|
531
|
+
sessionKey != null ? sessionKey : "",
|
|
532
|
+
checksum != null ? checksum : "",
|
|
533
|
+
manifestArray
|
|
534
|
+
);
|
|
535
|
+
} else {
|
|
536
|
+
bundle = updater.download(
|
|
537
|
+
latestUrl,
|
|
538
|
+
versionForUi,
|
|
539
|
+
sessionKey != null ? sessionKey : "",
|
|
540
|
+
checksum != null ? checksum : ""
|
|
541
|
+
);
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
// Set as next bundle
|
|
545
|
+
updater.setNextBundle(bundle.getId());
|
|
546
|
+
|
|
547
|
+
activity.runOnUiThread(() -> {
|
|
548
|
+
progressDialog.dismiss();
|
|
549
|
+
showSuccessWithReload("Update downloaded! Reload to apply version " + versionForUi + "?", () -> {
|
|
550
|
+
try {
|
|
551
|
+
if (bridge == null) {
|
|
552
|
+
logger.warn("Bridge is null, cannot reload app");
|
|
553
|
+
return;
|
|
554
|
+
}
|
|
555
|
+
updater.set(bundle);
|
|
556
|
+
String path = updater.getCurrentBundlePath();
|
|
557
|
+
if (updater.isUsingBuiltin()) {
|
|
558
|
+
bridge.setServerAssetPath(path);
|
|
559
|
+
} else {
|
|
560
|
+
bridge.setServerBasePath(path);
|
|
561
|
+
}
|
|
562
|
+
if (bridge.getWebView() != null) {
|
|
563
|
+
bridge.getWebView().reload();
|
|
564
|
+
}
|
|
565
|
+
} catch (Exception e) {
|
|
566
|
+
logger.error("Error applying bundle before reload: " + e.getMessage());
|
|
567
|
+
}
|
|
568
|
+
});
|
|
569
|
+
});
|
|
570
|
+
} catch (Exception e) {
|
|
571
|
+
activity.runOnUiThread(() -> {
|
|
572
|
+
progressDialog.dismiss();
|
|
573
|
+
showError("Failed to download update: " + e.getMessage());
|
|
574
|
+
});
|
|
575
|
+
}
|
|
576
|
+
});
|
|
577
|
+
}
|
|
578
|
+
);
|
|
579
|
+
})
|
|
580
|
+
.start();
|
|
581
|
+
} catch (Exception e) {
|
|
582
|
+
logger.error("Error selecting channel: " + e.getMessage());
|
|
583
|
+
isShowing = false;
|
|
584
|
+
}
|
|
585
|
+
});
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
private void showError(String message) {
|
|
589
|
+
logger.error(message);
|
|
590
|
+
new AlertDialog.Builder(activity)
|
|
591
|
+
.setTitle("Error")
|
|
592
|
+
.setMessage(message)
|
|
593
|
+
.setPositiveButton("OK", (d, w) -> {
|
|
594
|
+
d.dismiss();
|
|
595
|
+
isShowing = false;
|
|
596
|
+
})
|
|
597
|
+
.setOnDismissListener((d) -> isShowing = false)
|
|
598
|
+
.show();
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
private void showSuccess(String message) {
|
|
602
|
+
logger.info(message);
|
|
603
|
+
new AlertDialog.Builder(activity)
|
|
604
|
+
.setTitle("Success")
|
|
605
|
+
.setMessage(message)
|
|
606
|
+
.setPositiveButton("OK", (d, w) -> {
|
|
607
|
+
d.dismiss();
|
|
608
|
+
isShowing = false;
|
|
609
|
+
})
|
|
610
|
+
.setOnDismissListener((d) -> isShowing = false)
|
|
611
|
+
.show();
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
private void showSuccessWithReload(String message, Runnable onReload) {
|
|
615
|
+
logger.info(message);
|
|
616
|
+
new AlertDialog.Builder(activity)
|
|
617
|
+
.setTitle("Update Ready")
|
|
618
|
+
.setMessage(message)
|
|
619
|
+
.setPositiveButton("Reload Now", (d, w) -> {
|
|
620
|
+
d.dismiss();
|
|
621
|
+
isShowing = false;
|
|
622
|
+
if (onReload != null) {
|
|
623
|
+
onReload.run();
|
|
624
|
+
}
|
|
625
|
+
})
|
|
626
|
+
.setNegativeButton("Later", (d, w) -> {
|
|
627
|
+
d.dismiss();
|
|
628
|
+
isShowing = false;
|
|
629
|
+
})
|
|
630
|
+
.setOnDismissListener((d) -> isShowing = false)
|
|
631
|
+
.show();
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
private String getString(Map<String, Object> map, String key) {
|
|
635
|
+
Object value = map.get(key);
|
|
636
|
+
return value != null ? value.toString() : null;
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
private int dpToPx(int dp) {
|
|
640
|
+
float density = activity.getResources().getDisplayMetrics().density;
|
|
641
|
+
return Math.round(dp * density);
|
|
642
|
+
}
|
|
169
643
|
}
|