LCOV - code coverage report
Current view: top level - lib/widgets - contactrow.dart (source / functions) Hit Total Coverage
Test: lcov.info Lines: 0 126 0.0 %
Date: 2024-04-16 06:18:13 Functions: 0 0 -

          Line data    Source code
       1             : import 'dart:io';
       2             : 
       3             : import 'package:cwtch/models/appstate.dart';
       4             : import 'package:cwtch/models/contact.dart';
       5             : import 'package:cwtch/models/contactlist.dart';
       6             : import 'package:cwtch/models/profile.dart';
       7             : import 'package:cwtch/models/redaction.dart';
       8             : import 'package:cwtch/themes/opaque.dart';
       9             : import 'package:cwtch/views/contactsview.dart';
      10             : import 'package:flutter/material.dart';
      11             : import 'package:cwtch/widgets/profileimage.dart';
      12             : import 'package:provider/provider.dart';
      13             : import 'package:flutter_gen/gen_l10n/app_localizations.dart';
      14             : import '../main.dart';
      15             : import '../models/message.dart';
      16             : import '../settings.dart';
      17             : 
      18             : class ContactRow extends StatefulWidget {
      19             :   int? messageIndex;
      20             : 
      21           0 :   ContactRow({this.messageIndex});
      22           0 :   @override
      23           0 :   _ContactRowState createState() => _ContactRowState();
      24             : }
      25             : 
      26             : class _ContactRowState extends State<ContactRow> {
      27             :   bool isHover = false;
      28             :   Message? cachedMessage;
      29             : 
      30           0 :   @override
      31             :   Widget build(BuildContext context) {
      32           0 :     var contact = Provider.of<ContactInfoState>(context);
      33             : 
      34           0 :     if (widget.messageIndex != null && this.cachedMessage == null) {
      35           0 :       messageHandler(context, Provider.of<ProfileInfoState>(context, listen: false).onion, contact.identifier, ByIndex(widget.messageIndex!)).then((value) {
      36           0 :         setState(() {
      37           0 :           this.cachedMessage = value;
      38             :         });
      39             :       });
      40             :     }
      41             : 
      42             :     // Only groups have a sync status
      43             :     Widget? syncStatus;
      44           0 :     if (contact.isGroup) {
      45           0 :       syncStatus = Visibility(
      46           0 :           visible: contact.isGroup && contact.status == "Authenticated",
      47           0 :           child: LinearProgressIndicator(
      48           0 :             color: Provider.of<Settings>(context).theme.defaultButtonActiveColor,
      49           0 :             backgroundColor: Provider.of<Settings>(context).theme.defaultButtonDisabledColor,
      50           0 :             value: Provider.of<ProfileInfoState>(context).serverList.getServer(contact.server ?? "")?.syncProgress,
      51             :           ));
      52             :     }
      53             : 
      54           0 :     bool selected = Provider.of<AppState>(context).selectedConversation == contact.identifier;
      55           0 :     if (selected && widget.messageIndex != null) {
      56           0 :       if (selected && widget.messageIndex == Provider.of<AppState>(context).selectedSearchMessage) {
      57             :         selected = true;
      58             :       } else {
      59             :         selected = false;
      60             :       }
      61             :     }
      62           0 :     return InkWell(
      63             :       enableFeedback: true,
      64             :       splashFactory: InkSplash.splashFactory,
      65           0 :       child: Ink(
      66           0 :           color: selected ? Provider.of<Settings>(context).theme.backgroundHilightElementColor : Colors.transparent,
      67           0 :           child: Container(
      68           0 :               child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.center, children: [
      69           0 :             Padding(
      70             :                 padding: const EdgeInsets.all(6.0), //border size
      71           0 :                 child: ProfileImage(
      72           0 :                   badgeCount: contact.unreadMessages,
      73           0 :                   badgeColor: Provider.of<Settings>(context).theme.portraitContactBadgeColor,
      74           0 :                   badgeTextColor: Provider.of<Settings>(context).theme.portraitContactBadgeTextColor,
      75             :                   diameter: 64.0,
      76           0 :                   imagePath: Provider.of<Settings>(context).isExperimentEnabled(ImagePreviewsExperiment) ? contact.imagePath : contact.defaultImagePath,
      77           0 :                   disabled: !contact.isOnline(),
      78           0 :                   border: contact.getBorderColor(Provider.of<Settings>(context).theme),
      79             :                 )),
      80           0 :             Expanded(
      81           0 :                 child: Padding(
      82           0 :                     padding: EdgeInsets.all(6.0),
      83           0 :                     child: Column(
      84             :                       crossAxisAlignment: CrossAxisAlignment.start,
      85             :                       mainAxisAlignment: MainAxisAlignment.spaceBetween,
      86             :                       mainAxisSize: MainAxisSize.min,
      87           0 :                       children: [
      88           0 :                         Container(
      89             :                             clipBehavior: Clip.hardEdge,
      90           0 :                             height: Provider.of<Settings>(context).fontScaling * 14.0 + 5.0,
      91           0 :                             decoration: BoxDecoration(),
      92           0 :                             child: Text(
      93           0 :                               contact.augmentedNickname(context).trim() + (contact.messageDraft.isEmpty() ? "" : "*"),
      94           0 :                               style: TextStyle(
      95           0 :                                   fontSize: Provider.of<Settings>(context).fontScaling * 14.0,
      96             :                                   fontFamily: "Inter",
      97             :                                   fontWeight: FontWeight.bold,
      98           0 :                                   color: contact.isBlocked
      99           0 :                                       ? Provider.of<Settings>(context).theme.portraitBlockedTextColor
     100           0 :                                       : Provider.of<Settings>(context).theme.mainTextColor), //Provider.of<FlwtchState>(context).biggerFont,
     101             :                               softWrap: true,
     102             :                               overflow: TextOverflow.clip,
     103             :                               maxLines: 1,
     104             :                             )),
     105             :                         syncStatus ??
     106           0 :                             SizedBox(
     107             :                               width: 0,
     108             :                               height: 0,
     109             :                             ),
     110             :                         // we need to ignore the child widget in this context, otherwise gesture events will flow down...
     111           0 :                         IgnorePointer(
     112             :                             ignoring: true,
     113           0 :                             child: Visibility(
     114           0 :                               visible: this.cachedMessage != null,
     115             :                               maintainSize: false,
     116             :                               maintainInteractivity: false,
     117             :                               maintainSemantics: false,
     118             :                               maintainState: false,
     119           0 :                               child: this.cachedMessage == null ? CircularProgressIndicator() : this.cachedMessage!.getPreviewWidget(context),
     120             :                             )),
     121           0 :                         Container(
     122           0 :                             padding: EdgeInsets.all(0),
     123           0 :                             height: contact.isInvitation ? Provider.of<Settings>(context).fontScaling * 14.0 + 35.0 : Provider.of<Settings>(context).fontScaling * 14.0 + 5.0,
     124           0 :                             child: contact.isInvitation == true
     125           0 :                                 ? FittedBox(
     126             :                                     fit: BoxFit.cover,
     127           0 :                                     child: Row(mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.center, children: <Widget>[
     128           0 :                                       Padding(
     129           0 :                                           padding: EdgeInsets.all(2),
     130           0 :                                           child: TextButton.icon(
     131           0 :                                             label: Text(
     132           0 :                                               AppLocalizations.of(context)!.tooltipAcceptContactRequest,
     133           0 :                                               style: Provider.of<Settings>(context).scaleFonts(defaultTextButtonStyle),
     134             :                                             ),
     135           0 :                                             icon: Icon(
     136             :                                               Icons.favorite,
     137             :                                               size: 16,
     138           0 :                                               color: Provider.of<Settings>(context).theme.mainTextColor,
     139             :                                             ),
     140           0 :                                             onPressed: _btnApprove,
     141             :                                           )),
     142           0 :                                       Padding(
     143           0 :                                           padding: EdgeInsets.all(2),
     144           0 :                                           child: TextButton.icon(
     145           0 :                                             label: Text(
     146           0 :                                               AppLocalizations.of(context)!.tooltipRejectContactRequest,
     147           0 :                                               style: Provider.of<Settings>(context).scaleFonts(defaultTextButtonStyle),
     148             :                                             ),
     149           0 :                                             style: ButtonStyle(
     150           0 :                                                 backgroundColor: MaterialStateProperty.all(Provider.of<Settings>(context).theme.backgroundPaneColor),
     151           0 :                                                 foregroundColor: MaterialStateProperty.all(Provider.of<Settings>(context).theme.mainTextColor)),
     152           0 :                                             icon: Icon(Icons.delete, size: 16, color: Provider.of<Settings>(context).theme.mainTextColor),
     153           0 :                                             onPressed: _btnReject,
     154             :                                           ))
     155             :                                     ]))
     156           0 :                                 : (contact.isBlocked
     157           0 :                                     ? IconButton(
     158           0 :                                         padding: EdgeInsets.symmetric(vertical: 2.0, horizontal: 0.0),
     159           0 :                                         splashRadius: Material.defaultSplashRadius / 2,
     160             :                                         iconSize: 16,
     161           0 :                                         icon: Icon(Icons.block, color: Provider.of<Settings>(context).theme.mainTextColor),
     162             :                                         onPressed: null,
     163             :                                       )
     164           0 :                                     : Text(prettyDateString(context, widget.messageIndex == null ? contact.lastMessageSentTime : (this.cachedMessage?.getMetadata().timestamp ?? DateTime.now())),
     165           0 :                                         style: Provider.of<Settings>(context).scaleFonts(TextStyle(
     166             :                                           fontSize: 12.0,
     167             :                                           fontFamily: "Inter",
     168             :                                         ))))),
     169           0 :                         Visibility(
     170           0 :                             visible: !Provider.of<Settings>(context).streamerMode,
     171           0 :                             child: Container(
     172           0 :                                 padding: EdgeInsets.all(0),
     173           0 :                                 height: Provider.of<Settings>(context).fontScaling * 13.0 + 5.0,
     174           0 :                                 child: FittedBox(
     175             :                                     fit: BoxFit.scaleDown,
     176           0 :                                     child: Text(
     177           0 :                                       contact.onion,
     178             :                                       overflow: TextOverflow.ellipsis,
     179           0 :                                       style: Provider.of<Settings>(context).scaleFonts(TextStyle(
     180             :                                           fontSize: 13.0,
     181             :                                           fontFamily: "RobotoMono",
     182           0 :                                           color: ((contact.isBlocked ? Provider.of<Settings>(context).theme.portraitBlockedTextColor : Provider.of<Settings>(context).theme.mainTextColor) as Color)
     183           0 :                                               .withOpacity(0.8))),
     184             :                                     )))),
     185             :                       ],
     186             :                     ))),
     187           0 :             Visibility(
     188             :                 // only allow pinning for non-blocked and accepted conversations,
     189           0 :                 visible: contact.isAccepted() && (Platform.isAndroid || (!Platform.isAndroid && isHover) || contact.pinned),
     190           0 :                 child: IconButton(
     191           0 :                   tooltip: contact.pinned ? AppLocalizations.of(context)!.tooltipUnpinConversation : AppLocalizations.of(context)!.tooltipPinConversation,
     192           0 :                   icon: Icon(
     193           0 :                     contact.pinned ? Icons.push_pin : Icons.push_pin_outlined,
     194           0 :                     color: Provider.of<Settings>(context).theme.mainTextColor,
     195             :                   ),
     196           0 :                   onPressed: () {
     197           0 :                     if (contact.pinned) {
     198           0 :                       contact.unpin(context);
     199             :                     } else {
     200           0 :                       contact.pin(context);
     201             :                     }
     202           0 :                     Provider.of<ContactListState>(context, listen: false).resort();
     203             :                   },
     204             :                 ))
     205             :           ]))),
     206           0 :       onTap: () {
     207           0 :         setState(() {
     208           0 :           selectConversation(context, contact.identifier, widget.messageIndex);
     209             :         });
     210             :       },
     211           0 :       onHover: (hover) {
     212           0 :         if (isHover != hover) {
     213           0 :           setState(() {
     214           0 :             isHover = hover;
     215             :           });
     216             :         }
     217             :       },
     218             :     );
     219             :   }
     220             : 
     221           0 :   void _btnApprove() {
     222           0 :     Provider.of<ContactInfoState>(context, listen: false).accepted = true;
     223           0 :     Provider.of<FlwtchState>(context, listen: false)
     224           0 :         .cwtch
     225           0 :         .AcceptContact(Provider.of<ContactInfoState>(context, listen: false).profileOnion, Provider.of<ContactInfoState>(context, listen: false).identifier);
     226             :   }
     227             : 
     228           0 :   void _btnReject() {
     229           0 :     Provider.of<ContactInfoState>(context, listen: false).blocked = true;
     230           0 :     ContactInfoState contact = Provider.of<ContactInfoState>(context, listen: false);
     231           0 :     if (contact.isGroup == true) {
     232             :       // FIXME This flow is incorrect. Groups never just show up on the contact list anymore
     233           0 :       Provider.of<ProfileInfoState>(context, listen: false).removeContact(contact.onion);
     234             :     } else {
     235           0 :       Provider.of<FlwtchState>(context, listen: false).cwtch.BlockContact(Provider.of<ContactInfoState>(context, listen: false).profileOnion, contact.identifier);
     236             :     }
     237             :   }
     238             : }

Generated by: LCOV version 1.14