main: initial SSH-Key-List App
This commit is contained in:
parent
c4fe7a1afa
commit
b099cab718
@ -14,8 +14,15 @@ import 'package:oauth2/oauth2.dart' as oauth2;
|
|||||||
|
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
|
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
runApp(const MyApp());
|
runApp(
|
||||||
|
ChangeNotifierProvider(
|
||||||
|
create: (context) => SSHKeyList(),
|
||||||
|
child: const MyApp(),
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<oauth2.Client> getOAuth2Client() async {
|
Future<oauth2.Client> getOAuth2Client() async {
|
||||||
@ -335,7 +342,19 @@ class _MyHomePageState extends State<MyHomePage> {
|
|||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
TextButton(onPressed: doOAuth, child: Text("Oauth2 Login")),
|
TextButton(onPressed: doOAuth, child: Text("Oauth2 Login")),
|
||||||
Text('Current output:'),
|
Text('Current output:'),
|
||||||
|
Consumer(
|
||||||
|
builder: (BuildContext context, SSHKeyList sshKeyList, Widget? child) {
|
||||||
|
return Text(
|
||||||
|
sshKeyList.keysToKeep.isEmpty
|
||||||
|
? 'No keys selected to keep.'
|
||||||
|
: 'Keys selected to keep: ${sshKeyList.keysToKeep.join(', ')}',
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
Text(outputText, style: Theme.of(context).textTheme.headlineMedium),
|
Text(outputText, style: Theme.of(context).textTheme.headlineMedium),
|
||||||
|
// Generated code for this Text Widget...
|
||||||
|
KeepOrDeleteKey(sshKey: "ssh-ed22519 abs csas blabla"),
|
||||||
|
KeepOrDeleteKey(sshKey: "ssh-ed22519 abs "),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -413,3 +432,134 @@ class _MyHomePageState extends State<MyHomePage> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class SSHKeyList extends ChangeNotifier {
|
||||||
|
final List<String> _allKeys = [];
|
||||||
|
final List<String> _keysToKeep = [];
|
||||||
|
|
||||||
|
List<String> get allKeys => _allKeys;
|
||||||
|
List<String> get keysToKeep => _keysToKeep;
|
||||||
|
|
||||||
|
void keepKey(String key) {
|
||||||
|
if (_keysToKeep.contains(key)) {
|
||||||
|
// If the key is already in the list, do nothing
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_keysToKeep.add(key);
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
void selectKeyForDeletion(String key) {
|
||||||
|
_keysToKeep.remove(key);
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isKeySelectedToKeep(String key) {
|
||||||
|
return _keysToKeep.contains(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
void clearKeys() {
|
||||||
|
_keysToKeep.clear();
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class KeepOrDeleteKey extends StatefulWidget {
|
||||||
|
final String sshKey;
|
||||||
|
|
||||||
|
const KeepOrDeleteKey({super.key, required this.sshKey});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<KeepOrDeleteKey> createState() => _KeepOrDeleteKeyState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _KeepOrDeleteKeyState extends State<KeepOrDeleteKey> {
|
||||||
|
bool _selectedForDeletion = false;
|
||||||
|
|
||||||
|
bool get selectedForDeletion => _selectedForDeletion;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final key = widget.sshKey;
|
||||||
|
final isKeySelectedToKeep = context.select<SSHKeyList, bool>(
|
||||||
|
(keylist) => keylist.isKeySelectedToKeep(key),
|
||||||
|
);
|
||||||
|
|
||||||
|
final buttonStyleKeepActive = ButtonStyle(
|
||||||
|
backgroundColor: MaterialStateProperty.all(Colors.blue),
|
||||||
|
foregroundColor: MaterialStateProperty.all(Colors.white),
|
||||||
|
);
|
||||||
|
|
||||||
|
final buttonStyleDeleteActive = ButtonStyle(
|
||||||
|
backgroundColor: MaterialStateProperty.all(Colors.red),
|
||||||
|
foregroundColor: MaterialStateProperty.all(Colors.white),
|
||||||
|
);
|
||||||
|
|
||||||
|
ButtonStyle? buttonStyleKeep;
|
||||||
|
ButtonStyle? buttonStyleDelete = buttonStyleDeleteActive;
|
||||||
|
|
||||||
|
if (isKeySelectedToKeep) {
|
||||||
|
buttonStyleKeep = buttonStyleKeepActive;
|
||||||
|
buttonStyleDelete = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var title = "Unnamed Key";
|
||||||
|
final sshKeySplit = widget.sshKey.split(' ');
|
||||||
|
if (sshKeySplit.length >= 3) {
|
||||||
|
final potentialTitle = sshKeySplit.sublist(2).join(' ');
|
||||||
|
if (potentialTitle != "") {
|
||||||
|
title = potentialTitle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Card(
|
||||||
|
margin: EdgeInsets.fromLTRB(20, 20, 20, 0),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.all(20),
|
||||||
|
child: Text(title, style: TextStyle(fontSize: 25)),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.fromLTRB(20, 0, 20, 20),
|
||||||
|
child: Text(widget.sshKey, style: TextStyle(fontSize: 15)),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.fromLTRB(20, 0, 20, 20),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||||
|
children: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
setState(() {
|
||||||
|
_selectedForDeletion = true;
|
||||||
|
Provider.of<SSHKeyList>(
|
||||||
|
context,
|
||||||
|
listen: false,
|
||||||
|
).selectKeyForDeletion(widget.sshKey);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
style: buttonStyleDelete,
|
||||||
|
child: Text('Select for Deletion'),
|
||||||
|
),
|
||||||
|
TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
setState(() {
|
||||||
|
_selectedForDeletion = false;
|
||||||
|
Provider.of<SSHKeyList>(
|
||||||
|
context,
|
||||||
|
listen: false,
|
||||||
|
).keepKey(widget.sshKey);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
style: buttonStyleKeep,
|
||||||
|
child: Text('Keep Key'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -256,6 +256,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.16.0"
|
version: "1.16.0"
|
||||||
|
nested:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: nested
|
||||||
|
sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.0"
|
||||||
oauth2:
|
oauth2:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -352,6 +360,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.9.1"
|
version: "3.9.1"
|
||||||
|
provider:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: provider
|
||||||
|
sha256: "4abbd070a04e9ddc287673bf5a030c7ca8b685ff70218720abab8b092f53dd84"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "6.1.5"
|
||||||
sky_engine:
|
sky_engine:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description: flutter
|
description: flutter
|
||||||
|
@ -40,6 +40,7 @@ dependencies:
|
|||||||
oauth2: ^2.0.3
|
oauth2: ^2.0.3
|
||||||
webview_flutter: ^4.13.0
|
webview_flutter: ^4.13.0
|
||||||
url_launcher: ^6.3.1
|
url_launcher: ^6.3.1
|
||||||
|
provider: ^6.1.5
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user