Skip to content

Commit 7b9abfc

Browse files
committed
quality of life improvements
1 parent 9fbf568 commit 7b9abfc

File tree

10 files changed

+252
-75
lines changed

10 files changed

+252
-75
lines changed

lib/flash_partitions.dart

Lines changed: 117 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -44,69 +44,108 @@ class _FlashPartitionsState extends State<FlashPartitions> {
4444
Widget build(BuildContext context) {
4545
return Scaffold(
4646
appBar: AppBar(
47-
title: const Text('Flash Partitions'),
47+
title: Row(
48+
children: [
49+
const Text("Flash partitions"),
50+
Text(" | ${backupFolder?.path ?? "No folder selected"} | ", style: const TextStyle(fontSize: 18),),
51+
Text("Device: $device", style: const TextStyle(fontSize: 18),),
52+
53+
],
54+
)
4855
),
4956
body: Column(
5057
children: [
51-
Padding(
52-
padding: const EdgeInsets.all(16.0),
53-
child: Row(
54-
mainAxisAlignment: MainAxisAlignment.spaceBetween,
55-
crossAxisAlignment: CrossAxisAlignment.start,
56-
children: [
57-
Column(
58-
crossAxisAlignment: CrossAxisAlignment.start,
59-
children: [
60-
Text('Device: $device'),
61-
const SizedBox(height: 4),
62-
Text(
63-
'Backup Folder: ${backupFolder?.path ?? "Not selected"}'),
64-
],
65-
),
66-
Row(
67-
children: [
68-
ElevatedButton(
69-
onPressed: () {
70-
Process.run('fastboot', ['devices']).then((result) {
71-
setState(() {
72-
device = result.stdout.toString();
73-
});
74-
});
75-
},
76-
child: const Text('Refresh'),
77-
),
78-
const SizedBox(width: 16),
79-
ElevatedButton(
80-
onPressed: () {
81-
outputController.text = "";
82-
},
83-
child: const Text('Clear Output'),
84-
),
85-
const SizedBox(width: 16),
86-
ElevatedButton(
87-
onPressed: () async {
88-
String? directoryPath =
89-
await FilePicker.platform.getDirectoryPath();
90-
if (directoryPath != null) {
91-
setState(() {
92-
backupFolder = Directory(directoryPath);
93-
});
94-
retrievePartitionNames();
95-
}
96-
},
97-
child: const Text('Select Backup Folder'),
98-
),
99-
const SizedBox(width: 8),
100-
if (backupFolder != null)
101-
ElevatedButton(
102-
onPressed: flashAllPartitions,
103-
child: const Text("Flash All"),
104-
)
105-
],
106-
),
107-
],
108-
),
58+
const SizedBox(height: 8,),
59+
Row(
60+
mainAxisAlignment: MainAxisAlignment.center,
61+
children: [
62+
FilledButton(
63+
onPressed: () {
64+
Process.run('fastboot', ['-w']).then((result) {
65+
setState(() {
66+
device = result.stdout.toString();
67+
});
68+
});
69+
},
70+
child: const Text('Wipe userdata'),
71+
),
72+
const SizedBox(width: 16),
73+
FilledButton(
74+
onPressed: () {
75+
Process.run('fastboot', ['flashing', 'lock'])
76+
.then((result) {
77+
setState(() {
78+
device = result.stdout.toString();
79+
});
80+
});
81+
},
82+
child: const Text('Lock Bootloader'),
83+
),
84+
const SizedBox(width: 16),
85+
FilledButton(
86+
onPressed: () {
87+
Process.run('fastboot', ['flashing', 'unlock'])
88+
.then((result) {
89+
setState(() {
90+
device = result.stdout.toString();
91+
});
92+
});
93+
},
94+
child: const Text('Unlock Bootloader'),
95+
),
96+
const SizedBox(width: 16),
97+
FilledButton(
98+
onPressed: () {
99+
Process.run('fastboot', ['reboot', 'fastboot'])
100+
.then((result) {
101+
setState(() {
102+
device = result.stdout.toString();
103+
});
104+
});
105+
},
106+
child: const Text('Reboot to fastbootd'),
107+
),
108+
const SizedBox(width: 16),
109+
ElevatedButton(
110+
onPressed: () {
111+
Process.run('fastboot', ['devices']).then((result) {
112+
setState(() {
113+
device = result.stdout.toString();
114+
});
115+
});
116+
},
117+
child: const Text('Refresh'),
118+
),
119+
const SizedBox(width: 16),
120+
ElevatedButton(
121+
onPressed: () {
122+
outputController.text = "";
123+
},
124+
child: const Text('Clear Output'),
125+
),
126+
const SizedBox(width: 16),
127+
ElevatedButton(
128+
onPressed: () async {
129+
String? directoryPath =
130+
await FilePicker.platform.getDirectoryPath();
131+
if (directoryPath != null) {
132+
setState(() {
133+
backupFolder = Directory(directoryPath);
134+
});
135+
retrievePartitionNames();
136+
}
137+
},
138+
child: const Text('Select Backup Folder'),
139+
),
140+
const SizedBox(width: 8),
141+
if (backupFolder != null)
142+
ElevatedButton(
143+
onPressed: flashAllPartitions,
144+
child: const Text("Flash All"),
145+
)
146+
],
109147
),
148+
const SizedBox(height: 8,),
110149
Expanded(
111150
child: Row(
112151
children: [
@@ -119,7 +158,7 @@ class _FlashPartitionsState extends State<FlashPartitions> {
119158
title: Text(partitionNames[index]),
120159
subtitle: Text(
121160
'Flashing to ${partitionNames[index].split('\\').last} partition'),
122-
trailing: ElevatedButton(
161+
trailing: FilledButton(
123162
onPressed: () {
124163
outputController.text +=
125164
"Flashing ${partitionNames[index]}\n";
@@ -143,19 +182,25 @@ class _FlashPartitionsState extends State<FlashPartitions> {
143182
),
144183
const SizedBox(width: 16),
145184
Expanded(
146-
child: Padding(
147-
padding: const EdgeInsets.all(8.0),
148-
child: TextField(
149-
controller: outputController,
150-
readOnly: true,
151-
maxLines: 100,
152-
decoration: const InputDecoration(
153-
labelText: 'Output',
154-
border: OutlineInputBorder(),
155-
),
185+
child: Column(
186+
crossAxisAlignment: CrossAxisAlignment.start,
187+
children: [
188+
const Text(
189+
"Output",
190+
style: TextStyle(fontSize: 24),
156191
),
157-
),
158-
),
192+
Expanded(
193+
child: TextField(
194+
controller: outputController,
195+
readOnly: true,
196+
maxLines: 100,
197+
decoration: const InputDecoration(
198+
border: InputBorder.none,
199+
),
200+
),
201+
)
202+
],
203+
)),
159204
],
160205
),
161206
),

lib/home_screen.dart

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import 'dart:io';
33
import 'package:flutter/material.dart';
44
import 'package:file_picker/file_picker.dart';
55
import 'package:http/http.dart' as http;
6+
import 'package:url_launcher/url_launcher.dart';
67

78
class HomeScreen extends StatefulWidget {
89
const HomeScreen({super.key});
@@ -236,6 +237,24 @@ class _HomeScreenState extends State<HomeScreen> {
236237
}
237238

238239
void backupSelected() async {
240+
if (Directory(saveFolder).existsSync() == false) {
241+
return showDialog(
242+
context: context,
243+
builder: (context) {
244+
return AlertDialog(
245+
title: const Text("Backup Folder Required"),
246+
content: const Text("Please select a folder to back up to."),
247+
actions: [
248+
TextButton(
249+
onPressed: () {
250+
Navigator.of(context).pop();
251+
},
252+
child: const Text("Ok"))
253+
],
254+
);
255+
});
256+
}
257+
239258
setState(() {
240259
backupInProgress = true;
241260
});
@@ -296,7 +315,41 @@ class _HomeScreenState extends State<HomeScreen> {
296315

297316
return Scaffold(
298317
appBar: AppBar(
299-
title: Text('Partition Backup - ADB $adbVersion'),
318+
title: Text(
319+
'Partition Backup - ADB $adbVersion - ${saveFolder == "" ? "No save folder selected" : saveFolder}'),
320+
actions: [
321+
IconButton(
322+
onPressed: () {
323+
showDialog(
324+
context: context,
325+
builder: (context) {
326+
return AlertDialog(
327+
title: const Text("About this app"),
328+
content: const Column(
329+
crossAxisAlignment: CrossAxisAlignment.start,
330+
mainAxisSize: MainAxisSize.min,
331+
children: [
332+
Text("(c) 2024 Andrew Wang."),
333+
],
334+
),
335+
actions: [
336+
TextButton(
337+
onPressed: () {
338+
Navigator.pop(context);
339+
},
340+
child: const Text("Ok")),
341+
TextButton(
342+
onPressed: () {
343+
launchUrl(
344+
Uri.parse("https://github.com/flandolf"));
345+
},
346+
child: const Text("Github"))
347+
],
348+
);
349+
});
350+
},
351+
icon: const Icon(Icons.info))
352+
],
300353
),
301354
body: Column(
302355
children: [
@@ -508,6 +561,9 @@ class _HomeScreenState extends State<HomeScreen> {
508561
],
509562
),
510563
),
564+
const SizedBox(
565+
height: 16,
566+
)
511567
],
512568
),
513569
);

lib/main.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class MyApp extends StatelessWidget {
1616
title: 'Flutter Demo',
1717
theme: ThemeData(
1818
colorScheme: ColorScheme.fromSeed(
19-
seedColor: Colors.lime, brightness: Brightness.dark),
19+
seedColor: Colors.teal, brightness: Brightness.dark),
2020
useMaterial3: true,
2121
),
2222
debugShowCheckedModeBanner: false,

linux/flutter/generated_plugin_registrant.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66

77
#include "generated_plugin_registrant.h"
88

9+
#include <url_launcher_linux/url_launcher_plugin.h>
910

1011
void fl_register_plugins(FlPluginRegistry* registry) {
12+
g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
13+
fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
14+
url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);
1115
}

linux/flutter/generated_plugins.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#
44

55
list(APPEND FLUTTER_PLUGIN_LIST
6+
url_launcher_linux
67
)
78

89
list(APPEND FLUTTER_FFI_PLUGIN_LIST

macos/Flutter/GeneratedPluginRegistrant.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
import FlutterMacOS
66
import Foundation
77

8+
import url_launcher_macos
89

910
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
11+
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
1012
}

0 commit comments

Comments
 (0)