-
Notifications
You must be signed in to change notification settings - Fork 1k
Expand file tree
/
Copy pathwonder_events.dart
More file actions
174 lines (162 loc) · 6.33 KB
/
wonder_events.dart
File metadata and controls
174 lines (162 loc) · 6.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
import 'package:wonders/common_libs.dart';
import 'package:wonders/logic/common/animate_utils.dart';
import 'package:wonders/logic/common/platform_info.dart';
import 'package:wonders/logic/common/string_utils.dart';
import 'package:wonders/logic/data/wonder_data.dart';
import 'package:wonders/ui/common/app_backdrop.dart';
import 'package:wonders/ui/common/app_icons.dart';
import 'package:wonders/ui/common/centered_box.dart';
import 'package:wonders/ui/common/controls/app_header.dart';
import 'package:wonders/ui/common/curved_clippers.dart';
import 'package:wonders/ui/common/hidden_collectible.dart';
import 'package:wonders/ui/common/ignore_pointer.dart';
import 'package:wonders/ui/common/list_gradient.dart';
import 'package:wonders/ui/common/themed_text.dart';
import 'package:wonders/ui/common/timeline_event_card.dart';
import 'package:wonders/ui/common/utils/duration_utils.dart';
import 'package:wonders/ui/common/wonders_timeline_builder.dart';
import 'package:wonders/ui/wonder_illustrations/common/wonder_title_text.dart';
part 'widgets/_events_list.dart';
part 'widgets/_timeline_btn.dart';
part 'widgets/_wonder_image_with_timeline.dart';
class WonderEvents extends StatefulWidget {
const WonderEvents({super.key, required this.type, this.contentPadding = EdgeInsets.zero});
final WonderType type;
final EdgeInsets contentPadding;
@override
State<WonderEvents> createState() => _WonderEventsState();
}
class _WonderEventsState extends State<WonderEvents> {
late final _data = wondersLogic.getData(widget.type);
final _eventsListKey = GlobalKey<_EventsListState>();
double _scrollPos = 0;
void _handleScroll(double pos) => _scrollPos = pos;
@override
Widget build(BuildContext context) {
void handleTimelineBtnPressed() => context.go(ScreenPaths.timeline(widget.type));
// Main view content switches between 1 and 2 column layouts
// On mobile, use the 2 column layout on screens close to landscape (>.85). This is primarily an optimization for foldable devices which have square-ish dimensions when opened.
final twoColumnAspect = PlatformInfo.isMobile ? .85 : 1;
bool useTwoColumnLayout = context.mq.size.aspectRatio > twoColumnAspect;
bool smallMode = context.heightPx < 550;
return LayoutBuilder(
builder: (context, constraints) {
return Container(
color: $styles.colors.black,
child: SafeArea(
bottom: false,
child: Stack(
children: [
/// Main view
Positioned.fill(
top: smallMode ? 0 : $styles.insets.sm,
child: Padding(
padding: widget.contentPadding,
child: useTwoColumnLayout ? _buildTwoColumn(context) : _buildSingleColumn(),
),
),
/// Header w/ TimelineBtn
TopCenter(
child: AppHeader(
showBackBtn: false,
isTransparent: true,
trailing: (_) => CircleIconBtn(
icon: AppIcons.timeline,
onPressed: handleTimelineBtnPressed,
semanticLabel: $strings.eventsListButtonOpenGlobal,
),
),
),
],
),
),
);
},
);
}
/// Landscape layout is a row, with the WonderImage on left and EventsList on the right
Widget _buildTwoColumn(BuildContext context) {
bool smallMode = context.heightPx < 550;
final double timelineImageSize = (context.heightPx - 200).clamp(200, 500);
return Padding(
padding: EdgeInsets.symmetric(
vertical: smallMode ? $styles.insets.sm : $styles.insets.lg,
horizontal: $styles.insets.sm,
),
child: Row(
children: [
/// WonderImage w/ Timeline btn
Expanded(
child: CenteredBox(
width: $styles.sizes.maxContentWidth3,
child: Padding(
padding: EdgeInsets.symmetric(vertical: smallMode ? $styles.insets.sm : $styles.insets.lg),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
_WonderImageWithTimeline(data: _data, height: timelineImageSize),
Gap(smallMode ? $styles.insets.md : $styles.insets.lg),
SizedBox(width: 400, child: _TimelineBtn(type: widget.type)),
],
),
),
),
),
/// EventsList
Expanded(
child: CenteredBox(
width: $styles.sizes.maxContentWidth2,
child: _EventsList(
key: _eventsListKey,
data: _data,
topHeight: 100,
blurOnScroll: false,
onScroll: _handleScroll,
initialScrollOffset: _scrollPos,
),
),
),
],
),
);
}
/// Portrait layout is a stack with the EventsList scrolling overtop of the WonderImage
Widget _buildSingleColumn() {
return LayoutBuilder(
builder: (_, constraints) {
double topHeight = max(constraints.maxHeight * .55, 200);
return CenteredBox(
width: $styles.sizes.maxContentWidth2,
child: Stack(
children: [
/// Top content, sits underneath scrolling list
_WonderImageWithTimeline(height: topHeight, data: _data),
/// EventsList + TimelineBtn
Column(
children: [
Expanded(
/// EventsList
child: _EventsList(
key: _eventsListKey,
data: _data,
topHeight: topHeight,
blurOnScroll: true,
showTopGradient: false,
onScroll: _handleScroll,
initialScrollOffset: _scrollPos,
),
),
Gap($styles.insets.lg),
/// TimelineBtn
_TimelineBtn(type: _data.type, width: $styles.sizes.maxContentWidth2),
Gap($styles.insets.lg),
],
),
],
),
);
},
);
}
}