129 lines
3.2 KiB
Dart
129 lines
3.2 KiB
Dart
import 'package:flutter/foundation.dart';
|
|
import 'package:kooltab2/utils/app_update_util.dart';
|
|
import 'package:ota_update/ota_update.dart';
|
|
|
|
import '../models/settings.dart';
|
|
import '../services/settings_service.dart';
|
|
|
|
class SettingsViewModel extends ChangeNotifier {
|
|
final SettingsService settingsService;
|
|
|
|
SettingsViewModel({required this.settingsService});
|
|
|
|
AppSettings _settings = AppSettings.defaults;
|
|
bool _isLoading = false;
|
|
bool _hasLoaded = false;
|
|
String? _errorMessage;
|
|
|
|
final AppUpdateUtil _updater = AppUpdateUtil(
|
|
serverUrl: "https://updater.brammie15.dev",
|
|
);
|
|
|
|
bool _checkingForUpdates = false;
|
|
|
|
bool get checkingForUpdates => _checkingForUpdates;
|
|
|
|
AppSettings get settings => _settings;
|
|
|
|
bool get isLoading => _isLoading;
|
|
|
|
bool get hasLoaded => _hasLoaded;
|
|
|
|
String? get errorMessage => _errorMessage;
|
|
|
|
Future<void> ensureLoaded() async {
|
|
if (_hasLoaded || _isLoading) return;
|
|
await load();
|
|
}
|
|
|
|
Future<void> load() async {
|
|
if (_isLoading) return;
|
|
|
|
_isLoading = true;
|
|
_errorMessage = null;
|
|
notifyListeners();
|
|
|
|
try {
|
|
_settings = await settingsService.getSettings();
|
|
} catch (_) {
|
|
_errorMessage = 'Could not load settings.';
|
|
} finally {
|
|
_hasLoaded = true;
|
|
_isLoading = false;
|
|
notifyListeners();
|
|
}
|
|
}
|
|
|
|
Future<UpdateInfo?> checkForUpdates() async {
|
|
if (_checkingForUpdates) return null;
|
|
|
|
_checkingForUpdates = true;
|
|
notifyListeners();
|
|
|
|
try {
|
|
return await _updater.checkForUpdate();
|
|
} finally {
|
|
_checkingForUpdates = false;
|
|
notifyListeners();
|
|
}
|
|
}
|
|
|
|
Future<void> installUpdate(
|
|
UpdateInfo update, {
|
|
void Function(double progress)? onProgress,
|
|
}) async {
|
|
final url = update.download.startsWith("http")
|
|
? update.download
|
|
: "https://updater.brammie15.dev${update.download}";
|
|
|
|
debugPrint("Download Url: ${url}");
|
|
|
|
final stream = OtaUpdate().execute(
|
|
url,
|
|
destinationFilename: "update.apk",
|
|
sha256checksum: update.sha256,
|
|
);
|
|
|
|
await for (final event in stream) {
|
|
debugPrint("OTA: ${event.status} ${event.value}");
|
|
|
|
if (event.status == OtaStatus.DOWNLOADING) {
|
|
final progress = double.tryParse(event.value ?? "0") ?? 0;
|
|
|
|
onProgress?.call(progress / 100);
|
|
}
|
|
|
|
if (event.status == OtaStatus.DOWNLOAD_ERROR) {
|
|
throw Exception("Download failed: ${event.value}");
|
|
}
|
|
|
|
if (event.status == OtaStatus.INSTALLATION_ERROR) {
|
|
throw Exception("Installation failed: ${event.value}");
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Just flips the preference flag. Caller is responsible for having
|
|
/// already set/verified the actual PIN via PinLockViewModel first.
|
|
Future<void> updatePinRequired(bool value) =>
|
|
_save(_settings.copyWith(pinRequired: value));
|
|
|
|
Future<void> updateThemeMode(AppThemeMode mode) =>
|
|
_save(_settings.copyWith(themeMode: mode));
|
|
|
|
Future<void> _save(AppSettings updated) async {
|
|
final previous = _settings;
|
|
_settings = updated;
|
|
_errorMessage = null;
|
|
notifyListeners();
|
|
|
|
try {
|
|
await settingsService.saveSettings(updated);
|
|
} catch (_) {
|
|
_settings = previous;
|
|
_errorMessage = 'Could not save settings.';
|
|
notifyListeners();
|
|
}
|
|
}
|
|
}
|