How to implement user mentions in messages on Flutter?

1,877

try this one

UserTextfield class

class UserTextfield extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return BlocProvider(
      create: (context) => UserBloc(UrlUserRepository()),
      child: UserTextfieldPage(),
    );
  }
}

class UserTextfieldPage extends StatefulWidget {
  @override
  _UserTextfieldPageState createState() => _UserTextfieldPageState();
}

class _UserTextfieldPageState extends State<UserTextfieldPage> {
  bool _visibility = false;

  @override
  Widget build(BuildContext context) {

    return BlocBuilder<UserBloc, UserState>(
      builder: (context, state) {
        return Column(
          children: <Widget>[
            TextField(
              onChanged: (value) {
                final _tagRegex =
                    RegExp(r"\B@\w*[a-zA-Z]+\w*", caseSensitive: false);
                final sentences = value.split('\n');
                sentences.forEach(
                  (sentence) {
                    final words = sentence.split(' ');
                    String withat = words.last;
                    if (_tagRegex.hasMatch(withat)) {
                      String withoutat = withay.substring(1);
                      BlocProvider.of<UserBloc>(context).add(
                        Searchuser(searchtext: withoutat),
                      );
                      setState(() {
                        _visibility = true;
                      });
                    } else {
                      setState(() {
                        _visibility = false;
                      });
                    }
                  },
                );
              },
            ),
            _listviewWidget(state),
          ],
        );
      },
    );
  }

  Widget _listviewWidget(UserState state) {
    if (state is UserLoading) {
      return Center(
        child: CircularProgressIndicator(
          valueColor: new AlwaysStoppedAnimation<Color>(Colors.black),
        ),
      );
    } else if (state is UserLoaded) {
      return Expanded(
        child: Visibility(
          visible: _visibility,
          maintainSize: true,
          maintainAnimation: true,
          maintainState: true,
          child: ListView.builder(
            itemCount: state.userModel.userResult.length,
            itemBuilder: (context, index) {
              var listitem = state.userModel.userResult[index];
              return ListTile(
                title: Text(listitem.topic),
              );
            },
          ),
        ),
      );
    } else if (state is UserError) {
      return Align(
        alignment: Alignment.topCenter,
        child: Padding(
          padding: const EdgeInsets.all(8.0),
          child: Text(state.message),
        ),
      );
    } else {
      return Container();
    }
  }
}

UserBloc class

import 'dart:async';
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:your project file location/user_model.dart';
import 'package:your project file location/user_repository.dart';

part 'user_event.dart';
part 'user_state.dart';

class UserBloc extends Bloc<UserEvent, UserState> {
  final UserRepository userRepository;

  UserBloc(this.userRepository)
      : assert(userRepository != null),
        super(UserInitial());

  @override
  Stream<UserState> mapEventToState(
    UserEvent event,
  ) async* {
    if (event is Searchuser) {
      yield UserLoading();
      try {
        final userModel = await userRepository.getuser(event.searchtext);
        yield UserLoaded(userModel);
      } catch (_) {
        yield UserError(message: 'Something went to wrong');
      }
    }
  }
}

UserEvent class

part of 'User_bloc.dart';

abstract class UserEvent extends Equatable{
  const UserEvent();
}

class Searchuser extends UserEvent {
  final String searchtext;

  const Searchuser({this.searchtext});

  List<Object> get props => [searchtext];

  @override
  String toString() =>
      'Searchuser { searchtext: $searchtext }';
}

UserState class

part of 'user_bloc.dart';

abstract class UserState extends Equatable {
  const UserState();
}

class UserInitial extends UserState {
  @override
  List<Object> get props => [];
}

class UserLoading extends UserState {
  const UserLoading();

  @override
  List<Object> get props => [];
}

class UserLoaded extends UserState {
  final UserModel userModel;

  const UserLoaded(this.userModel);

  @override
  List<Object> get props => [userModel];
}

class UserError extends UserState {
  final String message;

  const UserError({this.message});

  @override
  List<Object> get props => [message];

  @override
  String toString() => 'UserError { message: $message }';
}

UserModel class

import 'package:equatable/equatable.dart';

class UserModel extends Equatable{
  final bool error;
  final List<UserResult> userResult;

  UserModel({this.error, this.userResult});

  factory UserModel.fromJson(Map<String, dynamic> json) {
    var resultList = json['data'] as List;

    List<UserResult> userResult =
        resultList.map((i) => UserResult.fromJson(i)).toList();

    return UserModel(
      error: json['error'],
      userResult: userResult,
    );
  }

  @override
  List<Object> get props => [error, userResult];
}

class UserResult extends Equatable {
  final String name;

  UserResult({this.name});

  factory UserResult.fromJson(Map<String, dynamic> json) {
    return UserResult(
      name: json["name"],
    );
  }
  @override
  List<Object> get props => [name];
  }

UserRepository class

import 'dart:async';
import 'dart:convert';

import 'package:http/http.dart' as http;
import 'package:your project file location/user_model.dart';

abstract class UserRepository {
  Future<UserModel> getuser(String searchtext);
}

class UrlUserRepository implements UserRepository {
  @override
  Future<UserModel> getuser(String searchtext) async {
    Map<String, dynamic> stringParams = {'searchtext': searchtext};

    var uriResponse = await http.post(your api, body: stringParams);

    if (uriResponse.statusCode == 200) {
      final String res = uriResponse.body;
      var resdata = json.decode(res);
      return UserModel.fromJson(resdata);
    } else {
      throw Exception('please, try again!');
    }
  }
}

json data

{
    "data": [
        {
            "name": "bharat"
        },
        {
            "name": "india"
        },
        {
            "name": "abbcc"
        },
        {
            "name": "abc"
        },
        {
            "name": "user"
        },
        {
            "name": "user1"
        },
        {
            "name": "user2"
        },
        {
            "name": "user3"
        },
        {
            "name": "user4"
        }
    ],
    "error": false,
    "message": "user feteched"
}
Share:
1,877
Ruslan Kryzhanovskiy
Author by

Ruslan Kryzhanovskiy

Updated on December 13, 2022

Comments

  • Ruslan Kryzhanovskiy
    Ruslan Kryzhanovskiy over 1 year

    I need to implement user mentions in the message as in popular messengers on Flutter. It’s necessary that when I click on a certain button in the input field a widget appears with the name and image of the user whom I mentioned.

    I tried extended_text_field but it is buggy