Skip to content

Commit

Permalink
TW-2046 Added name validation in group modification
Browse files Browse the repository at this point in the history
  • Loading branch information
KhaledNjim committed Nov 14, 2024
1 parent 356e2a5 commit 5f610de
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 52 deletions.
5 changes: 5 additions & 0 deletions lib/di/global/get_it_initializer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ import 'package:fluffychat/domain/usecase/search/search_recent_chat_interactor.d
import 'package:fluffychat/domain/usecase/search/server_search_interactor.dart';
import 'package:fluffychat/domain/usecase/settings/save_language_interactor.dart';
import 'package:fluffychat/domain/usecase/settings/update_profile_interactor.dart';
import 'package:fluffychat/domain/usecase/verify_name_interactor.dart';
import 'package:fluffychat/event/twake_event_dispatcher.dart';
import 'package:fluffychat/pages/chat/chat_pinned_events/pinned_events_controller.dart';
import 'package:fluffychat/utils/famedlysdk_store.dart';
Expand Down Expand Up @@ -344,6 +345,10 @@ class GetItInitializer {
getIt.registerSingleton<DownloadMediaFileInteractor>(
DownloadMediaFileInteractor(),
);

getIt.registerFactory<VerifyNameInteractor>(
() => VerifyNameInteractor(),
);
}

void _bindingControllers() {
Expand Down
23 changes: 22 additions & 1 deletion lib/pages/chat_details/chat_details_edit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,13 @@ import 'package:fluffychat/di/global/get_it_initializer.dart';
import 'package:fluffychat/domain/app_state/room/update_group_chat_failure.dart';
import 'package:fluffychat/domain/app_state/room/update_group_chat_success.dart';
import 'package:fluffychat/domain/app_state/room/upload_content_state.dart';
import 'package:fluffychat/domain/app_state/validator/verify_name_view_state.dart';
import 'package:fluffychat/domain/model/extensions/validator_failure_extension.dart';
import 'package:fluffychat/domain/model/verification/name_with_space_only_validator.dart';
import 'package:fluffychat/domain/usecase/room/update_group_chat_interactor.dart';
import 'package:fluffychat/domain/usecase/room/upload_content_for_web_interactor.dart';
import 'package:fluffychat/domain/usecase/room/upload_content_interactor.dart';
import 'package:fluffychat/domain/usecase/verify_name_interactor.dart';
import 'package:fluffychat/pages/chat_details/chat_details_edit_context_menu_actions.dart';
import 'package:fluffychat/pages/chat_details/chat_details_edit_view.dart';
import 'package:fluffychat/pages/chat_details/chat_details_edit_view_style.dart';
Expand Down Expand Up @@ -54,6 +58,7 @@ class ChatDetailsEditController extends State<ChatDetailsEdit>
final uploadContentInteractor = getIt.get<UploadContentInteractor>();
final uploadContentWebInteractor =
getIt.get<UploadContentInBytesInteractor>();
final verifyNameInteractor = getIt.get<VerifyNameInteractor>();

Room? room;

Expand All @@ -73,6 +78,7 @@ class ChatDetailsEditController extends State<ChatDetailsEdit>
final MenuController menuController = MenuController();

final isEditedGroupInfoNotifier = ValueNotifier<bool>(false);
final isValidGroupNameNotifier = ValueNotifier<bool>(false);

Client get client => Matrix.of(context).client;

Expand Down Expand Up @@ -443,6 +449,20 @@ class ChatDetailsEditController extends State<ChatDetailsEdit>
avatarAssetEntity = null;
}

String? getErrorMessage(String content) {
return verifyNameInteractor
.execute(content, [NameWithSpaceOnlyValidator()]).fold(
(failure) {
if (failure is VerifyNameFailure) {
return failure.getMessage(context);
} else {
return null;
}
},
(success) => null,
);
}

@override
void dispose() {
_clearImageInMemory();
Expand All @@ -463,11 +483,12 @@ class ChatDetailsEditController extends State<ChatDetailsEdit>
if (_isEditAvatar) {
return;
}

isEditedGroupInfoNotifier.value =
groupNameTextEditingController.text != room?.name;
groupNameEmptyNotifier.value =
groupNameTextEditingController.text.isEmpty;
isValidGroupNameNotifier.value =
getErrorMessage(groupNameTextEditingController.text) == null;
});
}

