double tap on messages to show options #63
@@ -99,6 +99,167 @@ class _ChatBubbleState extends State<ChatBubble> {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void showOptionsDialog() {
 | 
				
			||||||
 | 
					    showDialog(context: context, builder: (context) {
 | 
				
			||||||
 | 
					      var commonReactions = <String>['👍', '👎', '😆', '❤️', '👀'];
 | 
				
			||||||
 | 
					      var canReact = widget.bubbleData.messageType == GetRoomResponseObjectMessageType.comment;
 | 
				
			||||||
 | 
					      return SimpleDialog(
 | 
				
			||||||
 | 
					        children: [
 | 
				
			||||||
 | 
					          Visibility(
 | 
				
			||||||
 | 
					            visible: canReact,
 | 
				
			||||||
 | 
					            child: Column(
 | 
				
			||||||
 | 
					              mainAxisSize: MainAxisSize.min,
 | 
				
			||||||
 | 
					              children: [
 | 
				
			||||||
 | 
					                Wrap(
 | 
				
			||||||
 | 
					                  alignment: WrapAlignment.center,
 | 
				
			||||||
 | 
					                  children: [
 | 
				
			||||||
 | 
					                    ...commonReactions.map((e) => TextButton(
 | 
				
			||||||
 | 
					                      style: TextButton.styleFrom(
 | 
				
			||||||
 | 
					                          padding: EdgeInsets.zero,
 | 
				
			||||||
 | 
					                          tapTargetSize: MaterialTapTargetSize.shrinkWrap,
 | 
				
			||||||
 | 
					                          minimumSize: const Size(40, 40)
 | 
				
			||||||
 | 
					                      ),
 | 
				
			||||||
 | 
					                      onPressed: () {
 | 
				
			||||||
 | 
					                        Navigator.of(context).pop();
 | 
				
			||||||
 | 
					                        ReactMessage(
 | 
				
			||||||
 | 
					                          chatToken: widget.chatData.token,
 | 
				
			||||||
 | 
					                          messageId: widget.bubbleData.id,
 | 
				
			||||||
 | 
					                          params: ReactMessageParams(e),
 | 
				
			||||||
 | 
					                        ).run().then((value) => widget.refetch(renew: true));
 | 
				
			||||||
 | 
					                      },
 | 
				
			||||||
 | 
					                      child: Text(e),
 | 
				
			||||||
 | 
					                    ),
 | 
				
			||||||
 | 
					                    ),
 | 
				
			||||||
 | 
					                    IconButton(
 | 
				
			||||||
 | 
					                      onPressed: () {
 | 
				
			||||||
 | 
					                        showDialog(context: context, builder: (context) => AlertDialog(
 | 
				
			||||||
 | 
					                          contentPadding: const EdgeInsets.all(15),
 | 
				
			||||||
 | 
					                          titlePadding: const EdgeInsets.only(left: 6, top: 15),
 | 
				
			||||||
 | 
					                          title: Row(
 | 
				
			||||||
 | 
					                            mainAxisAlignment: MainAxisAlignment.start,
 | 
				
			||||||
 | 
					                            children: [
 | 
				
			||||||
 | 
					                              IconButton(
 | 
				
			||||||
 | 
					                                onPressed: () {
 | 
				
			||||||
 | 
					                                  Navigator.of(context).pop();
 | 
				
			||||||
 | 
					                                },
 | 
				
			||||||
 | 
					                                icon: const Icon(Icons.arrow_back),
 | 
				
			||||||
 | 
					                              ),
 | 
				
			||||||
 | 
					                              const SizedBox(width: 10),
 | 
				
			||||||
 | 
					                              const Text('Reagieren'),
 | 
				
			||||||
 | 
					                            ],
 | 
				
			||||||
 | 
					                          ),
 | 
				
			||||||
 | 
					                          content: SizedBox(
 | 
				
			||||||
 | 
					                            width: 256,
 | 
				
			||||||
 | 
					                            height: 270,
 | 
				
			||||||
 | 
					                            child: Column(
 | 
				
			||||||
 | 
					                              children: [
 | 
				
			||||||
 | 
					                                emojis.EmojiPicker(
 | 
				
			||||||
 | 
					                                  config: emojis.Config(
 | 
				
			||||||
 | 
					                                    height: 256,
 | 
				
			||||||
 | 
					                                    swapCategoryAndBottomBar: true,
 | 
				
			||||||
 | 
					                                    emojiViewConfig: emojis.EmojiViewConfig(
 | 
				
			||||||
 | 
					                                      backgroundColor: Theme.of(context).canvasColor,
 | 
				
			||||||
 | 
					                                      recentsLimit: 67,
 | 
				
			||||||
 | 
					                                      emojiSizeMax: 25,
 | 
				
			||||||
 | 
					                                      noRecents: const Text('Keine zuletzt verwendeten Emojis'),
 | 
				
			||||||
 | 
					                                      columns: 7,
 | 
				
			||||||
 | 
					                                    ),
 | 
				
			||||||
 | 
					                                    bottomActionBarConfig: const emojis.BottomActionBarConfig(
 | 
				
			||||||
 | 
					                                      enabled: false,
 | 
				
			||||||
 | 
					                                    ),
 | 
				
			||||||
 | 
					                                    categoryViewConfig: emojis.CategoryViewConfig(
 | 
				
			||||||
 | 
					                                      backgroundColor: Theme.of(context).hoverColor,
 | 
				
			||||||
 | 
					                                      iconColorSelected: Theme.of(context).primaryColor,
 | 
				
			||||||
 | 
					                                      indicatorColor: Theme.of(context).primaryColor,
 | 
				
			||||||
 | 
					                                    ),
 | 
				
			||||||
 | 
					                                    searchViewConfig: emojis.SearchViewConfig(
 | 
				
			||||||
 | 
					                                      backgroundColor: Theme.of(context).dividerColor,
 | 
				
			||||||
 | 
					                                      buttonColor: Theme.of(context).dividerColor,
 | 
				
			||||||
 | 
					                                      hintText: 'Suchen',
 | 
				
			||||||
 | 
					                                      buttonIconColor: Colors.white,
 | 
				
			||||||
 | 
					                                    ),
 | 
				
			||||||
 | 
					                                  ),
 | 
				
			||||||
 | 
					                                  onEmojiSelected: (emojis.Category? category, emojis.Emoji emoji) {
 | 
				
			||||||
 | 
					                                    Navigator.of(context).pop();
 | 
				
			||||||
 | 
					                                    Navigator.of(context).pop();
 | 
				
			||||||
 | 
					                                    ReactMessage(
 | 
				
			||||||
 | 
					                                      chatToken: widget.chatData.token,
 | 
				
			||||||
 | 
					                                      messageId: widget.bubbleData.id,
 | 
				
			||||||
 | 
					                                      params: ReactMessageParams(emoji.emoji),
 | 
				
			||||||
 | 
					                                    ).run().then((value) => widget.refetch(renew: true));
 | 
				
			||||||
 | 
					                                  },
 | 
				
			||||||
 | 
					                                ),
 | 
				
			||||||
 | 
					                              ],
 | 
				
			||||||
 | 
					                            ),
 | 
				
			||||||
 | 
					                          ),
 | 
				
			||||||
 | 
					                        ));
 | 
				
			||||||
 | 
					                      },
 | 
				
			||||||
 | 
					                      style: IconButton.styleFrom(
 | 
				
			||||||
 | 
					                        padding: EdgeInsets.zero,
 | 
				
			||||||
 | 
					                        tapTargetSize: MaterialTapTargetSize.shrinkWrap,
 | 
				
			||||||
 | 
					                        minimumSize: const Size(40, 40),
 | 
				
			||||||
 | 
					                      ),
 | 
				
			||||||
 | 
					                      icon: const Icon(Icons.add_circle_outline_outlined),
 | 
				
			||||||
 | 
					                    ),
 | 
				
			||||||
 | 
					                  ],
 | 
				
			||||||
 | 
					                ),
 | 
				
			||||||
 | 
					                const Divider(),
 | 
				
			||||||
 | 
					              ],
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
 | 
					          Visibility(
 | 
				
			||||||
 | 
					            visible: canReact,
 | 
				
			||||||
 | 
					            child: ListTile(
 | 
				
			||||||
 | 
					              leading: const Icon(Icons.emoji_emotions_outlined),
 | 
				
			||||||
 | 
					              title: const Text('Reaktionen'),
 | 
				
			||||||
 | 
					              onTap: () {
 | 
				
			||||||
 | 
					                Navigator.of(context).push(MaterialPageRoute(builder: (context) => MessageReactions(
 | 
				
			||||||
 | 
					                  token: widget.chatData.token,
 | 
				
			||||||
 | 
					                  messageId: widget.bubbleData.id,
 | 
				
			||||||
 | 
					                )));
 | 
				
			||||||
 | 
					              },
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
 | 
					          Visibility(
 | 
				
			||||||
 | 
					            visible: !message.containsFile,
 | 
				
			||||||
 | 
					            child: ListTile(
 | 
				
			||||||
 | 
					              leading: const Icon(Icons.copy),
 | 
				
			||||||
 | 
					              title: const Text('Nachricht kopieren'),
 | 
				
			||||||
 | 
					              onTap: () => {
 | 
				
			||||||
 | 
					                Clipboard.setData(ClipboardData(text: widget.bubbleData.message)),
 | 
				
			||||||
 | 
					                Navigator.of(context).pop(),
 | 
				
			||||||
 | 
					              },
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
 | 
					          Visibility(
 | 
				
			||||||
 | 
					            visible: !kReleaseMode && !widget.isSender && widget.chatData.type != GetRoomResponseObjectConversationType.oneToOne,
 | 
				
			||||||
 | 
					            child: ListTile(
 | 
				
			||||||
 | 
					              leading: const Icon(Icons.sms_outlined),
 | 
				
			||||||
 | 
					              title: Text("Private Nachricht an '${widget.bubbleData.actorDisplayName}'"),
 | 
				
			||||||
 | 
					              onTap: () => {
 | 
				
			||||||
 | 
					                Navigator.of(context).pop()
 | 
				
			||||||
 | 
					              },
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
 | 
					          Visibility(
 | 
				
			||||||
 | 
					            visible: widget.isSender && DateTime.fromMillisecondsSinceEpoch(widget.bubbleData.timestamp * 1000).add(const Duration(hours: 6)).isAfter(DateTime.now()),
 | 
				
			||||||
 | 
					            child: ListTile(
 | 
				
			||||||
 | 
					              leading: const Icon(Icons.delete_outline),
 | 
				
			||||||
 | 
					              title: const Text('Nachricht löschen'),
 | 
				
			||||||
 | 
					              onTap: () {
 | 
				
			||||||
 | 
					                DeleteMessage(widget.chatData.token, widget.bubbleData.id).run().then((value) {
 | 
				
			||||||
 | 
					                  Provider.of<ChatProps>(context, listen: false).run();
 | 
				
			||||||
 | 
					                  Navigator.of(context).pop();
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					              },
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
 | 
					          DebugTile(context).jsonData(widget.bubbleData.toJson()),
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  Widget build(BuildContext context) {
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
@@ -127,6 +288,54 @@ class _ChatBubbleState extends State<ChatBubble> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      children: [
 | 
					      children: [
 | 
				
			||||||
        GestureDetector(
 | 
					        GestureDetector(
 | 
				
			||||||
 | 
					          onLongPress: showOptionsDialog,
 | 
				
			||||||
 | 
					          onDoubleTap: showOptionsDialog,
 | 
				
			||||||
 | 
					          onTap: () {
 | 
				
			||||||
 | 
					            if(message.file == null) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if(downloadProgress > 0) {
 | 
				
			||||||
 | 
					              showDialog(context: context, builder: (context) => AlertDialog(
 | 
				
			||||||
 | 
					                  title: const Text('Download abbrechen?'),
 | 
				
			||||||
 | 
					                  content: const Text('Möchtest du den Download abbrechen?'),
 | 
				
			||||||
 | 
					                  actions: [
 | 
				
			||||||
 | 
					                    TextButton(onPressed: () {
 | 
				
			||||||
 | 
					                      Navigator.of(context).pop();
 | 
				
			||||||
 | 
					                    }, child: const Text('Nein')),
 | 
				
			||||||
 | 
					                    TextButton(onPressed: () {
 | 
				
			||||||
 | 
					                      downloadCore?.then((value) {
 | 
				
			||||||
 | 
					                        if(!value.isCancelled) value.cancel();
 | 
				
			||||||
 | 
					                        Navigator.of(context).pop();
 | 
				
			||||||
 | 
					                      });
 | 
				
			||||||
 | 
					                      setState(() {
 | 
				
			||||||
 | 
					                        downloadProgress = 0;
 | 
				
			||||||
 | 
					                        downloadCore = null;
 | 
				
			||||||
 | 
					                      });
 | 
				
			||||||
 | 
					                    }, child: const Text('Ja, Abbrechen'))
 | 
				
			||||||
 | 
					                  ],
 | 
				
			||||||
 | 
					                ));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              return;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            downloadProgress = 1;
 | 
				
			||||||
 | 
					            downloadCore = FileElement.download(context, message.file!.path!, message.file!.name, (progress) {
 | 
				
			||||||
 | 
					              if(progress > 1) {
 | 
				
			||||||
 | 
					                setState(() {
 | 
				
			||||||
 | 
					                  downloadProgress = progress;
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            }, (result) {
 | 
				
			||||||
 | 
					              setState(() {
 | 
				
			||||||
 | 
					                downloadProgress = 0;
 | 
				
			||||||
 | 
					              });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              if(result.type != ResultType.done) {
 | 
				
			||||||
 | 
					                showDialog(context: context, builder: (context) => AlertDialog(
 | 
				
			||||||
 | 
					                    content: Text(result.message),
 | 
				
			||||||
 | 
					                  ));
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
          child: Bubble(
 | 
					          child: Bubble(
 | 
				
			||||||
            style: getStyle(),
 | 
					            style: getStyle(),
 | 
				
			||||||
            child: Container(
 | 
					            child: Container(
 | 
				
			||||||
@@ -182,212 +391,6 @@ class _ChatBubbleState extends State<ChatBubble> {
 | 
				
			|||||||
              ),
 | 
					              ),
 | 
				
			||||||
            ),
 | 
					            ),
 | 
				
			||||||
          ),
 | 
					          ),
 | 
				
			||||||
          onLongPress: () {
 | 
					 | 
				
			||||||
            showDialog(context: context, builder: (context) {
 | 
					 | 
				
			||||||
              var commonReactions = <String>['👍', '👎', '😆', '❤️', '👀'];
 | 
					 | 
				
			||||||
              var canReact = widget.bubbleData.messageType == GetRoomResponseObjectMessageType.comment;
 | 
					 | 
				
			||||||
              return SimpleDialog(
 | 
					 | 
				
			||||||
                children: [
 | 
					 | 
				
			||||||
                  Visibility(
 | 
					 | 
				
			||||||
                    visible: canReact,
 | 
					 | 
				
			||||||
                    child: Column(
 | 
					 | 
				
			||||||
                      mainAxisSize: MainAxisSize.min,
 | 
					 | 
				
			||||||
                      children: [
 | 
					 | 
				
			||||||
                        Wrap(
 | 
					 | 
				
			||||||
                          alignment: WrapAlignment.center,
 | 
					 | 
				
			||||||
                          children: [
 | 
					 | 
				
			||||||
                            ...commonReactions.map((e) => TextButton(
 | 
					 | 
				
			||||||
                                style: TextButton.styleFrom(
 | 
					 | 
				
			||||||
                                    padding: EdgeInsets.zero,
 | 
					 | 
				
			||||||
                                    tapTargetSize: MaterialTapTargetSize.shrinkWrap,
 | 
					 | 
				
			||||||
                                    minimumSize: const Size(40, 40)
 | 
					 | 
				
			||||||
                                ),
 | 
					 | 
				
			||||||
                                onPressed: () {
 | 
					 | 
				
			||||||
                                  Navigator.of(context).pop();
 | 
					 | 
				
			||||||
                                  ReactMessage(
 | 
					 | 
				
			||||||
                                    chatToken: widget.chatData.token,
 | 
					 | 
				
			||||||
                                    messageId: widget.bubbleData.id,
 | 
					 | 
				
			||||||
                                    params: ReactMessageParams(e),
 | 
					 | 
				
			||||||
                                  ).run().then((value) => widget.refetch(renew: true));
 | 
					 | 
				
			||||||
                                },
 | 
					 | 
				
			||||||
                                child: Text(e),
 | 
					 | 
				
			||||||
                              ),
 | 
					 | 
				
			||||||
                            ),
 | 
					 | 
				
			||||||
                            IconButton(
 | 
					 | 
				
			||||||
                              onPressed: () {
 | 
					 | 
				
			||||||
                                showDialog(context: context, builder: (context) => AlertDialog(
 | 
					 | 
				
			||||||
                                    contentPadding: const EdgeInsets.all(15),
 | 
					 | 
				
			||||||
                                    titlePadding: const EdgeInsets.only(left: 6, top: 15),
 | 
					 | 
				
			||||||
                                    title: Row(
 | 
					 | 
				
			||||||
                                      mainAxisAlignment: MainAxisAlignment.start,
 | 
					 | 
				
			||||||
                                      children: [
 | 
					 | 
				
			||||||
                                        IconButton(
 | 
					 | 
				
			||||||
                                          onPressed: () {
 | 
					 | 
				
			||||||
                                            Navigator.of(context).pop();
 | 
					 | 
				
			||||||
                                          },
 | 
					 | 
				
			||||||
                                          icon: const Icon(Icons.arrow_back),
 | 
					 | 
				
			||||||
                                        ),
 | 
					 | 
				
			||||||
                                        const SizedBox(width: 10),
 | 
					 | 
				
			||||||
                                        const Text('Reagieren'),
 | 
					 | 
				
			||||||
                                      ],
 | 
					 | 
				
			||||||
                                    ),
 | 
					 | 
				
			||||||
                                    content: SizedBox(
 | 
					 | 
				
			||||||
                                      width: 256,
 | 
					 | 
				
			||||||
                                      height: 270,
 | 
					 | 
				
			||||||
                                      child: Column(
 | 
					 | 
				
			||||||
                                        children: [
 | 
					 | 
				
			||||||
                                          emojis.EmojiPicker(
 | 
					 | 
				
			||||||
                                            config: emojis.Config(
 | 
					 | 
				
			||||||
                                              height: 256,
 | 
					 | 
				
			||||||
                                              swapCategoryAndBottomBar: true,
 | 
					 | 
				
			||||||
                                              emojiViewConfig: emojis.EmojiViewConfig(
 | 
					 | 
				
			||||||
                                                backgroundColor: Theme.of(context).canvasColor,
 | 
					 | 
				
			||||||
                                                recentsLimit: 67,
 | 
					 | 
				
			||||||
                                                emojiSizeMax: 25,
 | 
					 | 
				
			||||||
                                                noRecents: const Text('Keine zuletzt verwendeten Emojis'),
 | 
					 | 
				
			||||||
                                                columns: 7,
 | 
					 | 
				
			||||||
                                              ),
 | 
					 | 
				
			||||||
                                              bottomActionBarConfig: const emojis.BottomActionBarConfig(
 | 
					 | 
				
			||||||
                                                enabled: false,
 | 
					 | 
				
			||||||
                                              ),
 | 
					 | 
				
			||||||
                                              categoryViewConfig: emojis.CategoryViewConfig(
 | 
					 | 
				
			||||||
                                                backgroundColor: Theme.of(context).hoverColor,
 | 
					 | 
				
			||||||
                                                iconColorSelected: Theme.of(context).primaryColor,
 | 
					 | 
				
			||||||
                                                indicatorColor: Theme.of(context).primaryColor,
 | 
					 | 
				
			||||||
                                              ),
 | 
					 | 
				
			||||||
                                              searchViewConfig: emojis.SearchViewConfig(
 | 
					 | 
				
			||||||
                                                backgroundColor: Theme.of(context).dividerColor,
 | 
					 | 
				
			||||||
                                                buttonColor: Theme.of(context).dividerColor,
 | 
					 | 
				
			||||||
                                                hintText: 'Suchen',
 | 
					 | 
				
			||||||
                                                buttonIconColor: Colors.white,
 | 
					 | 
				
			||||||
                                              ),
 | 
					 | 
				
			||||||
                                            ),
 | 
					 | 
				
			||||||
                                            onEmojiSelected: (emojis.Category? category, emojis.Emoji emoji) {
 | 
					 | 
				
			||||||
                                              Navigator.of(context).pop();
 | 
					 | 
				
			||||||
                                              Navigator.of(context).pop();
 | 
					 | 
				
			||||||
                                              ReactMessage(
 | 
					 | 
				
			||||||
                                                chatToken: widget.chatData.token,
 | 
					 | 
				
			||||||
                                                messageId: widget.bubbleData.id,
 | 
					 | 
				
			||||||
                                                params: ReactMessageParams(emoji.emoji),
 | 
					 | 
				
			||||||
                                              ).run().then((value) => widget.refetch(renew: true));
 | 
					 | 
				
			||||||
                                            },
 | 
					 | 
				
			||||||
                                          ),
 | 
					 | 
				
			||||||
                                        ],
 | 
					 | 
				
			||||||
                                      ),
 | 
					 | 
				
			||||||
                                    ),
 | 
					 | 
				
			||||||
                                  ));
 | 
					 | 
				
			||||||
                              },
 | 
					 | 
				
			||||||
                              style: IconButton.styleFrom(
 | 
					 | 
				
			||||||
                                padding: EdgeInsets.zero,
 | 
					 | 
				
			||||||
                                tapTargetSize: MaterialTapTargetSize.shrinkWrap,
 | 
					 | 
				
			||||||
                                minimumSize: const Size(40, 40),
 | 
					 | 
				
			||||||
                              ),
 | 
					 | 
				
			||||||
                              icon: const Icon(Icons.add_circle_outline_outlined),
 | 
					 | 
				
			||||||
                            ),
 | 
					 | 
				
			||||||
                          ],
 | 
					 | 
				
			||||||
                        ),
 | 
					 | 
				
			||||||
                        const Divider(),
 | 
					 | 
				
			||||||
                      ],
 | 
					 | 
				
			||||||
                    ),
 | 
					 | 
				
			||||||
                  ),
 | 
					 | 
				
			||||||
                  Visibility(
 | 
					 | 
				
			||||||
                    visible: canReact,
 | 
					 | 
				
			||||||
                    child: ListTile(
 | 
					 | 
				
			||||||
                      leading: const Icon(Icons.emoji_emotions_outlined),
 | 
					 | 
				
			||||||
                      title: const Text('Reaktionen'),
 | 
					 | 
				
			||||||
                      onTap: () {
 | 
					 | 
				
			||||||
                        Navigator.of(context).push(MaterialPageRoute(builder: (context) => MessageReactions(
 | 
					 | 
				
			||||||
                          token: widget.chatData.token,
 | 
					 | 
				
			||||||
                          messageId: widget.bubbleData.id,
 | 
					 | 
				
			||||||
                        )));
 | 
					 | 
				
			||||||
                      },
 | 
					 | 
				
			||||||
                    ),
 | 
					 | 
				
			||||||
                  ),
 | 
					 | 
				
			||||||
                  Visibility(
 | 
					 | 
				
			||||||
                    visible: !message.containsFile,
 | 
					 | 
				
			||||||
                    child: ListTile(
 | 
					 | 
				
			||||||
                      leading: const Icon(Icons.copy),
 | 
					 | 
				
			||||||
                      title: const Text('Nachricht kopieren'),
 | 
					 | 
				
			||||||
                      onTap: () => {
 | 
					 | 
				
			||||||
                        Clipboard.setData(ClipboardData(text: widget.bubbleData.message)),
 | 
					 | 
				
			||||||
                        Navigator.of(context).pop(),
 | 
					 | 
				
			||||||
                      },
 | 
					 | 
				
			||||||
                    ),
 | 
					 | 
				
			||||||
                  ),
 | 
					 | 
				
			||||||
                  Visibility(
 | 
					 | 
				
			||||||
                    visible: !kReleaseMode && !widget.isSender && widget.chatData.type != GetRoomResponseObjectConversationType.oneToOne,
 | 
					 | 
				
			||||||
                    child: ListTile(
 | 
					 | 
				
			||||||
                      leading: const Icon(Icons.sms_outlined),
 | 
					 | 
				
			||||||
                      title: Text("Private Nachricht an '${widget.bubbleData.actorDisplayName}'"),
 | 
					 | 
				
			||||||
                      onTap: () => {
 | 
					 | 
				
			||||||
                        Navigator.of(context).pop()
 | 
					 | 
				
			||||||
                      },
 | 
					 | 
				
			||||||
                    ),
 | 
					 | 
				
			||||||
                  ),
 | 
					 | 
				
			||||||
                  Visibility(
 | 
					 | 
				
			||||||
                    visible: widget.isSender && DateTime.fromMillisecondsSinceEpoch(widget.bubbleData.timestamp * 1000).add(const Duration(hours: 6)).isAfter(DateTime.now()),
 | 
					 | 
				
			||||||
                    child: ListTile(
 | 
					 | 
				
			||||||
                      leading: const Icon(Icons.delete_outline),
 | 
					 | 
				
			||||||
                      title: const Text('Nachricht löschen'),
 | 
					 | 
				
			||||||
                      onTap: () {
 | 
					 | 
				
			||||||
                        DeleteMessage(widget.chatData.token, widget.bubbleData.id).run().then((value) {
 | 
					 | 
				
			||||||
                          Provider.of<ChatProps>(context, listen: false).run();
 | 
					 | 
				
			||||||
                          Navigator.of(context).pop();
 | 
					 | 
				
			||||||
                        });
 | 
					 | 
				
			||||||
                      },
 | 
					 | 
				
			||||||
                    ),
 | 
					 | 
				
			||||||
                  ),
 | 
					 | 
				
			||||||
                  DebugTile(context).jsonData(widget.bubbleData.toJson()),
 | 
					 | 
				
			||||||
                ],
 | 
					 | 
				
			||||||
              );
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
          onTap: () {
 | 
					 | 
				
			||||||
            if(message.file == null) return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if(downloadProgress > 0) {
 | 
					 | 
				
			||||||
              showDialog(context: context, builder: (context) => AlertDialog(
 | 
					 | 
				
			||||||
                  title: const Text('Download abbrechen?'),
 | 
					 | 
				
			||||||
                  content: const Text('Möchtest du den Download abbrechen?'),
 | 
					 | 
				
			||||||
                  actions: [
 | 
					 | 
				
			||||||
                    TextButton(onPressed: () {
 | 
					 | 
				
			||||||
                      Navigator.of(context).pop();
 | 
					 | 
				
			||||||
                    }, child: const Text('Nein')),
 | 
					 | 
				
			||||||
                    TextButton(onPressed: () {
 | 
					 | 
				
			||||||
                      downloadCore?.then((value) {
 | 
					 | 
				
			||||||
                        if(!value.isCancelled) value.cancel();
 | 
					 | 
				
			||||||
                        Navigator.of(context).pop();
 | 
					 | 
				
			||||||
                      });
 | 
					 | 
				
			||||||
                      setState(() {
 | 
					 | 
				
			||||||
                        downloadProgress = 0;
 | 
					 | 
				
			||||||
                        downloadCore = null;
 | 
					 | 
				
			||||||
                      });
 | 
					 | 
				
			||||||
                    }, child: const Text('Ja, Abbrechen'))
 | 
					 | 
				
			||||||
                  ],
 | 
					 | 
				
			||||||
                ));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
              return;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            downloadProgress = 1;
 | 
					 | 
				
			||||||
            downloadCore = FileElement.download(context, message.file!.path!, message.file!.name, (progress) {
 | 
					 | 
				
			||||||
              if(progress > 1) {
 | 
					 | 
				
			||||||
                setState(() {
 | 
					 | 
				
			||||||
                  downloadProgress = progress;
 | 
					 | 
				
			||||||
                });
 | 
					 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
            }, (result) {
 | 
					 | 
				
			||||||
              setState(() {
 | 
					 | 
				
			||||||
                downloadProgress = 0;
 | 
					 | 
				
			||||||
              });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
              if(result.type != ResultType.done) {
 | 
					 | 
				
			||||||
                showDialog(context: context, builder: (context) => AlertDialog(
 | 
					 | 
				
			||||||
                    content: Text(result.message),
 | 
					 | 
				
			||||||
                  ));
 | 
					 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        Visibility(
 | 
					        Visibility(
 | 
				
			||||||
          visible: widget.bubbleData.reactions != null,
 | 
					          visible: widget.bubbleData.reactions != null,
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user