Update collectibles
This commit is contained in:
parent
b72118c56c
commit
973d9c61cf
@ -10,7 +10,13 @@ class CollectiblesLogic with ThrottledSaveLoadMixin {
|
||||
final List<CollectibleData> all = collectiblesData;
|
||||
|
||||
/// Current state for each collectible
|
||||
final statesById = ValueNotifier<Map<String, int>>({});
|
||||
late final statesById = ValueNotifier<Map<String, int>>({})..addListener(_updateCounts);
|
||||
|
||||
int _discoveredCount = 0;
|
||||
int get discoveredCount => _discoveredCount;
|
||||
|
||||
int _exploredCount = 0;
|
||||
int get exploredCount => _exploredCount;
|
||||
|
||||
CollectibleData? fromId(String? id) => id == null ? null : all.firstWhereOrNull((o) => o.id == id);
|
||||
|
||||
@ -18,13 +24,35 @@ class CollectiblesLogic with ThrottledSaveLoadMixin {
|
||||
return all.where((o) => o.wonder == wonder).toList(growable: false);
|
||||
}
|
||||
|
||||
void updateState(String id, int state) {
|
||||
void setState(String id, int state) {
|
||||
Map<String, int> states = Map.of(statesById.value);
|
||||
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++;
|
||||
});
|
||||
}
|
||||
|
||||
/// 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;
|
||||
}
|
||||
|
||||
bool isLost(WonderType wonderType, int i) {
|
||||
final datas = forWonder(wonderType);
|
||||
final states = statesById.value;
|
||||
|
@ -23,7 +23,7 @@ class CollectibleItem extends StatelessWidget with GetItMixin {
|
||||
|
||||
// wait to update the state, to ensure the hero works properly:
|
||||
await Future.delayed($styles.times.pageTransition);
|
||||
collectiblesLogic.updateState(collectible.id, CollectibleState.discovered);
|
||||
collectiblesLogic.setState(collectible.id, CollectibleState.discovered);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -6,14 +6,13 @@ import 'package:wonders/logic/common/string_utils.dart';
|
||||
import 'package:wonders/logic/data/collectible_data.dart';
|
||||
import 'package:wonders/logic/data/wonder_data.dart';
|
||||
import 'package:wonders/ui/common/controls/simple_header.dart';
|
||||
import 'package:wonders/ui/common/gradient_container.dart';
|
||||
import 'package:wonders/ui/common/modals/app_modals.dart';
|
||||
|
||||
part 'widgets/_collectible_image.dart';
|
||||
part 'widgets/_newly_discovered_items_btn.dart';
|
||||
part 'widgets/_collection_footer.dart';
|
||||
part 'widgets/_collection_list.dart';
|
||||
part 'widgets/_collection_list_card.dart';
|
||||
part 'widgets/_collection_footer.dart';
|
||||
part 'widgets/_newly_discovered_items_btn.dart';
|
||||
|
||||
class CollectionScreen extends StatefulWidget with GetItStatefulWidgetMixin {
|
||||
CollectionScreen({required this.fromId, Key? key}) : super(key: key);
|
||||
@ -25,13 +24,13 @@ class CollectionScreen extends StatefulWidget with GetItStatefulWidgetMixin {
|
||||
}
|
||||
|
||||
class _CollectionScreenState extends State<CollectionScreen> with GetItStateMixin {
|
||||
Map<String, int> _states = collectiblesLogic.statesById.value;
|
||||
final GlobalKey _scrollKey = GlobalKey();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
if (widget.fromId.isNotEmpty && _states[widget.fromId] == CollectibleState.discovered) {
|
||||
final states = collectiblesLogic.statesById.value;
|
||||
if (widget.fromId.isNotEmpty && states[widget.fromId] == CollectibleState.discovered) {
|
||||
scheduleMicrotask(() => _scrollToTarget(false));
|
||||
}
|
||||
}
|
||||
@ -52,12 +51,11 @@ class _CollectionScreenState extends State<CollectionScreen> with GetItStateMixi
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
_states = watchX((CollectiblesLogic o) => o.statesById);
|
||||
int discovered = 0, explored = 0, total = collectiblesLogic.all.length;
|
||||
_states.forEach((_, state) {
|
||||
if (state == CollectibleState.discovered) discovered++;
|
||||
if (state == CollectibleState.explored) explored++;
|
||||
});
|
||||
// Rebuild when collectible states change
|
||||
watchX((CollectiblesLogic o) => o.statesById);
|
||||
int discovered = collectiblesLogic.discoveredCount;
|
||||
int explored = collectiblesLogic.exploredCount;
|
||||
int total = collectiblesLogic.all.length;
|
||||
|
||||
return ColoredBox(
|
||||
color: $styles.colors.greyStrong,
|
||||
@ -69,7 +67,6 @@ class _CollectionScreenState extends State<CollectionScreen> with GetItStateMixi
|
||||
_NewlyDiscoveredItemsBtn(count: discovered, onPressed: _scrollToTarget),
|
||||
Flexible(
|
||||
child: _CollectionList(
|
||||
states: _states,
|
||||
fromId: widget.fromId,
|
||||
scrollKey: _scrollKey,
|
||||
onReset: discovered + explored > 0 ? _handleReset : null,
|
||||
|
@ -1,30 +1,31 @@
|
||||
part of '../collection_screen.dart';
|
||||
|
||||
@immutable
|
||||
class _CollectionList extends StatelessWidget {
|
||||
const _CollectionList({
|
||||
class _CollectionList extends StatelessWidget with GetItMixin {
|
||||
_CollectionList({
|
||||
Key? key,
|
||||
required this.states,
|
||||
this.onReset,
|
||||
this.fromId,
|
||||
required this.fromId,
|
||||
this.scrollKey,
|
||||
}) : super(key: key);
|
||||
|
||||
final Map<String, int> states;
|
||||
final VoidCallback? onReset;
|
||||
final Key? scrollKey;
|
||||
final String? fromId;
|
||||
final String fromId;
|
||||
|
||||
WonderType? get scrollTargetWonder {
|
||||
String? id = fromId;
|
||||
if (states[id] != CollectibleState.discovered) {
|
||||
id = states.keys.firstWhereOrNull((id) => states[id] == CollectibleState.discovered);
|
||||
CollectibleData? item;
|
||||
if (fromId.isEmpty) {
|
||||
item = collectiblesLogic.getFirstDiscoveredOrNull();
|
||||
} else {
|
||||
item = collectiblesLogic.fromId(fromId);
|
||||
}
|
||||
return collectiblesLogic.fromId(id)?.wonder;
|
||||
return item?.wonder;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
watchX((CollectiblesLogic o) => o.statesById);
|
||||
List<WonderData> wonders = wondersLogic.all;
|
||||
bool vtMode = context.isLandscape == false;
|
||||
final scrollWonder = scrollTargetWonder;
|
||||
@ -36,7 +37,6 @@ class _CollectionList extends StatelessWidget {
|
||||
height: vtMode ? 300 : 400,
|
||||
width: vtMode ? null : 600,
|
||||
fromId: fromId,
|
||||
states: states,
|
||||
data: d,
|
||||
);
|
||||
}).toList()
|
||||
@ -46,16 +46,11 @@ class _CollectionList extends StatelessWidget {
|
||||
scrollDirection: vtMode ? Axis.vertical : Axis.horizontal,
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all($styles.insets.lg),
|
||||
child: vtMode
|
||||
? SeparatedColumn(
|
||||
child: SeparatedFlex(
|
||||
direction: vtMode ? Axis.vertical : Axis.horizontal,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
separatorBuilder: () => Gap($styles.insets.lg),
|
||||
children: collections,
|
||||
)
|
||||
: SeparatedRow(
|
||||
separatorBuilder: () => Gap($styles.insets.xl * 2),
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: collections,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
@ -1,23 +1,21 @@
|
||||
part of '../collection_screen.dart';
|
||||
|
||||
class _CollectionListCard extends StatelessWidget {
|
||||
const _CollectionListCard(
|
||||
{Key? key, this.width, this.height, required this.data, required this.fromId, required this.states})
|
||||
: super(key: key);
|
||||
class _CollectionListCard extends StatelessWidget with GetItMixin {
|
||||
_CollectionListCard({Key? key, this.width, this.height, required this.data, required this.fromId}) : super(key: key);
|
||||
|
||||
final double? width;
|
||||
final double? height;
|
||||
final WonderData data;
|
||||
final String? fromId;
|
||||
final Map<String, int> states;
|
||||
final String fromId;
|
||||
|
||||
void _showDetails(BuildContext context, CollectibleData collectible) {
|
||||
context.push(ScreenPaths.artifact(collectible.artifactId));
|
||||
Future.delayed(300.ms).then((_) => collectiblesLogic.updateState(collectible.id, CollectibleState.explored));
|
||||
Future.delayed(300.ms).then((_) => collectiblesLogic.setState(collectible.id, CollectibleState.explored));
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final states = watchX((CollectiblesLogic o) => o.statesById);
|
||||
List<CollectibleData> collectibles = collectiblesLogic.forWonder(data.type);
|
||||
return Center(
|
||||
child: SizedBox(
|
||||
|
@ -7,11 +7,13 @@ class _AnimatedArrowButton extends StatelessWidget {
|
||||
final String semanticTitle;
|
||||
final VoidCallback onTap;
|
||||
|
||||
// Fades to 0 and back to 1
|
||||
final _fadeOutIn = TweenSequence<double>([
|
||||
TweenSequenceItem(tween: Tween(begin: 1, end: 0), weight: .5),
|
||||
TweenSequenceItem(tween: Tween(begin: 0, end: 1), weight: .5),
|
||||
]);
|
||||
|
||||
// Holds top alignment for first half, then jumps down and slides back up
|
||||
final _slideDown = TweenSequence<double>([
|
||||
TweenSequenceItem(tween: Tween(begin: 1, end: 1), weight: .5),
|
||||
TweenSequenceItem(tween: Tween(begin: -1, end: 1), weight: .5)
|
||||
@ -20,11 +22,9 @@ class _AnimatedArrowButton extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final Duration duration = $styles.times.med;
|
||||
final btnLbl = StringUtils.supplant($strings.animatedArrowSemanticSwipe, {'{title}': semanticTitle});
|
||||
return AppBtn.basic(
|
||||
semanticLabel: StringUtils.supplant(
|
||||
$strings.animatedArrowSemanticSwipe,
|
||||
{'{title}': semanticTitle},
|
||||
),
|
||||
semanticLabel: btnLbl,
|
||||
onPressed: onTap,
|
||||
child: SizedBox(
|
||||
height: 80,
|
||||
|
@ -1,10 +1,10 @@
|
||||
// This is a generated file; do not edit or check into version control.
|
||||
FLUTTER_ROOT=/Users/shawn/Dev/flutter
|
||||
FLUTTER_APPLICATION_PATH=/Users/shawn/Dev/gskinner/flutter-wonders-app
|
||||
FLUTTER_ROOT=C:\_dev\sdks\flutter
|
||||
FLUTTER_APPLICATION_PATH=C:\_dev\gskinner\flutter_wonders_app
|
||||
COCOAPODS_PARALLEL_CODE_SIGN=true
|
||||
FLUTTER_BUILD_DIR=build
|
||||
FLUTTER_BUILD_NAME=1.9.6
|
||||
FLUTTER_BUILD_NUMBER=1.9.6
|
||||
FLUTTER_BUILD_NAME=1.9.7
|
||||
FLUTTER_BUILD_NUMBER=1.9.7
|
||||
DART_OBFUSCATION=false
|
||||
TRACK_WIDGET_CREATION=true
|
||||
TREE_SHAKE_ICONS=false
|
||||
|
@ -1,11 +1,11 @@
|
||||
#!/bin/sh
|
||||
# This is a generated file; do not edit or check into version control.
|
||||
export "FLUTTER_ROOT=/Users/shawn/Dev/flutter"
|
||||
export "FLUTTER_APPLICATION_PATH=/Users/shawn/Dev/gskinner/flutter-wonders-app"
|
||||
export "FLUTTER_ROOT=C:\_dev\sdks\flutter"
|
||||
export "FLUTTER_APPLICATION_PATH=C:\_dev\gskinner\flutter_wonders_app"
|
||||
export "COCOAPODS_PARALLEL_CODE_SIGN=true"
|
||||
export "FLUTTER_BUILD_DIR=build"
|
||||
export "FLUTTER_BUILD_NAME=1.9.6"
|
||||
export "FLUTTER_BUILD_NUMBER=1.9.6"
|
||||
export "FLUTTER_BUILD_NAME=1.9.7"
|
||||
export "FLUTTER_BUILD_NUMBER=1.9.7"
|
||||
export "DART_OBFUSCATION=false"
|
||||
export "TRACK_WIDGET_CREATION=true"
|
||||
export "TREE_SHAKE_ICONS=false"
|
||||
|
Loading…
x
Reference in New Issue
Block a user