mirror of
https://github.com/immich-app/immich
synced 2026-08-15 13:03:57 +00:00
fix(mobile): disable iOS smart quotes/dashes in email/password inputs (#30767)
* fix(mobile): disable iOS smart quotes/dashes in email/password inputs * Remove enum prefixes
This commit is contained in:
parent
652ef8a427
commit
190a939af7
7 changed files with 95 additions and 3 deletions
|
|
@ -132,6 +132,8 @@ class HeaderKeyValueSettings extends StatelessWidget {
|
|||
border: const OutlineInputBorder(),
|
||||
),
|
||||
autocorrect: false,
|
||||
smartDashesType: .disabled,
|
||||
smartQuotesType: .disabled,
|
||||
onChanged: (headerKey) {
|
||||
header.key = headerKey;
|
||||
},
|
||||
|
|
@ -160,6 +162,8 @@ class HeaderKeyValueSettings extends StatelessWidget {
|
|||
border: const OutlineInputBorder(),
|
||||
),
|
||||
autocorrect: false,
|
||||
smartDashesType: .disabled,
|
||||
smartQuotesType: .disabled,
|
||||
onChanged: (headerValue) {
|
||||
header.value = headerValue;
|
||||
},
|
||||
|
|
|
|||
|
|
@ -493,14 +493,12 @@ class LoginForm extends HookConsumerWidget {
|
|||
builder: (context, form) => Column(
|
||||
spacing: ImmichSpacing.md,
|
||||
children: [
|
||||
ImmichTextInput(
|
||||
ImmichEmailInput(
|
||||
controller: emailController,
|
||||
label: context.t.email,
|
||||
hintText: context.t.login_form_email_hint,
|
||||
validator: _validateEmail,
|
||||
keyboardAction: TextInputAction.next,
|
||||
keyboardType: TextInputType.emailAddress,
|
||||
autofillHints: const [AutofillHints.email],
|
||||
onSubmit: (_) => passwordFocusNode.requestFocus(),
|
||||
),
|
||||
ImmichPasswordInput(
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
export 'src/color_override.dart';
|
||||
export 'src/components/close_button.dart';
|
||||
export 'src/components/column_button.dart';
|
||||
export 'src/components/email_input.dart';
|
||||
export 'src/components/form.dart';
|
||||
export 'src/components/formatted_text.dart';
|
||||
export 'src/components/icon_button.dart';
|
||||
|
|
|
|||
26
mobile/packages/ui/lib/src/components/email_input.dart
Normal file
26
mobile/packages/ui/lib/src/components/email_input.dart
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import 'package:flutter/services.dart';
|
||||
import 'package:immich_ui/src/components/text_input.dart';
|
||||
|
||||
/// An ImmichTextInput customized for receiving email addresses
|
||||
class ImmichEmailInput extends ImmichTextInput {
|
||||
const ImmichEmailInput({
|
||||
super.key,
|
||||
super.controller,
|
||||
super.focusNode,
|
||||
super.label,
|
||||
super.hintText,
|
||||
super.validator,
|
||||
super.onSubmit,
|
||||
super.keyboardAction,
|
||||
super.suffixIcon,
|
||||
super.enabled,
|
||||
super.autofocus,
|
||||
super.autovalidateMode,
|
||||
}) : super(
|
||||
keyboardType: .emailAddress,
|
||||
autofillHints: const [AutofillHints.email],
|
||||
autocorrect: false,
|
||||
smartDashesType: .disabled,
|
||||
smartQuotesType: .disabled,
|
||||
);
|
||||
}
|
||||
|
|
@ -47,6 +47,9 @@ class _ImmichPasswordInputState extends State<ImmichPasswordInput> {
|
|||
onSubmit: widget.onSubmit,
|
||||
keyboardAction: widget.keyboardAction,
|
||||
obscureText: !_visible,
|
||||
autocorrect: false,
|
||||
smartDashesType: .disabled,
|
||||
smartQuotesType: .disabled,
|
||||
suffixIcon: IconButton(
|
||||
onPressed: _toggleVisibility,
|
||||
icon: Icon(_visible ? Icons.visibility_off_rounded : Icons.visibility_rounded),
|
||||
|
|
|
|||
28
mobile/packages/ui/lib/src/previews/email_input.dart
Normal file
28
mobile/packages/ui/lib/src/previews/email_input.dart
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:immich_ui/src/components/email_input.dart';
|
||||
import 'package:immich_ui/src/previews.dart';
|
||||
|
||||
@ImmichPreview(group: 'EmailInput', name: 'Basic')
|
||||
Widget previewEmailInput() => const _PreviewEmailInput();
|
||||
|
||||
class _PreviewEmailInput extends StatefulWidget {
|
||||
const _PreviewEmailInput();
|
||||
|
||||
@override
|
||||
State<_PreviewEmailInput> createState() => _PreviewEmailInputState();
|
||||
}
|
||||
|
||||
class _PreviewEmailInputState extends State<_PreviewEmailInput> {
|
||||
final _controller = TextEditingController();
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_controller.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ImmichEmailInput(label: 'Email', hintText: 'user@immich.app', controller: _controller);
|
||||
}
|
||||
}
|
||||
32
mobile/packages/ui/test/smart_punctuation_test.dart
Normal file
32
mobile/packages/ui/test/smart_punctuation_test.dart
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:immich_ui/src/components/email_input.dart';
|
||||
import 'package:immich_ui/src/components/password_input.dart';
|
||||
|
||||
import 'test_utils.dart';
|
||||
|
||||
void main() {
|
||||
EditableText editable(WidgetTester tester) => tester.widget<EditableText>(find.byType(EditableText));
|
||||
|
||||
testWidgets('ImmichEmailInput disables smart punctuation', (tester) async {
|
||||
await tester.pumpTestWidget(const ImmichEmailInput());
|
||||
|
||||
expect(editable(tester).smartDashesType, SmartDashesType.disabled);
|
||||
expect(editable(tester).smartQuotesType, SmartQuotesType.disabled);
|
||||
});
|
||||
|
||||
testWidgets('ImmichPasswordInput disables smart punctuation', (tester) async {
|
||||
await tester.pumpTestWidget(const ImmichPasswordInput());
|
||||
|
||||
expect(editable(tester).obscureText, isTrue);
|
||||
expect(editable(tester).smartDashesType, SmartDashesType.disabled);
|
||||
expect(editable(tester).smartQuotesType, SmartQuotesType.disabled);
|
||||
|
||||
await tester.tap(find.byIcon(Icons.visibility_rounded));
|
||||
await tester.pump();
|
||||
|
||||
expect(editable(tester).obscureText, isFalse);
|
||||
expect(editable(tester).smartDashesType, SmartDashesType.disabled);
|
||||
expect(editable(tester).smartQuotesType, SmartQuotesType.disabled);
|
||||
});
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue