Merge branch 'main' into ui-polish-4
This commit is contained in:
commit
c6db38cb09
@ -9,6 +9,7 @@ class SettingsLogic with ThrottledSaveLoadMixin {
|
|||||||
late final hasCompletedOnboarding = ValueNotifier<bool>(false)..addListener(scheduleSave);
|
late final hasCompletedOnboarding = ValueNotifier<bool>(false)..addListener(scheduleSave);
|
||||||
late final hasDismissedSearchMessage = ValueNotifier<bool>(false)..addListener(scheduleSave);
|
late final hasDismissedSearchMessage = ValueNotifier<bool>(false)..addListener(scheduleSave);
|
||||||
late final currentLocale = ValueNotifier<String?>(null)..addListener(scheduleSave);
|
late final currentLocale = ValueNotifier<String?>(null)..addListener(scheduleSave);
|
||||||
|
late final currentWonder = ValueNotifier<int?>(null)..addListener(scheduleSave);
|
||||||
|
|
||||||
final bool useBlurs = !PlatformInfo.isAndroid;
|
final bool useBlurs = !PlatformInfo.isAndroid;
|
||||||
|
|
||||||
@ -17,6 +18,7 @@ class SettingsLogic with ThrottledSaveLoadMixin {
|
|||||||
hasCompletedOnboarding.value = value['hasCompletedOnboarding'] ?? false;
|
hasCompletedOnboarding.value = value['hasCompletedOnboarding'] ?? false;
|
||||||
hasDismissedSearchMessage.value = value['hasDismissedSearchMessage'] ?? false;
|
hasDismissedSearchMessage.value = value['hasDismissedSearchMessage'] ?? false;
|
||||||
currentLocale.value = value['currentLocale'];
|
currentLocale.value = value['currentLocale'];
|
||||||
|
currentWonder.value = value['currentWonder'];
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -25,6 +27,7 @@ class SettingsLogic with ThrottledSaveLoadMixin {
|
|||||||
'hasCompletedOnboarding': hasCompletedOnboarding.value,
|
'hasCompletedOnboarding': hasCompletedOnboarding.value,
|
||||||
'hasDismissedSearchMessage': hasDismissedSearchMessage.value,
|
'hasDismissedSearchMessage': hasDismissedSearchMessage.value,
|
||||||
'currentLocale': currentLocale.value,
|
'currentLocale': currentLocale.value,
|
||||||
|
'currentWonder': currentWonder.value,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,10 +25,7 @@ class HomeScreen extends StatefulWidget with GetItStatefulWidgetMixin {
|
|||||||
/// Shows a horizontally scrollable list PageView sandwiched between Foreground and Background layers
|
/// Shows a horizontally scrollable list PageView sandwiched between Foreground and Background layers
|
||||||
/// arranged in a parallax style.
|
/// arranged in a parallax style.
|
||||||
class _HomeScreenState extends State<HomeScreen> with SingleTickerProviderStateMixin {
|
class _HomeScreenState extends State<HomeScreen> with SingleTickerProviderStateMixin {
|
||||||
late final _pageController = PageController(
|
late final _pageController;
|
||||||
viewportFraction: 1,
|
|
||||||
initialPage: _numWonders * 9999, // allow 'infinite' scrolling by starting at a very high page
|
|
||||||
);
|
|
||||||
List<WonderData> get _wonders => wondersLogic.all;
|
List<WonderData> get _wonders => wondersLogic.all;
|
||||||
bool _isMenuOpen = false;
|
bool _isMenuOpen = false;
|
||||||
|
|
||||||
@ -53,8 +50,23 @@ class _HomeScreenState extends State<HomeScreen> with SingleTickerProviderStateM
|
|||||||
|
|
||||||
bool _isSelected(WonderType t) => t == currentWonder.type;
|
bool _isSelected(WonderType t) => t == currentWonder.type;
|
||||||
|
|
||||||
void _handlePageViewChanged(v) {
|
@override
|
||||||
setState(() => _wonderIndex = v % _numWonders);
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
// Create page controller,
|
||||||
|
// allow 'infinite' scrolling by starting at a very high page, or remember the previous value
|
||||||
|
final previousWonder = settingsLogic.currentWonder.value;
|
||||||
|
final initialPage = previousWonder ?? _numWonders * 9999;
|
||||||
|
_pageController = PageController(viewportFraction: 1, initialPage: initialPage);
|
||||||
|
_wonderIndex = initialPage % _numWonders;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _handlePageChanged(value) {
|
||||||
|
setState(() {
|
||||||
|
_wonderIndex = value % _numWonders;
|
||||||
|
// Save current wonder for next launch
|
||||||
|
settingsLogic.currentWonder.value = value;
|
||||||
|
});
|
||||||
AppHaptics.lightImpact();
|
AppHaptics.lightImpact();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,7 +154,7 @@ class _HomeScreenState extends State<HomeScreen> with SingleTickerProviderStateM
|
|||||||
return ExcludeSemantics(
|
return ExcludeSemantics(
|
||||||
child: PageView.builder(
|
child: PageView.builder(
|
||||||
controller: _pageController,
|
controller: _pageController,
|
||||||
onPageChanged: _handlePageViewChanged,
|
onPageChanged: _handlePageChanged,
|
||||||
itemBuilder: (_, index) {
|
itemBuilder: (_, index) {
|
||||||
final wonder = _wonders[index % _wonders.length];
|
final wonder = _wonders[index % _wonders.length];
|
||||||
final wonderType = wonder.type;
|
final wonderType = wonder.type;
|
||||||
|
@ -15,9 +15,9 @@ class IntroScreen extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _IntroScreenState extends State<IntroScreen> {
|
class _IntroScreenState extends State<IntroScreen> {
|
||||||
static const double _imageSize = 264;
|
static const double _imageSize = 250;
|
||||||
static const double _logoHeight = 126;
|
static const double _logoHeight = 126;
|
||||||
static const double _textHeight = 155;
|
static const double _textHeight = 100;
|
||||||
static const double _pageIndicatorHeight = 55;
|
static const double _pageIndicatorHeight = 55;
|
||||||
|
|
||||||
static List<_PageData> pageData = [];
|
static List<_PageData> pageData = [];
|
||||||
@ -132,7 +132,7 @@ class _IntroScreenState extends State<IntroScreen> {
|
|||||||
// page indicator:
|
// page indicator:
|
||||||
Container(
|
Container(
|
||||||
height: _pageIndicatorHeight,
|
height: _pageIndicatorHeight,
|
||||||
alignment: Alignment(0.0, -0.75),
|
alignment: Alignment(0.0, 0),
|
||||||
child: AppPageIndicator(
|
child: AppPageIndicator(
|
||||||
count: pageData.length, controller: _pageController, color: $styles.colors.offWhite),
|
count: pageData.length, controller: _pageController, color: $styles.colors.offWhite),
|
||||||
),
|
),
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:wonders/common_libs.dart';
|
import 'package:wonders/common_libs.dart';
|
||||||
|
import 'package:wonders/logic/common/platform_info.dart';
|
||||||
import 'package:wonders/logic/common/string_utils.dart';
|
import 'package:wonders/logic/common/string_utils.dart';
|
||||||
import 'package:wonders/logic/data/wonder_data.dart';
|
import 'package:wonders/logic/data/wonder_data.dart';
|
||||||
import 'package:wonders/ui/common/app_backdrop.dart';
|
import 'package:wonders/ui/common/app_backdrop.dart';
|
||||||
@ -26,6 +29,11 @@ class WonderEvents extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
void handleTimelineBtnPressed() => context.push(ScreenPaths.timeline(type));
|
void handleTimelineBtnPressed() => context.push(ScreenPaths.timeline(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 square-ish dimensions when opened.
|
||||||
|
final twoColumnAspect = PlatformInfo.isMobile ? .85 : 1;
|
||||||
|
bool useTwoColumnLayout = context.mq.size.aspectRatio > twoColumnAspect;
|
||||||
|
|
||||||
return LayoutBuilder(builder: (context, constraints) {
|
return LayoutBuilder(builder: (context, constraints) {
|
||||||
return Container(
|
return Container(
|
||||||
color: $styles.colors.black,
|
color: $styles.colors.black,
|
||||||
@ -33,10 +41,10 @@ class WonderEvents extends StatelessWidget {
|
|||||||
bottom: false,
|
bottom: false,
|
||||||
child: Stack(
|
child: Stack(
|
||||||
children: [
|
children: [
|
||||||
/// Main view switches between portrait and landscape views
|
/// Main view
|
||||||
Positioned.fill(
|
Positioned.fill(
|
||||||
top: $styles.insets.sm,
|
top: $styles.insets.sm,
|
||||||
child: context.isLandscape ? _buildLandscape(context) : _buildPortrait(),
|
child: useTwoColumnLayout ? _buildTwoColumn(context) : _buildSingleColumn(),
|
||||||
),
|
),
|
||||||
|
|
||||||
/// Header w/ TimelineBtn
|
/// Header w/ TimelineBtn
|
||||||
@ -58,7 +66,7 @@ class WonderEvents extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Landscape layout is a row, with the WonderImage on left and EventsList on the right
|
/// Landscape layout is a row, with the WonderImage on left and EventsList on the right
|
||||||
Widget _buildLandscape(BuildContext context) {
|
Widget _buildTwoColumn(BuildContext context) {
|
||||||
return Row(
|
return Row(
|
||||||
children: [
|
children: [
|
||||||
/// WonderImage w/ Timeline btn
|
/// WonderImage w/ Timeline btn
|
||||||
@ -104,7 +112,7 @@ class WonderEvents extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Portrait layout is a stack with the EventsList scrolling overtop of the WonderImage
|
/// Portrait layout is a stack with the EventsList scrolling overtop of the WonderImage
|
||||||
Widget _buildPortrait() {
|
Widget _buildSingleColumn() {
|
||||||
return LayoutBuilder(builder: (_, constraints) {
|
return LayoutBuilder(builder: (_, constraints) {
|
||||||
double topHeight = max(constraints.maxHeight * .55, 200);
|
double topHeight = max(constraints.maxHeight * .55, 200);
|
||||||
return CenteredBox(
|
return CenteredBox(
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
name: wonders
|
name: wonders
|
||||||
description: Explore the famous wonders of the world.
|
description: Explore the famous wonders of the world.
|
||||||
publish_to: "none"
|
publish_to: "none"
|
||||||
version: 2.0.8
|
version: 2.0.9+1
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.17.0 <3.0.0"
|
sdk: ">=2.17.0 <3.0.0"
|
||||||
|
@ -1,2 +1,3 @@
|
|||||||
# 2.0.8
|
# 2.0.9
|
||||||
- Styling polish / fixes
|
- Remember currently selected wonder on home page
|
||||||
|
- EventsView: switch to two-column layout at aspect ratios > .85
|
||||||
|
Loading…
x
Reference in New Issue
Block a user