diff --git a/tracking_flutter/ios/Runner.xcodeproj/project.pbxproj b/tracking_flutter/ios/Runner.xcodeproj/project.pbxproj index b49da22..7814def 100644 --- a/tracking_flutter/ios/Runner.xcodeproj/project.pbxproj +++ b/tracking_flutter/ios/Runner.xcodeproj/project.pbxproj @@ -505,8 +505,13 @@ ); PRODUCT_BUNDLE_IDENTIFIER = app.healthyhustle; PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; }; name = Profile; @@ -685,9 +690,14 @@ ); PRODUCT_BUNDLE_IDENTIFIER = app.healthyhustle; PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; }; name = Debug; @@ -709,8 +719,13 @@ ); PRODUCT_BUNDLE_IDENTIFIER = app.healthyhustle; PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; }; name = Release; diff --git a/tracking_flutter/lib/calendar/view/calendar_screen.dart b/tracking_flutter/lib/calendar/view/calendar_screen.dart index 63ad9b6..7163fde 100644 --- a/tracking_flutter/lib/calendar/view/calendar_screen.dart +++ b/tracking_flutter/lib/calendar/view/calendar_screen.dart @@ -21,6 +21,7 @@ import 'package:tracking_app/shared/theme/layout.dart'; import 'package:tracking_app/shared/toast.dart'; import 'package:tracking_app/shared/widgets/loading_indicator.dart'; import 'package:tracking_app/shared/widgets/mood_emoji.dart'; +import 'package:tracking_app/shared/widgets/moods_shader_mask.dart'; import 'package:tracking_app/shared/widgets/spacing.dart'; import 'package:tracking_app/update_mood/bloc/update_mood_bloc.dart'; import 'package:user_profile_repository/user_profile_repository.dart'; @@ -113,54 +114,60 @@ class _CalendarView extends StatelessWidget { buildWhen: (previous, current) => previous.moodsState != current.moodsState, builder: (context, state) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const VerticalSpacing.large(), - Center( - child: Container( - constraints: const BoxConstraints(maxWidth: 430), - padding: const EdgeInsets.symmetric( - horizontal: viewPaddingHorizontal, + return Center( + child: Container( + constraints: const BoxConstraints(maxWidth: maxViewWidth), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const VerticalSpacing.large(), + Center( + child: Container( + constraints: const BoxConstraints(maxWidth: 430), + padding: const EdgeInsets.symmetric( + horizontal: viewPaddingHorizontal, + ), + child: _Calendar( + targetMonthDate: state.targetDate.date, + moods: state.moodsState.moods, + ), + ), ), - child: _Calendar( - targetMonthDate: state.targetDate.date, - moods: state.moodsState.moods, + const VerticalSpacing.medium(), + Padding( + padding: const EdgeInsets.symmetric( + horizontal: viewPaddingHorizontal, + ), + child: Text( + translations.trackedMood, + style: Theme.of(context).textTheme.headlineSmall, + ), ), - ), + const VerticalSpacing.medium(), + if (state.moodsState.isLoading || + state.moodsState.isInitial) + const SizedBox( + height: 125, + child: Center(child: LoadingIndicator()), + ) + else if (state.moodsState.isSuccess && + state.moodsState.moods.isEmpty) + Padding( + padding: const EdgeInsets.symmetric( + horizontal: viewPaddingHorizontal, + ), + child: Text( + translations.noTrackedMood, + style: Theme.of(context).textTheme.bodyMedium, + ), + ) + else if (state.moodsState.isSuccess) + _MoodsInMonth(moods: state.moodsState.moods) + .animate() + .fadeIn(duration: animationDuration), + ], ), - const VerticalSpacing.large(), - Padding( - padding: const EdgeInsets.symmetric( - horizontal: viewPaddingHorizontal, - ), - child: Text( - translations.trackedMood, - style: Theme.of(context).textTheme.headlineSmall, - ), - ), - const VerticalSpacing.medium(), - if (state.moodsState.isLoading || state.moodsState.isInitial) - const SizedBox( - height: 125, - child: Center(child: LoadingIndicator()), - ) - else if (state.moodsState.isSuccess && - state.moodsState.moods.isEmpty) - Padding( - padding: const EdgeInsets.symmetric( - horizontal: viewPaddingHorizontal, - ), - child: Text( - translations.noTrackedMood, - style: Theme.of(context).textTheme.bodyMedium, - ), - ) - else if (state.moodsState.isSuccess) - _MoodsInMonth(moods: state.moodsState.moods) - .animate() - .fadeIn(duration: animationDuration), - ], + ), ); }, ), diff --git a/tracking_flutter/lib/calendar/view/widgets/calendar.dart b/tracking_flutter/lib/calendar/view/widgets/calendar.dart index 0c493af..25166d8 100644 --- a/tracking_flutter/lib/calendar/view/widgets/calendar.dart +++ b/tracking_flutter/lib/calendar/view/widgets/calendar.dart @@ -52,13 +52,14 @@ class _Calendar extends StatelessWidget { return Column( children: [ Padding( - padding: const EdgeInsets.only(left: 12, right: 2), + padding: + const EdgeInsets.symmetric(horizontal: horizontalPaddingLarge), child: _CalendarHeader(targetMonthDate: targetMonthDate), ), const VerticalSpacing.extraLarge(), CalendarCarousel( firstDayOfWeek: (0 + 1) % 7, - height: 350, + height: 335, todayButtonColor: _CalendarTheme.todayButtonColor, todayTextStyle: _CalendarTheme.todayTextStyle, daysTextStyle: _CalendarTheme.calendarDaysTextStyle, @@ -128,7 +129,6 @@ class _Calendar extends StatelessWidget { date: mood.createdOn.dateOnly, dot: Container( decoration: _CalendarTheme.eventDotDecoration, - margin: const EdgeInsets.symmetric(horizontal: 1), height: 6, width: 6, ).animate().fadeIn( @@ -190,7 +190,7 @@ class _CalendarHeader extends StatelessWidget { ), ), ), - const HorizontalSpacing.large(), + const HorizontalSpacing.extraLarge(), Material( color: Colors.transparent, child: InkWell( diff --git a/tracking_flutter/lib/calendar/view/widgets/moods_in_month.dart b/tracking_flutter/lib/calendar/view/widgets/moods_in_month.dart index e660814..554032f 100644 --- a/tracking_flutter/lib/calendar/view/widgets/moods_in_month.dart +++ b/tracking_flutter/lib/calendar/view/widgets/moods_in_month.dart @@ -9,21 +9,26 @@ class _MoodsInMonth extends StatelessWidget { @override Widget build(BuildContext context) { - return SingleChildScrollView( - scrollDirection: Axis.horizontal, - child: Row( - children: [ - const SizedBox(width: viewPaddingHorizontal), - for (final mood in moods) - Padding( - key: ValueKey(mood), - padding: const EdgeInsets.only( - right: verticalPaddingSmall, + return MoodsShaderMask( + begin: Alignment.centerLeft, + end: Alignment.centerRight, + stops: const [0.0, 0.9, 1.0], + child: SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Row( + children: [ + const SizedBox(width: viewPaddingHorizontal), + for (final mood in moods) + Padding( + key: ValueKey(mood), + padding: const EdgeInsets.only( + right: verticalPaddingSmall, + ), + child: _TrackedMood(mood: mood), ), - child: _TrackedMood(mood: mood), - ), - const SizedBox(width: viewPaddingHorizontal), - ], + const SizedBox(width: viewPaddingHorizontal), + ], + ), ), ); } diff --git a/tracking_flutter/lib/home/view/home_screen.dart b/tracking_flutter/lib/home/view/home_screen.dart index 4282d10..9cd29f5 100644 --- a/tracking_flutter/lib/home/view/home_screen.dart +++ b/tracking_flutter/lib/home/view/home_screen.dart @@ -31,7 +31,9 @@ import 'package:tracking_app/update_mood/bloc/update_mood_bloc.dart'; import 'package:tracking_app/user_profile/cubit/user_profile_cubit.dart'; import 'package:user_profile_repository/user_profile_repository.dart'; -part 'widgets/progress.dart'; +part 'widgets/home_moods.dart'; +part 'widgets/home_moods_header.dart'; +part 'widgets/home_progress.dart'; class HomeScreen extends StatelessWidget { const HomeScreen({super.key}); @@ -286,37 +288,8 @@ class _HomeContentView extends StatelessWidget { ), ), const VerticalSpacing.large(), - if (moods.isNotEmpty) - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - translations.recentlyTracked, - style: Theme.of(context).textTheme.headlineSmall, - ), - TextButton( - onPressed: () { - context.goNamed(RoutesNames.moods); - }, - child: Text( - translations.seeAll, - style: Theme.of(context).textTheme.bodySmall!.copyWith( - color: AppColors.blue, - ), - ), - ), - ], - ), - for (final mood in moods) - TrackedMood( - mood: mood, - onTap: () => context.pushNamed( - RoutesNames.updateMoodFromHome, - extra: UpdateMoodRouteParameters(mood: mood), - ), - ).animate().fadeIn( - duration: animationDuration, - ), + if (moods.isNotEmpty) const _HomeMoodsHeader(), + _HomeMoods(moods: moods), if (addExtraBottomSpace) const VerticalSpacing.extraLarge(), ], ), diff --git a/tracking_flutter/lib/home/view/widgets/home_moods.dart b/tracking_flutter/lib/home/view/widgets/home_moods.dart new file mode 100644 index 0000000..2134448 --- /dev/null +++ b/tracking_flutter/lib/home/view/widgets/home_moods.dart @@ -0,0 +1,26 @@ +part of '../home_screen.dart'; + +class _HomeMoods extends StatelessWidget { + const _HomeMoods({required this.moods}); + + final List moods; + + @override + Widget build(BuildContext context) { + return Column( + children: [ + for (final mood in moods) + TrackedMood( + mood: mood, + onTap: () => context.pushNamed( + RoutesNames.updateMoodFromHome, + extra: UpdateMoodRouteParameters(mood: mood), + ), + ).animate().fadeIn( + duration: animationDuration, + ), + const VerticalSpacing.medium(), + ], + ); + } +} diff --git a/tracking_flutter/lib/home/view/widgets/home_moods_header.dart b/tracking_flutter/lib/home/view/widgets/home_moods_header.dart new file mode 100644 index 0000000..bc8e741 --- /dev/null +++ b/tracking_flutter/lib/home/view/widgets/home_moods_header.dart @@ -0,0 +1,31 @@ +part of '../home_screen.dart'; + +class _HomeMoodsHeader extends StatelessWidget { + const _HomeMoodsHeader(); + + @override + Widget build(BuildContext context) { + final translations = AppLocalizations.of(context)!; + + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + translations.recentlyTracked, + style: Theme.of(context).textTheme.headlineSmall, + ), + TextButton( + onPressed: () { + context.goNamed(RoutesNames.moods); + }, + child: Text( + translations.seeAll, + style: Theme.of(context).textTheme.bodySmall!.copyWith( + color: AppColors.blue, + ), + ), + ), + ], + ); + } +} diff --git a/tracking_flutter/lib/home/view/widgets/progress.dart b/tracking_flutter/lib/home/view/widgets/home_progress.dart similarity index 100% rename from tracking_flutter/lib/home/view/widgets/progress.dart rename to tracking_flutter/lib/home/view/widgets/home_progress.dart diff --git a/tracking_flutter/lib/moods/view/moods_screen.dart b/tracking_flutter/lib/moods/view/moods_screen.dart index b9bd47d..b7f26b8 100644 --- a/tracking_flutter/lib/moods/view/moods_screen.dart +++ b/tracking_flutter/lib/moods/view/moods_screen.dart @@ -13,19 +13,17 @@ import 'package:tracking_app/moods/cubit/moods_cubit.dart'; import 'package:tracking_app/shared/router/routes_names.dart'; import 'package:tracking_app/shared/router/routes_parameters.dart'; import 'package:tracking_app/shared/theme/animation.dart'; -import 'package:tracking_app/shared/theme/colors.dart'; import 'package:tracking_app/shared/theme/layout.dart'; import 'package:tracking_app/shared/view/base_view.dart'; import 'package:tracking_app/shared/widgets/app_elevated_button.dart'; import 'package:tracking_app/shared/widgets/error_message.dart'; import 'package:tracking_app/shared/widgets/loading_indicator.dart'; +import 'package:tracking_app/shared/widgets/moods_shader_mask.dart'; import 'package:tracking_app/shared/widgets/tracked_mood.dart'; import 'package:tracking_app/update_mood/bloc/update_mood_bloc.dart'; import 'package:tracking_app/user_profile/cubit/user_profile_cubit.dart'; import 'package:user_profile_repository/user_profile_repository.dart'; -part 'widgets/moods_shader_mask.dart'; - class MoodsScreen extends StatelessWidget { const MoodsScreen({super.key}); @@ -211,6 +209,9 @@ class _MoodsContentViewState extends State<_MoodsContentView> { children: [ Expanded( child: MoodsShaderMask( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + stops: const [0.0, 0.95, 1.0], child: _buildMoods(), ), ), diff --git a/tracking_flutter/lib/settings/view/widgets/user_profile_avatar.dart b/tracking_flutter/lib/settings/view/widgets/user_profile_avatar.dart index 4002c8b..ff97e18 100644 --- a/tracking_flutter/lib/settings/view/widgets/user_profile_avatar.dart +++ b/tracking_flutter/lib/settings/view/widgets/user_profile_avatar.dart @@ -64,8 +64,10 @@ class _UserProfileAvatar extends StatelessWidget { title: AppLocalizations.of(context)!.selectEmoji, body: Padding( padding: const EdgeInsets.only(top: verticalPaddingLarge), - child: SizedBox( + child: Container( + constraints: const BoxConstraints(maxWidth: 500), width: double.maxFinite, + height: MediaQuery.of(context).size.height * 0.4, child: GridView.count( crossAxisCount: 4, crossAxisSpacing: 15, diff --git a/tracking_flutter/lib/shared/theme/layout.dart b/tracking_flutter/lib/shared/theme/layout.dart index 3fad1f8..7bb200f 100644 --- a/tracking_flutter/lib/shared/theme/layout.dart +++ b/tracking_flutter/lib/shared/theme/layout.dart @@ -7,5 +7,9 @@ const double verticalPaddingExtraExtraLarge = 60; const double horizontalPaddingSmall = 5; const double horizontalPaddingMedium = 10; const double horizontalPaddingLarge = 15; +const double horizontalPaddingExtraLarge = 30; const double viewPaddingVertical = 15; const double viewPaddingHorizontal = 25; + +// View size constants +const double maxViewWidth = 700; diff --git a/tracking_flutter/lib/shared/view/base_view.dart b/tracking_flutter/lib/shared/view/base_view.dart index e7bdc6a..462f2eb 100644 --- a/tracking_flutter/lib/shared/view/base_view.dart +++ b/tracking_flutter/lib/shared/view/base_view.dart @@ -21,7 +21,15 @@ class BaseView extends StatelessWidget { horizontal: addHorizontalPadding ? viewPaddingHorizontal : 0, vertical: addVerticalPadding ? viewPaddingVertical : 0, ), - child: child, + child: Align( + alignment: Alignment.topCenter, + child: Container( + constraints: const BoxConstraints( + maxWidth: maxViewWidth, + ), + child: child, + ), + ), ), ); } diff --git a/tracking_flutter/lib/shared/widgets/app_elevated_button.dart b/tracking_flutter/lib/shared/widgets/app_elevated_button.dart index 326105e..04d8e70 100644 --- a/tracking_flutter/lib/shared/widgets/app_elevated_button.dart +++ b/tracking_flutter/lib/shared/widgets/app_elevated_button.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:tracking_app/shared/theme/colors.dart'; +import 'package:tracking_app/shared/theme/layout.dart'; import 'package:tracking_app/shared/widgets/loading_indicator.dart'; class AppElevatedButton extends StatelessWidget { @@ -34,15 +35,18 @@ class AppElevatedButton extends StatelessWidget { ), ); - return ElevatedButton.icon( - key: key, - onPressed: isDisabled || isLoading ? null : onPressed, - icon: isLoading - ? const TinyLoadingIndicator( - color: AppColors.contentOnDarkBackgroundColor, - ) - : iconToBuild, - label: isLoading ? const SizedBox.shrink() : textToBuild, + return Container( + constraints: const BoxConstraints(maxWidth: maxViewWidth), + child: ElevatedButton.icon( + key: key, + onPressed: isDisabled || isLoading ? null : onPressed, + icon: isLoading + ? const TinyLoadingIndicator( + color: AppColors.contentOnDarkBackgroundColor, + ) + : iconToBuild, + label: isLoading ? const SizedBox.shrink() : textToBuild, + ), ); } } diff --git a/tracking_flutter/lib/moods/view/widgets/moods_shader_mask.dart b/tracking_flutter/lib/shared/widgets/moods_shader_mask.dart similarity index 56% rename from tracking_flutter/lib/moods/view/widgets/moods_shader_mask.dart rename to tracking_flutter/lib/shared/widgets/moods_shader_mask.dart index 5f78c1e..7ed9871 100644 --- a/tracking_flutter/lib/moods/view/widgets/moods_shader_mask.dart +++ b/tracking_flutter/lib/shared/widgets/moods_shader_mask.dart @@ -1,26 +1,33 @@ -part of '../moods_screen.dart'; +import 'package:flutter/material.dart'; +import 'package:tracking_app/shared/theme/colors.dart'; class MoodsShaderMask extends StatelessWidget { const MoodsShaderMask({ required this.child, + required this.begin, + required this.end, + required this.stops, super.key, }); + final Alignment begin; + final Alignment end; + final List stops; final Widget child; @override Widget build(BuildContext context) { return ShaderMask( shaderCallback: (Rect rect) { - return const LinearGradient( - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - colors: [ + return LinearGradient( + begin: begin, + end: end, + colors: const [ Colors.transparent, Colors.transparent, AppColors.primarySwatch, ], - stops: [0.0, 0.95, 1.0], + stops: stops, ).createShader(rect); }, blendMode: BlendMode.dstOut, diff --git a/tracking_flutter/lib/shared/widgets/spacing.dart b/tracking_flutter/lib/shared/widgets/spacing.dart index 4976244..dcacd43 100644 --- a/tracking_flutter/lib/shared/widgets/spacing.dart +++ b/tracking_flutter/lib/shared/widgets/spacing.dart @@ -42,7 +42,7 @@ class VerticalSpacing extends StatelessWidget { } } -enum HorizontalSpacingSize { small, medium, large } +enum HorizontalSpacingSize { small, medium, large, extraLarge } class HorizontalSpacing extends StatelessWidget { const HorizontalSpacing({ @@ -56,6 +56,8 @@ class HorizontalSpacing extends StatelessWidget { : size = HorizontalSpacingSize.medium; const HorizontalSpacing.large({super.key}) : size = HorizontalSpacingSize.large; + const HorizontalSpacing.extraLarge({super.key}) + : size = HorizontalSpacingSize.extraLarge; final HorizontalSpacingSize size; @@ -74,6 +76,8 @@ class HorizontalSpacing extends StatelessWidget { return horizontalPaddingMedium; case HorizontalSpacingSize.large: return horizontalPaddingLarge; + case HorizontalSpacingSize.extraLarge: + return horizontalPaddingExtraLarge; } } }