Split force update and check for update

This commit is contained in:
2025-09-27 21:49:13 +08:00
parent 113309257e
commit fe33931304
3 changed files with 95 additions and 75 deletions

View File

@@ -1,7 +1,6 @@
import "dart:async"; import "dart:async";
import "dart:convert"; import "dart:convert";
import "package:flutter/material.dart"; import "package:flutter/material.dart";
import "package:hooks_riverpod/hooks_riverpod.dart";
import "package:island/models/chat.dart"; import "package:island/models/chat.dart";
import "package:island/pods/lifecycle.dart"; import "package:island/pods/lifecycle.dart";
import "package:island/pods/chat/messages_notifier.dart"; import "package:island/pods/chat/messages_notifier.dart";

View File

@@ -211,21 +211,11 @@ class _AboutScreenState extends ConsumerState<AboutScreen> {
icon: Symbols.system_update, icon: Symbols.system_update,
title: 'Check for updates', title: 'Check for updates',
onTap: () async { onTap: () async {
// Fetch latest release and show the unified sheet
final svc = UpdateService(); final svc = UpdateService();
// Reuse service fetch + compare to decide content
showLoadingModal(context); showLoadingModal(context);
final release = await svc.fetchLatestRelease(); svc.checkForUpdates(context);
if (!context.mounted) return; if (!context.mounted) return;
hideLoadingModal(context); hideLoadingModal(context);
if (release != null) {
await svc.showUpdateSheet(context, release);
} else {
showInfoAlert(
'Currently cannot get update from the GitHub.',
'Unable to check for updates',
);
}
}, },
), ),
_buildListTile( _buildListTile(

View File

@@ -1,10 +1,13 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_cache_manager/flutter_cache_manager.dart'; import 'package:flutter_cache_manager/flutter_cache_manager.dart';
import 'package:gap/gap.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:island/pods/message.dart'; import 'package:island/pods/message.dart';
import 'package:island/pods/network.dart'; import 'package:island/pods/network.dart';
import 'package:island/pods/websocket.dart'; import 'package:island/pods/websocket.dart';
import 'package:island/services/update_service.dart';
import 'package:island/widgets/alert.dart';
import 'package:island/widgets/content/network_status_sheet.dart'; import 'package:island/widgets/content/network_status_sheet.dart';
import 'package:island/widgets/content/sheet.dart'; import 'package:island/widgets/content/sheet.dart';
import 'package:material_symbols_icons/symbols.dart'; import 'package:material_symbols_icons/symbols.dart';
@@ -65,69 +68,97 @@ class DebugSheet extends HookConsumerWidget {
return SheetScaffold( return SheetScaffold(
titleText: 'Debug', titleText: 'Debug',
heightFactor: 0.6, heightFactor: 0.6,
child: Column( child: SingleChildScrollView(
children: [ child: Column(
ListTile( children: [
minTileHeight: 48, const Gap(4),
leading: const Icon(Symbols.wifi), ListTile(
trailing: const Icon(Symbols.chevron_right), minTileHeight: 48,
title: Text('Connection Status'), leading: const Icon(Symbols.update),
contentPadding: EdgeInsets.symmetric(horizontal: 24), trailing: const Icon(Symbols.chevron_right),
onTap: () { title: Text('Force Update'),
showModalBottomSheet( contentPadding: const EdgeInsets.symmetric(horizontal: 24),
context: context, onTap: () async {
isScrollControlled: true, // Fetch latest release and show the unified sheet
builder: final svc = UpdateService();
(context) => NetworkStatusSheet( // Reuse service fetch + compare to decide content
onReconnect: () => wsNotifier.connect(), showLoadingModal(context);
), final release = await svc.fetchLatestRelease();
); if (!context.mounted) return;
}, hideLoadingModal(context);
), if (release != null) {
const Divider(height: 1), await svc.showUpdateSheet(context, release);
ListTile( } else {
minTileHeight: 48, showInfoAlert(
leading: const Icon(Symbols.copy_all), 'Currently cannot get update from the GitHub.',
trailing: const Icon(Symbols.chevron_right), 'Unable to check for updates',
contentPadding: EdgeInsets.symmetric(horizontal: 24), );
title: Text('Copy access token'), }
onTap: () async { }
final tk = ref.watch(tokenProvider); ),
Clipboard.setData(ClipboardData(text: tk!.token)); const Divider(height: 8),
}, ListTile(
), minTileHeight: 48,
ListTile( leading: const Icon(Symbols.wifi),
minTileHeight: 48, trailing: const Icon(Symbols.chevron_right),
leading: const Icon(Symbols.edit), title: Text('Connection Status'),
trailing: const Icon(Symbols.chevron_right), contentPadding: EdgeInsets.symmetric(horizontal: 24),
contentPadding: EdgeInsets.symmetric(horizontal: 24), onTap: () {
title: Text('Set access token'), showModalBottomSheet(
onTap: () async { context: context,
await _showSetTokenDialog(context, ref); isScrollControlled: true,
}, builder:
), (context) => NetworkStatusSheet(
const Divider(height: 1), onReconnect: () => wsNotifier.connect(),
ListTile( ),
minTileHeight: 48, );
leading: const Icon(Symbols.delete), },
trailing: const Icon(Symbols.chevron_right), ),
contentPadding: EdgeInsets.symmetric(horizontal: 24), const Divider(height: 8),
title: Text('Reset database'), ListTile(
onTap: () async { minTileHeight: 48,
resetDatabase(ref); leading: const Icon(Symbols.copy_all),
}, trailing: const Icon(Symbols.chevron_right),
), contentPadding: EdgeInsets.symmetric(horizontal: 24),
ListTile( title: Text('Copy access token'),
minTileHeight: 48, onTap: () async {
leading: const Icon(Symbols.clear), final tk = ref.watch(tokenProvider);
trailing: const Icon(Symbols.chevron_right), Clipboard.setData(ClipboardData(text: tk!.token));
contentPadding: EdgeInsets.symmetric(horizontal: 24), },
title: Text('Clear cache'), ),
onTap: () async { ListTile(
DefaultCacheManager().emptyCache(); minTileHeight: 48,
}, leading: const Icon(Symbols.edit),
), trailing: const Icon(Symbols.chevron_right),
], contentPadding: EdgeInsets.symmetric(horizontal: 24),
title: Text('Set access token'),
onTap: () async {
await _showSetTokenDialog(context, ref);
},
),
const Divider(height: 8),
ListTile(
minTileHeight: 48,
leading: const Icon(Symbols.delete),
trailing: const Icon(Symbols.chevron_right),
contentPadding: EdgeInsets.symmetric(horizontal: 24),
title: Text('Reset database'),
onTap: () async {
resetDatabase(ref);
},
),
ListTile(
minTileHeight: 48,
leading: const Icon(Symbols.clear),
trailing: const Icon(Symbols.chevron_right),
contentPadding: EdgeInsets.symmetric(horizontal: 24),
title: Text('Clear cache'),
onTap: () async {
DefaultCacheManager().emptyCache();
},
),
],
),
), ),
); );
} }