mirror of
				https://gitlab.com/famedly/fluffychat.git
				synced 2025-11-03 22:07:23 +01:00 
			
		
		
		
	refactor: New private chat view
This commit is contained in:
		
							parent
							
								
									001e0ee48f
								
							
						
					
					
						commit
						453d4f3423
					
				@ -16,7 +16,7 @@ import 'package:fluffychat/views/loading_view.dart';
 | 
			
		||||
import 'package:fluffychat/views/log_view.dart';
 | 
			
		||||
import 'package:fluffychat/views/login.dart';
 | 
			
		||||
import 'package:fluffychat/controllers/new_group_controller.dart';
 | 
			
		||||
import 'package:fluffychat/views/new_private_chat.dart';
 | 
			
		||||
import 'package:fluffychat/controllers/new_private_chat_controller.dart';
 | 
			
		||||
import 'package:fluffychat/views/search_view.dart';
 | 
			
		||||
import 'package:fluffychat/views/settings.dart';
 | 
			
		||||
import 'package:fluffychat/views/settings_3pid.dart';
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										116
									
								
								lib/controllers/new_private_chat_controller.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								lib/controllers/new_private_chat_controller.dart
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,116 @@
 | 
			
		||||
import 'dart:async';
 | 
			
		||||
 | 
			
		||||
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
 | 
			
		||||
import 'package:famedlysdk/famedlysdk.dart';
 | 
			
		||||
import 'package:fluffychat/utils/fluffy_share.dart';
 | 
			
		||||
import 'package:fluffychat/views/new_private_chat_view.dart';
 | 
			
		||||
import 'package:future_loading_dialog/future_loading_dialog.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/matrix.dart';
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
 | 
			
		||||
 | 
			
		||||
class NewPrivateChat extends StatefulWidget {
 | 
			
		||||
  @override
 | 
			
