From ad45cc1d7880b70b680d4425c26b4acb65c530fe Mon Sep 17 00:00:00 2001 From: Ian VanSchooten Date: Fri, 24 Jan 2025 07:51:37 -0500 Subject: [PATCH] Fix screen titles on iOS (#230) TODO: - [x] Address Android, which this probably breaks. Previously the back button was taking up all the room in the title bar, this fixes it so that we can see titles again. It also truncates site names so they stay to one line. |Before|After| |---|---| |![image](https://github.com/user-attachments/assets/3e07a50d-fb40-40da-87f8-4d623019b26d)|![Simulator 2025-01-23 16 32 34](https://github.com/user-attachments/assets/ea668973-e67d-4fc5-8731-578e5f3fdd27)| |Before|After| |---|---| |![image](https://github.com/user-attachments/assets/d95e1a9d-f431-42aa-a9f2-357b20c37abb)|![Simulator 2025-01-23 16 11 15](https://github.com/user-attachments/assets/ff3f664b-1983-4514-a492-cf585153e294)| |Before|After| |---|---| |![image](https://github.com/user-attachments/assets/0ea3aa0d-340a-44db-8a0a-e0c8032c2450)|![image](https://github.com/user-attachments/assets/fb7e26c5-5c67-4dd7-808c-d471ca1e913e)| |Before|After| |---|---| |![image](https://github.com/user-attachments/assets/bffec7e3-561d-4a43-ab8a-3bd1cc95003c)|![Simulator 2025-01-23 16 13 23](https://github.com/user-attachments/assets/288c1f7f-4d79-4b59-b693-0cbcdd2024db)| A few other "After" screenshots: |Logs|DN enrollment| |---|---| |![Simulator 2025-01-23 16 30 48](https://github.com/user-attachments/assets/4698939e-c4ad-4929-bd0b-1b72fc21c439)|![image](https://github.com/user-attachments/assets/4c738c41-af3c-4465-9907-76fce34ecdd9)| --- lib/components/SimplePage.dart | 8 +++++--- lib/components/SiteTitle.dart | 32 ++++++++++++++++++++++++++++++ lib/screens/HostInfoScreen.dart | 3 --- lib/screens/SiteDetailScreen.dart | 11 ++-------- lib/screens/SiteLogsScreen.dart | 12 +++-------- lib/screens/SiteTunnelsScreen.dart | 3 --- lib/services/utils.dart | 24 ++++++++++------------ 7 files changed, 52 insertions(+), 41 deletions(-) create mode 100644 lib/components/SiteTitle.dart diff --git a/lib/components/SimplePage.dart b/lib/components/SimplePage.dart index 7d25d16..a6205fe 100644 --- a/lib/components/SimplePage.dart +++ b/lib/components/SimplePage.dart @@ -101,11 +101,13 @@ class SimplePage extends StatelessWidget { backgroundColor: Theme.of(context).scaffoldBackgroundColor, appBar: PlatformAppBar( title: title, - leading: leadingAction != null ? leadingAction : Utils.leadingBackWidget(context), + leading: leadingAction, trailingActions: trailingActions, cupertino: (_, __) => CupertinoNavigationBarData( - transitionBetweenRoutes: false, - ), + transitionBetweenRoutes: false, + // TODO: set title on route, show here instead of just "Back" + previousPageTitle: 'Back', + padding: EdgeInsetsDirectional.only(end: 8.0)), ), body: SafeArea(child: realChild)); } diff --git a/lib/components/SiteTitle.dart b/lib/components/SiteTitle.dart new file mode 100644 index 0000000..55b3ed6 --- /dev/null +++ b/lib/components/SiteTitle.dart @@ -0,0 +1,32 @@ +import 'dart:io'; + +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; + +import '../models/Site.dart'; + +class SiteTitle extends StatelessWidget { + const SiteTitle({Key? key, required this.site}) : super(key: key); + + final Site site; + + @override + Widget build(BuildContext context) { + final dnIcon = + Theme.of(context).brightness == Brightness.dark ? 'images/dn-logo-dark.svg' : 'images/dn-logo-light.svg'; + + return IntrinsicWidth( + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 16), + child: Row(children: [ + site.managed + ? Padding(padding: EdgeInsets.only(right: 10), child: SvgPicture.asset(dnIcon, width: 12)) + : Container(), + Expanded( + child: Text( + site.name, + overflow: TextOverflow.ellipsis, + )) + ]))); + } +} diff --git a/lib/screens/HostInfoScreen.dart b/lib/screens/HostInfoScreen.dart index 7e5ac05..f70f881 100644 --- a/lib/screens/HostInfoScreen.dart +++ b/lib/screens/HostInfoScreen.dart @@ -59,9 +59,6 @@ class _HostInfoScreenState extends State { await _getHostInfo(); refreshController.refreshCompleted(); }, - leadingAction: Utils.leadingBackWidget(context, onPressed: () { - Navigator.pop(context); - }), child: Column( children: [_buildMain(), _buildDetails(), _buildRemotes(), !widget.pending ? _buildClose() : Container()])); } diff --git a/lib/screens/SiteDetailScreen.dart b/lib/screens/SiteDetailScreen.dart index e1a937a..58e0ad3 100644 --- a/lib/screens/SiteDetailScreen.dart +++ b/lib/screens/SiteDetailScreen.dart @@ -4,7 +4,6 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_platform_widgets/flutter_platform_widgets.dart'; -import 'package:flutter_svg/svg.dart'; import 'package:mobile_nebula/components/SimplePage.dart'; import 'package:mobile_nebula/components/config/ConfigPageItem.dart'; import 'package:mobile_nebula/components/config/ConfigItem.dart'; @@ -18,6 +17,7 @@ import 'package:mobile_nebula/services/utils.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; import '../components/DangerButton.dart'; +import '../components/SiteTitle.dart'; //TODO: If the site isn't active, don't respond to reloads on hostmaps //TODO: ios is now the problem with connecting screwing our ability to query the hostmap (its a race) @@ -81,14 +81,7 @@ class _SiteDetailScreenState extends State { @override Widget build(BuildContext context) { - final dnIcon = - Theme.of(context).brightness == Brightness.dark ? 'images/dn-logo-dark.svg' : 'images/dn-logo-light.svg'; - final title = Row(children: [ - site.managed - ? Padding(padding: EdgeInsets.only(right: 10), child: SvgPicture.asset(dnIcon, width: 12)) - : Container(), - Expanded(child: Text(site.name, style: TextStyle(fontWeight: FontWeight.bold))) - ]); + final title = SiteTitle(site: widget.site); return SimplePage( title: title, diff --git a/lib/screens/SiteLogsScreen.dart b/lib/screens/SiteLogsScreen.dart index 3ac812e..4b0b216 100644 --- a/lib/screens/SiteLogsScreen.dart +++ b/lib/screens/SiteLogsScreen.dart @@ -3,7 +3,6 @@ import 'dart:io'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_platform_widgets/flutter_platform_widgets.dart'; -import 'package:flutter_svg/svg.dart'; import 'package:mobile_nebula/components/SimplePage.dart'; import 'package:mobile_nebula/models/Site.dart'; import 'package:mobile_nebula/services/settings.dart'; @@ -11,6 +10,8 @@ import 'package:mobile_nebula/services/share.dart'; import 'package:mobile_nebula/services/utils.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; +import '../components/SiteTitle.dart'; + class SiteLogsScreen extends StatefulWidget { const SiteLogsScreen({Key? key, required this.site}) : super(key: key); @@ -40,14 +41,7 @@ class _SiteLogsScreenState extends State { @override Widget build(BuildContext context) { - final dnIcon = - Theme.of(context).brightness == Brightness.dark ? 'images/dn-logo-dark.svg' : 'images/dn-logo-light.svg'; - final title = Row(children: [ - widget.site.managed - ? Padding(padding: EdgeInsets.only(right: 10), child: SvgPicture.asset(dnIcon, width: 12)) - : Container(), - Expanded(child: Text(widget.site.name, style: TextStyle(fontWeight: FontWeight.bold))) - ]); + final title = SiteTitle(site: widget.site); return SimplePage( title: title, diff --git a/lib/screens/SiteTunnelsScreen.dart b/lib/screens/SiteTunnelsScreen.dart index 706d851..d9d4b72 100644 --- a/lib/screens/SiteTunnelsScreen.dart +++ b/lib/screens/SiteTunnelsScreen.dart @@ -95,9 +95,6 @@ class _SiteTunnelsScreenState extends State { return SimplePage( title: Text('$title Tunnels'), - leadingAction: Utils.leadingBackWidget(context, onPressed: () { - Navigator.pop(context); - }), refreshController: refreshController, onRefresh: () async { await _listHostmap(); diff --git a/lib/services/utils.dart b/lib/services/utils.dart index dbf7197..ba54edf 100644 --- a/lib/services/utils.dart +++ b/lib/services/utils.dart @@ -55,17 +55,15 @@ class Utils { /// Provide your own onPressed to override that behavior, just remember you have to pop static Widget leadingBackWidget(BuildContext context, {label = 'Back', Function? onPressed}) { if (Platform.isIOS) { - return CupertinoButton( - child: Row(children: [Icon(context.platformIcons.back), Text(label)]), - padding: EdgeInsets.zero, - onPressed: () { - if (onPressed == null) { - Navigator.pop(context); - } else { - onPressed(); - } - }, - ); + return CupertinoNavigationBarBackButton( + previousPageTitle: label, + onPressed: () { + if (onPressed == null) { + Navigator.pop(context); + } else { + onPressed(); + } + }); } return IconButton( @@ -84,9 +82,7 @@ class Utils { static Widget trailingSaveWidget(BuildContext context, Function onPressed) { return PlatformTextButton( - child: Text('Save', style: TextStyle(fontWeight: FontWeight.bold)), - padding: Platform.isAndroid ? null : EdgeInsets.zero, - onPressed: () => onPressed()); + child: Text('Save'), padding: Platform.isAndroid ? null : EdgeInsets.zero, onPressed: () => onPressed()); } /// Simple cross platform delete confirmation dialog - can also be used to confirm throwing away a change by swapping the deleteLabel