CH-J SM MobileSerververwaltung über SSH
Menü
Veröffentlichte Quellen

CH-J SM Mobile

Durchsuchen Sie Verzeichnisse und Dateien einer bestimmten Anwendungsausgabe.

Quellen als ZIP herunterladen
CH-J / SM Mobile 175 Dateien
sm-mobile-20261016T185235Z-8e93ecc1b59a Hinzugefügt: · Erstellt:
password_fields.dart Hinzugefügt: Datum nicht erfasst 3.9 KB · 119 Zeilen
Code Datei herunterladen
1import 'package:flutter/material.dart';
2import '../l10n/strings.dart';
3import '../services/vault.dart';
5/// A password field with a show/hide toggle. Nothing is trimmed, and any
6/// keyboard may be used (a numeric PIN is just a short password).
7class PasswordField extends StatefulWidget {
8 final TextEditingController controller;
9 final String label;
10 final bool autofocus;
11 final ValueChanged<String>? onSubmitted;
12 final ValueChanged<String>? onChanged;
13 final TextInputAction? action;
14 const PasswordField({
15 required this.controller,
16 required this.label,
17 this.autofocus = false,
18 this.onSubmitted,
19 this.onChanged,
20 this.action,
21 super.key,
22 });
23 @override
24 State<PasswordField> createState() => _PasswordFieldState();
27class _PasswordFieldState extends State<PasswordField> {
28 bool visible = false;
29 @override
30 Widget build(BuildContext context) => TextField(
31 controller: widget.controller,
32 obscureText: !visible,
33 enableSuggestions: false,
34 autocorrect: false,
35 autofocus: widget.autofocus,
36 keyboardType: visible ? TextInputType.visiblePassword : TextInputType.text,
37 textInputAction: widget.action,
38 onSubmitted: widget.onSubmitted,
39 onChanged: widget.onChanged,
40 decoration: InputDecoration(
41 labelText: widget.label,
42 suffixIcon: IconButton(
43 tooltip: context.tr(visible ? 'hidePassword' : 'showPassword'),
44 icon: Icon(visible ? Icons.visibility_off : Icons.visibility),
45 onPressed: () => setState(() => visible = !visible),
46 ),
47 ),
48 );
51/// Length counter, strength meter and short-password advice for a new
52/// master password.
53class PasswordAdvice extends StatelessWidget {
54 final String password;
55 const PasswordAdvice(this.password, {super.key});
56 @override
57 Widget build(BuildContext context) {
58 final scheme = Theme.of(context).colorScheme;
59 final n = passwordLength(password);
60 final strength = passwordStrength(password);
61 final inRange = n >= minPasswordLength && n <= maxPasswordLength;
62 final colors = [
63 scheme.error,
64 Colors.deepOrange,
65 Colors.amber.shade700,
66 Colors.lightGreen.shade700,
67 Colors.green.shade700,
68 ];
69 final muted = TextStyle(color: scheme.onSurfaceVariant, fontSize: 12);
70 return Column(
71 crossAxisAlignment: CrossAxisAlignment.stretch,
72 children: [
73 Row(
74 children: [
75 Expanded(
76 child: Semantics(
77 label: context.tr('passwordStrength'),
78 value: context.tr('strength$strength'),
79 child: ClipRRect(
80 borderRadius: BorderRadius.circular(4),
81 child: LinearProgressIndicator(
82 value: n == 0 ? 0 : (strength + 1) / 5,
83 minHeight: 6,
84 color: colors[strength],
85 backgroundColor: scheme.surfaceContainerHighest,
86 ),
87 ),
88 ),
89 ),
90 const SizedBox(width: 12),
91 Text(
92 '$n / $maxPasswordLength',
93 style: muted.copyWith(
94 color: n > maxPasswordLength ? scheme.error : null,
95 fontFeatures: const [FontFeature.tabularFigures()],
96 ),
97 ),
98 ],
99 ),
100 const SizedBox(height: 4),
101 Text(
102 n == 0
103 ? context.tr('passwordLength')
104 : '${context.tr('passwordStrength')}: '
105 '${context.tr('strength$strength')}'
106 '${inRange ? '' : ' · ${context.tr('passwordLength')}'}',
107 style: muted.copyWith(color: inRange || n == 0 ? null : scheme.error),
108 ),
109 if (inRange && n < 12) ...[
110 const SizedBox(height: 4),
111 Text(
112 context.tr('shortPasswordWarning'),
113 style: muted.copyWith(color: Colors.deepOrange),
114 ),
115 ],
116 ],
117 );
118 }
SHA-256150cdb6dde6e8e485dbbfb6b7f766c4007944c8e17fd82c6a37fea987fce169b

CH-J Proprietary Software License 1.14 · Die Quellen werden unter der CH-J Proprietary Software License 1.14 bereitgestellt. Ihre Verfügbarkeit ändert die Lizenzbedingungen nicht und gewährt keine zusätzlichen Rechte.

SHA-256 des Archivs46e427a43e87af091004f36145590bda8fe90086dfb0f631afeb5029fb0b5655
Dateien