Browse Source

neon: HomePage don't try opening the drawer in the loading state when navigating back

pull/362/head
Nikolas Rimikis 1 year ago
parent
commit
b57527f515
No known key found for this signature in database
GPG Key ID: 85ED1DE9786A4FF2
  1. 714
      packages/neon/neon/lib/src/pages/home.dart

714
packages/neon/neon/lib/src/pages/home.dart

@ -183,399 +183,393 @@ class _HomePageState extends State<HomePage> {
) => ) =>
OptionBuilder<NavigationMode>( OptionBuilder<NavigationMode>(
option: _globalOptions.navigationMode, option: _globalOptions.navigationMode,
builder: (final context, final navigationMode) => WillPopScope( builder: (final context, final navigationMode) {
onWillPop: () async { if (accountsSnapshot.hasData) {
if (_scaffoldKey.currentState!.isDrawerOpen) { final accounts = accountsSnapshot.data!;
Navigator.pop(context); final account = accounts.find(_account.id);
return true; if (account != null) {
} final isQuickBar = navigationMode == NavigationMode.quickBar;
final drawer = Builder(
_scaffoldKey.currentState!.openDrawer(); builder: (final context) => Drawer(
return false; width: isQuickBar ? kQuickBarWidth : null,
}, child: Container(
child: Builder( padding: isQuickBar ? const EdgeInsets.all(5) : null,
builder: (final context) { child: Column(
if (accountsSnapshot.hasData) { children: [
final accounts = accountsSnapshot.data!; Expanded(
final account = accounts.find(_account.id); child: Scrollbar(
if (account != null) { controller: drawerScrollController,
final isQuickBar = navigationMode == NavigationMode.quickBar; interactive: true,
final drawer = Builder( child: ListView(
builder: (final context) => Drawer( controller: drawerScrollController,
width: isQuickBar ? kQuickBarWidth : null, // Needed for the drawer header to also render in the statusbar
child: Container( padding: EdgeInsets.zero,
padding: isQuickBar ? const EdgeInsets.all(5) : null, children: [
child: Column( Builder(
children: [ builder: (final context) {
Expanded( if (accountsSnapshot.hasData) {
child: Scrollbar( if (isQuickBar) {
controller: drawerScrollController, return Column(
interactive: true, children: [
child: ListView( if (accounts.length != 1) ...[
controller: drawerScrollController, for (final account in accounts) ...[
// Needed for the drawer header to also render in the statusbar Container(
padding: EdgeInsets.zero, margin: const EdgeInsets.symmetric(
children: [ vertical: 5,
Builder( ),
builder: (final context) { child: IconButton(
if (accountsSnapshot.hasData) { onPressed: () {
if (isQuickBar) { _accountsBloc.setActiveAccount(account);
return Column( },
children: [ tooltip: account.client.humanReadableID,
if (accounts.length != 1) ...[ icon: IntrinsicHeight(
for (final account in accounts) ...[ child: NeonAccountAvatar(
Container( account: account,
margin: const EdgeInsets.symmetric(
vertical: 5,
),
child: IconButton(
onPressed: () {
_accountsBloc.setActiveAccount(account);
},
tooltip: account.client.humanReadableID,
icon: IntrinsicHeight(
child: NeonAccountAvatar(
account: account,
),
),
), ),
), ),
],
Container(
margin: const EdgeInsets.only(
top: 10,
),
child: Divider(
height: 5,
color: Theme.of(context).appBarTheme.foregroundColor,
),
), ),
], ),
], ],
); Container(
} margin: const EdgeInsets.only(
return DrawerHeader( top: 10,
decoration: BoxDecoration( ),
color: Theme.of(context).colorScheme.primary, child: Divider(
), height: 5,
child: Column( color: Theme.of(context).appBarTheme.foregroundColor,
crossAxisAlignment: CrossAxisAlignment.start, ),
mainAxisAlignment: MainAxisAlignment.spaceBetween, ),
children: [ ],
if (capabilities.data != null) ...[ ],
if (capabilities.data!.capabilities.theming?.name != );
null) ...[ }
Text( return DrawerHeader(
capabilities.data!.capabilities.theming!.name!, decoration: BoxDecoration(
style: DefaultTextStyle.of(context).style.copyWith( color: Theme.of(context).colorScheme.primary,
color: ),
Theme.of(context).appBarTheme.foregroundColor, child: Column(
), crossAxisAlignment: CrossAxisAlignment.start,
), mainAxisAlignment: MainAxisAlignment.spaceBetween,
], children: [
if (capabilities.data!.capabilities.theming?.logo != if (capabilities.data != null) ...[
null) ...[ if (capabilities.data!.capabilities.theming?.name != null) ...[
Flexible( Text(
child: NeonCachedUrlImage( capabilities.data!.capabilities.theming!.name!,
url: capabilities.data!.capabilities.theming!.logo!, style: DefaultTextStyle.of(context).style.copyWith(
color: Theme.of(context).appBarTheme.foregroundColor,
), ),
), ),
], ],
] else ...[ if (capabilities.data!.capabilities.theming?.logo != null) ...[
NeonException( Flexible(
capabilities.error, child: NeonCachedUrlImage(
onRetry: _capabilitiesBloc.refresh, url: capabilities.data!.capabilities.theming!.logo!,
),
NeonLinearProgressIndicator(
visible: capabilities.loading,
),
],
if (accounts.length != 1) ...[
DropdownButtonHideUnderline(
child: DropdownButton<String>(
isExpanded: true,
dropdownColor: Theme.of(context).colorScheme.primary,
iconEnabledColor:
Theme.of(context).colorScheme.onBackground,
value: _account.id,
items: accounts
.map<DropdownMenuItem<String>>(
(final account) => DropdownMenuItem<String>(
value: account.id,
child: NeonAccountTile(
account: account,
dense: true,
textColor: Theme.of(context)
.appBarTheme
.foregroundColor,
),
),
)
.toList(),
onChanged: (final id) {
if (id != null) {
_accountsBloc.setActiveAccount(accounts.find(id));
}
},
),
), ),
], ),
], ],
] else ...[
NeonException(
capabilities.error,
onRetry: _capabilitiesBloc.refresh,
),
NeonLinearProgressIndicator(
visible: capabilities.loading,
),
],
if (accounts.length != 1) ...[
DropdownButtonHideUnderline(
child: DropdownButton<String>(
isExpanded: true,
dropdownColor: Theme.of(context).colorScheme.primary,
iconEnabledColor:
Theme.of(context).colorScheme.onBackground,
value: _account.id,
items: accounts
.map<DropdownMenuItem<String>>(
(final account) => DropdownMenuItem<String>(
value: account.id,
child: NeonAccountTile(
account: account,
dense: true,
textColor:
Theme.of(context).appBarTheme.foregroundColor,
),
),
)
.toList(),
onChanged: (final id) {
if (id != null) {
_accountsBloc.setActiveAccount(accounts.find(id));
}
},
),
),
],
],
),
);
}
return Container();
},
),
NeonException(
appImplementations.error,
onlyIcon: isQuickBar,
onRetry: _appsBloc.refresh,
),
NeonLinearProgressIndicator(
visible: appImplementations.loading,
),
if (appImplementations.data != null) ...[
for (final appImplementation in appImplementations.data!) ...[
StreamBuilder<int>(
stream: appImplementation.getUnreadCounter(_appsBloc) ??
BehaviorSubject<int>.seeded(0),
builder: (final context, final unreadCounterSnapshot) {
final unreadCount = unreadCounterSnapshot.data ?? 0;
if (isQuickBar) {
return IconButton(
onPressed: () async {
await _appsBloc.setActiveApp(appImplementation.id);
},
tooltip: appImplementation.name(context),
icon: NeonAppImplementationIcon(
appImplementation: appImplementation,
unreadCount: unreadCount,
color: Theme.of(context).colorScheme.primary,
), ),
); );
} }
return Container(); return ListTile(
}, key: Key('app-${appImplementation.id}'),
), title: Row(
NeonException( mainAxisAlignment: MainAxisAlignment.spaceBetween,
appImplementations.error, children: [
onlyIcon: isQuickBar, Text(appImplementation.name(context)),
onRetry: _appsBloc.refresh, if (unreadCount > 0) ...[
), Text(
NeonLinearProgressIndicator( unreadCount.toString(),
visible: appImplementations.loading, style: TextStyle(
), color: Theme.of(context).colorScheme.primary,
if (appImplementations.data != null) ...[ fontWeight: FontWeight.bold,
for (final appImplementation in appImplementations.data!) ...[ fontSize: 14,
StreamBuilder<int>( ),
stream: appImplementation.getUnreadCounter(_appsBloc) ??
BehaviorSubject<int>.seeded(0),
builder: (final context, final unreadCounterSnapshot) {
final unreadCount = unreadCounterSnapshot.data ?? 0;
if (isQuickBar) {
return IconButton(
onPressed: () async {
await _appsBloc.setActiveApp(appImplementation.id);
},
tooltip: appImplementation.name(context),
icon: NeonAppImplementationIcon(
appImplementation: appImplementation,
unreadCount: unreadCount,
color: Theme.of(context).colorScheme.primary,
), ),
); ],
} ],
return ListTile( ),
key: Key('app-${appImplementation.id}'), leading: appImplementation.buildIcon(context),
title: Row( minLeadingWidth: 0,
mainAxisAlignment: MainAxisAlignment.spaceBetween, onTap: () async {
children: [ await _appsBloc.setActiveApp(appImplementation.id);
Text(appImplementation.name(context)),
if (unreadCount > 0) ...[
Text(
unreadCount.toString(),
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
fontWeight: FontWeight.bold,
fontSize: 14,
),
),
],
],
),
leading: appImplementation.buildIcon(context),
minLeadingWidth: 0,
onTap: () async {
await _appsBloc.setActiveApp(appImplementation.id);
if (!mounted) { if (!mounted) {
return; return;
} }
Scaffold.maybeOf(context)?.closeDrawer(); Scaffold.maybeOf(context)?.closeDrawer();
},
);
}, },
), );
], },
], ),
], ],
), ],
), ],
), ),
if (isQuickBar) ...[ ),
IconButton(
onPressed: () => const SettingsRoute().go(context),
tooltip: AppLocalizations.of(context).settings,
icon: Icon(
Icons.settings,
color: Theme.of(context).appBarTheme.foregroundColor,
),
),
] else ...[
ListTile(
key: const Key('settings'),
title: Text(AppLocalizations.of(context).settings),
leading: const Icon(Icons.settings),
minLeadingWidth: 0,
onTap: () async {
Scaffold.maybeOf(context)?.closeDrawer();
const SettingsRoute().go(context);
},
),
],
],
), ),
), if (isQuickBar) ...[
IconButton(
onPressed: () => const SettingsRoute().go(context),
tooltip: AppLocalizations.of(context).settings,
icon: Icon(
Icons.settings,
color: Theme.of(context).appBarTheme.foregroundColor,
),
),
] else ...[
ListTile(
key: const Key('settings'),
title: Text(AppLocalizations.of(context).settings),
leading: const Icon(Icons.settings),
minLeadingWidth: 0,
onTap: () async {
Scaffold.maybeOf(context)?.closeDrawer();
const SettingsRoute().go(context);
},
),
],
],
), ),
); ),
final appBar = AppBar( ),
scrolledUnderElevation: navigationMode != NavigationMode.drawer ? 0 : null, );
automaticallyImplyLeading: navigationMode == NavigationMode.drawer, final appBar = AppBar(
leadingWidth: isQuickBar ? kQuickBarWidth : null, scrolledUnderElevation: navigationMode != NavigationMode.drawer ? 0 : null,
leading: isQuickBar automaticallyImplyLeading: navigationMode == NavigationMode.drawer,
? Container( leadingWidth: isQuickBar ? kQuickBarWidth : null,
padding: const EdgeInsets.all(5), leading: isQuickBar
child: capabilities.data?.capabilities.theming?.logo != null ? Container(
? NeonCachedUrlImage( padding: const EdgeInsets.all(5),
url: capabilities.data!.capabilities.theming!.logo!, child: capabilities.data?.capabilities.theming?.logo != null
svgColor: Theme.of(context).iconTheme.color, ? NeonCachedUrlImage(
) url: capabilities.data!.capabilities.theming!.logo!,
: null, svgColor: Theme.of(context).iconTheme.color,
) )
: null, : null,
title: Column( )
crossAxisAlignment: CrossAxisAlignment.start, : null,
title: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [ children: [
Row( if (appImplementations.data != null && activeAppIDSnapshot.hasData) ...[
children: [ Flexible(
if (appImplementations.data != null && activeAppIDSnapshot.hasData) ...[ child: Text(
Flexible( appImplementations.data!.find(activeAppIDSnapshot.data!)!.name(context),
child: Text( ),
appImplementations.data!.find(activeAppIDSnapshot.data!)!.name(context), ),
), ],
), if (appImplementations.error != null) ...[
], const SizedBox(
if (appImplementations.error != null) ...[ width: 8,
const SizedBox( ),
width: 8, NeonException(
), appImplementations.error,
NeonException( onRetry: _appsBloc.refresh,
appImplementations.error, onlyIcon: true,
onRetry: _appsBloc.refresh, ),
onlyIcon: true, ],
), if (appImplementations.loading) ...[
], const SizedBox(
if (appImplementations.loading) ...[ width: 8,
const SizedBox( ),
width: 8, Expanded(
), child: NeonLinearProgressIndicator(
Expanded( color: Theme.of(context).appBarTheme.foregroundColor,
child: NeonLinearProgressIndicator( ),
color: Theme.of(context).appBarTheme.foregroundColor,
),
),
],
],
),
if (accounts.length > 1) ...[
Text(
account.client.humanReadableID,
style: Theme.of(context).textTheme.bodySmall,
), ),
], ],
], ],
), ),
actions: [ if (accounts.length > 1) ...[
if (notificationsAppImplementation.data != null) ...[ Text(
StreamBuilder<int>( account.client.humanReadableID,
stream: notificationsAppImplementation.data!.getUnreadCounter(_appsBloc), style: Theme.of(context).textTheme.bodySmall,
builder: (final context, final unreadCounterSnapshot) { ),
final unreadCount = unreadCounterSnapshot.data ?? 0; ],
return IconButton( ],
key: Key('app-${notificationsAppImplementation.data!.id}'), ),
onPressed: () async { actions: [
await _openNotifications( if (notificationsAppImplementation.data != null) ...[
notificationsAppImplementation.data!, StreamBuilder<int>(
accounts, stream: notificationsAppImplementation.data!.getUnreadCounter(_appsBloc),
account, builder: (final context, final unreadCounterSnapshot) {
); final unreadCount = unreadCounterSnapshot.data ?? 0;
}, return IconButton(
tooltip: AppLocalizations.of(context) key: Key('app-${notificationsAppImplementation.data!.id}'),
.appImplementationName(notificationsAppImplementation.data!.id), onPressed: () async {
icon: NeonAppImplementationIcon( await _openNotifications(
appImplementation: notificationsAppImplementation.data!, notificationsAppImplementation.data!,
unreadCount: unreadCount, accounts,
color: unreadCount > 0 account,
? Theme.of(context).colorScheme.primary
: Theme.of(context).colorScheme.onBackground,
size: const Size.square(kAvatarSize * 2 / 3),
),
); );
}, },
), tooltip: AppLocalizations.of(context)
], .appImplementationName(notificationsAppImplementation.data!.id),
IconButton( icon: NeonAppImplementationIcon(
onPressed: () { appImplementation: notificationsAppImplementation.data!,
AccountSettingsRoute(accountid: account.id).go(context); unreadCount: unreadCount,
}, color: unreadCount > 0
tooltip: AppLocalizations.of(context).settingsAccount, ? Theme.of(context).colorScheme.primary
icon: IntrinsicWidth( : Theme.of(context).colorScheme.onBackground,
child: NeonAccountAvatar( size: const Size.square(kAvatarSize * 2 / 3),
account: account,
), ),
), );
},
),
],
IconButton(
onPressed: () {
AccountSettingsRoute(accountid: account.id).go(context);
},
tooltip: AppLocalizations.of(context).settingsAccount,
icon: IntrinsicWidth(
child: NeonAccountAvatar(
account: account,
), ),
], ),
); ),
],
);
final body = Builder( final body = Builder(
builder: (final context) => Row( builder: (final context) => Row(
children: [ children: [
if (navigationMode == NavigationMode.quickBar) ...[ if (navigationMode == NavigationMode.quickBar) ...[
drawer, drawer,
], ],
Expanded( Expanded(
child: Column( child: Column(
children: [ children: [
if (appImplementations.data != null) ...[ if (appImplementations.data != null) ...[
if (appImplementations.data!.isEmpty) ...[ if (appImplementations.data!.isEmpty) ...[
Expanded( Expanded(
child: Center( child: Center(
child: Text( child: Text(
AppLocalizations.of(context).errorNoCompatibleNextcloudAppsFound, AppLocalizations.of(context).errorNoCompatibleNextcloudAppsFound,
textAlign: TextAlign.center, textAlign: TextAlign.center,
),
),
), ),
] else ...[ ),
if (activeAppIDSnapshot.hasData) ...[ ),
Expanded( ] else ...[
child: appImplementations.data! if (activeAppIDSnapshot.hasData) ...[
.find(activeAppIDSnapshot.data!)! Expanded(
.buildPage(context, _appsBloc), child: appImplementations.data!
), .find(activeAppIDSnapshot.data!)!
], .buildPage(context, _appsBloc),
], ),
], ],
], ],
), ],
), ],
], ),
), ),
); ],
),
);
return Row( return WillPopScope(
children: [ onWillPop: () async {
if (navigationMode == NavigationMode.drawerAlwaysVisible) ...[ if (_scaffoldKey.currentState!.isDrawerOpen) {
drawer, Navigator.pop(context);
], return true;
Expanded( }
child: Scaffold(
key: _scaffoldKey, _scaffoldKey.currentState!.openDrawer();
resizeToAvoidBottomInset: false, return false;
drawer: navigationMode == NavigationMode.drawer ? drawer : null, },
appBar: appBar, child: Row(
body: body, children: [
), if (navigationMode == NavigationMode.drawerAlwaysVisible) ...[
), drawer,
], ],
); Expanded(
} child: Scaffold(
} key: _scaffoldKey,
return const Scaffold(); resizeToAvoidBottomInset: false,
}, drawer: navigationMode == NavigationMode.drawer ? drawer : null,
), appBar: appBar,
), body: body,
),
),
],
),
);
}
}
return const Scaffold();
},
), ),
), ),
), ),

Loading…
Cancel
Save