Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion packages/neon/neon_dashboard/lib/l10n/en.arb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"@@locale": "en",
"noEntries": "No entries"
"noEntries": "No entries",
"setUserStatus": "Set status"
}
6 changes: 6 additions & 0 deletions packages/neon/neon_dashboard/lib/l10n/localizations.dart
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,12 @@ abstract class DashboardLocalizations {
/// In en, this message translates to:
/// **'No entries'**
String get noEntries;

/// No description provided for @setUserStatus.
///
/// In en, this message translates to:
/// **'Set status'**
String get setUserStatus;
}

class _DashboardLocalizationsDelegate extends LocalizationsDelegate<DashboardLocalizations> {
Expand Down
3 changes: 3 additions & 0 deletions packages/neon/neon_dashboard/lib/l10n/localizations_en.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,7 @@ class DashboardLocalizationsEn extends DashboardLocalizations {

@override
String get noEntries => 'No entries';

@override
String get setUserStatus => 'Set status';
}
140 changes: 117 additions & 23 deletions packages/neon/neon_dashboard/lib/src/pages/main.dart
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import 'dart:math';

import 'package:flutter/material.dart';
import 'package:intersperse/intersperse.dart';
import 'package:neon_dashboard/l10n/localizations.dart';
import 'package:neon_dashboard/src/blocs/dashboard.dart';
import 'package:neon_dashboard/src/widgets/dry_intrinsic_height.dart';
import 'package:neon_dashboard/src/widgets/widget.dart';
import 'package:neon_dashboard/src/widgets/widget_button.dart';
import 'package:neon_dashboard/src/widgets/widget_item.dart';
import 'package:neon_framework/blocs.dart';
import 'package:neon_framework/models.dart';
import 'package:neon_framework/theme.dart';
import 'package:neon_framework/utils.dart';
import 'package:neon_framework/widgets.dart';
Expand All @@ -23,17 +25,25 @@ class DashboardMainPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final bloc = NeonProvider.of<DashboardBloc>(context);
final accountsBloc = NeonProvider.of<AccountsBloc>(context);
final userStatusBloc = accountsBloc.activeUserStatusBloc;

return NeonCustomBackground(
child: ResultBuilder.behaviorSubject(
subject: bloc.widgets,
builder: (context, snapshot) {
Widget? child;
if (snapshot.hasData) {
builder: (context, result) {
final children = <Widget>[
_buildStatuses(
account: accountsBloc.activeAccount.value!,
userStatusBloc: userStatusBloc,
),
];

if (result.hasData) {
var minHeight = 504.0;

final children = <Widget>[];
for (final widget in snapshot.requireData.entries) {
final widgets = <Widget>[];
for (final widget in result.requireData.entries) {
final items = buildWidgetItems(
context: context,
widget: widget.key,
Expand All @@ -43,40 +53,50 @@ class DashboardMainPage extends StatelessWidget {
final height = items.map((i) => i.height!).reduce((a, b) => a + b);
minHeight = max(minHeight, height);

children.add(
widgets.add(
DashboardWidget(
widget: widget.key,
children: items,
),
);
}

child = Wrap(
alignment: WrapAlignment.center,
spacing: 8,
runSpacing: 8,
children: children
.map(
(widget) => SizedBox(
width: 320,
height: minHeight + 24,
child: widget,
),
)
.toList(),
children.add(
Wrap(
alignment: WrapAlignment.center,
spacing: 8,
runSpacing: 8,
children: widgets
.map(
(widget) => SizedBox(
width: 320,
height: minHeight + 24,
child: widget,
),
)
.toList(),
),
);
}

return Center(
child: NeonListView.custom(
scrollKey: 'dashboard',
isLoading: snapshot.isLoading,
error: snapshot.error,
isLoading: result.isLoading,
error: result.error,
onRefresh: bloc.refresh,
sliver: SliverFillRemaining(
hasScrollBody: false,
child: Center(
child: child,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: children
.intersperse(
const SizedBox(
height: 40,
),
)
.toList(),
),
),
),
Expand All @@ -86,6 +106,80 @@ class DashboardMainPage extends StatelessWidget {
);
}

Widget _buildStatuses({
required Account account,
required UserStatusBloc userStatusBloc,
}) =>
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ResultBuilder.behaviorSubject(
subject: userStatusBloc.status,
builder: (context, statusResult) {
if (statusResult.hasData) {
final status = statusResult.requireData;

final label = StringBuffer();
if (status.icon == null && status.message == null) {
label.write(DashboardLocalizations.of(context).setUserStatus);
} else {
if (status.icon != null) {
label.write(status.icon);
}
if (status.icon != null && status.message != null) {
label.write(' ');
}
if (status.message != null) {
label.write(status.message);
}
}

return _buildStatus(
context: context,
icon: NeonServerIcon(icon: 'user-status-${status.status == 'offline' ? 'invisible' : status.status}'),
label: Text(label.toString()),
onPressed: () async {
await showDialog<void>(
context: context,
builder: (context) => NeonUserStatusDialog(
account: account,
),
);
},
);
}

return const SizedBox.shrink();
},
),
]
.intersperse(
const SizedBox(
width: 20,
),
)
.toList(),
);

Widget _buildStatus({
required BuildContext context,
required Widget icon,
required Widget label,
required VoidCallback onPressed,
}) =>
ActionChip(
avatar: icon,
label: label,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50),
side: BorderSide(
color: Theme.of(context).colorScheme.primary,
),
),
padding: const EdgeInsets.all(15),
onPressed: onPressed,
);

/// Builds the list of messages, [items] and buttons for a [widget].
@visibleForTesting
static Iterable<SizedBox> buildWidgetItems({
Expand Down
1 change: 1 addition & 0 deletions packages/neon/neon_dashboard/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ dependencies:
flutter_localizations:
sdk: flutter
go_router: ^13.0.0
intersperse: ^2.0.0
meta: ^1.0.0
neon_framework:
git:
Expand Down
1 change: 1 addition & 0 deletions packages/neon_framework/lib/blocs.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ export 'package:neon_framework/src/bloc/result.dart';
// TODO: Remove access to the AccountsBloc. Apps should not need to access this
export 'package:neon_framework/src/blocs/accounts.dart' show AccountsBloc;
export 'package:neon_framework/src/blocs/timer.dart';
export 'package:neon_framework/src/blocs/user_status.dart';
16 changes: 15 additions & 1 deletion packages/neon_framework/lib/l10n/en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -233,5 +233,19 @@
"type": "int"
}
}
}
},
"userStatusSetStatus": "Set status",
"userStatusOnline": "Online",
"userStatusAway": "Away",
"userStatusDoNotDisturb": "Do not disturb",
"userStatusDoNotDisturbDescription": "Mute all notifications",
"userStatusInvisible": "Invisible",
"userStatusInvisibleDescription": "Appear offline",
"userStatusClearAfter": "Clear status after",
"userStatusClearAtDoNotClear": "Do not clear",
"userStatusClearAtToday": "Today",
"userStatusClearAtThisWeek": "This week",
"userStatusActionClear": "Clear status",
"userStatusStatusMessage": "Status message",
"userStatusOnlineStatus": "Online status"
}
84 changes: 84 additions & 0 deletions packages/neon_framework/lib/l10n/localizations.dart
Original file line number Diff line number Diff line change
Expand Up @@ -754,6 +754,90 @@ abstract class NeonLocalizations {
/// In en, this message translates to:
/// **'{time} {time,plural, =1{year}other{years}}'**
String relativeTimeYears(int time);

/// No description provided for @userStatusSetStatus.
///
/// In en, this message translates to:
/// **'Set status'**
String get userStatusSetStatus;

/// No description provided for @userStatusOnline.
///
/// In en, this message translates to:
/// **'Online'**
String get userStatusOnline;

/// No description provided for @userStatusAway.
///
/// In en, this message translates to:
/// **'Away'**
String get userStatusAway;

/// No description provided for @userStatusDoNotDisturb.
///
/// In en, this message translates to:
/// **'Do not disturb'**
String get userStatusDoNotDisturb;

/// No description provided for @userStatusDoNotDisturbDescription.
///
/// In en, this message translates to:
/// **'Mute all notifications'**
String get userStatusDoNotDisturbDescription;

/// No description provided for @userStatusInvisible.
///
/// In en, this message translates to:
/// **'Invisible'**
String get userStatusInvisible;

/// No description provided for @userStatusInvisibleDescription.
///
/// In en, this message translates to:
/// **'Appear offline'**
String get userStatusInvisibleDescription;

/// No description provided for @userStatusClearAfter.
///
/// In en, this message translates to:
/// **'Clear status after'**
String get userStatusClearAfter;

/// No description provided for @userStatusClearAtDoNotClear.
///
/// In en, this message translates to:
/// **'Do not clear'**
String get userStatusClearAtDoNotClear;

/// No description provided for @userStatusClearAtToday.
///
/// In en, this message translates to:
/// **'Today'**
String get userStatusClearAtToday;

/// No description provided for @userStatusClearAtThisWeek.
///
/// In en, this message translates to:
/// **'This week'**
String get userStatusClearAtThisWeek;

/// No description provided for @userStatusActionClear.
///
/// In en, this message translates to:
/// **'Clear status'**
String get userStatusActionClear;

/// No description provided for @userStatusStatusMessage.
///
/// In en, this message translates to:
/// **'Status message'**
String get userStatusStatusMessage;

/// No description provided for @userStatusOnlineStatus.
///
/// In en, this message translates to:
/// **'Online status'**
String get userStatusOnlineStatus;
}

class _NeonLocalizationsDelegate extends LocalizationsDelegate<NeonLocalizations> {
Expand Down
42 changes: 42 additions & 0 deletions packages/neon_framework/lib/l10n/localizations_en.dart
Original file line number Diff line number Diff line change
Expand Up @@ -415,4 +415,46 @@ class NeonLocalizationsEn extends NeonLocalizations {
);
return '$time $_temp0';
}

@override
String get userStatusSetStatus => 'Set status';

@override
String get userStatusOnline => 'Online';

@override
String get userStatusAway => 'Away';

@override
String get userStatusDoNotDisturb => 'Do not disturb';

@override
String get userStatusDoNotDisturbDescription => 'Mute all notifications';

@override
String get userStatusInvisible => 'Invisible';

@override
String get userStatusInvisibleDescription => 'Appear offline';

@override
String get userStatusClearAfter => 'Clear status after';

@override
String get userStatusClearAtDoNotClear => 'Do not clear';

@override
String get userStatusClearAtToday => 'Today';

@override
String get userStatusClearAtThisWeek => 'This week';

@override
String get userStatusActionClear => 'Clear status';

@override
String get userStatusStatusMessage => 'Status message';

@override
String get userStatusOnlineStatus => 'Online status';
}
Loading