first working version

This commit is contained in:
stopflock committed 2026-09-23 14:39:11 -05:00
1 parent c95171a3ad
commit 54ef1b8afc
26 files changed
+745 -27

No files matched your search

+60
View File
@@ -0,0 +1,60 @@
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../services/osm_block_service.dart';
import 'settings_state.dart';
/// Tracks whether the current user has an active OSM DWG block.
///
/// Persisted per upload mode so the last known state survives app restarts
/// (e.g. launching offline) - a failed/inconclusive check leaves the
/// persisted value untouched rather than assuming "not blocked".
class AccountBlockState extends ChangeNotifier {
final OSMBlockService _blockService;
AccountBlockState({OSMBlockService? blockService})
: _blockService = blockService ?? OSMBlockService();
bool _isBlocked = false;
bool get isBlocked => _isBlocked;
/// Load the last known block state for the given upload mode.
Future<void> init(UploadMode uploadMode) async {
final prefs = await SharedPreferences.getInstance();
_isBlocked = prefs.getBool(_prefsKey(uploadMode)) ?? false;
notifyListeners();
}
/// Check for an active block. Returns the conclusive result (true/false),
/// or null if the check was inconclusive (offline, error, not logged in,
/// simulate mode). On null, the previously known state is left unchanged.
Future<bool?> check({
required String? accessToken,
required UploadMode uploadMode,
}) async {
final result = await _blockService.checkActiveBlock(
accessToken: accessToken,
uploadMode: uploadMode,
);
if (result != null && result != _isBlocked) {
_isBlocked = result;
final prefs = await SharedPreferences.getInstance();
await prefs.setBool(_prefsKey(uploadMode), result);
notifyListeners();
}
return result;
}
/// Clear block state (called on logout).
void clear() {
if (_isBlocked) {
_isBlocked = false;
notifyListeners();
}
}
String _prefsKey(UploadMode uploadMode) => 'account_blocked_${uploadMode.name}';
}
+14
View File
@@ -20,11 +20,13 @@ class UploadQueueState extends ChangeNotifier {
final List<PendingUpload> _queue = [];
Timer? _uploadTimer;
int _activeUploadCount = 0;
bool _isPausedDueToBlock = false;
// Getters
int get pendingCount => _queue.length;
List<PendingUpload> get pendingUploads => List.unmodifiable(_queue);
int get activeUploadCount => _activeUploadCount;
bool get isPausedDueToBlock => _isPausedDueToBlock;
// Initialize by loading queue from storage and repopulate cache with pending nodes
Future<void> init() async {
@@ -326,8 +328,10 @@ class UploadQueueState extends ChangeNotifier {
required bool pauseQueueProcessing,
required UploadMode uploadMode,
required Future<String?> Function() getAccessToken,
required Future<bool?> Function() checkActiveBlock,
}) {
_uploadTimer?.cancel();
_isPausedDueToBlock = false;
// No uploads if queue is empty, offline mode is enabled, or queue processing is paused
if (_queue.isEmpty || offlineMode || pauseQueueProcessing) return;
@@ -386,6 +390,16 @@ class UploadQueueState extends ChangeNotifier {
final access = await getAccessToken();
if (access == null) return; // not logged in
// Don't start new uploads if the user has an active OSM block.
// Leave the item pending - it'll be retried next time the uploader starts.
if (await checkActiveBlock() == true) {
debugPrint('[UploadQueue] Active block detected, pausing queue processing');
_isPausedDueToBlock = true;
_uploadTimer?.cancel();
notifyListeners();
return;
}
// Start processing the next pending upload
final item = pendingItems.first;
debugPrint('[UploadQueue] Starting new upload processing for item at ${item.coord} ($_activeUploadCount/$kMaxConcurrentUploads active)');