LCOV - code coverage report
Current view: top level - lib/widgets - contactrow.dart (source / functions) Hit Total Coverage
Test: lcov.info Lines: 0 123 0.0 %
Date: 2024-02-26 20:09:01 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: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.center, children: [
      68           0 :             Padding(
      69             :                 padding: const EdgeInsets.all(6.0), //border size
      70           0 :                 child: ProfileImage(
      71           0 :                   badgeCount: contact.unreadMessages,
      72           0 :                   badgeColor: Provider.of<Settings>(context).theme.portraitContactBadgeColor,
      73           0 :                   badgeTextColor: Provider.of<Settings>(context).theme.portraitContactBadgeTextColor,
      74             :                   diameter: 64.0,
      75           0 :                   imagePath: Provider.of<Settings>(context).isExperimentEnabled(ImagePreviewsExperiment) ? contact.imagePath : contact.defaultImagePath,
      76           0 :                   disabled: !contact.isOnline(),
      77           0 :                   border: contact.getBorderColor(Provider.of<Settings>(context).theme),
      78             :                 )),
      79           0 :             Expanded(
      80           0 :                 child: Padding(
      81           0 :                     padding: EdgeInsets.all(6.0),
      82           0 :                     child: Column(
      83             :                       crossAxisAlignment: CrossAxisAlignment.start,
      84             :                       mainAxisAlignment: MainAxisAlignment.spaceBetween,
      85             :                       mainAxisSize: MainAxisSize.min,
      86           0 :                       children: [
      87           0 :                         Container(
      88             :                             clipBehavior: Clip.hardEdge,
      89           0 :                             height: Provider.of<Settings>(context).fontScaling * 14.0 + 5.0,
      90           0 :                             decoration: BoxDecoration(),
      91           0 :                             child: Text(
      92           0 :                               contact.augmentedNickname(context).trim() + (contact.messageDraft.isEmpty() ? "" : "*"),
      93           0 :                               style: TextStyle(
      94           0 :                                   fontSize: Provider.of<Settings>(context).fontScaling * 14.0,
      95             :                                   fontFamily: "Inter",
      96             :                                   fontWeight: FontWeight.bold,
      97           0 :                                   color: contact.isBlocked
      98           0 :                                       ? Provider.of<Settings>(context).theme.portraitBlockedTextColor
      99           0 :                                       : Provider.of<Settings>(context).theme.mainTextColor), //Provider.of<FlwtchState>(context).biggerFont,
     100             :                               softWrap: true,
     101             :                               overflow: TextOverflow.clip,
     102             :                               maxLines: 1,
     103             :                             )),
     104             :                         syncStatus ??
     105           0 :                             SizedBox(
     106             :                               width: 0,
     107             :                               height: 0,
     108             :                             ),
     109             :                         // we need to ignore the child widget in this context, otherwise gesture events will flow down...
     110           0 :                         IgnorePointer(
     111             :                             ignoring: true,
     112           0 :                             child: Visibility(
     113           0 :                               visible: this.cachedMessage != null,
     114             :                               maintainSize: false,
     115             :                               maintainInteractivity: false,
     116             :                               maintainSemantics: false,
     117             :                               maintainState: false,
     118           0 :                               child: this.cachedMessage == null ? CircularProgressIndicator() : this.cachedMessage!.getPreviewWidget(context),
     119             :                             )),
     120           0 :                         Container(
     121           0 :                             padding: EdgeInsets.all(0),
     122           0 :                             height: contact.isInvitation ? Provider.of<Settings>(context).fontScaling * 14.0 + 35.0 : Provider.of<Settings>(context).fontScaling * 14.0 + 5.0,
     123           0 :                             child: contact.isInvitation == true
     124           0 :                                 ? Wrap(alignment: WrapAlignment.start, direction: Axis.vertical, children: <Widget>[
     125           0 :                                     Padding(
     126           0 :                                         padding: EdgeInsets.all(2),
     127           0 :                                         child: TextButton.icon(
     128           0 :                                           label: Text(
     129           0 :                                             AppLocalizations.of(context)!.tooltipAcceptContactRequest,
     130           0 :                                             style: Provider.of<Settings>(context).scaleFonts(defaultTextButtonStyle),
     131             :                                           ),
     132           0 :                                           icon: Icon(
     133             :                                             Icons.favorite,
     134             :                                             size: 16,
     135           0 :                                             color: Provider.of<Settings>(context).theme.mainTextColor,
     136             :                                           ),
     137           0 :                                           onPressed: _btnApprove,
     138             :                                         )),
     139           0 :                                     Padding(
     140           0 :                                         padding: EdgeInsets.all(2),
     141           0 :                                         child: TextButton.icon(
     142           0 :                                           label: Text(
     143           0 :                                             AppLocalizations.of(context)!.tooltipRejectContactRequest,
     144           0 :                                             style: Provider.of<Settings>(context).scaleFonts(defaultTextButtonStyle),
     145             :                                           ),
     146           0 :                                           style: ButtonStyle(
     147           0 :                                               backgroundColor: MaterialStateProperty.all(Provider.of<Settings>(context).theme.backgroundPaneColor),
     148           0 :                                               foregroundColor: MaterialStateProperty.all(Provider.of<Settings>(context).theme.mainTextColor)),
     149           0 :                                           icon: Icon(Icons.delete, size: 16, color: Provider.of<Settings>(context).theme.mainTextColor),
     150           0 :                                           onPressed: _btnReject,
     151             :                                         ))
     152             :                                   ])
     153           0 :                                 : (contact.isBlocked
     154           0 :                                     ? IconButton(
     155           0 :                                         padding: EdgeInsets.symmetric(vertical: 2.0, horizontal: 0.0),
     156           0 :                                         splashRadius: Material.defaultSplashRadius / 2,
     157             :                                         iconSize: 16,
     158           0 :                                         icon: Icon(Icons.block, color: Provider.of<Settings>(context).theme.mainTextColor),
     159             :                                         onPressed: null,
     160             :                                       )
     161           0 :                                     : Text(prettyDateString(context, widget.messageIndex == null ? contact.lastMessageSentTime : (this.cachedMessage?.getMetadata().timestamp ?? DateTime.now())),
     162           0 :                                         style: Provider.of<Settings>(context).scaleFonts(TextStyle(
     163             :                                           fontSize: 12.0,
     164             :                                           fontFamily: "Inter",
     165             :                                         ))))),
     166           0 :                         Visibility(
     167           0 :                             visible: !Provider.of<Settings>(context).streamerMode,
     168           0 :                             child: Container(
     169           0 :                                 padding: EdgeInsets.all(0),
     170           0 :                                 height: Provider.of<Settings>(context).fontScaling * 13.0 + 5.0,
     171           0 :                                 child: Text(
     172           0 :                                   contact.onion,
     173             :                                   overflow: TextOverflow.ellipsis,
     174           0 :                                   style: Provider.of<Settings>(context).scaleFonts(TextStyle(
     175             :                                       fontSize: 13.0,
     176             :                                       fontFamily: "RobotoMono",
     177           0 :                                       color: ((contact.isBlocked ? Provider.of<Settings>(context).theme.portraitBlockedTextColor : Provider.of<Settings>(context).theme.mainTextColor) as Color)
     178           0 :                                           .withOpacity(0.8))),
     179             :                                 ))),
     180             :                       ],
     181             :                     ))),
     182           0 :             Visibility(
     183             :                 // only allow pinning for non-blocked and accepted conversations,
     184           0 :                 visible: contact.isAccepted() && (Platform.isAndroid || (!Platform.isAndroid && isHover) || contact.pinned),
     185           0 :                 child: IconButton(
     186           0 :                   tooltip: contact.pinned ? AppLocalizations.of(context)!.tooltipUnpinConversation : AppLocalizations.of(context)!.tooltipPinConversation,
     187           0 :                   icon: Icon(
     188           0 :                     contact.pinned ? Icons.push_pin : Icons.push_pin_outlined,
     189           0 :                     color: Provider.of<Settings>(context).theme.mainTextColor,
     190             :                   ),
     191           0 :                   onPressed: () {
     192           0 :                     if (contact.pinned) {
     193           0 :                       contact.unpin(context);
     194             :                     } else {
     195           0 :                       contact.pin(context);
     196             :                     }
     197           0 :                     Provider.of<ContactListState>(context, listen: false).resort();
     198             :                   },
     199             :                 ))
     200             :           ])),
     201           0 :       onTap: () {
     202           0 :         setState(() {
     203           0 :           selectConversation(context, contact.identifier, widget.messageIndex);
     204             :         });
     205             :       },
     206           0 :       onHover: (hover) {
     207           0 :         if (isHover != hover) {
     208           0 :           setState(() {
     209           0 :             isHover = hover;
     210             :           });
     211             :         }
     212             :       },
     213             :     );
     214             :   }
     215             : 
     216           0 :   void _btnApprove() {
     217           0 :     Provider.of<ContactInfoState>(context, listen: false).accepted = true;
     218           0 :     Provider.of<FlwtchState>(context, listen: false)
     219           0 :         .cwtch
     220           0 :         .AcceptContact(Provider.of<ContactInfoState>(context, listen: false).profileOnion, Provider.of<ContactInfoState>(context, listen: false).identifier);
     221             :   }
     222             : 
     223           0 :   void _btnReject() {
     224           0 :     Provider.of<ContactInfoState>(context, listen: false).blocked = true;
     225           0 :     ContactInfoState contact = Provider.of<ContactInfoState>(context, listen: false);
     226           0 :     if (contact.isGroup == true) {
     227             :       // FIXME This flow is incorrect. Groups never just show up on the contact list anymore
     228           0 :       Provider.of<ProfileInfoState>(context, listen: false).removeContact(contact.onion);
     229             :     } else {
     230           0 :       Provider.of<FlwtchState>(context, listen: false).cwtch.BlockContact(Provider.of<ContactInfoState>(context, listen: false).profileOnion, contact.identifier);
     231             :     }
     232             :   }
     233             : }

Generated by: LCOV version 1.14