2023-10-23 17:43:16 -06:00
|
|
|
import 'dart:convert';
|
|
|
|
|
2024-01-22 15:08:58 -07:00
|
|
|
import 'package:http/http.dart' as http;
|
2022-08-29 20:38:28 -06:00
|
|
|
import 'package:wonders/common_libs.dart';
|
2024-01-18 12:43:03 -07:00
|
|
|
import 'package:wonders/logic/common/platform_info.dart';
|
2022-08-29 20:38:28 -06:00
|
|
|
import 'package:wonders/logic/common/save_load_mixin.dart';
|
|
|
|
import 'package:wonders/logic/data/collectible_data.dart';
|
2024-01-18 12:43:03 -07:00
|
|
|
import 'package:wonders/logic/native_widget_service.dart';
|
2022-08-29 20:38:28 -06:00
|
|
|
|
|
|
|
class CollectiblesLogic with ThrottledSaveLoadMixin {
|
|
|
|
@override
|
|
|
|
String get fileName => 'collectibles.dat';
|
|
|
|
|
|
|
|
/// Holds all collectibles that the views should care about
|
|
|
|
final List<CollectibleData> all = collectiblesData;
|
|
|
|
|
|
|
|
/// Current state for each collectible
|
2022-11-14 09:14:08 -07:00
|
|
|
late final statesById = ValueNotifier<Map<String, int>>({})..addListener(_updateCounts);
|
|
|
|
|
|
|
|
int _discoveredCount = 0;
|
2023-10-23 17:43:16 -06:00
|
|
|
|
2022-11-14 09:14:08 -07:00
|
|
|
int get discoveredCount => _discoveredCount;
|
|
|
|
|
|
|
|
int _exploredCount = 0;
|
2023-10-23 17:43:16 -06:00
|
|
|
|
2022-11-14 09:14:08 -07:00
|
|
|
int get exploredCount => _exploredCount;
|
2022-08-29 20:38:28 -06:00
|
|
|
|
2024-01-18 12:43:03 -07:00
|
|
|
late final _nativeWidget = GetIt.I<NativeWidgetService>();
|
|
|
|
|
|
|
|
void init() => _nativeWidget.init();
|
2023-10-23 17:43:16 -06:00
|
|
|
|
2022-08-29 20:38:28 -06:00
|
|
|
CollectibleData? fromId(String? id) => id == null ? null : all.firstWhereOrNull((o) => o.id == id);
|
|
|
|
|
|
|
|
List<CollectibleData> forWonder(WonderType wonder) {
|
|
|
|
return all.where((o) => o.wonder == wonder).toList(growable: false);
|
|
|
|
}
|
|
|
|
|
2022-11-14 09:14:08 -07:00
|
|
|
void setState(String id, int state) {
|
2022-08-29 20:38:28 -06:00
|
|
|
Map<String, int> states = Map.of(statesById.value);
|
2023-11-20 12:56:38 -07:00
|
|
|
states[id] = state;
|
|
|
|
statesById.value = states;
|
2023-10-23 17:43:16 -06:00
|
|
|
if (state == CollectibleState.discovered) {
|
|
|
|
final data = fromId(id)!;
|
2024-01-22 15:08:58 -07:00
|
|
|
_updateNativeWidgetTextData(
|
2023-10-23 17:43:16 -06:00
|
|
|
title: data.title,
|
|
|
|
id: data.id,
|
|
|
|
imageUrl: data.imageUrlSmall,
|
|
|
|
);
|
|
|
|
}
|
2022-08-29 20:38:28 -06:00
|
|
|
scheduleSave();
|
|
|
|
}
|
|
|
|
|
2022-11-14 09:14:08 -07:00
|
|
|
void _updateCounts() {
|
|
|
|
_discoveredCount = _exploredCount = 0;
|
|
|
|
statesById.value.forEach((_, state) {
|
|
|
|
if (state == CollectibleState.discovered) _discoveredCount++;
|
|
|
|
if (state == CollectibleState.explored) _exploredCount++;
|
|
|
|
});
|
2024-01-18 11:22:31 -07:00
|
|
|
final foundCount = discoveredCount + exploredCount;
|
2024-01-22 15:08:58 -07:00
|
|
|
_nativeWidget.save<int>('discoveredCount', foundCount).then((value) {
|
|
|
|
_nativeWidget.markDirty();
|
|
|
|
});
|
2024-01-18 12:43:03 -07:00
|
|
|
|
2024-01-18 11:22:31 -07:00
|
|
|
debugPrint('setting discoveredCount for home widget $foundCount');
|
2022-11-14 09:14:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Get a discovered item, sorted by the order of wondersLogic.all
|
|
|
|
CollectibleData? getFirstDiscoveredOrNull() {
|
|
|
|
List<CollectibleData> 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;
|
|
|
|
}
|
|
|
|
|
2022-08-29 20:38:28 -06:00
|
|
|
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<String, int> states = {};
|
|
|
|
for (int i = 0; i < all.length; i++) {
|
|
|
|
states[all[i].id] = CollectibleState.lost;
|
|
|
|
}
|
2024-01-22 15:08:58 -07:00
|
|
|
if (_nativeWidget.isSupported) {
|
|
|
|
_updateNativeWidgetTextData(); // clear home widget data
|
|
|
|
}
|
2022-08-29 20:38:28 -06:00
|
|
|
statesById.value = states;
|
|
|
|
debugPrint('collection reset');
|
|
|
|
scheduleSave();
|
|
|
|
}
|
|
|
|
|
2024-01-22 15:08:58 -07:00
|
|
|
Future<void> _updateNativeWidgetTextData({String title = '', String id = '', String imageUrl = ''}) async {
|
2023-10-23 17:43:16 -06:00
|
|
|
// Save title
|
2024-01-18 12:43:03 -07:00
|
|
|
await _nativeWidget.save<String>('lastDiscoveredTitle', title);
|
2023-10-23 17:43:16 -06:00
|
|
|
// Subtitle
|
|
|
|
String subTitle = '';
|
2024-01-18 11:22:31 -07:00
|
|
|
if (id.isNotEmpty) {
|
2023-10-23 17:43:16 -06:00
|
|
|
final artifactData = await artifactLogic.getArtifactByID(id);
|
|
|
|
subTitle = artifactData?.date ?? '';
|
|
|
|
}
|
2024-01-18 12:43:03 -07:00
|
|
|
await _nativeWidget.save<String>('lastDiscoveredSubTitle', subTitle);
|
2023-10-23 17:43:16 -06:00
|
|
|
// Image,
|
|
|
|
// Download, convert to base64 string and write to shared widget data
|
|
|
|
String imageBase64 = '';
|
2024-01-18 11:22:31 -07:00
|
|
|
if (imageUrl.isNotEmpty) {
|
2023-10-23 17:43:16 -06:00
|
|
|
var bytes = await http.readBytes(Uri.parse(imageUrl));
|
|
|
|
imageBase64 = base64Encode(bytes);
|
|
|
|
debugPrint('Saving base64 bytes: $imageBase64');
|
|
|
|
}
|
2024-01-18 12:43:03 -07:00
|
|
|
await _nativeWidget.save<String>('lastDiscoveredImageData', imageBase64);
|
|
|
|
await _nativeWidget.markDirty();
|
2023-10-23 17:43:16 -06:00
|
|
|
}
|
|
|
|
|
2022-08-29 20:38:28 -06:00
|
|
|
@override
|
|
|
|
void copyFromJson(Map<String, dynamic> value) {
|
|
|
|
Map<String, int> 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<String, dynamic> toJson() => statesById.value;
|
|
|
|
}
|