import 'dart:convert'; import 'package:home_widget/home_widget.dart'; import 'package:wonders/common_libs.dart'; import 'package:wonders/logic/common/save_load_mixin.dart'; import 'package:wonders/logic/data/collectible_data.dart'; import 'package:http/http.dart' as http; class CollectiblesLogic with ThrottledSaveLoadMixin { @override String get fileName => 'collectibles.dat'; static const _appGroupId = 'group.com.gskinner.flutter.wonders.widget'; static const _appName = 'WonderousWidget'; /// Holds all collectibles that the views should care about final List all = collectiblesData; /// Current state for each collectible late final statesById = ValueNotifier>({})..addListener(_updateCounts); int _discoveredCount = 0; int get discoveredCount => _discoveredCount; int _exploredCount = 0; int get exploredCount => _exploredCount; void init() { HomeWidget.setAppGroupId(_appGroupId); } CollectibleData? fromId(String? id) => id == null ? null : all.firstWhereOrNull((o) => o.id == id); List forWonder(WonderType wonder) { return all.where((o) => o.wonder == wonder).toList(growable: false); } void setState(String id, int state) { Map states = Map.of(statesById.value); if (state == CollectibleState.discovered) { final data = fromId(id)!; _updateHomeWidgetTextData( title: data.title, id: data.id, imageUrl: data.imageUrlSmall, ); } states[id] = state; statesById.value = states; scheduleSave(); } void _updateCounts() { _discoveredCount = _exploredCount = 0; statesById.value.forEach((_, state) { if (state == CollectibleState.discovered) _discoveredCount++; if (state == CollectibleState.explored) _exploredCount++; }); HomeWidget.saveWidgetData('discoveredCount', _discoveredCount).then((value){ HomeWidget.updateWidget(iOSName: _appName); }); debugPrint('setting discovered count for home widget $_discoveredCount'); } /// Get a discovered item, sorted by the order of wondersLogic.all CollectibleData? getFirstDiscoveredOrNull() { List discovered = []; statesById.value.forEach((key, value) { if (value == CollectibleState.discovered) discovered.add(fromId(key)!); }); for (var w in wondersLogic.all) { for (var d in discovered) { if (d.wonder == w.type) return d; } } return null; } bool isLost(WonderType wonderType, int i) { final datas = forWonder(wonderType); final states = statesById.value; if (datas.length > i && states.containsKey(datas[i].id)) { return states[datas[i].id] == CollectibleState.lost; } return true; } void reset() { Map states = {}; for (int i = 0; i < all.length; i++) { states[all[i].id] = CollectibleState.lost; } _updateHomeWidgetTextData(); // clear home widget data statesById.value = states; debugPrint('collection reset'); scheduleSave(); } Future _updateHomeWidgetTextData({String title = '', String id = '', String imageUrl = ''}) async { // Save title HomeWidget.saveWidgetData('lastDiscoveredTitle', title); // Subtitle String subTitle = ''; if(id.isNotEmpty){ final artifactData = await artifactLogic.getArtifactByID(id); subTitle = artifactData?.date ?? ''; } HomeWidget.saveWidgetData('lastDiscoveredSubTitle', subTitle); // Image, // Download, convert to base64 string and write to shared widget data String imageBase64 = ''; if(imageUrl.isNotEmpty){ var bytes = await http.readBytes(Uri.parse(imageUrl)); imageBase64 = base64Encode(bytes); debugPrint('Saving base64 bytes: $imageBase64'); } HomeWidget.saveWidgetData('lastDiscoveredImageData', imageBase64); HomeWidget.updateWidget(iOSName: _appName); } @override void copyFromJson(Map value) { Map states = {}; for (int i = 0; i < all.length; i++) { String id = all[i].id; states[id] = value[id] ?? CollectibleState.lost; } statesById.value = states; } @override Map toJson() => statesById.value; }