Skip to content

Commit c6d5d18

Browse files
committed
updated dependencies, updated cryptography code and biometrics. squashed folder bug. updated version name.
1 parent 9a952d8 commit c6d5d18

File tree

6 files changed

+225
-184
lines changed

6 files changed

+225
-184
lines changed

lib/screens/lock_screen.dart

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,8 @@ class _LockScreenState extends State<LockScreen> {
2424
try {
2525
final bool didAuthenticate = await _auth.authenticate(
2626
localizedReason: 'Please authenticate to unlock SmoothSSH',
27-
options: const AuthenticationOptions(
28-
biometricOnly: false,
29-
stickyAuth: true,
30-
),
27+
biometricOnly: false,
28+
persistAcrossBackgrounding: true,
3129
);
3230

3331
if (didAuthenticate && mounted) {

lib/screens/settings_screen.dart

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -224,10 +224,8 @@ class _SettingsScreenState extends State<SettingsScreen> {
224224

225225
final bool didAuthenticate = await auth.authenticate(
226226
localizedReason: reason,
227-
options: const AuthenticationOptions(
228-
biometricOnly: false,
229-
stickyAuth: true,
230-
),
227+
biometricOnly: false,
228+
persistAcrossBackgrounding: true,
231229
);
232230

233231
if (didAuthenticate) {
@@ -400,7 +398,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
400398
const ListTile(
401399
leading: Icon(Icons.info_outline, color: Colors.grey),
402400
title: Text('SmoothSSH'),
403-
subtitle: Text('Version 0.1.0 - Zippy Zebra', style: TextStyle(color: Colors.grey, fontSize: 12)),
401+
subtitle: Text('Version 0.1.5 - Atomic Axolotl', style: TextStyle(color: Colors.grey, fontSize: 12)),
404402
),
405403
const Divider(height: 1),
406404
ListTile(
@@ -412,7 +410,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
412410
showLicensePage(
413411
context: context,
414412
applicationName: 'SmoothSSH',
415-
applicationVersion: '0.1.0-alpha - Zippy Zebra',
413+
applicationVersion: '0.1.5-alpha - Atomic Axolotl',
416414
applicationIcon: Padding(
417415
padding: const EdgeInsets.all(16.0),
418416
child: Icon(Icons.terminal, size: 48, color: Theme.of(context).primaryColor),

lib/services/connection_service.dart

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,15 +45,9 @@ class ConnectionService {
4545
final index = all.indexWhere((element) => element.id == id);
4646
if (index != -1) {
4747
final old = all[index];
48-
final updated = Connection(
49-
id: old.id,
50-
label: old.label,
51-
host: old.host,
52-
port: old.port,
53-
identityId: old.identityId,
54-
usageCount: old.usageCount + 1,
55-
);
56-
all[index] = updated;
48+
final Map<String, dynamic> json = old.toJson();
49+
json['usageCount'] = (json['usageCount'] as int? ?? 0) + 1;
50+
all[index] = Connection.fromJson(json);
5751
await _storage.write(key: _key, value: jsonEncode(all.map((e) => e.toJson()).toList()));
5852
}
5953
}

lib/widgets/terminal_keyboard.dart

Lines changed: 139 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -34,38 +34,20 @@ class _TerminalKeyboardState extends State<TerminalKeyboard> {
3434
}
3535

3636
void _sendKey(TerminalKey key) {
37-
widget.terminal.keyInput(
38-
key,
39-
ctrl: _isCtrlActive,
40-
alt: _isAltActive,
41-
);
42-
43-
if (_isCtrlActive || _isAltActive) {
44-
setState(() {
45-
_isCtrlActive = false;
46-
_isAltActive = false;
47-
});
37+
widget.terminal.keyInput(key, alt: _isAltActive);
38+
if (_isAltActive) {
39+
setState(() => _isAltActive = false);
4840
}
4941
}
5042

51-
void _sendText(String text) {
52-
if (_isCtrlActive) {
53-
if (text.length == 1) {
54-
final charCode = text.toLowerCase().codeUnitAt(0);
55-
if (charCode >= 97 && charCode <= 122) {
56-
widget.terminal.paste(String.fromCharCode(charCode - 96));
57-
}
58-
}
59-
} else {
60-
widget.terminal.paste(text);
61-
}
43+
void _sendCtrlByte(String char) {
44+
final code = char.toUpperCase().codeUnitAt(0) - 64;
45+
widget.terminal.textInput(String.fromCharCode(code));
46+
setState(() => _isCtrlActive = false);
47+
}
6248

63-
if (_isCtrlActive || _isAltActive) {
64-
setState(() {
65-
_isCtrlActive = false;
66-
_isAltActive = false;
67-
});
68-
}
49+
void _sendText(String text) {
50+
widget.terminal.paste(text);
6951
}
7052

7153
@override
@@ -78,58 +60,83 @@ class _TerminalKeyboardState extends State<TerminalKeyboard> {
7860
color: theme.colorScheme.surface,
7961
border: Border(top: BorderSide(color: theme.dividerColor)),
8062
),
81-
child: ListView(
82-
scrollDirection: Axis.horizontal,
83-
padding: const EdgeInsets.symmetric(horizontal: 4),
84-
children: [
85-
86-
_buildToggleKey('CTRL', _isCtrlActive, () => setState(() => _isCtrlActive = !_isCtrlActive)),
87-
_buildToggleKey('ALT', _isAltActive, () => setState(() => _isAltActive = !_isAltActive)),
88-
_buildVerticalDivider(),
63+
child: _isCtrlActive ? _buildCtrlActiveRow() : _buildNormalRow(),
64+
);
65+
}
8966

90-
_buildTerminalKey('ESC', TerminalKey.escape),
91-
_buildTerminalKey('TAB', TerminalKey.tab),
92-
_buildTerminalKey('↑', TerminalKey.arrowUp),
93-
_buildTerminalKey('↓', TerminalKey.arrowDown),
94-
_buildTerminalKey('←', TerminalKey.arrowLeft),
95-
_buildTerminalKey('→', TerminalKey.arrowRight),
96-
_buildVerticalDivider(),
67+
Widget _buildNormalRow() {
68+
final theme = Theme.of(context);
69+
return ListView(
70+
scrollDirection: Axis.horizontal,
71+
padding: const EdgeInsets.symmetric(horizontal: 4),
72+
children: [
73+
_buildToggleKey('CTRL', _isCtrlActive, () => setState(() => _isCtrlActive = true)),
74+
_buildToggleKey('ALT', _isAltActive, () => setState(() => _isAltActive = !_isAltActive)),
75+
_buildVerticalDivider(),
9776

98-
_buildTerminalKey('HOME', TerminalKey.home),
99-
_buildTerminalKey('END', TerminalKey.end),
100-
_buildTerminalKey('PGUP', TerminalKey.pageUp),
101-
_buildTerminalKey('PGDN', TerminalKey.pageDown),
102-
_buildTerminalKey('DEL', TerminalKey.delete),
103-
_buildVerticalDivider(),
77+
_buildTerminalKey('ESC', TerminalKey.escape),
78+
_buildTerminalKey('TAB', TerminalKey.tab),
79+
_buildTerminalKey('↑', TerminalKey.arrowUp),
80+
_buildTerminalKey('↓', TerminalKey.arrowDown),
81+
_buildTerminalKey('←', TerminalKey.arrowLeft),
82+
_buildTerminalKey('→', TerminalKey.arrowRight),
83+
_buildVerticalDivider(),
10484

105-
_buildTerminalKey('F1', TerminalKey.f1),
106-
_buildTerminalKey('F2', TerminalKey.f2),
107-
_buildTerminalKey('F3', TerminalKey.f3),
108-
_buildTerminalKey('F4', TerminalKey.f4),
109-
_buildTerminalKey('F5', TerminalKey.f5),
110-
_buildTerminalKey('F6', TerminalKey.f6),
111-
_buildTerminalKey('F7', TerminalKey.f7),
112-
_buildTerminalKey('F8', TerminalKey.f8),
113-
_buildTerminalKey('F9', TerminalKey.f9),
114-
_buildTerminalKey('F10', TerminalKey.f10),
115-
_buildVerticalDivider(),
85+
_buildTerminalKey('HOME', TerminalKey.home),
86+
_buildTerminalKey('END', TerminalKey.end),
87+
_buildTerminalKey('PGUP', TerminalKey.pageUp),
88+
_buildTerminalKey('PGDN', TerminalKey.pageDown),
89+
_buildTerminalKey('DEL', TerminalKey.delete),
90+
_buildVerticalDivider(),
11691

117-
..._snippets.map((snippet) => _buildSnippetKey(snippet)),
92+
_buildTerminalKey('F1', TerminalKey.f1),
93+
_buildTerminalKey('F2', TerminalKey.f2),
94+
_buildTerminalKey('F3', TerminalKey.f3),
95+
_buildTerminalKey('F4', TerminalKey.f4),
96+
_buildTerminalKey('F5', TerminalKey.f5),
97+
_buildTerminalKey('F6', TerminalKey.f6),
98+
_buildTerminalKey('F7', TerminalKey.f7),
99+
_buildTerminalKey('F8', TerminalKey.f8),
100+
_buildTerminalKey('F9', TerminalKey.f9),
101+
_buildTerminalKey('F10', TerminalKey.f10),
102+
_buildVerticalDivider(),
118103

119-
Padding(
120-
padding: const EdgeInsets.only(left: 4.0, right: 16.0),
121-
child: TextButton(
122-
style: TextButton.styleFrom(
123-
backgroundColor: theme.primaryColor.withOpacity(0.15),
124-
minimumSize: const Size(40, 35),
125-
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
126-
),
127-
onPressed: _showAddSnippetDialog,
128-
child: Icon(Icons.add, color: theme.primaryColor, size: 18),
104+
..._snippets.map((snippet) => _buildSnippetKey(snippet)),
105+
106+
Padding(
107+
padding: const EdgeInsets.only(left: 4.0, right: 16.0),
108+
child: TextButton(
109+
focusNode: FocusNode(canRequestFocus: false),
110+
style: TextButton.styleFrom(
111+
backgroundColor: theme.primaryColor.withOpacity(0.15),
112+
minimumSize: const Size(40, 35),
113+
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
129114
),
115+
onPressed: _showAddSnippetDialog,
116+
child: Icon(Icons.add, color: theme.primaryColor, size: 18),
130117
),
131-
],
132-
),
118+
),
119+
],
120+
);
121+
}
122+
123+
Widget _buildCtrlActiveRow() {
124+
return ListView(
125+
scrollDirection: Axis.horizontal,
126+
padding: const EdgeInsets.symmetric(horizontal: 4),
127+
children: [
128+
_buildToggleKey('CANCEL', true, () => setState(() => _isCtrlActive = false), isCancel: true),
129+
_buildVerticalDivider(),
130+
131+
_buildActionKey('C', 'SIGINT', () => _sendCtrlByte('C')),
132+
_buildActionKey('D', 'EOF', () => _sendCtrlByte('D')),
133+
_buildActionKey('Z', 'SUSPEND', () => _sendCtrlByte('Z')),
134+
_buildActionKey('L', 'CLEAR', () => _sendCtrlByte('L')),
135+
_buildActionKey('A', 'HOME', () => _sendCtrlByte('A')),
136+
_buildActionKey('E', 'END', () => _sendCtrlByte('E')),
137+
_buildActionKey('W', 'DEL WORD', () => _sendCtrlByte('W')),
138+
_buildActionKey('U', 'DEL LINE', () => _sendCtrlByte('U')),
139+
],
133140
);
134141
}
135142

@@ -141,13 +148,16 @@ class _TerminalKeyboardState extends State<TerminalKeyboard> {
141148
);
142149
}
143150

144-
Widget _buildToggleKey(String label, bool isActive, VoidCallback onPressed) {
151+
Widget _buildToggleKey(String label, bool isActive, VoidCallback onPressed, {bool isCancel = false}) {
145152
final theme = Theme.of(context);
153+
final bgColor = isCancel ? Colors.red.withOpacity(0.8) : (isActive ? theme.primaryColor : theme.dividerColor.withOpacity(0.5));
154+
146155
return Padding(
147156
padding: const EdgeInsets.symmetric(horizontal: 2, vertical: 6),
148157
child: TextButton(
158+
focusNode: FocusNode(canRequestFocus: false),
149159
style: TextButton.styleFrom(
150-
backgroundColor: isActive ? theme.primaryColor : theme.dividerColor.withOpacity(0.5),
160+
backgroundColor: bgColor,
151161
minimumSize: const Size(45, 35),
152162
padding: const EdgeInsets.symmetric(horizontal: 8),
153163
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(6)),
@@ -156,7 +166,7 @@ class _TerminalKeyboardState extends State<TerminalKeyboard> {
156166
child: Text(
157167
label,
158168
style: TextStyle(
159-
color: isActive ? theme.colorScheme.surface : theme.textTheme.bodyMedium?.color,
169+
color: isActive || isCancel ? theme.colorScheme.surface : theme.textTheme.bodyMedium?.color,
160170
fontWeight: FontWeight.bold,
161171
fontSize: 12
162172
),
@@ -169,6 +179,7 @@ class _TerminalKeyboardState extends State<TerminalKeyboard> {
169179
return Padding(
170180
padding: const EdgeInsets.symmetric(horizontal: 2, vertical: 6),
171181
child: TextButton(
182+
focusNode: FocusNode(canRequestFocus: false),
172183
style: TextButton.styleFrom(
173184
backgroundColor: Colors.transparent,
174185
minimumSize: const Size(45, 35),
@@ -187,32 +198,64 @@ class _TerminalKeyboardState extends State<TerminalKeyboard> {
187198
);
188199
}
189200

190-
Widget _buildSnippetKey(Snippet snippet) {
201+
Widget _buildActionKey(String letter, String subtitle, VoidCallback onPressed) {
191202
final theme = Theme.of(context);
192203
return Padding(
193204
padding: const EdgeInsets.symmetric(horizontal: 3, vertical: 6),
194-
child: InkWell(
195-
onLongPress: () => _confirmDeleteSnippet(snippet),
196-
child: TextButton(
197-
style: TextButton.styleFrom(
198-
backgroundColor: theme.primaryColor.withOpacity(0.1),
199-
minimumSize: const Size(60, 35),
200-
padding: const EdgeInsets.symmetric(horizontal: 12),
201-
shape: RoundedRectangleBorder(
202-
borderRadius: BorderRadius.circular(6),
203-
side: BorderSide(color: theme.primaryColor.withOpacity(0.3)),
204-
),
205+
child: TextButton(
206+
focusNode: FocusNode(canRequestFocus: false),
207+
style: TextButton.styleFrom(
208+
backgroundColor: theme.primaryColor.withOpacity(0.1),
209+
minimumSize: const Size(55, 35),
210+
padding: const EdgeInsets.symmetric(horizontal: 8),
211+
shape: RoundedRectangleBorder(
212+
borderRadius: BorderRadius.circular(6),
213+
side: BorderSide(color: theme.primaryColor.withOpacity(0.5)),
205214
),
206-
onPressed: () {
207-
String toSend = snippet.command;
208-
if (snippet.autoEnter && !_isCtrlActive) toSend += '\r';
209-
_sendText(toSend);
210-
},
211-
child: Text(
212-
snippet.label,
213-
style: TextStyle(color: theme.primaryColor, fontWeight: FontWeight.bold, fontSize: 12),
215+
),
216+
onPressed: onPressed,
217+
child: Column(
218+
mainAxisAlignment: MainAxisAlignment.center,
219+
children: [
220+
Text(
221+
letter,
222+
style: TextStyle(color: theme.primaryColor, fontWeight: FontWeight.bold, fontSize: 14, height: 1.0),
223+
),
224+
Text(
225+
subtitle,
226+
style: const TextStyle(color: Colors.grey, fontSize: 8, height: 1.0),
227+
),
228+
],
229+
),
230+
),
231+
);
232+
}
233+
234+
Widget _buildSnippetKey(Snippet snippet) {
235+
final theme = Theme.of(context);
236+
return Padding(
237+
padding: const EdgeInsets.symmetric(horizontal: 3, vertical: 6),
238+
child: TextButton(
239+
focusNode: FocusNode(canRequestFocus: false),
240+
style: TextButton.styleFrom(
241+
backgroundColor: theme.primaryColor.withOpacity(0.1),
242+
minimumSize: const Size(60, 35),
243+
padding: const EdgeInsets.symmetric(horizontal: 12),
244+
shape: RoundedRectangleBorder(
245+
borderRadius: BorderRadius.circular(6),
246+
side: BorderSide(color: theme.primaryColor.withOpacity(0.3)),
214247
),
215248
),
249+
onPressed: () {
250+
String toSend = snippet.command;
251+
if (snippet.autoEnter) toSend += '\r';
252+
_sendText(toSend);
253+
},
254+
onLongPress: () => _confirmDeleteSnippet(snippet),
255+
child: Text(
256+
snippet.label,
257+
style: TextStyle(color: theme.primaryColor, fontWeight: FontWeight.bold, fontSize: 12),
258+
),
216259
),
217260
);
218261
}

0 commit comments

Comments
 (0)