181 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
			
		
		
	
	
			181 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
import 'package:dash_chat_2/dash_chat_2.dart';
 | 
						|
import 'package:flutter/material.dart';
 | 
						|
import 'package:flutter_hbb/common.dart';
 | 
						|
import 'package:flutter_hbb/models/chat_model.dart';
 | 
						|
import 'package:get/get.dart';
 | 
						|
import 'package:provider/provider.dart';
 | 
						|
 | 
						|
import '../../mobile/pages/home_page.dart';
 | 
						|
 | 
						|
enum ChatPageType {
 | 
						|
  mobileMain,
 | 
						|
  desktopCM,
 | 
						|
}
 | 
						|
 | 
						|
class ChatPage extends StatelessWidget implements PageShape {
 | 
						|
  late final ChatModel chatModel;
 | 
						|
  final ChatPageType? type;
 | 
						|
 | 
						|
  ChatPage({ChatModel? chatModel, this.type}) {
 | 
						|
    this.chatModel = chatModel ?? gFFI.chatModel;
 | 
						|
  }
 | 
						|
 | 
						|
  @override
 | 
						|
  final title = translate("Chat");
 | 
						|
 | 
						|
  @override
 | 
						|
  final icon = unreadTopRightBuilder(gFFI.chatModel.mobileUnreadSum);
 | 
						|
 | 
						|
  @override
 | 
						|
  final appBarActions = [
 | 
						|
    PopupMenuButton<MessageKey>(
 | 
						|
        tooltip: "",
 | 
						|
        icon: unreadTopRightBuilder(gFFI.chatModel.mobileUnreadSum,
 | 
						|
            icon: Icon(Icons.group)),
 | 
						|
        itemBuilder: (context) {
 | 
						|
          // only mobile need [appBarActions], just bind gFFI.chatModel
 | 
						|
          final chatModel = gFFI.chatModel;
 | 
						|
          return chatModel.messages.entries.map((entry) {
 | 
						|
            final key = entry.key;
 | 
						|
            final user = entry.value.chatUser;
 | 
						|
            final client = gFFI.serverModel.clients
 | 
						|
                .firstWhereOrNull((e) => e.id == key.connId);
 | 
						|
            final connected =
 | 
						|
                gFFI.serverModel.clients.any((e) => e.id == key.connId);
 | 
						|
            return PopupMenuItem<MessageKey>(
 | 
						|
              child: Row(
 | 
						|
                children: [
 | 
						|
                  Icon(
 | 
						|
                          key.isOut
 | 
						|
                              ? Icons.call_made_rounded
 | 
						|
                              : Icons.call_received_rounded,
 | 
						|
                          color: MyTheme.accent)
 | 
						|
                      .marginOnly(right: 6),
 | 
						|
                  Text("${user.firstName}   ${user.id}"),
 | 
						|
                  if (connected)
 | 
						|
                    Container(
 | 
						|
                      width: 10,
 | 
						|
                      height: 10,
 | 
						|
                      decoration: BoxDecoration(
 | 
						|
                          shape: BoxShape.circle,
 | 
						|
                          color: Color.fromARGB(255, 46, 205, 139)),
 | 
						|
                    ).marginSymmetric(horizontal: 2),
 | 
						|
                  if (client != null)
 | 
						|
                    unreadMessageCountBuilder(client.unreadChatMessageCount)
 | 
						|
                        .marginOnly(left: 4)
 | 
						|
                ],
 | 
						|
              ),
 | 
						|
              value: key,
 | 
						|
            );
 | 
						|
          }).toList();
 | 
						|
        },
 | 
						|
        onSelected: (key) {
 | 
						|
          gFFI.chatModel.changeCurrentKey(key);
 | 
						|
        })
 | 
						|
  ];
 | 
						|
 | 
						|
  @override
 | 
						|
  Widget build(BuildContext context) {
 | 
						|
    return ChangeNotifierProvider.value(
 | 
						|
      value: chatModel,
 | 
						|
      child: Container(
 | 
						|
        color: Theme.of(context).scaffoldBackgroundColor,
 | 
						|
        child: Consumer<ChatModel>(
 | 
						|
          builder: (context, chatModel, child) {
 | 
						|
            final readOnly = type == ChatPageType.mobileMain &&
 | 
						|
                    (chatModel.currentKey.connId == ChatModel.clientModeID ||
 | 
						|
                        gFFI.serverModel.clients.every((e) =>
 | 
						|
                            e.id != chatModel.currentKey.connId ||
 | 
						|
                            chatModel.currentUser == null)) ||
 | 
						|
                type == ChatPageType.desktopCM &&
 | 
						|
                    gFFI.serverModel.clients
 | 
						|
                            .firstWhereOrNull(
 | 
						|
                                (e) => e.id == chatModel.currentKey.connId)
 | 
						|
                            ?.disconnected ==
 | 
						|
                        true;
 | 
						|
            return Stack(
 | 
						|
              children: [
 | 
						|
                LayoutBuilder(builder: (context, constraints) {
 | 
						|
                  final chat = DashChat(
 | 
						|
                    onSend: chatModel.send,
 | 
						|
                    currentUser: chatModel.me,
 | 
						|
                    messages: chatModel
 | 
						|
                            .messages[chatModel.currentKey]?.chatMessages ??
 | 
						|
                        [],
 | 
						|
                    readOnly: readOnly,
 | 
						|
                    inputOptions: InputOptions(
 | 
						|
                      focusNode: chatModel.inputNode,
 | 
						|
                      textController: chatModel.textController,
 | 
						|
                      inputTextStyle: TextStyle(
 | 
						|
                          fontSize: 14,
 | 
						|
                          color: Theme.of(context).textTheme.titleLarge?.color),
 | 
						|
                      inputDecoration: InputDecoration(
 | 
						|
                        isDense: true,
 | 
						|
                        hintText: translate('Write a message'),
 | 
						|
                        filled: true,
 | 
						|
                        fillColor: Theme.of(context).colorScheme.background,
 | 
						|
                        contentPadding: EdgeInsets.all(10),
 | 
						|
                        border: OutlineInputBorder(
 | 
						|
                          borderRadius: BorderRadius.circular(10.0),
 | 
						|
                          borderSide: const BorderSide(
 | 
						|
                            width: 1,
 | 
						|
                            style: BorderStyle.solid,
 | 
						|
                          ),
 | 
						|
                        ),
 | 
						|
                      ),
 | 
						|
                      sendButtonBuilder: defaultSendButton(
 | 
						|
                        padding:
 | 
						|
                            EdgeInsets.symmetric(horizontal: 6, vertical: 0),
 | 
						|
                        color: MyTheme.accent,
 | 
						|
                        icon: Icons.send_rounded,
 | 
						|
                      ),
 | 
						|
                    ),
 | 
						|
                    messageOptions: MessageOptions(
 | 
						|
                      showOtherUsersAvatar: false,
 | 
						|
                      showOtherUsersName: false,
 | 
						|
                      textColor: Colors.white,
 | 
						|
                      maxWidth: constraints.maxWidth * 0.7,
 | 
						|
                      messageTextBuilder: (message, _, __) {
 | 
						|
                        final isOwnMessage = message.user.id.isBlank!;
 | 
						|
                        return Column(
 | 
						|
                          crossAxisAlignment: isOwnMessage
 | 
						|
                              ? CrossAxisAlignment.end
 | 
						|
                              : CrossAxisAlignment.start,
 | 
						|
                          children: <Widget>[
 | 
						|
                            Text(message.text,
 | 
						|
                                style: TextStyle(color: Colors.white)),
 | 
						|
                            Text(
 | 
						|
                              "${message.createdAt.hour}:${message.createdAt.minute.toString().padLeft(2, '0')}",
 | 
						|
                              style: TextStyle(
 | 
						|
                                color: Colors.white,
 | 
						|
                                fontSize: 8,
 | 
						|
                              ),
 | 
						|
                            ).marginOnly(top: 3),
 | 
						|
                          ],
 | 
						|
                        );
 | 
						|
                      },
 | 
						|
                      messageDecorationBuilder:
 | 
						|
                          (message, previousMessage, nextMessage) {
 | 
						|
                        final isOwnMessage = message.user.id.isBlank!;
 | 
						|
                        return defaultMessageDecoration(
 | 
						|
                          color:
 | 
						|
                              isOwnMessage ? MyTheme.accent : Colors.blueGrey,
 | 
						|
                          borderTopLeft: 8,
 | 
						|
                          borderTopRight: 8,
 | 
						|
                          borderBottomRight: isOwnMessage ? 2 : 8,
 | 
						|
                          borderBottomLeft: isOwnMessage ? 8 : 2,
 | 
						|
                        );
 | 
						|
                      },
 | 
						|
                    ),
 | 
						|
                  );
 | 
						|
                  return SelectionArea(child: chat);
 | 
						|
                }),
 | 
						|
              ],
 | 
						|
            ).paddingOnly(bottom: 8);
 | 
						|
          },
 | 
						|
        ),
 | 
						|
      ),
 | 
						|
    );
 | 
						|
  }
 | 
						|
}
 |