From 6944e0c586be4bd41e5acaef4e3d2f1bae9d6699 Mon Sep 17 00:00:00 2001 From: Sergey Dmitriev <51058739+0niel@users.noreply.github.com> Date: Fri, 15 Sep 2023 10:52:44 +0300 Subject: [PATCH 1/5] fix: Make tags scrollable and add selected tag --- .../bloc/news_bloc/news_bloc.dart | 12 ++++++- .../pages/news/news_details_page.dart | 5 +-- lib/presentation/pages/news/news_page.dart | 36 ++++++++++--------- .../pages/news/widgets/news_card.dart | 17 +++------ 4 files changed, 39 insertions(+), 31 deletions(-) diff --git a/lib/presentation/bloc/news_bloc/news_bloc.dart b/lib/presentation/bloc/news_bloc/news_bloc.dart index 8158ce10..fa70536b 100644 --- a/lib/presentation/bloc/news_bloc/news_bloc.dart +++ b/lib/presentation/bloc/news_bloc/news_bloc.dart @@ -28,6 +28,16 @@ class NewsBloc extends Bloc { return tag; } + static bool isTagsNotEmpty(List tags) { + if (tags.isEmpty) { + return false; + } else if (tags.length == 1 && tags[0].isEmpty) { + return false; + } + + return true; + } + void _onNewsLoadEvent(NewsLoadEvent event, Emitter emit) async { if (state is NewsLoaded) { final st = state as NewsLoaded; @@ -48,7 +58,7 @@ class NewsBloc extends Bloc { emit(NewsLoaded( news: event.refresh == true ? r : st.news + r, tags: st.tags, - selectedTag: st.selectedTag, + selectedTag: event.tag, page: st.page + 1, )); }, diff --git a/lib/presentation/pages/news/news_details_page.dart b/lib/presentation/pages/news/news_details_page.dart index a22c3e1e..e556f5ab 100644 --- a/lib/presentation/pages/news/news_details_page.dart +++ b/lib/presentation/pages/news/news_details_page.dart @@ -4,6 +4,7 @@ import 'package:flutter_html_iframe/flutter_html_iframe.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:intl/intl.dart'; import 'package:rtu_mirea_app/domain/entities/news_item.dart'; +import 'package:rtu_mirea_app/presentation/bloc/news_bloc/news_bloc.dart'; import 'package:rtu_mirea_app/presentation/pages/news/widgets/tag_badge.dart'; import 'package:rtu_mirea_app/presentation/widgets/images_horizontal_slider.dart'; import 'package:url_launcher/url_launcher_string.dart'; @@ -103,11 +104,11 @@ class _NewsItemInfo extends StatelessWidget { Widget build(BuildContext context) { return Row( crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: tags.isNotEmpty + mainAxisAlignment: NewsBloc.isTagsNotEmpty(tags) ? MainAxisAlignment.spaceBetween : MainAxisAlignment.start, children: [ - tags.isNotEmpty + NewsBloc.isTagsNotEmpty(tags) ? Expanded( child: Wrap( spacing: 8, diff --git a/lib/presentation/pages/news/news_page.dart b/lib/presentation/pages/news/news_page.dart index caffad7a..0461046e 100644 --- a/lib/presentation/pages/news/news_page.dart +++ b/lib/presentation/pages/news/news_page.dart @@ -94,26 +94,30 @@ class _NewsPageState extends State { ), const SizedBox(height: 16), Expanded( - child: Wrap( - spacing: 8, - runSpacing: 8, - children: List.generate(loadedState.tags.length, (index) { - if (loadedState.selectedTag == - loadedState.tags[index]) { + child: SingleChildScrollView( + physics: const BouncingScrollPhysics(), + child: Wrap( + spacing: 8, + runSpacing: 8, + children: + List.generate(loadedState.tags.length, (index) { + if (loadedState.selectedTag == + loadedState.tags[index]) { + return TagBadge( + tag: loadedState.tags[index], + color: AppTheme.colors.colorful04, + onPressed: () => _filterNewsByTag( + context.read(), "все"), + ); + } return TagBadge( tag: loadedState.tags[index], - color: AppTheme.colors.colorful04, onPressed: () => _filterNewsByTag( - context.read(), "все"), + context.read(), + loadedState.tags[index]), ); - } - return TagBadge( - tag: loadedState.tags[index], - onPressed: () => _filterNewsByTag( - context.read(), - loadedState.tags[index]), - ); - }), + }), + ), ), ), ], diff --git a/lib/presentation/pages/news/widgets/news_card.dart b/lib/presentation/pages/news/widgets/news_card.dart index 66ae84b6..70cf582e 100644 --- a/lib/presentation/pages/news/widgets/news_card.dart +++ b/lib/presentation/pages/news/widgets/news_card.dart @@ -4,6 +4,7 @@ import 'package:firebase_analytics/firebase_analytics.dart'; import 'package:flutter/material.dart'; import 'package:rtu_mirea_app/domain/entities/news_item.dart'; import 'package:intl/intl.dart'; +import 'package:rtu_mirea_app/presentation/bloc/news_bloc/news_bloc.dart'; import 'package:rtu_mirea_app/presentation/core/routes/routes.gr.dart'; import 'package:rtu_mirea_app/presentation/pages/news/widgets/tag_badge.dart'; import 'package:rtu_mirea_app/presentation/theme.dart'; @@ -17,16 +18,6 @@ class NewsCard extends StatelessWidget { const NewsCard({Key? key, required this.newsItem, this.onClickNewsTag}) : super(key: key); - bool isTagsNotEmpty() { - if (newsItem.tags.isEmpty) { - return false; - } else if (newsItem.tags.length == 1 && newsItem.tags[0].isEmpty) { - return false; - } - - return true; - } - @override Widget build(BuildContext context) { return GestureDetector( @@ -123,8 +114,10 @@ class NewsCard extends StatelessWidget { textAlign: TextAlign.start, style: AppTextStyle.captionL .copyWith(color: AppTheme.colors.secondary)), - isTagsNotEmpty() ? const SizedBox(height: 16) : Container(), - isTagsNotEmpty() + NewsBloc.isTagsNotEmpty(newsItem.tags) + ? const SizedBox(height: 16) + : Container(), + NewsBloc.isTagsNotEmpty(newsItem.tags) ? _Tags( tags: newsItem.tags, onClick: onClickNewsTag, From 5b4d232006f40cb17bbae319d4647abdf08ec130 Mon Sep 17 00:00:00 2001 From: Sergey Dmitriev <51058739+0niel@users.noreply.github.com> Date: Fri, 15 Sep 2023 10:53:13 +0300 Subject: [PATCH 2/5] ui: Change stories size and make it scrollable --- .../schedule/widgets/schedule_page_view.dart | 117 ++++++++++-------- .../pages/schedule/widgets/story_item.dart | 5 +- 2 files changed, 68 insertions(+), 54 deletions(-) diff --git a/lib/presentation/pages/schedule/widgets/schedule_page_view.dart b/lib/presentation/pages/schedule/widgets/schedule_page_view.dart index d9c84a5c..f0b28d10 100644 --- a/lib/presentation/pages/schedule/widgets/schedule_page_view.dart +++ b/lib/presentation/pages/schedule/widgets/schedule_page_view.dart @@ -37,6 +37,8 @@ class _SchedulePageViewState extends State { late int _selectedPage; late int _selectedWeek; + final _scrollNotifier = ValueNotifier(0); + @override void initState() { super.initState(); @@ -160,30 +162,38 @@ class _SchedulePageViewState extends State { lessons = _getLessonsWithEmpty(lessons, state.activeGroup); } - return ListView.separated( - itemCount: lessons.length, - physics: const BouncingScrollPhysics(), - itemBuilder: (context, i) { - return Padding( - padding: const EdgeInsets.symmetric(horizontal: 24), - child: lessons[i].name.replaceAll(' ', '') != '' - ? LessonCard( - name: lessons[i].name, - timeStart: lessons[i].timeStart, - timeEnd: lessons[i].timeEnd, - room: lessons[i].rooms.join(', '), - type: lessons[i].types, - teacher: lessons[i].teachers.join(', '), - ) - : EmptyLessonCard( - timeStart: lessons[i].timeStart, - timeEnd: lessons[i].timeEnd, - ), - ); - }, - separatorBuilder: (context, index) { - return const SizedBox(height: 8); + return NotificationListener( + onNotification: (notification) { + if (notification is ScrollUpdateNotification) { + _scrollNotifier.value = notification.metrics.extentBefore; + } + return true; }, + child: ListView.separated( + itemCount: lessons.length, + physics: const BouncingScrollPhysics(), + itemBuilder: (context, i) { + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 24), + child: lessons[i].name.replaceAll(' ', '') != '' + ? LessonCard( + name: lessons[i].name, + timeStart: lessons[i].timeStart, + timeEnd: lessons[i].timeEnd, + room: lessons[i].rooms.join(', '), + type: lessons[i].types, + teacher: lessons[i].teachers.join(', '), + ) + : EmptyLessonCard( + timeStart: lessons[i].timeStart, + timeEnd: lessons[i].timeEnd, + ), + ); + }, + separatorBuilder: (context, index) { + return const SizedBox(height: 8); + }, + ), ); } } @@ -420,35 +430,40 @@ class _SchedulePageViewState extends State { } Widget _buildStories(List stories) { - return SizedBox( - height: 120, - child: ListView.separated( - padding: const EdgeInsets.symmetric(horizontal: 20), - scrollDirection: Axis.horizontal, - itemBuilder: (_, int i) { - if (DateTime.now().compareTo(stories[i].stopShowDate) == -1) { - return Container( - decoration: BoxDecoration( - boxShadow: [ - BoxShadow( - color: Theme.of(context).shadowColor.withOpacity( - AppTheme.themeMode == ThemeMode.dark ? 0.1 : 0.1), - blurRadius: 10, - offset: const Offset(0, 4), + return ValueListenableBuilder( + valueListenable: _scrollNotifier, + builder: (context, value, child) { + return SizedBox( + height: value > 80 ? 0 : 80 - value, + child: ListView.separated( + padding: const EdgeInsets.symmetric(horizontal: 20), + scrollDirection: Axis.horizontal, + itemBuilder: (_, int i) { + if (DateTime.now().compareTo(stories[i].stopShowDate) == -1) { + return Container( + decoration: BoxDecoration( + boxShadow: [ + BoxShadow( + color: Theme.of(context).shadowColor.withOpacity( + AppTheme.themeMode == ThemeMode.dark ? 0.1 : 0.1), + blurRadius: 10, + offset: const Offset(0, 4), + ), + ], ), - ], - ), - child: StoryWidget( - stories: stories, - storyIndex: i, - ), - ); - } - return Container(); - }, - separatorBuilder: (_, int i) => const SizedBox(width: 10), - itemCount: stories.length, - ), + child: StoryWidget( + stories: stories, + storyIndex: i, + ), + ); + } + return Container(); + }, + separatorBuilder: (_, int i) => const SizedBox(width: 10), + itemCount: stories.length, + ), + ); + }, ); } diff --git a/lib/presentation/pages/schedule/widgets/story_item.dart b/lib/presentation/pages/schedule/widgets/story_item.dart index 7be7d3d5..ffadd7a6 100644 --- a/lib/presentation/pages/schedule/widgets/story_item.dart +++ b/lib/presentation/pages/schedule/widgets/story_item.dart @@ -1,4 +1,3 @@ - import 'package:auto_route/auto_route.dart'; import 'package:flutter/material.dart'; import 'package:rtu_mirea_app/domain/entities/story.dart'; @@ -23,8 +22,8 @@ class StoryWidget extends StatelessWidget { child: Hero( tag: stories[storyIndex].title, child: Container( - height: 120, - width: 88, + height: 80, + width: 68, padding: const EdgeInsets.all(8), clipBehavior: Clip.antiAlias, alignment: Alignment.bottomLeft, From 8f7e0636498acfef95cc76e7302147bfac9b43f3 Mon Sep 17 00:00:00 2001 From: Sergey Dmitriev <51058739+0niel@users.noreply.github.com> Date: Fri, 15 Sep 2023 10:53:53 +0300 Subject: [PATCH 3/5] ui: Update onboarding text --- lib/presentation/pages/onboarding/onboarding_page.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/presentation/pages/onboarding/onboarding_page.dart b/lib/presentation/pages/onboarding/onboarding_page.dart index 3b63c9f0..b5f8c16e 100644 --- a/lib/presentation/pages/onboarding/onboarding_page.dart +++ b/lib/presentation/pages/onboarding/onboarding_page.dart @@ -52,7 +52,7 @@ class _OnBoardingPageState extends State { static const List titlesTexts = [ 'Добро пожаловать!', 'Смотри расписание!', - 'Будь в курсе, не надевая штаны!', + 'Будь в курсе в любой момент!', // 'Ставь цели!', //'Коммуницируй!', ]; From e140d9a7748796cd16c35d8ffcd8b792a56a447d Mon Sep 17 00:00:00 2001 From: Sergey Dmitriev <51058739+0niel@users.noreply.github.com> Date: Fri, 15 Sep 2023 10:54:13 +0300 Subject: [PATCH 4/5] chore: Upgrade oauth2 client deps --- pubspec.yaml | 2 +- windows/runner/flutter_window.cpp | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index f8d0ec11..a20793f4 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -170,7 +170,7 @@ dependencies: firebase_core_web: ^2.5.0 firebase_analytics: ^10.4.1 - oauth2_client: ^3.2.1 + oauth2_client: ^3.2.2 # Flutter Secure Storage provides API to store data in secure storage. # See https://pub.dev/packages/flutter_secure_storage diff --git a/windows/runner/flutter_window.cpp b/windows/runner/flutter_window.cpp index b25e363e..955ee303 100644 --- a/windows/runner/flutter_window.cpp +++ b/windows/runner/flutter_window.cpp @@ -31,6 +31,11 @@ bool FlutterWindow::OnCreate() { this->Show(); }); + // Flutter can complete the first frame before the "show window" callback is + // registered. The following call ensures a frame is pending to ensure the + // window is shown. It is a no-op if the first frame hasn't completed yet. + flutter_controller_->ForceRedraw(); + return true; } From 9c6880b1be719b4758dffa46e15f8b37d2059a11 Mon Sep 17 00:00:00 2001 From: Sergey Dmitriev <51058739+0niel@users.noreply.github.com> Date: Fri, 15 Sep 2023 11:12:59 +0300 Subject: [PATCH 5/5] chore: Update app version --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index a20793f4..d6734e83 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -12,7 +12,7 @@ publish_to: 'none' # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.3.5+29 +version: 1.3.6+30 environment: sdk: ">=3.1.1"