LCOV - code coverage report
Current view: top level - lib/widgets - eventbubble.dart (source / functions) Hit Total Coverage
Test: lcov.info Lines: 0 69 0.0 %
Date: 2026-08-30 05:23:47 Functions: 0 0 -

          Line data    Source code
       1             : import 'dart:convert';
       2             : import 'package:flutter/material.dart';
       3             : import 'package:provider/provider.dart';
       4             : 
       5             : import 'package:cwtch/cwtch_icons_icons.dart';
       6             : import 'package:cwtch/l10n/app_localizations.dart';
       7             : import 'package:cwtch/models/contact.dart';
       8             : import 'package:cwtch/models/profile.dart';
       9             : import 'package:cwtch/themes/opaque.dart';
      10             : 
      11             : import '../constants.dart';
      12             : import '../settings.dart';
      13             : 
      14             : // WithheldBubble is displayed for messages hidden by default due to +m
      15             : class EventBubble extends StatefulWidget {
      16             :   final String content;
      17             :   dynamic? message;
      18             :   String? errorMessage = null;
      19             :   String? stringified = null;
      20             : 
      21           0 :   EventBubble(this.content) {
      22             :     try {
      23           0 :       this.message = jsonDecode(this.content);
      24             :     } catch (e) {
      25           0 :       this.errorMessage = "json decode error $e: " + this.content;
      26             :     }
      27             :   }
      28             : 
      29           0 :   @override
      30           0 :   EventBubbleState createState() => EventBubbleState();
      31             : }
      32             : 
      33             : class EventBubbleState extends State<EventBubble> {
      34           0 :   @override
      35             :   Widget build(BuildContext context) {
      36           0 :     if (widget.stringified == null) {
      37             :       try {
      38           0 :         widget.stringified = stringify(); // + widget.message["b"];//.keys.join(",");
      39             :       } catch (e) {
      40           0 :         widget.stringified = "parse error $e";
      41             :       }
      42             :     }
      43             : 
      44           0 :     return Align(
      45             :       alignment: Alignment.center,
      46           0 :       child: Padding(
      47           0 :         padding: EdgeInsets.all(5.0),
      48           0 :         child: Container(
      49           0 :           decoration: BoxDecoration(
      50           0 :             color: Provider.of<Settings>(context).theme.messageFromOtherBackgroundColor,
      51           0 :             border: Border.all(color: Provider.of<Settings>(context).theme.messageFromOtherBackgroundColor, width: 1),
      52           0 :             borderRadius: BorderRadius.only(topLeft: Radius.circular(8), topRight: Radius.circular(8), bottomLeft: Radius.circular(8), bottomRight: Radius.circular(8)),
      53             :           ),
      54           0 :           child: Padding(
      55           0 :             padding: EdgeInsets.all(9.0),
      56           0 :             child: Text(widget.stringified ?? "", style: Provider.of<Settings>(context).scaleFonts(defaultTextStyle), maxLines: 3),
      57             :           ),
      58             :         ),
      59             :       ),
      60             :     );
      61             :   }
      62             : 
      63           0 :   String stringify() {
      64           0 :     if (widget.errorMessage != null) {
      65           0 :       return widget.errorMessage!;
      66             :     }
      67             : 
      68           0 :     int eventCode = widget.message["e"];
      69             :     switch (eventCode) {
      70           0 :       case AddMemberEvent:
      71           0 :         if (widget.message["a"].toString() == Provider.of<ContactInfoState>(context, listen: false).onion) {
      72           0 :           return r("\$handle joined the group");
      73             :         } else {
      74           0 :           return r("\$author added \$handle to the group");
      75             :         }
      76           0 :       case RemoveMemberEvent:
      77           0 :         dynamic params = jsonDecode(widget.message["b"]);
      78           0 :         if (widget.message["a"].toString() == params["h"]) {
      79           0 :           return r("\$author left the group");
      80             :         } else {
      81           0 :           return r("\$author removed \$handle from the group");
      82             :         }
      83           0 :       case ChangeMemberRoleEvent:
      84           0 :         return r("\$author changed \$handle to \$role");
      85           0 :       case ChangeGroupModeEvent:
      86           0 :         return r("\$author changed the group mode to \$mode");
      87           0 :       case ChangeGroupMaskEvent:
      88           0 :         return r("\$author changed the group mask to \$mask");
      89           0 :       case UpdateGroupMetadataEvent:
      90           0 :         return r("\$author updated the group name/attributes");
      91           0 :       case UpdateGroupPictureEvent:
      92           0 :         return r("\$author updated the group picture");
      93             :       default:
      94           0 :         return r("(Missing message: \$author did an event code \$e");
      95             :     }
      96             :   }
      97             : 
      98           0 :   String r(String input) {
      99             :     // widget.message {
     100             :     // g: group onion
     101             :     // a: author onion
     102             :     // m: member message id
     103             :     // b: event parameters {
     104             :     //    Additive: "true"|"false" for mode/mask
     105             :     //    a: mask bit
     106             :     //    h: handle
     107             :     //    n: mask bit
     108             :     //    r: role
     109             :     // t: ?
     110             :     // s: sig?
     111             :     // e: event code
     112           0 :     String author = widget.message["a"].toString();
     113           0 :     if (author == Provider.of<ProfileInfoState>(context).onion) {
     114             :       author = "You";
     115             :     } else {
     116           0 :       ContactInfoState? contact = Provider.of<ProfileInfoState>(context).contactList.findContact(author);
     117             :       if (contact != null) {
     118           0 :         author = contact.nickname;
     119             :       }
     120             :     }
     121             : 
     122             :     String handle = "";
     123             :     String role = "";
     124             :     String mode = "";
     125             :     String mask = "";
     126             : 
     127           0 :     if (widget.message.containsKey("b")) {
     128           0 :       dynamic params = jsonDecode(widget.message["b"]);
     129             : 
     130           0 :       if (params.containsKey("h")) {
     131           0 :         handle = params["h"];
     132           0 :         if (handle == Provider.of<ProfileInfoState>(context).onion) {
     133             :           handle = "you";
     134             :         } else {
     135           0 :           ContactInfoState? contact = Provider.of<ProfileInfoState>(context).contactList.findContact(handle);
     136             :           if (contact != null) {
     137           0 :             handle = contact.nickname;
     138             :           }
     139             :         }
     140             :       }
     141             : 
     142           0 :       if (params.containsKey("r")) {
     143           0 :         role = params["r"];
     144             :       }
     145             : 
     146           0 :       String additive = (params.containsKey("Additive") && params["Additive"]) ? "+" : "-";
     147           0 :       if (params.containsKey("a")) {
     148           0 :         mode = additive + params["a"];
     149             :       }
     150           0 :       if (params.containsKey("n")) {
     151           0 :         mask = additive + params["n"];
     152             :       }
     153             :     }
     154             : 
     155             :     return input
     156           0 :         .replaceAll("\$author", author)
     157           0 :         .replaceAll("\$e", widget.message["e"].toString())
     158           0 :         .replaceAll("\$handle", handle)
     159           0 :         .replaceAll("\$role", role)
     160           0 :         .replaceAll("\$mask", mask)
     161           0 :         .replaceAll("\$mode", mode);
     162             :   }
     163             : }

Generated by: LCOV version 1.14