Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added an app bar icon when there's an update #142

Merged
merged 3 commits into from
Dec 1, 2024
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
2 changes: 2 additions & 0 deletions lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import 'package:elastic_dashboard/services/log.dart';
import 'package:elastic_dashboard/services/nt_connection.dart';
import 'package:elastic_dashboard/services/nt_widget_builder.dart';
import 'package:elastic_dashboard/services/settings.dart';
import 'package:elastic_dashboard/services/update_checker.dart';

void main() async {
WidgetsFlutterBinding.ensureInitialized();
Expand Down Expand Up @@ -216,6 +217,7 @@ class _ElasticState extends State<Elastic> {
ntConnection: widget.ntConnection,
preferences: widget.preferences,
version: widget.version,
updateChecker: UpdateChecker(currentVersion: widget.version),
onColorChanged: (color) => setState(() {
teamColor = color;
widget.preferences.setInt(PrefKeys.teamColor, color.value);
Expand Down
111 changes: 74 additions & 37 deletions lib/pages/dashboard_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class DashboardPage extends StatefulWidget {
final String version;
final NTConnection ntConnection;
final SharedPreferences preferences;
final UpdateChecker updateChecker;
final Function(Color color)? onColorChanged;
final Function(FlexSchemeVariant variant)? onThemeVariantChanged;

Expand All @@ -52,6 +53,7 @@ class DashboardPage extends StatefulWidget {
required this.ntConnection,
required this.preferences,
required this.version,
required this.updateChecker,
this.onColorChanged,
this.onThemeVariantChanged,
});
Expand All @@ -62,7 +64,6 @@ class DashboardPage extends StatefulWidget {

class _DashboardPageState extends State<DashboardPage> with WindowListener {
late final SharedPreferences preferences = widget.preferences;
late final UpdateChecker _updateChecker;
late final RobotNotificationsListener _robotNotificationListener;

final List<TabData> _tabData = [];
Expand All @@ -72,14 +73,16 @@ class _DashboardPageState extends State<DashboardPage> with WindowListener {
late int _gridSize =
preferences.getInt(PrefKeys.gridSize) ?? Defaults.gridSize;

UpdateCheckerResponse lastUpdateResponse =
UpdateCheckerResponse(updateAvailable: false, error: false);

int _currentTabIndex = 0;

bool _addWidgetDialogVisible = false;

@override
void initState() {
super.initState();
_updateChecker = UpdateChecker(currentVersion: widget.version);

windowManager.addListener(this);
if (!Platform.environment.containsKey('FLUTTER_TEST')) {
Expand Down Expand Up @@ -385,7 +388,11 @@ class _DashboardPageState extends State<DashboardPage> with WindowListener {
ButtonThemeData buttonTheme = ButtonTheme.of(context);

UpdateCheckerResponse updateResponse =
await _updateChecker.isUpdateAvailable();
await widget.updateChecker.isUpdateAvailable();

if (mounted) {
setState(() => lastUpdateResponse = updateResponse);
}

if (updateResponse.error && notifyIfError) {
ElegantNotification notification = ElegantNotification(
Expand Down Expand Up @@ -428,20 +435,20 @@ class _DashboardPageState extends State<DashboardPage> with WindowListener {
),
icon: const Icon(Icons.info, color: Color(0xff0066FF)),
description: const Text('A new update is available!'),
action: Text(
'Update',
style: textTheme.bodyMedium!.copyWith(
color: buttonTheme.colorScheme?.primary,
fontWeight: FontWeight.bold,
),
),
onNotificationPressed: () async {
Uri url = Uri.parse(Settings.releasesLink);
action: TextButton(
onPressed: () async {
Uri url = Uri.parse(Settings.releasesLink);

if (await canLaunchUrl(url)) {
await launchUrl(url);
}
},
if (await canLaunchUrl(url)) {
await launchUrl(url);
}
},
child: Text('Update',
style: textTheme.bodyMedium!.copyWith(
color: buttonTheme.colorScheme?.primary,
fontWeight: FontWeight.bold,
)),
),
);

if (mounted) {
Expand Down Expand Up @@ -1580,35 +1587,65 @@ class _DashboardPageState extends State<DashboardPage> with WindowListener {
: null,
child: const Text('Add Widget'),
),
if ((preferences.getBool(PrefKeys.layoutLocked) ??
Defaults.layoutLocked)) ...[
const VerticalDivider(),
// Unlock Layout
Tooltip(
message: 'Unlock Layout',
child: MenuItemButton(
style: menuButtonStyle.copyWith(
minimumSize:
const WidgetStatePropertyAll(Size(36.0, double.infinity)),
maximumSize:
const WidgetStatePropertyAll(Size(36.0, double.infinity)),
),
onPressed: () {
_unlockLayout();
setState(() {});
},
child: const Icon(Icons.lock_outline),
],
);

final List<Widget> trailing = [
if ((preferences.getBool(PrefKeys.layoutLocked) ??
Defaults.layoutLocked)) ...[
const VerticalDivider(),
// Unlock Layout
Tooltip(
message: 'Unlock Layout',
child: MenuItemButton(
style: menuButtonStyle.copyWith(
minimumSize:
const WidgetStatePropertyAll(Size(36.0, double.infinity)),
maximumSize:
const WidgetStatePropertyAll(Size(36.0, double.infinity)),
),
onPressed: () {
_unlockLayout();
setState(() {});
},
child: const Icon(Icons.lock_outline),
),
],
),
],
);
if (lastUpdateResponse.updateAvailable) ...[
const VerticalDivider(),
Tooltip(
message: 'Download version ${lastUpdateResponse.latestVersion}',
child: MenuItemButton(
style: menuButtonStyle.copyWith(
minimumSize:
const WidgetStatePropertyAll(Size(36.0, double.infinity)),
maximumSize:
const WidgetStatePropertyAll(Size(36.0, double.infinity)),
),
onPressed: () async {
Uri url = Uri.parse(Settings.releasesLink);

if (await canLaunchUrl(url)) {
await launchUrl(url);
}
},
child: const Icon(Icons.update, color: Colors.orange),
),
),
],
];

if (trailing.isNotEmpty) {
trailing.add(const VerticalDivider());
}

return Scaffold(
appBar: CustomAppBar(
titleText: appTitle,
onWindowClose: onWindowClose,
menuBar: menuBar,
leading: menuBar,
trailing: trailing,
),
body: Focus(
autofocus: true,
Expand Down
21 changes: 12 additions & 9 deletions lib/widgets/custom_appbar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,28 @@ import 'package:elastic_dashboard/services/settings.dart';
class CustomAppBar extends AppBar {
final String titleText;
final Color? appBarColor;
final MenuBar menuBar;
final VoidCallback? onWindowClose;

final List<Widget> trailing;

static const double _leadingSize = 500;
static const ThemeType buttonType = ThemeType.materia;

CustomAppBar(
{super.key,
this.titleText = 'Elastic',
this.appBarColor,
this.onWindowClose,
required this.menuBar})
: super(
CustomAppBar({
super.key,
this.titleText = 'Elastic',
this.appBarColor,
this.onWindowClose,
this.trailing = const [],
required super.leading,
}) : super(
toolbarHeight: 36,
backgroundColor: appBarColor ?? const Color.fromARGB(255, 25, 25, 25),
elevation: 0.0,
scrolledUnderElevation: 0.0,
leading: menuBar,
leadingWidth: _leadingSize,
centerTitle: true,
notificationPredicate: (_) => false,
actions: [
SizedBox(
width: _leadingSize,
Expand All @@ -37,6 +39,7 @@ class CustomAppBar extends AppBar {
const Expanded(
child: _WindowDragArea(),
),
...trailing.map((e) => ExcludeFocus(child: e)),
InkWell(
canRequestFocus: false,
onTap: () async => await windowManager.minimize(),
Expand Down
4 changes: 4 additions & 0 deletions lib/widgets/editable_tab_bar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ class EditableTabBar extends StatelessWidget {
},
);
},
// The tab itself
child: AnimatedContainer(
duration: const Duration(milliseconds: 300),
curve: Curves.easeOutExpo,
Expand Down Expand Up @@ -199,12 +200,14 @@ class EditableTabBar extends StatelessWidget {
: theme.colorScheme.onPrimaryContainer,
),
),
// Spacing for close button
Visibility(
visible: !(preferences
.getBool(PrefKeys.layoutLocked) ??
Defaults.layoutLocked),
child: const SizedBox(width: 10),
),
// Close button
Visibility(
visible: !(preferences
.getBool(PrefKeys.layoutLocked) ??
Expand Down Expand Up @@ -235,6 +238,7 @@ class EditableTabBar extends StatelessWidget {
),
),
const SizedBox(width: 16),
// Tab movement buttons (move left, close, move right)
Row(
children: [
IconButton(
Expand Down
Loading