]> git.proxmox.com Git - flutter/proxmox_login_manager.git/blob - lib/proxmox_login_selector.dart
add multi session usage
[flutter/proxmox_login_manager.git] / lib / proxmox_login_selector.dart
1 import 'package:flutter/material.dart';
2 import 'package:proxmox_login_manager/proxmox_general_settings_form.dart';
3 import 'package:proxmox_login_manager/proxmox_login_form.dart';
4 import 'package:proxmox_login_manager/proxmox_login_model.dart';
5 import 'package:proxmox_dart_api_client/proxmox_dart_api_client.dart'
6 as proxclient;
7 import 'package:proxmox_login_manager/extension.dart';
8
9 typedef OnLoginCallback = Function(proxclient.ProxmoxApiClient client);
10
11 class ProxmoxLoginSelector extends StatefulWidget {
12 final OnLoginCallback onLogin;
13
14 const ProxmoxLoginSelector({Key key, this.onLogin}) : super(key: key);
15
16 @override
17 _ProxmoxLoginSelectorState createState() => _ProxmoxLoginSelectorState();
18 }
19
20 class _ProxmoxLoginSelectorState extends State<ProxmoxLoginSelector> {
21 Future<ProxmoxLoginStorage> loginStorage;
22 @override
23 void initState() {
24 super.initState();
25 loginStorage = ProxmoxLoginStorage.fromLocalStorage();
26 }
27
28 @override
29 Widget build(BuildContext context) {
30 return SafeArea(
31 child: Scaffold(
32 appBar: AppBar(
33 title: Column(
34 crossAxisAlignment: CrossAxisAlignment.start,
35 children: [
36 Text(
37 'Proxmox',
38 style: TextStyle(
39 fontSize: 14,
40 ),
41 ),
42 Text(
43 'Virtual Environment',
44 style: TextStyle(
45 fontSize: 14,
46 ),
47 )
48 ],
49 ),
50 actions: [
51 IconButton(
52 icon: Icon(Icons.settings),
53 onPressed: () {
54 Navigator.of(context).push(MaterialPageRoute(
55 builder: (context) => ProxmoxGeneralSettingsForm(),
56 ));
57 })
58 ],
59 ),
60 body: FutureBuilder<ProxmoxLoginStorage>(
61 future: loginStorage,
62 builder: (context, snapshot) {
63 if (!snapshot.hasData) {
64 return Center(
65 child: CircularProgressIndicator(),
66 );
67 }
68 if (snapshot.hasData && (snapshot.data.logins?.isEmpty ?? true)) {
69 return Center(
70 child: Text('Add an account'),
71 );
72 }
73 var items = <Widget>[];
74 final logins = snapshot.data?.logins;
75
76 final activeSessions =
77 logins.rebuild((b) => b.where((b) => b.activeSession));
78
79 if (activeSessions.isNotEmpty) {
80 items.addAll([
81 Padding(
82 padding: const EdgeInsets.all(12.0),
83 child: Text(
84 'Active Sessions',
85 style: TextStyle(
86 fontSize: 18,
87 fontWeight: FontWeight.bold,
88 ),
89 ),
90 ),
91 ...activeSessions.map((s) => ListTile(
92 title: Text(s.fullHostname),
93 subtitle: Text(s.fullUsername),
94 trailing: Icon(Icons.navigate_next),
95 leading: PopupMenuButton(
96 icon: Icon(Icons.more_vert, color: Colors.green),
97 itemBuilder: (context) => [
98 PopupMenuItem(
99 child: ListTile(
100 dense: true,
101 leading: Icon(Icons.logout),
102 title: Text('Logout'),
103 onTap: () async {
104 await snapshot.data
105 .rebuild((b) => b.logins
106 .rebuildWhere((m) => s == m,
107 (b) => b..ticket = ''))
108 .saveToDisk();
109 refreshFromStorage();
110 Navigator.of(context).pop();
111 },
112 ),
113 ),
114 ]),
115 onTap: () => _login(user: s),
116 )),
117 ]);
118 }
119 items.addAll([
120 Padding(
121 padding: const EdgeInsets.all(12.0),
122 child: Text(
123 'Available Sites',
124 style: TextStyle(
125 fontSize: 18,
126 fontWeight: FontWeight.bold,
127 ),
128 ),
129 ),
130 ...logins.where((b) => !b.activeSession)?.map((l) => ListTile(
131 title: Text(l.fullHostname),
132 subtitle: Text(l.fullUsername),
133 trailing: Icon(Icons.navigate_next),
134 leading: PopupMenuButton(
135 itemBuilder: (context) => [
136 PopupMenuItem(
137 child: ListTile(
138 dense: true,
139 leading: Icon(Icons.delete),
140 title: Text('Delete'),
141 onTap: () async {
142 await snapshot.data
143 .rebuild((b) => b.logins.remove(l))
144 .saveToDisk();
145 refreshFromStorage();
146 Navigator.of(context).pop();
147 },
148 ),
149 ),
150 ]),
151 onTap: () => _login(user: l),
152 ))
153 ]);
154 return ListView(
155 children: items,
156 );
157 }),
158 floatingActionButton: FloatingActionButton.extended(
159 onPressed: () => _login(isCreate: true),
160 label: Text('Add'),
161 icon: Icon(Icons.account_circle),
162 ),
163 ),
164 );
165 }
166
167 Future<void> _login({ProxmoxLoginModel user, bool isCreate = false}) async {
168 final client = await Navigator.of(context).push(MaterialPageRoute(
169 builder: (context) => ProxmoxLoginPage(
170 userModel: user,
171 isCreate: isCreate,
172 ticket: user?.ticket,
173 )));
174 refreshFromStorage();
175 if (client != null) {
176 widget.onLogin(client);
177 }
178 }
179
180 void refreshFromStorage() {
181 setState(() {
182 loginStorage = ProxmoxLoginStorage.fromLocalStorage();
183 });
184 }
185 }