		||||
  NewPrivateChatController createState() => NewPrivateChatController();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class NewPrivateChatController extends State<NewPrivateChat> {
 | 
			
		||||
  TextEditingController controller = TextEditingController();
 | 
			
		||||
  final formKey = GlobalKey<FormState>();
 | 
			
		||||
  bool loading = false;
 | 
			
		||||
  String currentSearchTerm;
 | 
			
		||||
  List<Profile> foundProfiles = [];
 | 
			
		||||
  Timer coolDown;
 | 
			
		||||
  Profile get foundProfile =>
 | 
			
		||||
      foundProfiles.firstWhere((user) => user.userId == '@$currentSearchTerm',
 | 
			
		||||
          orElse: () => null);
 | 
			
		||||
  bool get correctMxId =>
 | 
			
		||||
      foundProfiles
 | 
			
		||||
          .indexWhere((user) => user.userId == '@$currentSearchTerm') !=
 | 
			
		||||
      -1;
 | 
			
		||||
 | 
			
		||||
  void submitAction([_]) async {
 | 
			
		||||
    controller.text = controller.text.replaceAll('@', '').trim();
 | 
			
		||||
    if (controller.text.isEmpty) return;
 | 
			
		||||
    if (!formKey.currentState.validate()) return;
 | 
			
		||||
    final matrix = Matrix.of(context);
 | 
			
		||||
 | 
			
		||||
    if ('@' + controller.text == matrix.client.userID) return;
 | 
			
		||||
 | 
			
		||||
    final user = User(
 | 
			
		||||
      '@' + controller.text,
 | 
			
		||||
      room: Room(id: '', client: matrix.client),
 | 
			
		||||
    );
 | 
			
		||||
    final roomID = await showFutureLoadingDialog(
 | 
			
		||||
      context: context,
 | 
			
		||||
      future: () => user.startDirectChat(),
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    if (roomID.error == null) {
 | 
			
		||||
      await AdaptivePageLayout.of(context)
 | 
			
		||||
          .popAndPushNamed('/rooms/${roomID.result}');
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void searchUserWithCoolDown([_]) async {
 | 
			
		||||
    coolDown?.cancel();
 | 
			
		||||
    coolDown = Timer(
 | 
			
		||||
      Duration(milliseconds: 500),
 | 
			
		||||
      () => searchUser(controller.text),
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void searchUser(String text) async {
 | 
			
		||||
    if (text.isEmpty) {
 | 
			
		||||
      setState(() {
 | 
			
		||||
        foundProfiles = [];
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
    currentSearchTerm = text;
 | 
			
		||||
    if (currentSearchTerm.isEmpty) return;
 | 
			
		||||
    if (loading) return;
 | 
			
		||||
    setState(() => loading = true);
 | 
			
		||||
    final matrix = Matrix.of(context);
 | 
			
		||||
    UserSearchResult response;
 | 
			
		||||
    try {
 | 
			
		||||
      response = await matrix.client.searchUser(text, limit: 10);
 | 
			
		||||
    } catch (_) {}
 | 
			
		||||
    setState(() => loading = false);
 | 
			
		||||
    if (response?.results?.isEmpty ?? true) return;
 | 
			
		||||
    setState(() {
 | 
			
		||||
      foundProfiles = List<Profile>.from(response.results);
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  String validateForm(String value) {
 | 
			
		||||
    if (value.isEmpty) {
 | 
			
		||||
      return L10n.of(context).pleaseEnterAMatrixIdentifier;
 | 
			
		||||
    }
 | 
			
		||||
    final matrix = Matrix.of(context);
 | 
			
		||||
    final mxid = '@' + controller.text.trim();
 | 
			
		||||
    if (mxid == matrix.client.userID) {
 | 
			
		||||
      return L10n.of(context).youCannotInviteYourself;
 | 
			
		||||
    }
 | 
			
		||||
    if (!mxid.contains('@')) {
 | 
			
		||||
      return L10n.of(context).makeSureTheIdentifierIsValid;
 | 
			
		||||
    }
 | 
			
		||||
    if (!mxid.contains(':')) {
 | 
			
		||||
      return L10n.of(context).makeSureTheIdentifierIsValid;
 | 
			
		||||
    }
 | 
			
		||||
    return null;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void inviteAction() => FluffyShare.share(
 | 
			
		||||
        L10n.of(context).inviteText(Matrix.of(context).client.userID,
 | 
			
		||||
            'https://matrix.to/#/${Matrix.of(context).client.userID}'),
 | 
			
		||||
        context,
 | 
			
		||||
      );
 | 
			
		||||
 | 
			
		||||
  void pickUser(Profile foundProfile) => setState(
 | 
			
		||||
        () => controller.text =
 | 
			
		||||
            currentSearchTerm = foundProfile.userId.substring(1),
 | 
			
		||||
      );
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) => NewPrivateChatView(this);
 | 
			
		||||
}
 | 
			
		||||
@ -1,229 +0,0 @@
 | 
			
		||||
import 'dart:async';
 | 
			
		||||
 | 
			
		||||
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
 | 
			
		||||
import 'package:famedlysdk/famedlysdk.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/avatar.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/contacts_list.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/max_width_body.dart';
 | 
			
		||||
import 'package:future_loading_dialog/future_loading_dialog.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/matrix.dart';
 | 
			
		||||
import 'package:fluffychat/utils/fluffy_share.dart';
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
 | 
			
		||||
 | 
			
		||||
class NewPrivateChat extends StatefulWidget {
 | 
			
		||||
  @override
 | 
			
		||||
  _NewPrivateChatState createState() => _NewPrivateChatState();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class _NewPrivateChatState extends State<NewPrivateChat> {
 | 
			
		||||
  TextEditingController controller = TextEditingController();
 | 
			
		||||
  final _formKey = GlobalKey<FormState>();
 | 
			
		||||
  bool loading = false;
 | 
			
		||||
  String currentSearchTerm;
 | 
			
		||||
  List<Profile> foundProfiles = [];
 | 
			
		||||
  Timer coolDown;
 | 
			
		||||
  Profile get foundProfile =>
 | 
			
		||||
      foundProfiles.firstWhere((user) => user.userId == '@$currentSearchTerm',
 | 
			
		||||
          orElse: () => null);
 | 
			
		||||
  bool get correctMxId =>
 | 
			
		||||
      foundProfiles
 | 
			
		||||
          .indexWhere((user) => user.userId == '@$currentSearchTerm') !=
 | 
			
		||||
      -1;
 | 
			
		||||
 | 
			
		||||
  void submitAction(BuildContext context) async {
 | 
			
		||||
    controller.text = controller.text.replaceAll('@', '').trim();
 | 
			
		||||
    if (controller.text.isEmpty) return;
 | 
			
		||||
    if (!_formKey.currentState.validate()) return;
 | 
			
		||||
    final matrix = Matrix.of(context);
 | 
			
		||||
 | 
			
		||||
    if ('@' + controller.text == matrix.client.userID) return;
 | 
			
		||||
 | 
			
		||||
    final user = User(
 | 
			
		||||
      '@' + controller.text,
 | 
			
		||||
      room: Room(id: '', client: matrix.client),
 | 
			
		||||
    );
 | 
			
		||||
    final roomID = await showFutureLoadingDialog(
 | 
			
		||||
      context: context,
 | 
			
		||||
      future: () => user.startDirectChat(),
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    if (roomID.error == null) {
 | 
			
		||||
      await AdaptivePageLayout.of(context)
 | 
			
		||||
          .popAndPushNamed('/rooms/${roomID.result}');
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void searchUserWithCoolDown(BuildContext context) async {
 | 
			
		||||
    coolDown?.cancel();
 | 
			
		||||
    coolDown = Timer(
 | 
			
		||||
      Duration(milliseconds: 500),
 | 
			
		||||
      () => searchUser(context, controller.text),
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void searchUser(BuildContext context, String text) async {
 | 
			
		||||
    if (text.isEmpty) {
 | 
			
		||||
      setState(() {
 | 
			
		||||
        foundProfiles = [];
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
    currentSearchTerm = text;
 | 
			
		||||
    if (currentSearchTerm.isEmpty) return;
 | 
			
		||||
    if (loading) return;
 | 
			
		||||
    setState(() => loading = true);
 | 
			
		||||
    final matrix = Matrix.of(context);
 | 
			
		||||
    UserSearchResult response;
 | 
			
		||||
    try {
 | 
			
		||||
      response = await matrix.client.searchUser(text, limit: 10);
 | 
			
		||||
    } catch (_) {}
 | 
			
		||||
    setState(() => loading = false);
 | 
			
		||||
    if (response?.results?.isEmpty ?? true) return;
 | 
			
		||||
    setState(() {
 | 
			
		||||
      foundProfiles = List<Profile>.from(response.results);
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    return Scaffold(
 | 
			
		||||
      appBar: AppBar(
 | 
			
		||||
        leading: BackButton(),
 | 
			
		||||
        title: Text(L10n.of(context).newChat),
 | 
			
		||||
        elevation: 0,
 | 
			
		||||
        actions: [
 | 
			
		||||
          TextButton(
 | 
			
		||||
            onPressed: () => AdaptivePageLayout.of(context)
 | 
			
		||||
                .pushNamedAndRemoveUntilIsFirst('/newgroup'),
 | 
			
		||||
            child: Text(
 | 
			
		||||
              L10n.of(context).createNewGroup,
 | 
			
		||||
              style: TextStyle(color: Theme.of(context).accentColor),
 | 
			
		||||
            ),
 | 
			
		||||
          )
 | 
			
		||||
        ],
 | 
			
		||||
      ),
 | 
			
		||||
      body: MaxWidthBody(
 | 
			
		||||
        child: Column(
 | 
			
		||||
          children: <Widget>[
 | 
			
		||||
            Padding(
 | 
			
		||||
              padding: const EdgeInsets.all(12.0),
 | 
			
		||||
              child: Form(
 | 
			
		||||
                key: _formKey,
 | 
			
		||||
                child: TextFormField(
 | 
			
		||||
                  controller: controller,
 | 
			
		||||
                  //autofocus: true,
 | 
			
		||||
                  autocorrect: false,
 | 
			
		||||
                  onChanged: (String text) => searchUserWithCoolDown(context),
 | 
			
		||||
                  textInputAction: TextInputAction.go,
 | 
			
		||||
                  onFieldSubmitted: (s) => submitAction(context),
 | 
			
		||||
                  validator: (value) {
 | 
			
		||||
                    if (value.isEmpty) {
 | 
			
		||||
                      return L10n.of(context).pleaseEnterAMatrixIdentifier;
 | 
			
		||||
                    }
 | 
			
		||||
                    final matrix = Matrix.of(context);
 | 
			
		||||
                    final mxid = '@' + controller.text.trim();
 | 
			
		||||
                    if (mxid == matrix.client.userID) {
 | 
			
		||||
                      return L10n.of(context).youCannotInviteYourself;
 | 
			
		||||
                    }
 | 
			
		||||
                    if (!mxid.contains('@')) {
 | 
			
		||||
                      return L10n.of(context).makeSureTheIdentifierIsValid;
 | 
			
		||||
                    }
 | 
			
		||||
                    if (!mxid.contains(':')) {
 | 
			
		||||
                      return L10n.of(context).makeSureTheIdentifierIsValid;
 | 
			
		||||
                    }
 | 
			
		||||
                    return null;
 | 
			
		||||
                  },
 | 
			
		||||
                  decoration: InputDecoration(
 | 
			
		||||
                    labelText: L10n.of(context).enterAUsername,
 | 
			
		||||
                    prefixIcon: loading
 | 
			
		||||
                        ? Container(
 | 
			
		||||
                            padding: const EdgeInsets.all(8.0),
 | 
			
		||||
                            width: 12,
 | 
			
		||||
                            height: 12,
 | 
			
		||||
                            child: CircularProgressIndicator(),
 | 
			
		||||
                          )
 | 
			
		||||
                        : correctMxId
 | 
			
		||||
                            ? Padding(
 | 
			
		||||
                                padding: const EdgeInsets.all(8.0),
 | 
			
		||||
                                child: Avatar(
 | 
			
		||||
                                  foundProfile.avatarUrl,
 | 
			
		||||
                                  foundProfile.displayname ??
 | 
			
		||||
                                      foundProfile.userId,
 | 
			
		||||
                                  size: 12,
 | 
			
		||||
                                ),
 | 
			
		||||
                              )
 | 
			
		||||
                            : Icon(Icons.account_circle_outlined),
 | 
			
		||||
                    prefixText: '@',
 | 
			
		||||
                    suffixIcon: IconButton(
 | 
			
		||||
                      onPressed: () => submitAction(context),
 | 
			
		||||
                      icon: Icon(Icons.arrow_forward_outlined),
 | 
			
		||||
                    ),
 | 
			
		||||
                    hintText: '${L10n.of(context).username.toLowerCase()}',
 | 
			
		||||
                  ),
 | 
			
		||||
                ),
 | 
			
		||||
              ),
 | 
			
		||||
            ),
 | 
			
		||||
            Divider(height: 1),
 | 
			
		||||
            ListTile(
 | 
			
		||||
              leading: CircleAvatar(
 | 
			
		||||
                radius: Avatar.defaultSize / 2,
 | 
			
		||||
                foregroundColor: Theme.of(context).accentColor,
 | 
			
		||||
                backgroundColor: Theme.of(context).secondaryHeaderColor,
 | 
			
		||||
                child: Icon(Icons.share_outlined),
 | 
			
		||||
              ),
 | 
			
		||||
              onTap: () => FluffyShare.share(
 | 
			
		||||
                  L10n.of(context).inviteText(Matrix.of(context).client.userID,
 | 
			
		||||
                      'https://matrix.to/#/${Matrix.of(context).client.userID}'),
 | 
			
		||||
                  context),
 | 
			
		||||
              title: Text('${L10n.of(context).yourOwnUsername}:'),
 | 
			
		||||
              subtitle: Text(
 | 
			
		||||
                Matrix.of(context).client.userID,
 | 
			
		||||
                style: TextStyle(color: Theme.of(context).accentColor),
 | 
			
		||||
              ),
 | 
			
		||||
            ),
 | 
			
		||||
            Divider(height: 1),
 | 
			
		||||
            if (foundProfiles.isNotEmpty)
 | 
			
		||||
              Expanded(
 | 
			
		||||
                child: ListView.builder(
 | 
			
		||||
                  itemCount: foundProfiles.length,
 | 
			
		||||
                  itemBuilder: (BuildContext context, int i) {
 | 
			
		||||
                    final foundProfile = foundProfiles[i];
 | 
			
		||||
                    return ListTile(
 | 
			
		||||
                      onTap: () {
 | 
			
		||||
                        setState(() {
 | 
			
		||||
                          controller.text = currentSearchTerm =
 | 
			
		||||
                              foundProfile.userId.substring(1);
 | 
			
		||||
                        });
 | 
			
		||||
                      },
 | 
			
		||||
                      leading: Avatar(
 | 
			
		||||
                        foundProfile.avatarUrl,
 | 
			
		||||
                        foundProfile.displayname ?? foundProfile.userId,
 | 
			
		||||
                        //size: 24,
 | 
			
		||||
                      ),
 | 
			
		||||
                      title: Text(
 | 
			
		||||
                        foundProfile.displayname ??
 | 
			
		||||
                            foundProfile.userId.localpart,
 | 
			
		||||
                        style: TextStyle(),
 | 
			
		||||
                        maxLines: 1,
 | 
			
		||||
                      ),
 | 
			
		||||
                      subtitle: Text(
 | 
			
		||||
                        foundProfile.userId,
 | 
			
		||||
                        maxLines: 1,
 | 
			
		||||
                        style: TextStyle(
 | 
			
		||||
                          fontSize: 12,
 | 
			
		||||
                        ),
 | 
			
		||||
                      ),
 | 
			
		||||
                    );
 | 
			
		||||
                  },
 | 
			
		||||
                ),
 | 
			
		||||
              ),
 | 
			
		||||
            if (foundProfiles.isEmpty)
 | 
			
		||||
              Expanded(
 | 
			
		||||
                child: ContactsList(searchController: controller),
 | 
			
		||||
              ),
 | 
			
		||||
          ],
 | 
			
		||||
        ),
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										133
									
								
								lib/views/new_private_chat_view.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								lib/views/new_private_chat_view.dart
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,133 @@
 | 
			
		||||
import 'package:adaptive_page_layout/adaptive_page_layout.dart';
 | 
			
		||||
import 'package:fluffychat/controllers/new_private_chat_controller.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/avatar.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/contacts_list.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/max_width_body.dart';
 | 
			
		||||
import 'package:fluffychat/views/widgets/matrix.dart';
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
 | 
			
		||||
import 'package:famedlysdk/famedlysdk.dart';
 | 
			
		||||
 | 
			
		||||
class NewPrivateChatView extends StatelessWidget {
 | 
			
		||||
  final NewPrivateChatController controller;
 | 
			
		||||
 | 
			
		||||
  const NewPrivateChatView(this.controller, {Key key}) : super(key: key);
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    return Scaffold(
 | 
			
		||||
      appBar: AppBar(
 | 
			
		||||
        leading: BackButton(),
 | 
			
		||||
        title: Text(L10n.of(context).newChat),
 | 
			
		||||
        elevation: 0,
 | 
			
		||||
        actions: [
 | 
			
		||||
          TextButton(
 | 
			
		||||
            onPressed: () => AdaptivePageLayout.of(context)
 | 
			
		||||
                .pushNamedAndRemoveUntilIsFirst('/newgroup'),
 | 
			
		||||
            child: Text(
 | 
			
		||||
              L10n.of(context).createNewGroup,
 | 
			
		||||
              style: TextStyle(color: Theme.of(context).accentColor),
 | 
			
		||||
            ),
 | 
			
		||||
          )
 | 
			
		||||
        ],
 | 
			
		||||
      ),
 | 
			
		||||
      body: MaxWidthBody(
 | 
			
		||||
        child: Column(
 | 
			
		||||
          children: <Widget>[
 | 
			
		||||
            Padding(
 | 
			
		||||
              padding: const EdgeInsets.all(12.0),
 | 
			
		||||
              child: Form(
 | 
			
		||||
                key: controller.formKey,
 | 
			
		||||
                child: TextFormField(
 | 
			
		||||
                  controller: controller.controller,
 | 
			
		||||
                  autocorrect: false,
 | 
			
		||||
                  onChanged: controller.searchUserWithCoolDown,
 | 
			
		||||
                  textInputAction: TextInputAction.go,
 | 
			
		||||
                  onFieldSubmitted: controller.submitAction,
 | 
			
		||||
                  validator: controller.validateForm,
 | 
			
		||||
                  decoration: InputDecoration(
 | 
			
		||||
                    labelText: L10n.of(context).enterAUsername,
 | 
			
		||||
                    prefixIcon: controller.loading
 | 
			
		||||
                        ? Container(
 | 
			
		||||
                            padding: const EdgeInsets.all(8.0),
 | 
			
		||||
                            width: 12,
 | 
			
		||||
                            height: 12,
 | 
			
		||||
                            child: CircularProgressIndicator(),
 | 
			
		||||
                          )
 | 
			
		||||
                        : controller.correctMxId
 | 
			
		||||
                            ? Padding(
 | 
			
		||||
                                padding: const EdgeInsets.all(8.0),
 | 
			
		||||
                                child: Avatar(
 | 
			
		||||
                                  controller.foundProfile.avatarUrl,
 | 
			
		||||
                                  controller.foundProfile.displayname ??
 | 
			
		||||
                                      controller.foundProfile.userId,
 | 
			
		||||
                                  size: 12,
 | 
			
		||||
                                ),
 | 
			
		||||
                              )
 | 
			
		||||
                            : Icon(Icons.account_circle_outlined),
 | 
			
		||||
                    prefixText: '@',
 | 
			
		||||
                    suffixIcon: IconButton(
 | 
			
		||||
                      onPressed: controller.submitAction,
 | 
			
		||||
                      icon: Icon(Icons.arrow_forward_outlined),
 | 
			
		||||
                    ),
 | 
			
		||||
                    hintText: '${L10n.of(context).username.toLowerCase()}',
 | 
			
		||||
                  ),
 | 
			
		||||
                ),
 | 
			
		||||
              ),
 | 
			
		||||
            ),
 | 
			
		||||
            Divider(height: 1),
 | 
			
		||||
            ListTile(
 | 
			
		||||
              leading: CircleAvatar(
 | 
			
		||||
                radius: Avatar.defaultSize / 2,
 | 
			
		||||
                foregroundColor: Theme.of(context).accentColor,
 | 
			
		||||
                backgroundColor: Theme.of(context).secondaryHeaderColor,
 | 
			
		||||
                child: Icon(Icons.share_outlined),
 | 
			
		||||
              ),
 | 
			
		||||
              onTap: controller.inviteAction,
 | 
			
		||||
              title: Text('${L10n.of(context).yourOwnUsername}:'),
 | 
			
		||||
              subtitle: Text(
 | 
			
		||||
                Matrix.of(context).client.userID,
 | 
			
		||||
                style: TextStyle(color: Theme.of(context).accentColor),
 | 
			
		||||
              ),
 | 
			
		||||
            ),
 | 
			
		||||
            Divider(height: 1),
 | 
			
		||||
            if (controller.foundProfiles.isNotEmpty)
 | 
			
		||||
              Expanded(
 | 
			
		||||
                child: ListView.builder(
 | 
			
		||||
                  itemCount: controller.foundProfiles.length,
 | 
			
		||||
                  itemBuilder: (BuildContext context, int i) {
 | 
			
		||||
                    final foundProfile = controller.foundProfiles[i];
 | 
			
		||||
                    return ListTile(
 | 
			
		||||
                      onTap: () => controller.pickUser(foundProfile),
 | 
			
		||||
                      leading: Avatar(
 | 
			
		||||
                        foundProfile.avatarUrl,
 | 
			
		||||
                        foundProfile.displayname ?? foundProfile.userId,
 | 
			
		||||
                        //size: 24,
 | 
			
		||||
                      ),
 | 
			
		||||
                      title: Text(
 | 
			
		||||
                        foundProfile.displayname ??
 | 
			
		||||
                            foundProfile.userId.localpart,
 | 
			
		||||
                        style: TextStyle(),
 | 
			
		||||
                        maxLines: 1,
 | 
			
		||||
                      ),
 | 
			
		||||
                      subtitle: Text(
 | 
			
		||||
                        foundProfile.userId,
 | 
			
		||||
                        maxLines: 1,
 | 
			
		||||
                        style: TextStyle(
 | 
			
		||||
                          fontSize: 12,
 | 
			
		||||
                        ),
 | 
			
		||||
                      ),
 | 
			
		||||
                    );
 | 
			
		||||
                  },
 | 
			
		||||
                ),
 | 
			
		||||
              ),
 | 
			
		||||
            if (controller.foundProfiles.isEmpty)
 | 
			
		||||
              Expanded(
 | 
			
		||||
                child: ContactsList(searchController: controller.controller),
 | 
			
		||||
              ),
 | 
			
		||||
          ],
 | 
			
		||||
        ),
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user