Implement offline mode
This commit is contained in:
@@ -6,6 +6,7 @@ import 'package:sheetless/core/models/config.dart';
|
||||
import 'package:sheetless/core/models/sheet.dart';
|
||||
import 'package:sheetless/core/services/api_client.dart';
|
||||
import 'package:sheetless/core/services/storage_service.dart';
|
||||
import 'package:sheetless/core/services/sync_service.dart';
|
||||
|
||||
import '../../app.dart';
|
||||
import '../auth/login_page.dart';
|
||||
@@ -34,8 +35,11 @@ class _HomePageState extends State<HomePage> with RouteAware {
|
||||
final _storageService = StorageService();
|
||||
|
||||
ApiClient? _apiClient;
|
||||
late Future<List<Sheet>> _sheetsFuture;
|
||||
SyncService? _syncService;
|
||||
late Future<SyncResult> _syncFuture;
|
||||
List<Sheet> _sheets = [];
|
||||
bool _isShuffling = false;
|
||||
bool _isOnline = true;
|
||||
String? _appName;
|
||||
String? _appVersion;
|
||||
|
||||
@@ -52,7 +56,7 @@ class _HomePageState extends State<HomePage> with RouteAware {
|
||||
});
|
||||
|
||||
_loadAppInfo();
|
||||
_sheetsFuture = _loadSheets();
|
||||
_syncFuture = _loadSheets();
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -90,19 +94,29 @@ class _HomePageState extends State<HomePage> with RouteAware {
|
||||
});
|
||||
}
|
||||
|
||||
Future<List<Sheet>> _loadSheets() async {
|
||||
Future<SyncResult> _loadSheets() async {
|
||||
final url = await _storageService.readSecure(SecureStorageKey.url);
|
||||
final jwt = await _storageService.readSecure(SecureStorageKey.jwt);
|
||||
|
||||
_apiClient = ApiClient(baseUrl: url!, token: jwt);
|
||||
_syncService = SyncService(
|
||||
apiClient: _apiClient!,
|
||||
storageService: _storageService,
|
||||
);
|
||||
|
||||
final sheets = await _apiClient!.fetchSheets();
|
||||
_log.info('${sheets.length} sheets fetched');
|
||||
// Perform sync (fetches sheets, uploads pending changes/annotations)
|
||||
final result = await _syncService!.sync();
|
||||
_log.info(
|
||||
'${result.sheets.length} sheets loaded (online: ${result.isOnline}, '
|
||||
'changes synced: ${result.changesSynced}, '
|
||||
'annotations synced: ${result.annotationsSynced})',
|
||||
);
|
||||
|
||||
final sortedSheets = await _sortSheetsByRecency(sheets);
|
||||
_log.info('${sortedSheets.length} sheets sorted');
|
||||
// Sort and store sheets
|
||||
_sheets = await _sortSheetsByRecency(result.sheets);
|
||||
_isOnline = result.isOnline;
|
||||
|
||||
return sortedSheets;
|
||||
return result;
|
||||
}
|
||||
|
||||
Future<List<Sheet>> _sortSheetsByRecency(List<Sheet> sheets) async {
|
||||
@@ -128,7 +142,7 @@ class _HomePageState extends State<HomePage> with RouteAware {
|
||||
|
||||
Future<void> _refreshSheets() async {
|
||||
setState(() {
|
||||
_sheetsFuture = _loadSheets();
|
||||
_syncFuture = _loadSheets();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -137,12 +151,10 @@ class _HomePageState extends State<HomePage> with RouteAware {
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
void _handleShuffleChanged(bool enabled) async {
|
||||
final sheets = await _sheetsFuture;
|
||||
|
||||
if (enabled) {
|
||||
sheets.shuffle();
|
||||
_sheets.shuffle();
|
||||
} else {
|
||||
await _sortSheetsByRecency(sheets);
|
||||
await _sortSheetsByRecency(_sheets);
|
||||
}
|
||||
|
||||
setState(() => _isShuffling = enabled);
|
||||
@@ -181,7 +193,16 @@ class _HomePageState extends State<HomePage> with RouteAware {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: const Text('Sheetless')),
|
||||
appBar: AppBar(
|
||||
title: const Text('Sheetless'),
|
||||
actions: [
|
||||
if (!_isOnline)
|
||||
const Padding(
|
||||
padding: EdgeInsets.only(right: 8),
|
||||
child: Icon(Icons.cloud_off, color: Colors.orange),
|
||||
),
|
||||
],
|
||||
),
|
||||
endDrawer: AppDrawer(
|
||||
isShuffling: _isShuffling,
|
||||
onShuffleChanged: _handleShuffleChanged,
|
||||
@@ -194,8 +215,8 @@ class _HomePageState extends State<HomePage> with RouteAware {
|
||||
}
|
||||
|
||||
Widget _buildBody() {
|
||||
return FutureBuilder<List<Sheet>>(
|
||||
future: _sheetsFuture,
|
||||
return FutureBuilder<SyncResult>(
|
||||
future: _syncFuture,
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.connectionState != ConnectionState.done) {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
@@ -208,8 +229,9 @@ class _HomePageState extends State<HomePage> with RouteAware {
|
||||
|
||||
if (snapshot.hasData) {
|
||||
return SheetsList(
|
||||
sheets: snapshot.data!,
|
||||
sheets: _sheets,
|
||||
onSheetSelected: _openSheet,
|
||||
syncService: _syncService!,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user