Update scrollbars

This commit is contained in:
Hillel Coren 2021-03-04 19:52:29 +02:00
parent e1794cfdb1
commit a6692f0525
8 changed files with 212 additions and 179 deletions

View File

@ -36,7 +36,7 @@ import 'package:invoiceninja_flutter/utils/platforms.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
import 'package:invoiceninja_flutter/utils/colors.dart'; import 'package:invoiceninja_flutter/utils/colors.dart';
class MenuDrawer extends StatelessWidget { class MenuDrawer extends StatefulWidget {
const MenuDrawer({ const MenuDrawer({
Key key, Key key,
@required this.viewModel, @required this.viewModel,
@ -45,6 +45,26 @@ class MenuDrawer extends StatelessWidget {
final MenuDrawerVM viewModel; final MenuDrawerVM viewModel;
static const LOGO_WIDTH = 38.0; static const LOGO_WIDTH = 38.0;
@override
_MenuDrawerState createState() => _MenuDrawerState();
}
class _MenuDrawerState extends State<MenuDrawer> {
ScrollController _scrollController;
@override
void initState() {
super.initState();
_scrollController = ScrollController();
}
@override
void dispose() {
_scrollController.dispose();
super.dispose();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final Store<AppState> store = StoreProvider.of<AppState>(context); final Store<AppState> store = StoreProvider.of<AppState>(context);
@ -52,20 +72,21 @@ class MenuDrawer extends StatelessWidget {
final enableDarkMode = state.prefState.enableDarkMode; final enableDarkMode = state.prefState.enableDarkMode;
final localization = AppLocalization.of(context); final localization = AppLocalization.of(context);
final account = state.account; final account = state.account;
final company = viewModel.selectedCompany; final company = widget.viewModel.selectedCompany;
if (company == null) { if (company == null) {
return Container(); return Container();
} }
Widget _companyLogo(CompanyEntity company) => Widget _companyLogo(CompanyEntity company) => company
company.settings.companyLogo != null && .settings.companyLogo !=
company.settings.companyLogo.isNotEmpty null &&
? CachedImage( company.settings.companyLogo.isNotEmpty
width: LOGO_WIDTH, ? CachedImage(
url: account.defaultUrl + company.settings.companyLogo, width: MenuDrawer.LOGO_WIDTH,
) url: account.defaultUrl + company.settings.companyLogo,
: Image.asset('assets/images/logo.png', width: LOGO_WIDTH); )
: Image.asset('assets/images/logo.png', width: MenuDrawer.LOGO_WIDTH);
Widget _companyListItem(CompanyEntity company) { Widget _companyListItem(CompanyEntity company) {
final userCompany = state.userCompanyStates final userCompany = state.userCompanyStates
@ -107,12 +128,12 @@ class MenuDrawer extends StatelessWidget {
tooltip: localization.selectCompany, tooltip: localization.selectCompany,
child: SizedBox( child: SizedBox(
height: 48, height: 48,
width: LOGO_WIDTH, width: MenuDrawer.LOGO_WIDTH,
child: _companyLogo(viewModel.selectedCompany), child: _companyLogo(widget.viewModel.selectedCompany),
), ),
color: Theme.of(context).cardColor, color: Theme.of(context).cardColor,
itemBuilder: (BuildContext context) => [ itemBuilder: (BuildContext context) => [
...viewModel.state.companies ...widget.viewModel.state.companies
.map((company) => PopupMenuItem<String>( .map((company) => PopupMenuItem<String>(
child: _companyListItem(company), child: _companyListItem(company),
value: company.id, value: company.id,
@ -144,14 +165,14 @@ class MenuDrawer extends StatelessWidget {
], ],
onSelected: (String companyId) { onSelected: (String companyId) {
if (companyId == 'company') { if (companyId == 'company') {
viewModel.onAddCompany(context); widget.viewModel.onAddCompany(context);
} else if (companyId == 'logout') { } else if (companyId == 'logout') {
viewModel.onLogoutTap(context); widget.viewModel.onLogoutTap(context);
} else { } else {
final company = final company =
state.companies.firstWhere((company) => company.id == companyId); state.companies.firstWhere((company) => company.id == companyId);
final index = state.companies.indexOf(company); final index = state.companies.indexOf(company);
viewModel.onCompanyChanged(context, index, company); widget.viewModel.onCompanyChanged(context, index, company);
} }
}, },
); );
@ -159,7 +180,7 @@ class MenuDrawer extends StatelessWidget {
final _expandedCompanySelector = state.companies.isEmpty final _expandedCompanySelector = state.companies.isEmpty
? SizedBox() ? SizedBox()
: AppDropdownButton<String>( : AppDropdownButton<String>(
value: viewModel.selectedCompanyIndex, value: widget.viewModel.selectedCompanyIndex,
items: [ items: [
...state.companies ...state.companies
.map((CompanyEntity company) => DropdownMenuItem<String>( .map((CompanyEntity company) => DropdownMenuItem<String>(
@ -192,13 +213,13 @@ class MenuDrawer extends StatelessWidget {
], ],
onChanged: (dynamic value) { onChanged: (dynamic value) {
if (value == 'company') { if (value == 'company') {
viewModel.onAddCompany(context); widget.viewModel.onAddCompany(context);
} else if (value == 'logout') { } else if (value == 'logout') {
viewModel.onLogoutTap(context); widget.viewModel.onLogoutTap(context);
} else { } else {
final index = int.parse(value); final index = int.parse(value);
viewModel.onCompanyChanged( widget.viewModel
context, index, state.companies[index]); .onCompanyChanged(context, index, state.companies[index]);
} }
}, },
); );
@ -228,141 +249,147 @@ class MenuDrawer extends StatelessWidget {
: Expanded( : Expanded(
child: Container( child: Container(
color: Theme.of(context).cardColor, color: Theme.of(context).cardColor,
child: ListView( child: Scrollbar(
shrinkWrap: true, controller: _scrollController,
children: <Widget>[ isAlwaysShown: isDesktop(context),
if (state.account.debugEnabled) child: ListView(
if (state.isMenuCollapsed) controller: _scrollController,
Tooltip( shrinkWrap: true,
message: localization.debugModeIsEnabled, children: <Widget>[
child: ListTile( if (state.account.debugEnabled)
onTap: () => launch(kDebugModeUrl), if (state.isMenuCollapsed)
leading: Tooltip(
Icon(Icons.warning, color: Colors.red), message: localization.debugModeIsEnabled,
), child: ListTile(
) onTap: () => launch(kDebugModeUrl),
else leading:
ListTile( Icon(Icons.warning, color: Colors.red),
tileColor: Colors.red.shade800, ),
title: Padding( )
padding: const EdgeInsets.only(bottom: 6), else
child: IconText( ListTile(
icon: Icons.warning, tileColor: Colors.red.shade800,
text: localization.debugModeIsEnabled, title: Padding(
padding: const EdgeInsets.only(bottom: 6),
child: IconText(
icon: Icons.warning,
text: localization.debugModeIsEnabled,
style: TextStyle(color: Colors.white),
),
),
subtitle: Text(
localization.debugModeIsEnabledHelp,
style: TextStyle(color: Colors.white), style: TextStyle(color: Colors.white),
), ),
onTap: () => launch(kDebugModeUrl),
), ),
subtitle: Text( DrawerTile(
localization.debugModeIsEnabledHelp, company: company,
style: TextStyle(color: Colors.white), icon: getEntityIcon(EntityType.dashboard),
), title: localization.dashboard,
onTap: () => launch(kDebugModeUrl), onTap: () => viewEntitiesByType(
), context: context,
DrawerTile( entityType: EntityType.dashboard),
company: company, onLongPress: () => store.dispatch(ViewDashboard(
icon: getEntityIcon(EntityType.dashboard), navigator: Navigator.of(context),
title: localization.dashboard, filter: '')),
onTap: () => viewEntitiesByType( ),
context: context, DrawerTile(
entityType: EntityType.dashboard), company: company,
onLongPress: () => store.dispatch(ViewDashboard( entityType: EntityType.client,
navigator: Navigator.of(context), filter: '')), icon: getEntityIcon(EntityType.client),
), title: localization.clients,
DrawerTile( iconTooltip: localization.newClient,
company: company, ),
entityType: EntityType.client, DrawerTile(
icon: getEntityIcon(EntityType.client), company: company,
title: localization.clients, entityType: EntityType.product,
iconTooltip: localization.newClient, icon: getEntityIcon(EntityType.product),
), title: localization.products,
DrawerTile( iconTooltip: localization.newProduct,
company: company, ),
entityType: EntityType.product, DrawerTile(
icon: getEntityIcon(EntityType.product), company: company,
title: localization.products, entityType: EntityType.invoice,
iconTooltip: localization.newProduct, icon: getEntityIcon(EntityType.invoice),
), title: localization.invoices,
DrawerTile( iconTooltip: localization.newInvoice,
company: company, ),
entityType: EntityType.invoice, DrawerTile(
icon: getEntityIcon(EntityType.invoice), company: company,
title: localization.invoices, entityType: EntityType.payment,
iconTooltip: localization.newInvoice, icon: getEntityIcon(EntityType.payment),
), title: localization.payments,
DrawerTile( iconTooltip: localization.newPayment,
company: company, ),
entityType: EntityType.payment, DrawerTile(
icon: getEntityIcon(EntityType.payment), company: company,
title: localization.payments, entityType: EntityType.recurringInvoice,
iconTooltip: localization.newPayment, icon: getEntityIcon(EntityType.recurringInvoice),
), title: localization.recurringInvoices,
DrawerTile( iconTooltip: localization.newRecurringInvoice,
company: company, ),
entityType: EntityType.recurringInvoice, DrawerTile(
icon: getEntityIcon(EntityType.recurringInvoice), company: company,
title: localization.recurringInvoices, entityType: EntityType.quote,
iconTooltip: localization.newRecurringInvoice, icon: getEntityIcon(EntityType.quote),
), title: localization.quotes,
DrawerTile( iconTooltip: localization.newQuote,
company: company, ),
entityType: EntityType.quote, DrawerTile(
icon: getEntityIcon(EntityType.quote), company: company,
title: localization.quotes, entityType: EntityType.credit,
iconTooltip: localization.newQuote, icon: getEntityIcon(EntityType.credit),
), title: localization.credits,
DrawerTile( iconTooltip: localization.newCredit,
company: company, ),
entityType: EntityType.credit, DrawerTile(
icon: getEntityIcon(EntityType.credit), company: company,
title: localization.credits, entityType: EntityType.project,
iconTooltip: localization.newCredit, icon: getEntityIcon(EntityType.project),
), title: localization.projects,
DrawerTile( iconTooltip: localization.newProject,
company: company, ),
entityType: EntityType.project, DrawerTile(
icon: getEntityIcon(EntityType.project), company: company,
title: localization.projects, entityType: EntityType.task,
iconTooltip: localization.newProject, icon: getEntityIcon(EntityType.task),
), title: localization.tasks,
DrawerTile( iconTooltip: localization.newTask,
company: company, ),
entityType: EntityType.task, DrawerTile(
icon: getEntityIcon(EntityType.task), company: company,
title: localization.tasks, entityType: EntityType.vendor,
iconTooltip: localization.newTask, icon: getEntityIcon(EntityType.vendor),
), title: localization.vendors,
DrawerTile( iconTooltip: localization.newVendor,
company: company, ),
entityType: EntityType.vendor, DrawerTile(
icon: getEntityIcon(EntityType.vendor), company: company,
title: localization.vendors, entityType: EntityType.expense,
iconTooltip: localization.newVendor, icon: getEntityIcon(EntityType.expense),
), title: localization.expenses,
DrawerTile( iconTooltip: localization.newExpense,
company: company, ),
entityType: EntityType.expense, // STARTER: menu - do not remove comment
icon: getEntityIcon(EntityType.expense), DrawerTile(
title: localization.expenses, company: company,
iconTooltip: localization.newExpense, icon: getEntityIcon(EntityType.reports),
), title: localization.reports,
// STARTER: menu - do not remove comment onTap: () => viewEntitiesByType(
DrawerTile( context: context,
company: company, entityType: EntityType.reports),
icon: getEntityIcon(EntityType.reports), ),
title: localization.reports, DrawerTile(
onTap: () => viewEntitiesByType( company: company,
context: context, icon: getEntityIcon(EntityType.settings),
entityType: EntityType.reports), title: localization.settings,
), onTap: () => viewEntitiesByType(
DrawerTile( context: context,
company: company, entityType: EntityType.settings),
icon: getEntityIcon(EntityType.settings), ),
title: localization.settings, ],
onTap: () => viewEntitiesByType( ),
context: context,
entityType: EntityType.settings),
),
],
), ),
)), )),
SizedBox( SizedBox(

View File

@ -1,6 +1,5 @@
import 'dart:async'; import 'dart:async';
import 'package:draggable_scrollbar/draggable_scrollbar.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart' hide DataRow, DataCell, DataColumn; import 'package:flutter/material.dart' hide DataRow, DataCell, DataColumn;
import 'package:flutter_redux/flutter_redux.dart'; import 'package:flutter_redux/flutter_redux.dart';
@ -157,7 +156,29 @@ class _EntityListState extends State<EntityList> {
fit: FlexFit.loose, fit: FlexFit.loose,
child: entityList.isEmpty child: entityList.isEmpty
? HelpText(AppLocalization.of(context).noRecordsFound) ? HelpText(AppLocalization.of(context).noRecordsFound)
: DraggableScrollbar.semicircle( : Scrollbar(
controller: _scrollController,
isAlwaysShown: isDesktop(context),
child: ListView.separated(
padding: const EdgeInsets.symmetric(vertical: 25),
controller: _scrollController,
separatorBuilder: (context, index) =>
(index == 0 || index == entityList.length)
? SizedBox()
: ListDivider(),
itemCount: entityList.length + 2,
itemBuilder: (BuildContext context, index) {
if (index == 0 || index == entityList.length + 1) {
return Container(
color: Theme.of(context).cardColor,
height: 25,
);
} else {
return widget.itemBuilder(context, index - 1);
}
},
),
) /*DraggableScrollbar.semicircle(
backgroundColor: Theme.of(context).backgroundColor, backgroundColor: Theme.of(context).backgroundColor,
scrollbarTimeToFade: Duration(seconds: 1), scrollbarTimeToFade: Duration(seconds: 1),
controller: _scrollController, controller: _scrollController,
@ -180,7 +201,8 @@ class _EntityListState extends State<EntityList> {
} }
}, },
), ),
), )*/
,
), ),
], ],
); );

View File

@ -1,7 +1,6 @@
import 'dart:math'; import 'dart:math';
import 'package:charts_common/common.dart'; import 'package:charts_common/common.dart';
import 'package:charts_flutter/flutter.dart' as charts; import 'package:charts_flutter/flutter.dart' as charts;
import 'package:draggable_scrollbar/draggable_scrollbar.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:invoiceninja_flutter/constants.dart'; import 'package:invoiceninja_flutter/constants.dart';
@ -402,10 +401,9 @@ class DashboardPanels extends StatelessWidget {
children: <Widget>[ children: <Widget>[
Padding( Padding(
padding: const EdgeInsets.only(top: 74), padding: const EdgeInsets.only(top: 74),
child: DraggableScrollbar.semicircle( child: Scrollbar(
backgroundColor: Theme.of(context).backgroundColor,
scrollbarTimeToFade: Duration(seconds: 1),
controller: scrollController, controller: scrollController,
isAlwaysShown: isDesktop(context),
child: ListView( child: ListView(
controller: scrollController, controller: scrollController,
children: <Widget>[ children: <Widget>[

View File

@ -1,4 +1,3 @@
import 'package:draggable_scrollbar/draggable_scrollbar.dart';
import 'package:invoiceninja_flutter/ui/app/forms/custom_field.dart'; import 'package:invoiceninja_flutter/ui/app/forms/custom_field.dart';
import 'package:invoiceninja_flutter/ui/app/forms/decorated_form_field.dart'; import 'package:invoiceninja_flutter/ui/app/forms/decorated_form_field.dart';
import 'package:invoiceninja_flutter/ui/app/help_text.dart'; import 'package:invoiceninja_flutter/ui/app/help_text.dart';
@ -12,6 +11,7 @@ import 'package:invoiceninja_flutter/utils/formatting.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:invoiceninja_flutter/data/models/models.dart'; import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:invoiceninja_flutter/utils/platforms.dart';
class InvoiceEditItems extends StatefulWidget { class InvoiceEditItems extends StatefulWidget {
const InvoiceEditItems({ const InvoiceEditItems({
@ -83,10 +83,8 @@ class _InvoiceEditItemsState extends State<InvoiceEditItems> {
return HelpText(localization.clickPlusToAddItem); return HelpText(localization.clickPlusToAddItem);
} }
return DraggableScrollbar.semicircle( return Scrollbar(
backgroundColor: Theme.of(context).backgroundColor, isAlwaysShown: isDesktop(context),
scrollbarTimeToFade: Duration(seconds: 1),
controller: _scrollController,
child: ListView( child: ListView(
controller: _scrollController, controller: _scrollController,
children: [ children: [

View File

@ -1,4 +1,3 @@
import 'package:draggable_scrollbar/draggable_scrollbar.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:invoiceninja_flutter/constants.dart'; import 'package:invoiceninja_flutter/constants.dart';
@ -68,10 +67,8 @@ class _SettingsListState extends State<SettingsList> {
filter: settingsUIState.filter, filter: settingsUIState.filter,
); );
return DraggableScrollbar.semicircle( return Scrollbar(
backgroundColor: Theme.of(context).backgroundColor, isAlwaysShown: isDesktop(context),
scrollbarTimeToFade: Duration(seconds: 1),
controller: _scrollController,
child: ListView( child: ListView(
controller: _scrollController, controller: _scrollController,
children: <Widget>[ children: <Widget>[

View File

@ -60,7 +60,6 @@ dependencies:
contacts_service: ^0.4.6 contacts_service: ^0.4.6
extended_image: 1.3.1-dev #TODO remove extended_image: 1.3.1-dev #TODO remove
file_picker: ^2.1.1 file_picker: ^2.1.1
draggable_scrollbar: ^0.0.4
dependency_overrides: dependency_overrides:
# https://github.com/flutter/flutter/issues/70433#issuecomment-727154345 # https://github.com/flutter/flutter/issues/70433#issuecomment-727154345

View File

@ -232,13 +232,6 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.1" version: "1.0.1"
draggable_scrollbar:
dependency: "direct main"
description:
name: draggable_scrollbar
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.4"
extended_image: extended_image:
dependency: "direct main" dependency: "direct main"
description: description:

View File

@ -74,7 +74,6 @@ dependencies:
contacts_service: ^0.4.6 contacts_service: ^0.4.6
extended_image: 1.3.1-dev #TODO remove extended_image: 1.3.1-dev #TODO remove
file_picker: ^2.1.1 file_picker: ^2.1.1
draggable_scrollbar: ^0.0.4
dependency_overrides: dependency_overrides:
# https://github.com/flutter/flutter/issues/70433#issuecomment-727154345 # https://github.com/flutter/flutter/issues/70433#issuecomment-727154345