diff --git a/.drone.yml b/.drone.yml index daf3031..a3c4a7e 100644 --- a/.drone.yml +++ b/.drone.yml @@ -4,7 +4,7 @@ name: default steps: - name: build - image: cirrusci/flutter:3.0.5 + image: cirrusci/flutter:3.3.9 commands: - flutter doctor - flutter pub get diff --git a/CHANGELOG.md b/CHANGELOG.md index fb2aff9..f1948c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,13 @@ # CHANGELOG -## 1.4.3+16 - UNRELEASED +## 1.5.0+16 - UNRELEASED +* Switched to Material You defaulting to blue swatch colors respecting dark mode +* Switched to Material You navigation bar and removed unsupported swipe navigation * Increased target SDK to `33` -* Increased dart to `>= 2.17.3` +* Increased dart to `>= 2.18.6` * Indicate configuration loading in profile view * Switched linked git repository away from GitHub -* Updated dependencies +* Updated internal dependencies ## 1.4.2+15 * Minor cleanup diff --git a/lib/app.dart b/lib/app.dart index 1eebc52..51dac04 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -1,10 +1,10 @@ +import 'package:dynamic_color/dynamic_color.dart'; import 'package:flutter/material.dart'; import 'package:flutter_translate/flutter_translate.dart'; import 'package:intl/date_symbol_data_local.dart'; import 'package:provider/provider.dart'; import 'core/enums/refresh_event.dart'; -import 'core/enums/swipe_event.dart'; import 'core/manager/dialog_manager.dart'; import 'core/manager/lifecycle_manager.dart'; import 'core/models/session.dart'; @@ -12,13 +12,14 @@ import 'core/services/dialog_service.dart'; import 'core/services/navigation_service.dart'; import 'core/services/refresh_service.dart'; import 'core/services/session_service.dart'; -import 'core/services/swipe_service.dart'; import 'locator.dart'; import 'ui/app_router.dart'; import 'ui/shared/app_colors.dart'; import 'ui/views/startup_view.dart'; class MyApp extends StatelessWidget { + static final _defaultLightColorScheme = ColorScheme.fromSwatch(primarySwatch: myColor, brightness: Brightness.light); + static final _defaultDarkColorScheme = ColorScheme.fromSwatch(primarySwatch: myColor, brightness: Brightness.dark); MyApp() { initializeDateFormatting('en'); @@ -30,34 +31,32 @@ class MyApp extends StatelessWidget { return LocalizationProvider( state: LocalizationProvider.of(context).state, - child: StreamProvider( + child: StreamProvider( initialData: null, - create: (context) => locator().swipeEventController.stream, - child: StreamProvider( - initialData: null, - create: (context) => locator().refreshEventController.stream, - child: StreamProvider( - initialData: Session.initial(), - create: (context) => locator().sessionController.stream, - child: LifeCycleManager( - child: MaterialApp( - debugShowCheckedModeBanner: false, - title: translate('app.title'), - builder: (context, child) => Navigator( - key: locator().dialogNavigationKey, - onGenerateRoute: (settings) => - MaterialPageRoute(builder: (context) => DialogManager(child: child)), - ), - theme: ThemeData( - brightness: Brightness.light, - primarySwatch: primaryAccentColor as MaterialColor?, - primaryColor: primaryAccentColor), - onGenerateRoute: AppRouter.generateRoute, - navigatorKey: locator().navigationKey, - home: StartUpView(), - supportedLocales: localizationDelegate.supportedLocales, - locale: localizationDelegate.currentLocale, - )), - )))); + create: (context) => locator().refreshEventController.stream, + child: StreamProvider( + initialData: Session.initial(), + create: (context) => locator().sessionController.stream, + child: LifeCycleManager(child: DynamicColorBuilder(builder: (lightColorScheme, darkColorScheme) { + return MaterialApp( + debugShowCheckedModeBanner: false, + title: translate('app.title'), + builder: (context, child) => Navigator( + key: locator().dialogNavigationKey, + onGenerateRoute: (settings) => MaterialPageRoute(builder: (context) => DialogManager(child: child)), + ), + theme: ThemeData( + useMaterial3: true, + brightness: Brightness.light, + colorScheme: lightColorScheme ?? _defaultLightColorScheme), + darkTheme: ThemeData(useMaterial3: true, colorScheme: darkColorScheme ?? _defaultDarkColorScheme), + onGenerateRoute: AppRouter.generateRoute, + navigatorKey: locator().navigationKey, + home: StartUpView(), + supportedLocales: localizationDelegate.supportedLocales, + locale: localizationDelegate.currentLocale, + ); + })), + ))); } } diff --git a/lib/core/enums/swipe_event.dart b/lib/core/enums/swipe_event.dart deleted file mode 100644 index 20afbbb..0000000 --- a/lib/core/enums/swipe_event.dart +++ /dev/null @@ -1 +0,0 @@ -enum SwipeEvent { Start, Left, Right, End } diff --git a/lib/core/services/swipe_service.dart b/lib/core/services/swipe_service.dart deleted file mode 100644 index e77f1a9..0000000 --- a/lib/core/services/swipe_service.dart +++ /dev/null @@ -1,13 +0,0 @@ -import 'dart:async'; - -import '../enums/swipe_event.dart'; - -class SwipeService { - StreamController swipeEventController = StreamController.broadcast(); - - void addEvent(SwipeEvent event) { - if (swipeEventController.hasListener) { - swipeEventController.add(event); - } - } -} diff --git a/lib/core/viewmodels/upload_model.dart b/lib/core/viewmodels/upload_model.dart index 67b7acd..8be82a9 100644 --- a/lib/core/viewmodels/upload_model.dart +++ b/lib/core/viewmodels/upload_model.dart @@ -12,7 +12,6 @@ import 'package:receive_sharing_intent/receive_sharing_intent.dart'; import '../../locator.dart'; import '../enums/error_code.dart'; import '../enums/refresh_event.dart'; -import '../enums/swipe_event.dart'; import '../enums/viewstate.dart'; import '../error/rest_service_exception.dart'; import '../error/service_exception.dart'; @@ -22,7 +21,6 @@ import '../models/rest/uploaded_response.dart'; import '../services/file_service.dart'; import '../services/link_service.dart'; import '../services/refresh_service.dart'; -import '../services/swipe_service.dart'; import '../util/logger.dart'; import '../util/paste_util.dart'; import 'base_model.dart'; @@ -32,7 +30,6 @@ class UploadModel extends BaseModel { final FileService _fileService = locator(); final LinkService _linkService = locator(); final RefreshService _refreshService = locator(); - final SwipeService _swipeService = locator(); TextEditingController _pasteTextController = TextEditingController(); bool pasteTextTouched = false; @@ -67,9 +64,6 @@ class UploadModel extends BaseModel { }); }).toList(); setStateView(ViewState.Idle); - if (paths!.isNotEmpty && paths!.length > 0) { - _swipeService.addEvent(SwipeEvent.Start); - } } }, onError: (err) { _errorIntentHandle(err); @@ -88,9 +82,6 @@ class UploadModel extends BaseModel { }); }).toList(); setStateView(ViewState.Idle); - if (paths!.isNotEmpty && paths!.length > 0) { - _swipeService.addEvent(SwipeEvent.Start); - } } }, onError: (err) { _errorIntentHandle(err); @@ -102,7 +93,6 @@ class UploadModel extends BaseModel { setStateView(ViewState.Busy); pasteTextController.text = value; setStateView(ViewState.Idle); - _swipeService.addEvent(SwipeEvent.Start); } }, onError: (err) { _errorIntentHandle(err); @@ -114,9 +104,6 @@ class UploadModel extends BaseModel { setStateView(ViewState.Busy); pasteTextController.text = value; setStateView(ViewState.Idle); - if (paths!.isNotEmpty && paths!.length > 0) { - _swipeService.addEvent(SwipeEvent.Start); - } } }, onError: (err) { _errorIntentHandle(err); @@ -128,8 +115,6 @@ class UploadModel extends BaseModel { errorMessage = translate('upload.retrieval_intent'); _logger.e('Error while retrieving shared data: $err'); setStateView(ViewState.Idle); - - _swipeService.addEvent(SwipeEvent.Start); } String? generatePasteLinks(Map? uploads, String url) { diff --git a/lib/locator.dart b/lib/locator.dart index df04114..97bc207 100644 --- a/lib/locator.dart +++ b/lib/locator.dart @@ -11,7 +11,6 @@ import 'core/services/permission_service.dart'; import 'core/services/refresh_service.dart'; import 'core/services/session_service.dart'; import 'core/services/storage_service.dart'; -import 'core/services/swipe_service.dart'; import 'core/services/user_service.dart'; import 'core/viewmodels/about_model.dart'; import 'core/viewmodels/history_model.dart'; @@ -42,7 +41,6 @@ void setupLocator() { locator.registerLazySingleton(() => LinkService()); locator.registerLazySingleton(() => PermissionService()); locator.registerLazySingleton(() => RefreshService()); - locator.registerLazySingleton(() => SwipeService()); /// view models locator.registerFactory(() => StartUpViewModel()); diff --git a/lib/ui/shared/app_colors.dart b/lib/ui/shared/app_colors.dart index 4f22032..7fd9024 100644 --- a/lib/ui/shared/app_colors.dart +++ b/lib/ui/shared/app_colors.dart @@ -1,10 +1,5 @@ import 'package:flutter/material.dart'; -const Color backgroundColor = whiteColor; - -/// Colors -const Color primaryBackgroundColor = whiteColor; - const Map colors = { 50: Color.fromRGBO(63, 69, 75, .1), 100: Color.fromRGBO(63, 69, 75, .2), @@ -19,8 +14,6 @@ const Map colors = { }; const MaterialColor myColor = MaterialColor(0xFF3F454B, colors); const Color primaryAccentColor = myColor; -const Color buttonBackgroundColor = primaryAccentColor; -const Color buttonForegroundColor = whiteColor; const Color blueColor = Colors.blue; const Color whiteColor = Colors.white; diff --git a/lib/ui/shared/text_styles.dart b/lib/ui/shared/text_styles.dart index d7d2139..54ed9b0 100644 --- a/lib/ui/shared/text_styles.dart +++ b/lib/ui/shared/text_styles.dart @@ -1,4 +1,3 @@ import 'package:flutter/material.dart'; -const headerStyle = TextStyle(fontSize: 35, fontWeight: FontWeight.w900); const subHeaderStyle = TextStyle(fontSize: 16.0, fontWeight: FontWeight.w500); diff --git a/lib/ui/views/about_view.dart b/lib/ui/views/about_view.dart index e8c79ef..524e68b 100644 --- a/lib/ui/views/about_view.dart +++ b/lib/ui/views/about_view.dart @@ -6,7 +6,6 @@ import '../../core/enums/viewstate.dart'; import '../../core/viewmodels/about_model.dart'; import '../../ui/shared/text_styles.dart'; import '../../ui/shared/ui_helpers.dart'; -import '../shared/app_colors.dart'; import '../widgets/my_appbar.dart'; import 'base_view.dart'; @@ -31,7 +30,6 @@ class AboutView extends StatelessWidget { title: Text(translate('titles.about')), enableAbout: false, ), - backgroundColor: backgroundColor, body: model.state == ViewState.Busy ? Center(child: CircularProgressIndicator()) : Container( diff --git a/lib/ui/views/history_view.dart b/lib/ui/views/history_view.dart index 315bbe7..a9f5e80 100644 --- a/lib/ui/views/history_view.dart +++ b/lib/ui/views/history_view.dart @@ -13,7 +13,6 @@ import '../../core/viewmodels/history_model.dart'; import '../../ui/widgets/centered_error_row.dart'; import '../shared/app_colors.dart'; import '../widgets/my_appbar.dart'; -import '../widgets/swipe_navigation.dart'; import 'base_view.dart'; class HistoryView extends StatelessWidget { @@ -26,10 +25,8 @@ class HistoryView extends StatelessWidget { model.init(); return model.getHistory(); }, - builder: (context, model, child) => Scaffold( - appBar: MyAppBar(title: Text(translate('titles.history'))), - backgroundColor: backgroundColor, - body: SwipeNavigation(child: _render(model, context))), + builder: (context, model, child) => + Scaffold(appBar: MyAppBar(title: Text(translate('titles.history'))), body: _render(model, context)), ); } diff --git a/lib/ui/views/home_view.dart b/lib/ui/views/home_view.dart index 816027b..3214916 100644 --- a/lib/ui/views/home_view.dart +++ b/lib/ui/views/home_view.dart @@ -3,7 +3,6 @@ import 'package:flutter_translate/flutter_translate.dart'; import '../../core/enums/viewstate.dart'; import '../../core/viewmodels/home_model.dart'; -import '../shared/app_colors.dart'; import '../widgets/my_appbar.dart'; import 'base_view.dart'; @@ -15,7 +14,6 @@ class HomeView extends StatelessWidget { return BaseView( builder: (context, model, child) => Scaffold( appBar: MyAppBar(title: Text(translate('app.title'))), - backgroundColor: backgroundColor, body: model.state == ViewState.Busy ? Center(child: CircularProgressIndicator()) : Container()), ); } diff --git a/lib/ui/views/login_view.dart b/lib/ui/views/login_view.dart index b075a56..4917f32 100644 --- a/lib/ui/views/login_view.dart +++ b/lib/ui/views/login_view.dart @@ -36,7 +36,6 @@ class LoginView extends StatelessWidget { onModelReady: (model) => model.init(), builder: (context, model, child) => Scaffold( appBar: MyAppBar(title: Text(translate('titles.login'))), - backgroundColor: backgroundColor, body: model.state == ViewState.Busy ? Center(child: CircularProgressIndicator()) : ListView( @@ -56,7 +55,7 @@ class LoginView extends StatelessWidget { style: subHeaderStyle, ), InkWell( - child: Icon(Icons.help, color: buttonBackgroundColor), + child: Icon(Icons.help), onTap: () { _dialogService.showDialog( title: translate('login.compatibility_dialog.title'), @@ -85,7 +84,7 @@ class LoginView extends StatelessWidget { apiKeyController: model.apiKeyController), UIHelper.verticalSpaceMedium(), ElevatedButton( - child: Text(translate('login.button'), style: TextStyle(color: buttonForegroundColor)), + child: Text(translate('login.button')), onPressed: () async { var loginSuccess = await model.login(); if (loginSuccess) { diff --git a/lib/ui/views/navbar_authenticated.dart b/lib/ui/views/navbar_authenticated.dart new file mode 100644 index 0000000..681ee9a --- /dev/null +++ b/lib/ui/views/navbar_authenticated.dart @@ -0,0 +1,70 @@ +import 'package:fbmobile/core/util/logger.dart'; +import 'package:fbmobile/ui/views/profile_view.dart'; +import 'package:fbmobile/ui/views/upload_view.dart'; +import 'package:flutter/material.dart'; +import 'package:logger/logger.dart'; + +import '../shared/app_colors.dart'; +import 'history_view.dart'; + +class AuthenticatedNavBarView extends StatefulWidget { + @override + AuthenticatedNavBarState createState() => AuthenticatedNavBarState(); +} + +class AuthenticatedNavBarState extends State with SingleTickerProviderStateMixin { + final Logger _logger = getLogger(); + int _currentTabIndex = 0; + + void updateIndex(int targetIndex) { + setState(() { + _currentTabIndex = targetIndex; + _logger.d("Changing current tab index to '$targetIndex'"); + }); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + bottomNavigationBar: NavigationBar( + key: UniqueKey(), + onDestinationSelected: (int index) { + updateIndex(index); + }, + selectedIndex: _currentTabIndex, + labelBehavior: NavigationDestinationLabelBehavior.alwaysHide, + destinations: const [ + NavigationDestination( + icon: Icon(Icons.upload_outlined), + label: 'Upload', + ), + NavigationDestination( + icon: Icon(Icons.history_outlined), + label: 'History', + ), + NavigationDestination( + icon: Icon(Icons.person_outlined), + label: 'Profile', + ), + ], + ), + body: [ + Container( + color: myColor, + alignment: Alignment.center, + child: UploadView(), + ), + Container( + color: myColor, + alignment: Alignment.center, + child: HistoryView(), + ), + Container( + color: myColor, + alignment: Alignment.center, + child: ProfileView(), + ), + ][_currentTabIndex], + ); + } +} diff --git a/lib/ui/views/profile_view.dart b/lib/ui/views/profile_view.dart index 22c2eee..965b948 100644 --- a/lib/ui/views/profile_view.dart +++ b/lib/ui/views/profile_view.dart @@ -10,7 +10,6 @@ import '../shared/app_colors.dart'; import '../shared/text_styles.dart'; import '../shared/ui_helpers.dart'; import '../widgets/my_appbar.dart'; -import '../widgets/swipe_navigation.dart'; import 'base_view.dart'; class ProfileView extends StatelessWidget { @@ -19,10 +18,8 @@ class ProfileView extends StatelessWidget { @override Widget build(BuildContext context) { return BaseView( - builder: (context, model, child) => Scaffold( - appBar: MyAppBar(title: Text(translate('titles.profile'))), - backgroundColor: backgroundColor, - body: SwipeNavigation(child: _render(model, context)))); + builder: (context, model, child) => + Scaffold(appBar: MyAppBar(title: Text(translate('titles.profile'))), body: _render(model, context))); } Widget _render(ProfileModel model, BuildContext context) { @@ -60,15 +57,13 @@ class ProfileView extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.center, children: [ CircularProgressIndicator(), - Text(translate('profile.show_config_loading'), - style: TextStyle(color: buttonBackgroundColor)) + Text(translate('profile.show_config_loading')), ], )) : ElevatedButton.icon( icon: Icon(Icons.settings, color: blueColor), label: Text( translate('profile.show_config'), - style: TextStyle(color: buttonForegroundColor), ), onPressed: () async { await model.showConfig(url); @@ -80,7 +75,6 @@ class ProfileView extends StatelessWidget { icon: Icon(Icons.lock, color: orangeColor), label: Text( translate('profile.reveal_api_key'), - style: TextStyle(color: buttonForegroundColor), ), onPressed: () { model.revealApiKey(apiKey); @@ -92,7 +86,6 @@ class ProfileView extends StatelessWidget { icon: Icon(Icons.exit_to_app, color: redColor), label: Text( translate('profile.logout'), - style: TextStyle(color: buttonForegroundColor), ), onPressed: () async { await model.logout(); diff --git a/lib/ui/views/tabbar_anonymous.dart b/lib/ui/views/tabbar_anonymous.dart deleted file mode 100644 index c4b68c4..0000000 --- a/lib/ui/views/tabbar_anonymous.dart +++ /dev/null @@ -1,67 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_translate/flutter_translate.dart'; - -import '../shared/app_colors.dart'; -import 'login_view.dart'; - -class AnonymousTabBarView extends StatefulWidget { - @override - AnonymousTabBarState createState() => AnonymousTabBarState(); -} - -class AnonymousTabBarState extends State with SingleTickerProviderStateMixin { - TabController? _tabController; - int _currentTabIndex = 0; - - List _realPages = [LoginView()]; - List _tabPages = [LoginView()]; - List _hasInit = [true]; - - List _tabsButton = [ - Tab( - icon: Icon(Icons.person_outline, color: blueColor), - child: Text( - translate('tabs.login'), - style: TextStyle(color: blueColor), - ), - ) - ]; - - @override - void initState() { - super.initState(); - _tabController = TabController(length: _realPages.length, vsync: this) - ..addListener(() { - int selectedIndex = _tabController!.index; - if (_currentTabIndex != selectedIndex) { - if (!_hasInit[selectedIndex]) { - _tabPages[selectedIndex] = _realPages[selectedIndex]; - _hasInit[selectedIndex] = true; - } - setState(() => _currentTabIndex = selectedIndex); - } - }); - } - - @override - void dispose() { - _tabController!.dispose(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - body: IndexedStack(index: _currentTabIndex, children: _tabPages), - bottomNavigationBar: BottomAppBar( - child: TabBar( - labelColor: primaryAccentColor, - indicatorColor: blueColor, - indicatorWeight: 3.0, - tabs: _tabsButton, - controller: _tabController, - ), - ), - ); - } -} diff --git a/lib/ui/views/tabbar_authenticated.dart b/lib/ui/views/tabbar_authenticated.dart deleted file mode 100644 index 2259dd9..0000000 --- a/lib/ui/views/tabbar_authenticated.dart +++ /dev/null @@ -1,149 +0,0 @@ -import 'dart:async'; -import 'dart:math'; - -import 'package:flutter/material.dart'; -import 'package:flutter_translate/flutter_translate.dart'; -import 'package:logger/logger.dart'; - -import '../../core/enums/swipe_event.dart'; -import '../../core/services/swipe_service.dart'; -import '../../core/util/logger.dart'; -import '../../locator.dart'; -import '../shared/app_colors.dart'; -import 'history_view.dart'; -import 'profile_view.dart'; -import 'upload_view.dart'; - -class AuthenticatedTabBarView extends StatefulWidget { - @override - AuthenticatedTabBarState createState() => AuthenticatedTabBarState(); -} - -class AuthenticatedTabBarState extends State with SingleTickerProviderStateMixin { - final Logger _logger = getLogger(); - final SwipeService _swipeService = locator(); - - late StreamSubscription _swipeEventSubscription; - TabController? _tabController; - int _currentTabIndex = 0; - - List _realPages = [UploadView(), HistoryView(), ProfileView()]; - List _tabPages = [ - UploadView(), - Container(), - Container(), - ]; - List _hasInit = [true, false, false]; - - @override - void initState() { - super.initState(); - _tabController = TabController(length: _realPages.length, vsync: this) - ..addListener(() { - int selectedIndex = _tabController!.index; - if (_currentTabIndex != selectedIndex) { - if (!_hasInit[selectedIndex]) { - _tabPages[selectedIndex] = _realPages[selectedIndex]; - _hasInit[selectedIndex] = true; - } - setState(() => _currentTabIndex = selectedIndex); - } - }); - - _swipeEventSubscription = _swipeService.swipeEventController.stream.listen((SwipeEvent event) { - _logger.d('Received a swipe event for the authenticated tab bar: $event'); - - int targetIndex = _currentTabIndex; - if (SwipeEvent.Left == event) { - targetIndex = min(_currentTabIndex + 1, _realPages.length - 1); - } - - if (SwipeEvent.Right == event) { - targetIndex = max(_currentTabIndex - 1, 0); - } - - if (SwipeEvent.Start == event) { - targetIndex = 0; - } - - if (SwipeEvent.End == event) { - targetIndex = _tabPages.length - 1; - } - - _logger.d("Changing to tab '$targetIndex' because of a swipe event '$event'"); - _tabController!.animateTo(targetIndex); - }); - } - - @override - void dispose() { - _tabController!.dispose(); - _swipeEventSubscription.cancel(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - double width = MediaQuery.of(context).size.width; - double yourWidth = width / 3; - double yourHeight = 55; - - Color colorTabItem0 = _currentTabIndex == 0 ? blueColor : primaryAccentColor; - Color colorTabItem1 = _currentTabIndex == 1 ? blueColor : primaryAccentColor; - Color colorTabItem2 = _currentTabIndex == 2 ? blueColor : primaryAccentColor; - - List _tabsButton = [ - Container( - width: yourWidth, - height: yourHeight, - alignment: Alignment.center, - child: Tab( - icon: Icon( - _currentTabIndex == 0 ? Icons.upload_outlined : Icons.upload_rounded, - color: colorTabItem0, - ), - child: Text(translate('tabs.upload'), style: TextStyle(color: colorTabItem0)), - ), - ), - Container( - width: yourWidth, - height: yourHeight, - alignment: Alignment.center, - child: Tab( - icon: Icon( - _currentTabIndex == 1 ? Icons.history_outlined : Icons.history_rounded, - color: colorTabItem1, - ), - child: Text(translate('tabs.history'), style: TextStyle(color: colorTabItem1)), - ), - ), - Container( - width: yourWidth, - height: yourHeight, - alignment: Alignment.center, - child: Tab( - icon: Icon( - _currentTabIndex == 2 ? Icons.person_outlined : Icons.person_rounded, - color: colorTabItem2, - ), - child: Text(translate('tabs.profile'), style: TextStyle(color: colorTabItem2)), - ), - ), - ]; - - return Scaffold( - body: IndexedStack(index: _currentTabIndex, children: _tabPages), - bottomNavigationBar: BottomAppBar( - child: TabBar( - indicatorSize: TabBarIndicatorSize.label, - labelColor: primaryAccentColor, - indicatorColor: blueColor, - indicatorWeight: 3.0, - labelPadding: EdgeInsets.all(0), - tabs: _tabsButton, - isScrollable: true, - controller: _tabController, - )), - ); - } -} diff --git a/lib/ui/views/tabbar_container_view.dart b/lib/ui/views/tabbar_container_view.dart index f9dead3..a166355 100644 --- a/lib/ui/views/tabbar_container_view.dart +++ b/lib/ui/views/tabbar_container_view.dart @@ -1,9 +1,9 @@ +import 'package:fbmobile/ui/views/login_view.dart'; +import 'package:fbmobile/ui/views/navbar_authenticated.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import '../../core/models/session.dart'; -import 'tabbar_anonymous.dart'; -import 'tabbar_authenticated.dart'; class TabBarContainerView extends StatelessWidget { @override @@ -12,9 +12,11 @@ class TabBarContainerView extends StatelessWidget { bool isAuthenticated = currentSession != null ? currentSession.apiKey.isNotEmpty : false; if (isAuthenticated) { - return AuthenticatedTabBarView(); + return AuthenticatedNavBarView(); } - return AnonymousTabBarView(); + return Container( + child: LoginView(), + ); } } diff --git a/lib/ui/views/upload_view.dart b/lib/ui/views/upload_view.dart index 3896d3a..589e70a 100644 --- a/lib/ui/views/upload_view.dart +++ b/lib/ui/views/upload_view.dart @@ -9,7 +9,6 @@ import '../../core/viewmodels/upload_model.dart'; import '../shared/app_colors.dart'; import '../widgets/centered_error_row.dart'; import '../widgets/my_appbar.dart'; -import '../widgets/swipe_navigation.dart'; import 'base_view.dart'; class UploadView extends StatelessWidget { @@ -19,10 +18,8 @@ class UploadView extends StatelessWidget { Widget build(BuildContext context) { return BaseView( onModelReady: (model) => model.init(), - builder: (context, model, child) => Scaffold( - appBar: MyAppBar(title: Text(translate('titles.upload'))), - backgroundColor: backgroundColor, - body: SwipeNavigation(child: _render(model, context)))); + builder: (context, model, child) => + Scaffold(appBar: MyAppBar(title: Text(translate('titles.upload'))), body: _render(model, context))); } bool _isUploadButtonEnabled(UploadModel model) { @@ -55,7 +52,6 @@ class UploadView extends StatelessWidget { decoration: InputDecoration( prefixIcon: Icon( Icons.text_snippet, - color: buttonBackgroundColor, ), suffixIcon: IconButton( onPressed: () => model.pasteTextController.clear(), @@ -83,7 +79,6 @@ class UploadView extends StatelessWidget { onPressed: () => model.openFileExplorer(), label: Text( translate('upload.open_file_explorer'), - style: TextStyle(color: buttonForegroundColor), )), ElevatedButton.icon( icon: Icon(Icons.cancel, color: orangeColor), @@ -92,7 +87,6 @@ class UploadView extends StatelessWidget { : null, label: Text( translate('upload.clear_temporary_files'), - style: TextStyle(color: buttonForegroundColor), )), ], )), @@ -141,7 +135,6 @@ class UploadView extends StatelessWidget { icon: Icon(Icons.upload_rounded, color: greenColor), label: Text( translate('upload.upload'), - style: TextStyle(color: buttonForegroundColor), )), ])), model.errorMessage != null && model.errorMessage!.isNotEmpty diff --git a/lib/ui/widgets/my_appbar.dart b/lib/ui/widgets/my_appbar.dart index 9fc52f6..92940a6 100644 --- a/lib/ui/widgets/my_appbar.dart +++ b/lib/ui/widgets/my_appbar.dart @@ -1,7 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import '../shared/app_colors.dart'; import '../widgets/about_iconbutton.dart'; class MyAppBar extends AppBar { @@ -9,15 +7,7 @@ class MyAppBar extends AppBar { static final List aboutDisabledWidgets = []; MyAppBar({Key? key, required Widget title, List? actionWidgets, bool enableAbout = true}) - : super( - key: key, - title: Row(children: [title]), - actions: _renderIconButtons(actionWidgets, enableAbout), - systemOverlayStyle: SystemUiOverlayStyle( - systemNavigationBarColor: primaryAccentColor, // Navigation bar - statusBarColor: primaryAccentColor, // Status bar - ), - backgroundColor: primaryAccentColor); + : super(key: key, title: Row(children: [title]), actions: _renderIconButtons(actionWidgets, enableAbout)); static List _renderIconButtons(List? actionWidgets, bool aboutEnabled) { if (actionWidgets == null) { diff --git a/lib/ui/widgets/swipe_navigation.dart b/lib/ui/widgets/swipe_navigation.dart deleted file mode 100644 index 12dfb37..0000000 --- a/lib/ui/widgets/swipe_navigation.dart +++ /dev/null @@ -1,37 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:simple_gesture_detector/simple_gesture_detector.dart'; - -import '../../core/enums/swipe_event.dart'; -import '../../core/services/swipe_service.dart'; -import '../../locator.dart'; - -class SwipeNavigation extends StatefulWidget { - /// Widget to be augmented with gesture detection. - final Widget? child; - - /// Creates a [SwipeNavigation] widget. - const SwipeNavigation({ - Key? key, - this.child, - }) : super(key: key); - - @override - _SwipeNavigationState createState() => _SwipeNavigationState(); -} - -class _SwipeNavigationState extends State { - final SwipeService _swipeService = locator(); - - void _onHorizontalSwipe(SwipeDirection direction) { - if (direction == SwipeDirection.left) { - _swipeService.addEvent(SwipeEvent.Left); - } else { - _swipeService.addEvent(SwipeEvent.Right); - } - } - - @override - Widget build(BuildContext context) { - return SimpleGestureDetector(onHorizontalSwipe: _onHorizontalSwipe, child: widget.child!); - } -} diff --git a/pubspec.lock b/pubspec.lock index 6cfedb2..cc95a6a 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -7,14 +7,14 @@ packages: name: _fe_analyzer_shared url: "https://pub.dartlang.org" source: hosted - version: "46.0.0" + version: "50.0.0" analyzer: dependency: transitive description: name: analyzer url: "https://pub.dartlang.org" source: hosted - version: "4.6.0" + version: "5.2.0" args: dependency: transitive description: @@ -28,7 +28,7 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.8.2" + version: "2.9.0" boolean_selector: dependency: transitive description: @@ -42,14 +42,14 @@ packages: name: build url: "https://pub.dartlang.org" source: hosted - version: "2.3.0" + version: "2.3.1" build_config: dependency: transitive description: name: build_config url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.1.1" build_daemon: dependency: transitive description: @@ -63,21 +63,21 @@ packages: name: build_resolvers url: "https://pub.dartlang.org" source: hosted - version: "2.0.9" + version: "2.1.0" build_runner: dependency: "direct dev" description: name: build_runner url: "https://pub.dartlang.org" source: hosted - version: "2.2.0" + version: "2.3.2" build_runner_core: dependency: transitive description: name: build_runner_core url: "https://pub.dartlang.org" source: hosted - version: "7.2.3" + version: "7.2.7" built_collection: dependency: transitive description: @@ -91,28 +91,21 @@ packages: name: built_value url: "https://pub.dartlang.org" source: hosted - version: "8.4.0" + version: "8.4.2" built_value_generator: dependency: "direct dev" description: name: built_value_generator url: "https://pub.dartlang.org" source: hosted - version: "8.4.0" + version: "8.4.2" characters: dependency: transitive description: name: characters url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.1" + version: "1.2.1" checked_yaml: dependency: transitive description: @@ -133,14 +126,14 @@ packages: name: clock url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.1.1" code_builder: dependency: transitive description: name: code_builder url: "https://pub.dartlang.org" source: hosted - version: "4.2.0" + version: "4.3.0" collection: dependency: transitive description: @@ -154,7 +147,14 @@ packages: name: convert url: "https://pub.dartlang.org" source: hosted - version: "3.0.2" + version: "3.1.1" + cross_file: + dependency: transitive + description: + name: cross_file + url: "https://pub.dartlang.org" + source: hosted + version: "0.3.3+2" crypto: dependency: transitive description: @@ -175,7 +175,14 @@ packages: name: dart_style url: "https://pub.dartlang.org" source: hosted - version: "2.2.3" + version: "2.2.4" + dynamic_color: + dependency: "direct main" + description: + name: dynamic_color + url: "https://pub.dartlang.org" + source: hosted + version: "1.5.4" expandable: dependency: "direct main" description: @@ -189,7 +196,7 @@ packages: name: fake_async url: "https://pub.dartlang.org" source: hosted - version: "1.3.0" + version: "1.3.1" ffi: dependency: transitive description: @@ -203,14 +210,14 @@ packages: name: file url: "https://pub.dartlang.org" source: hosted - version: "6.1.2" + version: "6.1.4" file_picker: dependency: "direct main" description: name: file_picker url: "https://pub.dartlang.org" source: hosted - version: "5.0.1" + version: "5.2.4" fixnum: dependency: transitive description: @@ -265,7 +272,7 @@ packages: name: frontend_server_client url: "https://pub.dartlang.org" source: hosted - version: "2.1.3" + version: "3.2.0" get_it: dependency: "direct main" description: @@ -279,14 +286,14 @@ packages: name: glob url: "https://pub.dartlang.org" source: hosted - version: "2.1.0" + version: "2.1.1" graphs: dependency: transitive description: name: graphs url: "https://pub.dartlang.org" source: hosted - version: "2.1.0" + version: "2.2.0" http: dependency: "direct main" description: @@ -307,7 +314,7 @@ packages: name: http_parser url: "https://pub.dartlang.org" source: hosted - version: "4.0.1" + version: "4.0.2" intl: dependency: transitive description: @@ -335,14 +342,14 @@ packages: name: json_annotation url: "https://pub.dartlang.org" source: hosted - version: "4.6.0" + version: "4.7.0" json_serializable: dependency: "direct dev" description: name: json_serializable url: "https://pub.dartlang.org" source: hosted - version: "6.3.1" + version: "6.5.4" linkify: dependency: transitive description: @@ -363,35 +370,35 @@ packages: name: logging url: "https://pub.dartlang.org" source: hosted - version: "1.0.2" + version: "1.1.0" matcher: dependency: transitive description: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.11" + version: "0.12.12" material_color_utilities: dependency: transitive description: name: material_color_utilities url: "https://pub.dartlang.org" source: hosted - version: "0.1.4" + version: "0.1.5" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.8.0" mime: dependency: transitive description: name: mime url: "https://pub.dartlang.org" source: hosted - version: "1.0.2" + version: "1.0.3" nested: dependency: transitive description: @@ -412,49 +419,42 @@ packages: name: package_info_plus url: "https://pub.dartlang.org" source: hosted - version: "1.4.3+1" - package_info_plus_linux: - dependency: transitive - description: - name: package_info_plus_linux - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - package_info_plus_macos: - dependency: transitive - description: - name: package_info_plus_macos - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.0" + version: "3.0.2" package_info_plus_platform_interface: dependency: transitive description: name: package_info_plus_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "1.0.2" - package_info_plus_web: - dependency: transitive - description: - name: package_info_plus_web - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - package_info_plus_windows: - dependency: transitive - description: - name: package_info_plus_windows - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" + version: "2.0.1" path: dependency: transitive description: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.8.1" + version: "1.8.2" + path_provider: + dependency: transitive + description: + name: path_provider + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.11" + path_provider_android: + dependency: transitive + description: + name: path_provider_android + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.22" + path_provider_ios: + dependency: transitive + description: + name: path_provider_ios + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.11" path_provider_linux: dependency: transitive description: @@ -462,55 +462,62 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.7" + path_provider_macos: + dependency: transitive + description: + name: path_provider_macos + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.6" path_provider_platform_interface: dependency: transitive description: name: path_provider_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "2.0.4" + version: "2.0.5" path_provider_windows: dependency: transitive description: name: path_provider_windows url: "https://pub.dartlang.org" source: hosted - version: "2.1.2" + version: "2.1.3" permission_handler: dependency: "direct main" description: name: permission_handler url: "https://pub.dartlang.org" source: hosted - version: "10.0.0" + version: "10.2.0" permission_handler_android: dependency: transitive description: name: permission_handler_android url: "https://pub.dartlang.org" source: hosted - version: "10.0.0" + version: "10.2.0" permission_handler_apple: dependency: transitive description: name: permission_handler_apple url: "https://pub.dartlang.org" source: hosted - version: "9.0.4" + version: "9.0.7" permission_handler_platform_interface: dependency: transitive description: name: permission_handler_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "3.7.0" + version: "3.9.0" permission_handler_windows: dependency: transitive description: name: permission_handler_windows url: "https://pub.dartlang.org" source: hosted - version: "0.1.0" + version: "0.1.2" platform: dependency: transitive description: @@ -524,7 +531,7 @@ packages: name: plugin_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "2.1.2" + version: "2.1.3" pool: dependency: transitive description: @@ -545,21 +552,21 @@ packages: name: provider url: "https://pub.dartlang.org" source: hosted - version: "6.0.3" + version: "6.0.5" pub_semver: dependency: transitive description: name: pub_semver url: "https://pub.dartlang.org" source: hosted - version: "2.1.1" + version: "2.1.3" pubspec_parse: dependency: transitive description: name: pubspec_parse url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" + version: "1.2.1" quiver: dependency: transitive description: @@ -580,42 +587,14 @@ packages: name: share_plus url: "https://pub.dartlang.org" source: hosted - version: "4.0.10+1" - share_plus_linux: - dependency: transitive - description: - name: share_plus_linux - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.0" - share_plus_macos: - dependency: transitive - description: - name: share_plus_macos - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.1" + version: "6.3.0" share_plus_platform_interface: dependency: transitive description: name: share_plus_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "3.0.3" - share_plus_web: - dependency: transitive - description: - name: share_plus_web - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.1" - share_plus_windows: - dependency: transitive - description: - name: share_plus_windows - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.1" + version: "3.2.0" shared_preferences: dependency: "direct main" description: @@ -629,7 +608,7 @@ packages: name: shared_preferences_android url: "https://pub.dartlang.org" source: hosted - version: "2.0.12" + version: "2.0.14" shared_preferences_ios: dependency: transitive description: @@ -643,7 +622,7 @@ packages: name: shared_preferences_linux url: "https://pub.dartlang.org" source: hosted - version: "2.1.1" + version: "2.1.2" shared_preferences_macos: dependency: transitive description: @@ -657,7 +636,7 @@ packages: name: shared_preferences_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "2.1.0" shared_preferences_web: dependency: transitive description: @@ -671,28 +650,21 @@ packages: name: shared_preferences_windows url: "https://pub.dartlang.org" source: hosted - version: "2.1.1" + version: "2.1.2" shelf: dependency: transitive description: name: shelf url: "https://pub.dartlang.org" source: hosted - version: "1.3.2" + version: "1.4.0" shelf_web_socket: dependency: transitive description: name: shelf_web_socket url: "https://pub.dartlang.org" source: hosted - version: "1.0.2" - simple_gesture_detector: - dependency: "direct main" - description: - name: simple_gesture_detector - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.0" + version: "1.0.3" sky_engine: dependency: transitive description: flutter @@ -704,21 +676,21 @@ packages: name: source_gen url: "https://pub.dartlang.org" source: hosted - version: "1.2.2" + version: "1.2.6" source_helper: dependency: transitive description: name: source_helper url: "https://pub.dartlang.org" source: hosted - version: "1.3.2" + version: "1.3.3" source_span: dependency: transitive description: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.8.2" + version: "1.9.0" stack_trace: dependency: transitive description: @@ -732,7 +704,7 @@ packages: name: stacked url: "https://pub.dartlang.org" source: hosted - version: "2.3.15" + version: "3.0.1" stacked_core: dependency: transitive description: @@ -753,28 +725,28 @@ packages: name: stream_transform url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "2.1.0" string_scanner: dependency: transitive description: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.1.1" term_glyph: dependency: transitive description: name: term_glyph url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" + version: "1.2.1" test_api: dependency: transitive description: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.4.9" + version: "0.4.12" timing: dependency: transitive description: @@ -802,14 +774,14 @@ packages: name: url_launcher url: "https://pub.dartlang.org" source: hosted - version: "6.1.5" + version: "6.1.7" url_launcher_android: dependency: transitive description: name: url_launcher_android url: "https://pub.dartlang.org" source: hosted - version: "6.0.17" + version: "6.0.22" url_launcher_ios: dependency: transitive description: @@ -837,7 +809,7 @@ packages: name: url_launcher_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "2.1.0" + version: "2.1.1" url_launcher_web: dependency: transitive description: @@ -852,6 +824,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "3.0.1" + uuid: + dependency: transitive + description: + name: uuid + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.7" validators: dependency: "direct main" description: @@ -872,7 +851,7 @@ packages: name: watcher url: "https://pub.dartlang.org" source: hosted - version: "1.0.1" + version: "1.0.2" web_socket_channel: dependency: transitive description: @@ -886,14 +865,14 @@ packages: name: win32 url: "https://pub.dartlang.org" source: hosted - version: "2.7.0" + version: "3.1.2" xdg_directories: dependency: transitive description: name: xdg_directories url: "https://pub.dartlang.org" source: hosted - version: "0.2.0+1" + version: "0.2.0+2" yaml: dependency: transitive description: @@ -902,5 +881,5 @@ packages: source: hosted version: "3.1.1" sdks: - dart: ">=2.17.3 <3.0.0" - flutter: ">=3.0.0" + dart: ">=2.18.6 <3.0.0" + flutter: ">=3.3.0" diff --git a/pubspec.yaml b/pubspec.yaml index 6a95cd7..6f7365d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -11,10 +11,10 @@ description: A mobile client for FileBin. # 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.4.3+16 +version: 1.5.0+16 environment: - sdk: '>=2.17.3 <3.0.0' + sdk: '>=2.18.5 <3.0.0' dependencies: flutter: @@ -23,31 +23,31 @@ dependencies: flutter_localizations: sdk: flutter flutter_translate: 4.0.3 - provider: 6.0.3 - stacked: 2.3.15 + provider: 6.0.5 + stacked: 3.0.1 get_it: 7.2.0 logger: 1.1.0 shared_preferences: 2.0.15 http: 0.13.5 validators: 3.0.0 flutter_linkify: 5.0.2 - url_launcher: 6.1.5 + url_launcher: 6.1.7 expandable: 5.0.1 - share_plus: 4.0.10+1 - file_picker: 5.0.1 + share_plus: 6.3.0 + file_picker: 5.2.4 clipboard: 0.1.3 receive_sharing_intent: 1.4.5 - permission_handler: 10.0.0 - package_info_plus: 1.4.3+1 - simple_gesture_detector: 0.2.0 - json_annotation: 4.6.0 + permission_handler: 10.2.0 + package_info_plus: 3.0.2 + json_annotation: 4.7.0 + dynamic_color: 1.5.4 dev_dependencies: flutter_test: sdk: flutter - build_runner: 2.2.0 - built_value_generator: 8.4.0 - json_serializable: 6.3.1 + build_runner: 2.3.2 + built_value_generator: 8.4.2 + json_serializable: 6.5.4 # For information on the generic Dart part of this file, see the # following page: https://www.dartlang.org/tools/pub/pubspec