Browse Source

neon: HomePage improve code readability of the loading state

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

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

@ -184,391 +184,389 @@ class _HomePageState extends State<HomePage> {
OptionBuilder<NavigationMode>( OptionBuilder<NavigationMode>(
option: _globalOptions.navigationMode, option: _globalOptions.navigationMode,
builder: (final context, final navigationMode) { builder: (final context, final navigationMode) {
if (accountsSnapshot.hasData) { final accounts = accountsSnapshot.data;
final accounts = accountsSnapshot.data!; final account = accounts?.find(_account.id);
final account = accounts.find(_account.id); if (accounts == null || account == null) {
if (account != null) { return const Scaffold();
final isQuickBar = navigationMode == NavigationMode.quickBar; }
final drawer = Builder(
builder: (final context) => Drawer( final isQuickBar = navigationMode == NavigationMode.quickBar;
width: isQuickBar ? kQuickBarWidth : null, final drawer = Builder(
child: Container( builder: (final context) => Drawer(
padding: isQuickBar ? const EdgeInsets.all(5) : null, width: isQuickBar ? kQuickBarWidth : null,
child: Column( child: Container(
children: [ padding: isQuickBar ? const EdgeInsets.all(5) : null,
Expanded( child: Column(
child: Scrollbar( children: [
controller: drawerScrollController, Expanded(
interactive: true, child: Scrollbar(
child: ListView( controller: drawerScrollController,
controller: drawerScrollController, interactive: true,
// Needed for the drawer header to also render in the statusbar child: ListView(
padding: EdgeInsets.zero, controller: drawerScrollController,
children: [ // Needed for the drawer header to also render in the statusbar
Builder( padding: EdgeInsets.zero,
builder: (final context) { children: [
if (accountsSnapshot.hasData) { Builder(
if (isQuickBar) { builder: (final context) {
return Column( if (accountsSnapshot.hasData) {
children: [ if (isQuickBar) {
if (accounts.length != 1) ...[ return Column(
for (final account in accounts) ...[ children: [
Container( if (accounts.length != 1) ...[
margin: const EdgeInsets.symmetric( for (final account in accounts) ...[
vertical: 5, Container(
), margin: const EdgeInsets.symmetric(
child: IconButton( vertical: 5,
onPressed: () { ),
_accountsBloc.setActiveAccount(account); child: IconButton(
}, onPressed: () {
tooltip: account.client.humanReadableID, _accountsBloc.setActiveAccount(account);
icon: IntrinsicHeight( },
child: NeonAccountAvatar( tooltip: account.client.humanReadableID,
account: account, 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( }
capabilities.data!.capabilities.theming!.name!, return DrawerHeader(
style: DefaultTextStyle.of(context).style.copyWith( decoration: BoxDecoration(
color: Theme.of(context).appBarTheme.foregroundColor, color: Theme.of(context).colorScheme.primary,
), ),
), child: Column(
], crossAxisAlignment: CrossAxisAlignment.start,
if (capabilities.data!.capabilities.theming?.logo != null) ...[ mainAxisAlignment: MainAxisAlignment.spaceBetween,
Flexible( children: [
child: NeonCachedUrlImage( if (capabilities.data != null) ...[
url: capabilities.data!.capabilities.theming!.logo!, if (capabilities.data!.capabilities.theming?.name != null) ...[
Text(
capabilities.data!.capabilities.theming!.name!,
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 WillPopScope( return WillPopScope(
onWillPop: () async { onWillPop: () async {
if (_scaffoldKey.currentState!.isDrawerOpen) { if (_scaffoldKey.currentState!.isDrawerOpen) {
Navigator.pop(context); Navigator.pop(context);
return true; return true;
} }
_scaffoldKey.currentState!.openDrawer(); _scaffoldKey.currentState!.openDrawer();
return false; return false;
}, },
child: Row( child: Row(
children: [ children: [
if (navigationMode == NavigationMode.drawerAlwaysVisible) ...[ if (navigationMode == NavigationMode.drawerAlwaysVisible) ...[
drawer, drawer,
], ],
Expanded( Expanded(
child: Scaffold( child: Scaffold(
key: _scaffoldKey, key: _scaffoldKey,
resizeToAvoidBottomInset: false, resizeToAvoidBottomInset: false,
drawer: navigationMode == NavigationMode.drawer ? drawer : null, drawer: navigationMode == NavigationMode.drawer ? drawer : null,
appBar: appBar, appBar: appBar,
body: body, body: body,
), ),
),
],
), ),
); ],
} ),
} );
return const Scaffold();
}, },
), ),
), ),

Loading…
Cancel
Save