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)|
This commit is contained in:
Ian VanSchooten 2025-01-24 07:51:37 -05:00 committed by GitHub
parent ae412cc407
commit ad45cc1d78
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 52 additions and 41 deletions

View file

@ -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));
}

View file

@ -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,
))
])));
}
}

View file

@ -59,9 +59,6 @@ class _HostInfoScreenState extends State<HostInfoScreen> {
await _getHostInfo();
refreshController.refreshCompleted();
},
leadingAction: Utils.leadingBackWidget(context, onPressed: () {
Navigator.pop(context);
}),
child: Column(
children: [_buildMain(), _buildDetails(), _buildRemotes(), !widget.pending ? _buildClose() : Container()]));
}

View file

@ -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<SiteDetailScreen> {
@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,

View file

@ -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<SiteLogsScreen> {
@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,

View file

@ -95,9 +95,6 @@ class _SiteTunnelsScreenState extends State<SiteTunnelsScreen> {
return SimplePage(
title: Text('$title Tunnels'),
leadingAction: Utils.leadingBackWidget(context, onPressed: () {
Navigator.pop(context);
}),
refreshController: refreshController,
onRefresh: () async {
await _listHostmap();

View file

@ -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: <Widget>[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