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

Generated by: LCOV version 1.14