Expand Down
113 changes: 63 additions & 50 deletions lib/pages/chat_details/chat_details_edit_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -67,23 +67,28 @@ class ChatDetailsEditView extends StatelessWidget {
),
const Spacer(),
ValueListenableBuilder(
valueListenable: controller.isEditedGroupInfoNotifier,
builder: (context, value, child) {
if (!value) {
return const SizedBox.shrink();
}
return child!;
valueListenable: controller.isValidGroupNameNotifier,
builder: (context, isValid, child) {
return ValueListenableBuilder(
valueListenable: controller.isEditedGroupInfoNotifier,
builder: (context, value, child) {
if (!value || !isValid) {
return const SizedBox.shrink();
}
return child!;
},
child: Padding(
padding: ChatDetailEditViewStyle.doneIconPadding,
child: IconButton(
highlightColor: Colors.transparent,
hoverColor: Colors.transparent,
splashColor: Colors.transparent,
onPressed: () => controller.handleSaveAction(context),
icon: const Icon(Icons.done),
),
),
);
},
child: Padding(
padding: ChatDetailEditViewStyle.doneIconPadding,
child: IconButton(
highlightColor: Colors.transparent,
hoverColor: Colors.transparent,
splashColor: Colors.transparent,
onPressed: () => controller.handleSaveAction(context),
icon: const Icon(Icons.done),
),
),
),
],
),
Expand Down Expand Up @@ -323,40 +328,48 @@ class _GroupNameField extends StatelessWidget {
Widget build(BuildContext context) {
return Padding(
padding: ChatDetailEditViewStyle.textFieldPadding,
child: TextField(
style: ChatDetailEditViewStyle.textFieldStyle(context),
controller: controller.groupNameTextEditingController,
contextMenuBuilder: mobileTwakeContextMenuBuilder,
focusNode: controller.groupNameFocusNode,
decoration: InputDecoration(
border: OutlineInputBorder(
borderSide: BorderSide(color: Theme.of(context).colorScheme.shadow),
),
labelText: L10n.of(context)!.widgetName,
labelStyle: ChatDetailEditViewStyle.textFieldLabelStyle(context),
hintText: L10n.of(context)!.enterGroupName,
hintStyle: ChatDetailEditViewStyle.textFieldHintStyle(context),
contentPadding: ChatDetailEditViewStyle.contentPadding,
suffixIcon: ValueListenableBuilder<bool>(
valueListenable: controller.groupNameEmptyNotifier,
builder: (context, isGroupNameEmpty, child) {
if (isGroupNameEmpty) {
return child!;
}

return IconButton(
onPressed: () =>
controller.groupNameTextEditingController.clear(),
icon: Icon(
Icons.cancel_outlined,
size: ChatDetailEditViewStyle.clearIconSize,
color: Theme.of(context).colorScheme.onSurfaceVariant,
),
);
},
child: const SizedBox.shrink(),
),
),
child: ValueListenableBuilder(
valueListenable: controller.isValidGroupNameNotifier,
builder: (context, value, _) {
return TextField(
style: ChatDetailEditViewStyle.textFieldStyle(context),
controller: controller.groupNameTextEditingController,
contextMenuBuilder: mobileTwakeContextMenuBuilder,
focusNode: controller.groupNameFocusNode,
decoration: InputDecoration(
border: OutlineInputBorder(
borderSide:
BorderSide(color: Theme.of(context).colorScheme.shadow),
),
labelText: L10n.of(context)!.widgetName,
labelStyle: ChatDetailEditViewStyle.textFieldLabelStyle(context),
hintText: L10n.of(context)!.enterGroupName,
hintStyle: ChatDetailEditViewStyle.textFieldHintStyle(context),
contentPadding: ChatDetailEditViewStyle.contentPadding,
errorText: controller.getErrorMessage(
controller.groupNameTextEditingController.text,
),
suffixIcon: ValueListenableBuilder<bool>(
valueListenable: controller.groupNameEmptyNotifier,
builder: (context, isGroupNameEmpty, child) {
if (isGroupNameEmpty) {
return child!;
}
return IconButton(
onPressed: () =>
controller.groupNameTextEditingController.clear(),
icon: Icon(
Icons.cancel_outlined,
size: ChatDetailEditViewStyle.clearIconSize,
color: Theme.of(context).colorScheme.onSurfaceVariant,
),
);
},
child: const SizedBox.shrink(),
),
),
);
},
),
);
}
Expand Down
2 changes: 1 addition & 1 deletion lib/pages/new_group/new_group_chat_info.dart
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class NewGroupChatInfoController extends State<NewGroupChatInfo>
final groupNameTextEditingController = TextEditingController();
final avatarAssetEntityNotifier = ValueNotifier<AssetEntity?>(null);
final avatarFilePickerNotifier = ValueNotifier<MatrixFile?>(null);
VerifyNameInteractor verifyNameInteractor = VerifyNameInteractor();
VerifyNameInteractor verifyNameInteractor = getIt.get<VerifyNameInteractor>();

final groupNameFocusNode = FocusNode();
StreamSubscription? createNewGroupChatInteractorStreamSubscription;
Expand Down

0 comments on commit 5f610de

Please sign in to comment.