Polish and refactor collections views
This commit is contained in:
parent
c3034a5f97
commit
05ad64c2f6
@ -62,6 +62,7 @@ class CollectibleFoundScreen extends StatelessWidget {
|
|||||||
height: context.heightPx * .35,
|
height: context.heightPx * .35,
|
||||||
child: Center(child: Hero(tag: 'collectible_image_${collectible.id}', child: _buildImage(context))),
|
child: Center(child: Hero(tag: 'collectible_image_${collectible.id}', child: _buildImage(context))),
|
||||||
),
|
),
|
||||||
|
Gap($styles.insets.lg),
|
||||||
_buildRibbon(context),
|
_buildRibbon(context),
|
||||||
Gap($styles.insets.sm),
|
Gap($styles.insets.sm),
|
||||||
_buildTitle(context, collectible.title, $styles.text.h2, $styles.colors.offWhite, t * 1.5),
|
_buildTitle(context, collectible.title, $styles.text.h2, $styles.colors.offWhite, t * 1.5),
|
||||||
|
@ -9,9 +9,10 @@ import 'package:wonders/ui/common/controls/simple_header.dart';
|
|||||||
import 'package:wonders/ui/common/gradient_container.dart';
|
import 'package:wonders/ui/common/gradient_container.dart';
|
||||||
import 'package:wonders/ui/common/modals/app_modals.dart';
|
import 'package:wonders/ui/common/modals/app_modals.dart';
|
||||||
|
|
||||||
part 'widgets/_collection_tile.dart';
|
part 'widgets/_collectible_image.dart';
|
||||||
part 'widgets/_newly_discovered_row.dart';
|
part 'widgets/_newly_discovered_items_btn.dart';
|
||||||
part 'widgets/_collection_list.dart';
|
part 'widgets/_collection_list.dart';
|
||||||
|
part 'widgets/_collection_list_card.dart';
|
||||||
part 'widgets/_collection_footer.dart';
|
part 'widgets/_collection_footer.dart';
|
||||||
|
|
||||||
class CollectionScreen extends StatefulWidget with GetItStatefulWidgetMixin {
|
class CollectionScreen extends StatefulWidget with GetItStatefulWidgetMixin {
|
||||||
@ -25,15 +26,7 @@ class CollectionScreen extends StatefulWidget with GetItStatefulWidgetMixin {
|
|||||||
|
|
||||||
class _CollectionScreenState extends State<CollectionScreen> with GetItStateMixin {
|
class _CollectionScreenState extends State<CollectionScreen> with GetItStateMixin {
|
||||||
Map<String, int> _states = collectiblesLogic.statesById.value;
|
Map<String, int> _states = collectiblesLogic.statesById.value;
|
||||||
GlobalKey? _scrollKey;
|
final GlobalKey _scrollKey = GlobalKey();
|
||||||
|
|
||||||
WonderType? get scrollTargetWonder {
|
|
||||||
String? id = widget.fromId;
|
|
||||||
if (_states[id] != CollectibleState.discovered) {
|
|
||||||
id = _states.keys.firstWhereOrNull((id) => _states[id] == CollectibleState.discovered);
|
|
||||||
}
|
|
||||||
return collectiblesLogic.fromId(id)?.wonder;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@ -44,16 +37,11 @@ class _CollectionScreenState extends State<CollectionScreen> with GetItStateMixi
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _scrollToTarget([bool animate = true]) {
|
void _scrollToTarget([bool animate = true]) {
|
||||||
if (_scrollKey != null) {
|
if (_scrollKey.currentContext != null) {
|
||||||
Scrollable.ensureVisible(_scrollKey!.currentContext!, alignment: 0.15, duration: animate ? 300.ms : 0.ms);
|
Scrollable.ensureVisible(_scrollKey.currentContext!, alignment: 0.15, duration: animate ? 300.ms : 0.ms);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _showDetails(BuildContext context, CollectibleData collectible) {
|
|
||||||
context.push(ScreenPaths.artifact(collectible.artifactId));
|
|
||||||
Future.delayed(300.ms).then((_) => collectiblesLogic.updateState(collectible.id, CollectibleState.explored));
|
|
||||||
}
|
|
||||||
|
|
||||||
void _handleReset() async {
|
void _handleReset() async {
|
||||||
String msg = $strings.collectionPopupResetConfirm;
|
String msg = $strings.collectionPopupResetConfirm;
|
||||||
final result = await showModal(context, child: OkCancelModal(msg: msg));
|
final result = await showModal(context, child: OkCancelModal(msg: msg));
|
||||||
@ -71,9 +59,6 @@ class _CollectionScreenState extends State<CollectionScreen> with GetItStateMixi
|
|||||||
if (state == CollectibleState.explored) explored++;
|
if (state == CollectibleState.explored) explored++;
|
||||||
});
|
});
|
||||||
|
|
||||||
WonderType? scrollWonder = scrollTargetWonder;
|
|
||||||
if (scrollWonder != null) _scrollKey = GlobalKey();
|
|
||||||
|
|
||||||
return ColoredBox(
|
return ColoredBox(
|
||||||
color: $styles.colors.greyStrong,
|
color: $styles.colors.greyStrong,
|
||||||
child: Column(
|
child: Column(
|
||||||
@ -81,14 +66,12 @@ class _CollectionScreenState extends State<CollectionScreen> with GetItStateMixi
|
|||||||
Expanded(
|
Expanded(
|
||||||
child: Column(crossAxisAlignment: CrossAxisAlignment.stretch, children: [
|
child: Column(crossAxisAlignment: CrossAxisAlignment.stretch, children: [
|
||||||
SimpleHeader($strings.collectionTitleCollection),
|
SimpleHeader($strings.collectionTitleCollection),
|
||||||
_NewlyDiscoveredRow(count: discovered, onPressed: _scrollToTarget),
|
_NewlyDiscoveredItemsBtn(count: discovered, onPressed: _scrollToTarget),
|
||||||
Flexible(
|
Flexible(
|
||||||
child: _CollectionList(
|
child: _CollectionList(
|
||||||
states: _states,
|
states: _states,
|
||||||
fromId: widget.fromId,
|
fromId: widget.fromId,
|
||||||
scrollKey: _scrollKey,
|
scrollKey: _scrollKey,
|
||||||
scrollWonder: scrollWonder,
|
|
||||||
onPressed: (o) => _showDetails(context, o),
|
|
||||||
onReset: discovered + explored > 0 ? _handleReset : null,
|
onReset: discovered + explored > 0 ? _handleReset : null,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
part of '../collection_screen.dart';
|
part of '../collection_screen.dart';
|
||||||
|
|
||||||
class _CollectionTile extends StatelessWidget {
|
class _CollectibleImage extends StatelessWidget {
|
||||||
const _CollectionTile({
|
const _CollectibleImage({
|
||||||
Key? key,
|
Key? key,
|
||||||
required this.collectible,
|
required this.collectible,
|
||||||
required this.state,
|
required this.state,
|
@ -5,31 +5,38 @@ class _CollectionList extends StatelessWidget {
|
|||||||
const _CollectionList({
|
const _CollectionList({
|
||||||
Key? key,
|
Key? key,
|
||||||
required this.states,
|
required this.states,
|
||||||
required this.onPressed,
|
|
||||||
this.onReset,
|
this.onReset,
|
||||||
this.fromId,
|
this.fromId,
|
||||||
this.scrollWonder,
|
|
||||||
this.scrollKey,
|
this.scrollKey,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
final Map<String, int> states;
|
final Map<String, int> states;
|
||||||
final ValueSetter<CollectibleData> onPressed;
|
|
||||||
final VoidCallback? onReset;
|
final VoidCallback? onReset;
|
||||||
final Key? scrollKey;
|
final Key? scrollKey;
|
||||||
final WonderType? scrollWonder;
|
|
||||||
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);
|
||||||
|
}
|
||||||
|
return collectiblesLogic.fromId(id)?.wonder;
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
List<WonderData> wonders = wondersLogic.all;
|
List<WonderData> wonders = wondersLogic.all;
|
||||||
bool vtMode = context.isLandscape == false;
|
bool vtMode = context.isLandscape == false;
|
||||||
|
final scrollWonder = scrollTargetWonder;
|
||||||
// Create list of collections that is shared by both hz and vt layouts
|
// Create list of collections that is shared by both hz and vt layouts
|
||||||
List<Widget> collections = [
|
List<Widget> collections = [
|
||||||
...wonders.map((d) {
|
...wonders.map((d) {
|
||||||
return _buildSingleCollection(
|
return _CollectionListCard(
|
||||||
context,
|
key: d.type == scrollWonder ? scrollKey : null,
|
||||||
height: vtMode ? 300 : 400,
|
height: vtMode ? 300 : 400,
|
||||||
width: vtMode ? null : 600,
|
width: vtMode ? null : 600,
|
||||||
|
fromId: fromId,
|
||||||
|
states: states,
|
||||||
data: d,
|
data: d,
|
||||||
);
|
);
|
||||||
}).toList()
|
}).toList()
|
||||||
@ -54,50 +61,6 @@ class _CollectionList extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildSingleCollection(BuildContext context, {double? width, double? height, required WonderData data}) {
|
|
||||||
List<CollectibleData> collectibles = collectiblesLogic.forWonder(data.type);
|
|
||||||
|
|
||||||
return Center(
|
|
||||||
child: SizedBox(
|
|
||||||
width: width ?? double.infinity,
|
|
||||||
height: height ?? double.infinity,
|
|
||||||
child: Column(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
/// Title
|
|
||||||
Text(
|
|
||||||
data.title.toUpperCase(),
|
|
||||||
key: data.type == scrollWonder ? scrollKey : null,
|
|
||||||
textAlign: TextAlign.left,
|
|
||||||
style: $styles.text.title1.copyWith(color: $styles.colors.offWhite),
|
|
||||||
),
|
|
||||||
Gap($styles.insets.md),
|
|
||||||
|
|
||||||
/// Images
|
|
||||||
Expanded(
|
|
||||||
child: SeparatedRow(
|
|
||||||
separatorBuilder: () => Gap($styles.insets.sm),
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
||||||
children: [
|
|
||||||
...collectibles.map((e) {
|
|
||||||
int state = states[e.id] ?? CollectibleState.lost;
|
|
||||||
return Flexible(
|
|
||||||
child: _CollectionTile(
|
|
||||||
collectible: e,
|
|
||||||
state: state,
|
|
||||||
onPressed: onPressed,
|
|
||||||
heroTag: e.id == fromId ? 'collectible_image_$fromId' : null,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}).toList()
|
|
||||||
]),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Restore reset functionality somehow
|
// TODO: Restore reset functionality somehow
|
||||||
// Widget _buildResetBtn(BuildContext context) {
|
// Widget _buildResetBtn(BuildContext context) {
|
||||||
// Widget btn = AppBtn.from(
|
// Widget btn = AppBtn.from(
|
||||||
|
61
lib/ui/screens/collection/widgets/_collection_list_card.dart
Normal file
61
lib/ui/screens/collection/widgets/_collection_list_card.dart
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
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);
|
||||||
|
|
||||||
|
final double? width;
|
||||||
|
final double? height;
|
||||||
|
final WonderData data;
|
||||||
|
final String? fromId;
|
||||||
|
final Map<String, int> states;
|
||||||
|
|
||||||
|
void _showDetails(BuildContext context, CollectibleData collectible) {
|
||||||
|
context.push(ScreenPaths.artifact(collectible.artifactId));
|
||||||
|
Future.delayed(300.ms).then((_) => collectiblesLogic.updateState(collectible.id, CollectibleState.explored));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
List<CollectibleData> collectibles = collectiblesLogic.forWonder(data.type);
|
||||||
|
return Center(
|
||||||
|
child: SizedBox(
|
||||||
|
width: width ?? double.infinity,
|
||||||
|
height: height ?? double.infinity,
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
/// Title
|
||||||
|
Text(
|
||||||
|
data.title.toUpperCase(),
|
||||||
|
textAlign: TextAlign.left,
|
||||||
|
style: $styles.text.title1.copyWith(color: $styles.colors.offWhite),
|
||||||
|
),
|
||||||
|
Gap($styles.insets.md),
|
||||||
|
|
||||||
|
/// Images
|
||||||
|
Expanded(
|
||||||
|
child: SeparatedRow(
|
||||||
|
separatorBuilder: () => Gap($styles.insets.sm),
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
|
children: [
|
||||||
|
...collectibles.map((e) {
|
||||||
|
int state = states[e.id] ?? CollectibleState.lost;
|
||||||
|
return Flexible(
|
||||||
|
child: _CollectibleImage(
|
||||||
|
collectible: e,
|
||||||
|
state: state,
|
||||||
|
onPressed: (c) => _showDetails(context, c),
|
||||||
|
heroTag: e.id == fromId ? 'collectible_image_$fromId' : null,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}).toList()
|
||||||
|
]),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -1,8 +1,8 @@
|
|||||||
part of '../collection_screen.dart';
|
part of '../collection_screen.dart';
|
||||||
|
|
||||||
@immutable
|
@immutable
|
||||||
class _NewlyDiscoveredRow extends StatelessWidget {
|
class _NewlyDiscoveredItemsBtn extends StatelessWidget {
|
||||||
const _NewlyDiscoveredRow({Key? key, this.count = 0, required this.onPressed}) : super(key: key);
|
const _NewlyDiscoveredItemsBtn({Key? key, this.count = 0, required this.onPressed}) : super(key: key);
|
||||||
|
|
||||||
final int count;
|
final int count;
|
||||||
final VoidCallback onPressed;
|
final VoidCallback onPressed;
|
12
pubspec.lock
12
pubspec.lock
@ -245,7 +245,7 @@ packages:
|
|||||||
name: file
|
name: file
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.1.4"
|
version: "6.1.2"
|
||||||
fixnum:
|
fixnum:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -259,7 +259,7 @@ packages:
|
|||||||
name: flextras
|
name: flextras
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.0.2"
|
version: "1.0.0"
|
||||||
flutter:
|
flutter:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description: flutter
|
description: flutter
|
||||||
@ -1034,7 +1034,7 @@ packages:
|
|||||||
name: test_api
|
name: test_api
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.4.14"
|
version: "0.4.12"
|
||||||
timing:
|
timing:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -1132,14 +1132,14 @@ packages:
|
|||||||
name: vector_math
|
name: vector_math
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.3"
|
version: "2.1.2"
|
||||||
vm_service:
|
vm_service:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: vm_service
|
name: vm_service
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "9.4.0"
|
version: "9.3.0"
|
||||||
watcher:
|
watcher:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -1197,5 +1197,5 @@ packages:
|
|||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.0"
|
version: "2.3.0"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=2.18.0 <3.0.0"
|
dart: ">=2.17.1 <3.0.0"
|
||||||
flutter: ">=3.0.0"
|
flutter: ">=3.0.0"
|
||||||
|
@ -19,7 +19,7 @@ dependencies:
|
|||||||
drop_cap_text: ^1.1.3
|
drop_cap_text: ^1.1.3
|
||||||
equatable: ^2.0.5
|
equatable: ^2.0.5
|
||||||
extra_alignments: ^1.0.0+1
|
extra_alignments: ^1.0.0+1
|
||||||
flextras: ^0.0.2
|
flextras: ^1.0.0
|
||||||
flutter_animate: ^1.0.0
|
flutter_animate: ^1.0.0
|
||||||
flutter_circular_text: ^0.3.1
|
flutter_circular_text: ^0.3.1
|
||||||
flutter_displaymode: ^0.4.0
|
flutter_displaymode: ^0.4.0
|
||||||
|
Loading…
x
Reference in New Issue
Block a user