Skip to content

Commit

Permalink
Add DangerButton component (#219)
Browse files Browse the repository at this point in the history
This pulls out a component that we can use for "dangerous" operations like deleting, and styles it in one place.

It also starts to move us slowly towards Material 3, with the rounded corners on these buttons in Android.  

Android:

|Before Light|Before Dark|After Light|After Dark|
|---|---|---|---|
|<img width="425" alt="Android Studio 2025-01-15 14 16 36" src="https://github.com/user-attachments/assets/4823e551-6a40-48dd-9bc1-3004699b90ea" />|<img width="417" alt="Android Studio 2025-01-15 14 16 47" src="https://github.com/user-attachments/assets/df5461fd-586e-47bb-99b9-0212e63f0454" />|<img width="413" alt="Android Studio 2025-01-15 14 15 59" src="https://github.com/user-attachments/assets/d88a6225-b71a-4886-8387-e35811a3a6ec" />|<img width="418" alt="Android Studio 2025-01-15 14 16 15" src="https://github.com/user-attachments/assets/d4f23b1c-7003-4a00-b865-4a123d8fe3e9" />|


iOS:

|Before Light|Before Dark|After Light|After Dark|
|---|---|---|---|
|<img width="437" alt="Simulator 2025-01-15 15 56 26" src="https://github.com/user-attachments/assets/87c4eed3-6d07-4858-8ad8-d8c011538154" />|<img width="445" alt="Simulator 2025-01-15 15 56 36" src="https://github.com/user-attachments/assets/9dc5b174-7bc7-48ec-a3c0-61633168c31a" />|<img width="439" alt="Simulator 2025-01-15 16 05 23" src="https://github.com/user-attachments/assets/31dc9ab6-8a3c-49c7-892d-627f16e2a8cd" />|<img width="444" alt="Simulator 2025-01-15 16 05 37" src="https://github.com/user-attachments/assets/979280d6-e1f4-4d57-a86a-10bb4def729a" />|
  • Loading branch information
IanVS authored Jan 16, 2025
1 parent 46f029a commit 9918376
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 30 deletions.
28 changes: 28 additions & 0 deletions lib/components/DangerButton.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import 'dart:io';

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

class DangerButton extends StatelessWidget {
const DangerButton({Key? key, required this.child, this.onPressed}) : super(key: key);

final Widget child;
final GestureTapCallback? onPressed;

@override
Widget build(BuildContext context) {
if (Platform.isAndroid) {
return FilledButton(
onPressed: onPressed,
child: child,
style: FilledButton.styleFrom(backgroundColor: Theme.of(context).colorScheme.error));
} else {
// Workaround for https://github.com/flutter/flutter/issues/161590
final themeData = CupertinoTheme.of(context);
return CupertinoTheme(
data: themeData.copyWith(primaryColor: CupertinoColors.white),
child: CupertinoButton(
child: child, onPressed: onPressed, color: CupertinoColors.systemRed.resolveFrom(context)));
}
}
}
18 changes: 12 additions & 6 deletions lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import 'dart:async';

import 'package:flutter/cupertino.dart' show CupertinoThemeData, DefaultCupertinoLocalizations;
import 'package:flutter/cupertino.dart' show CupertinoThemeData, DefaultCupertinoLocalizations, CupertinoColors;
import 'package:flutter/material.dart'
show BottomSheetThemeData, Colors, DefaultMaterialLocalizations, ThemeData, ThemeMode;
show BottomSheetThemeData, ColorScheme, Colors, DefaultMaterialLocalizations, ThemeData, ThemeMode;
import 'package:flutter/scheduler.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
Expand Down Expand Up @@ -87,8 +87,11 @@ class _AppState extends State<App> {
Widget build(BuildContext context) {
final ThemeData lightTheme = ThemeData(
useMaterial3: false,
brightness: Brightness.light,
primarySwatch: Colors.blueGrey,
colorScheme: ColorScheme.fromSwatch(
brightness: Brightness.light,
primarySwatch: Colors.blueGrey,
errorColor: CupertinoColors.systemRed.resolveFrom(context),
),
primaryColor: Colors.blueGrey[900],
fontFamily: 'PublicSans',
//scaffoldBackgroundColor: Colors.grey[100],
Expand All @@ -100,8 +103,11 @@ class _AppState extends State<App> {

final ThemeData darkTheme = ThemeData(
useMaterial3: false,
brightness: Brightness.dark,
primarySwatch: Colors.grey,
colorScheme: ColorScheme.fromSwatch(
brightness: Brightness.dark,
primarySwatch: Colors.grey,
errorColor: CupertinoColors.systemRed.resolveFrom(context),
),
primaryColor: Colors.grey[900],
fontFamily: 'PublicSans',
scaffoldBackgroundColor: Colors.grey[800],
Expand Down
4 changes: 2 additions & 2 deletions lib/screens/HostInfoScreen.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_platform_widgets/flutter_platform_widgets.dart';
import 'package:mobile_nebula/components/DangerButton.dart';
import 'package:mobile_nebula/components/SimplePage.dart';
import 'package:mobile_nebula/components/config/ConfigCheckboxItem.dart';
import 'package:mobile_nebula/components/config/ConfigItem.dart';
Expand Down Expand Up @@ -161,9 +162,8 @@ class _HostInfoScreenState extends State<HostInfoScreen> {
padding: EdgeInsets.only(top: 50, bottom: 10, left: 10, right: 10),
child: SizedBox(
width: double.infinity,
child: PlatformElevatedButton(
child: DangerButton(
child: Text('Close Tunnel'),
color: CupertinoColors.systemRed.resolveFrom(context),
onPressed: () => Utils.confirmDelete(context, 'Close Tunnel?', () async {
try {
await widget.site.closeTunnel(hostInfo.vpnIp);
Expand Down
18 changes: 10 additions & 8 deletions lib/screens/SiteDetailScreen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import 'package:mobile_nebula/screens/siteConfig/SiteConfigScreen.dart';
import 'package:mobile_nebula/services/utils.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';

import '../components/DangerButton.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)

Expand Down Expand Up @@ -256,14 +258,14 @@ class _SiteDetailScreenState extends State<SiteDetailScreen> {
padding: EdgeInsets.only(top: 50, bottom: 10, left: 10, right: 10),
child: SizedBox(
width: double.infinity,
child: PlatformElevatedButton(
child: Text('Delete'),
color: CupertinoColors.systemRed.resolveFrom(context),
onPressed: () => Utils.confirmDelete(context, 'Delete Site?', () async {
if (await _deleteSite()) {
Navigator.of(context).pop();
}
}))));
child: DangerButton(
child: Text('Delete'),
onPressed: () => Utils.confirmDelete(context, 'Delete Site?', () async {
if (await _deleteSite()) {
Navigator.of(context).pop();
}
}),
)));
}

_listHostmap() async {
Expand Down
7 changes: 3 additions & 4 deletions lib/screens/siteConfig/CertificateDetailsScreen.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_platform_widgets/flutter_platform_widgets.dart';
import 'package:mobile_nebula/components/DangerButton.dart';
import 'package:mobile_nebula/components/FormPage.dart';
import 'package:mobile_nebula/components/config/ConfigItem.dart';
import 'package:mobile_nebula/components/config/ConfigSection.dart';
Expand Down Expand Up @@ -164,9 +165,8 @@ class _CertificateDetailsScreenState extends State<CertificateDetailsScreen> {
padding: EdgeInsets.only(top: 50, bottom: 10, left: 10, right: 10),
child: SizedBox(
width: double.infinity,
child: PlatformElevatedButton(
child: DangerButton(
child: Text('Replace certificate'),
color: CupertinoColors.systemRed.resolveFrom(context),
onPressed: () {
Utils.openPage(context, (context) {
return AddCertificateScreen(
Expand Down Expand Up @@ -199,9 +199,8 @@ class _CertificateDetailsScreenState extends State<CertificateDetailsScreen> {
padding: EdgeInsets.only(top: 50, bottom: 10, left: 10, right: 10),
child: SizedBox(
width: double.infinity,
child: PlatformElevatedButton(
child: DangerButton(
child: Text('Delete'),
color: CupertinoColors.systemRed.resolveFrom(context),
onPressed: () => Utils.confirmDelete(context, title, () async {
Navigator.pop(context);
widget.onDelete!();
Expand Down
15 changes: 7 additions & 8 deletions lib/screens/siteConfig/StaticHostmapScreen.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_platform_widgets/flutter_platform_widgets.dart';
import 'package:mobile_nebula/components/DangerButton.dart';
import 'package:mobile_nebula/components/FormPage.dart';
import 'package:mobile_nebula/components/IPAndPortFormField.dart';
import 'package:mobile_nebula/components/IPFormField.dart';
Expand Down Expand Up @@ -119,14 +120,12 @@ class _StaticHostmapScreenState extends State<StaticHostmapScreen> {
padding: EdgeInsets.only(top: 50, bottom: 10, left: 10, right: 10),
child: SizedBox(
width: double.infinity,
child: PlatformElevatedButton(
child: Text('Delete'),
color: CupertinoColors.systemRed.resolveFrom(context),
onPressed: () => Utils.confirmDelete(context, 'Delete host map?', () {
Navigator.of(context).pop();
widget.onDelete!();
}),
)))
child: DangerButton(
child: Text('Delete'),
onPressed: () => Utils.confirmDelete(context, 'Delete host map?', () {
Navigator.of(context).pop();
widget.onDelete!();
}))))
: Container()
]));
}
Expand Down
4 changes: 2 additions & 2 deletions lib/screens/siteConfig/UnsafeRouteScreen.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter_platform_widgets/flutter_platform_widgets.dart';
import 'package:mobile_nebula/components/CIDRFormField.dart';
import 'package:mobile_nebula/components/DangerButton.dart';
import 'package:mobile_nebula/components/FormPage.dart';
import 'package:mobile_nebula/components/IPFormField.dart';
import 'package:mobile_nebula/components/config/ConfigItem.dart';
Expand Down Expand Up @@ -96,9 +97,8 @@ class _UnsafeRouteScreenState extends State<UnsafeRouteScreen> {
padding: EdgeInsets.only(top: 50, bottom: 10, left: 10, right: 10),
child: SizedBox(
width: double.infinity,
child: PlatformElevatedButton(
child: DangerButton(
child: Text('Delete'),
color: CupertinoColors.systemRed.resolveFrom(context),
onPressed: () => Utils.confirmDelete(context, 'Delete unsafe route?', () {
Navigator.of(context).pop();
widget.onDelete!();
Expand Down

0 comments on commit 9918376

Please sign in to comment.