LCOV - code coverage report
Current view: top level - lib/views - remoteserverview.dart (source / functions) Hit Total Coverage
Test: lcov.info Lines: 0 88 0.0 %
Date: 2026-07-15 19:28:30 Functions: 0 0 -

          Line data    Source code
       1             : import 'package:cwtch/cwtch_icons_icons.dart';
       2             : import 'package:cwtch/models/contact.dart';
       3             : import 'package:cwtch/models/profile.dart';
       4             : import 'package:cwtch/models/remoteserver.dart';
       5             : import 'package:cwtch/widgets/buttontextfield.dart';
       6             : import 'package:cwtch/widgets/cwtchlabel.dart';
       7             : import 'package:flutter/material.dart';
       8             : import 'package:cwtch/settings.dart';
       9             : import 'package:provider/provider.dart';
      10             : import 'package:cwtch/l10n/app_localizations.dart';
      11             : 
      12             : import '../main.dart';
      13             : import '../themes/opaque.dart';
      14             : 
      15             : /// Pane to add or edit a server
      16             : class RemoteServerView extends StatefulWidget {
      17           0 :   const RemoteServerView();
      18             : 
      19           0 :   @override
      20           0 :   _RemoteServerViewState createState() => _RemoteServerViewState();
      21             : }
      22             : 
      23             : class _RemoteServerViewState extends State<RemoteServerView> {
      24             :   final _formKey = GlobalKey<FormState>();
      25             : 
      26             :   final ctrlrDesc = TextEditingController(text: "");
      27             : 
      28           0 :   @override
      29             :   void initState() {
      30           0 :     super.initState();
      31             :   }
      32             : 
      33           0 :   @override
      34             :   void dispose() {
      35           0 :     super.dispose();
      36             :   }
      37             : 
      38           0 :   @override
      39             :   Widget build(BuildContext context) {
      40           0 :     var serverInfoState = Provider.of<RemoteServerInfoState>(context, listen: false);
      41           0 :     if (serverInfoState.description.isNotEmpty) {
      42           0 :       ctrlrDesc.text = serverInfoState.description;
      43             :     }
      44             : 
      45           0 :     return Consumer3<ProfileInfoState, RemoteServerInfoState, Settings>(
      46           0 :       builder: (context, profile, serverInfoState, settings, child) {
      47           0 :         return Scaffold(
      48           0 :           backgroundColor: Provider.of<Settings>(context).theme.backgroundMainColor,
      49           0 :           appBar: AppBar(title: Text(ctrlrDesc.text.isNotEmpty ? ctrlrDesc.text : serverInfoState.onion)),
      50           0 :           body: Container(
      51           0 :             margin: EdgeInsets.fromLTRB(30, 0, 30, 10),
      52           0 :             padding: EdgeInsets.fromLTRB(20, 0, 20, 10),
      53           0 :             child: Column(
      54             :               mainAxisAlignment: MainAxisAlignment.start,
      55             :               crossAxisAlignment: CrossAxisAlignment.start,
      56           0 :               children: [
      57           0 :                 SizedBox(height: 20),
      58           0 :                 CwtchLabel(label: AppLocalizations.of(context)!.serverAddress),
      59           0 :                 SizedBox(height: 20),
      60           0 :                 SelectableText(serverInfoState.onion),
      61             : 
      62             :                 // Description
      63           0 :                 SizedBox(height: 20),
      64           0 :                 CwtchLabel(label: AppLocalizations.of(context)!.serverDescriptionLabel),
      65           0 :                 Text(AppLocalizations.of(context)!.serverDescriptionDescription),
      66           0 :                 SizedBox(height: 20),
      67           0 :                 CwtchButtonTextField(
      68           0 :                   controller: ctrlrDesc,
      69             :                   readonly: false,
      70           0 :                   tooltip: AppLocalizations.of(context)!.saveBtn,
      71           0 :                   labelText: AppLocalizations.of(context)!.fieldDescriptionLabel,
      72           0 :                   icon: Icon(Icons.save),
      73           0 :                   onPressed: () {
      74           0 :                     Provider.of<FlwtchState>(context, listen: false).cwtch.SetConversationAttribute(profile.onion, serverInfoState.identifier, "server.description", ctrlrDesc.text);
      75           0 :                     serverInfoState.updateDescription(ctrlrDesc.text);
      76             :                   },
      77             :                 ),
      78             : 
      79           0 :                 SizedBox(height: 20),
      80           0 :                 Row(
      81             :                   crossAxisAlignment: CrossAxisAlignment.center,
      82             :                   mainAxisAlignment: MainAxisAlignment.end,
      83           0 :                   children: [
      84           0 :                     Tooltip(
      85           0 :                       message: serverInfoState.groups.isNotEmpty ? AppLocalizations.of(context)!.cannotDeleteServerIfActiveGroups : AppLocalizations.of(context)!.leaveConversation,
      86           0 :                       child: ElevatedButton.icon(
      87           0 :                         onPressed: serverInfoState.groups.isNotEmpty
      88             :                             ? null
      89           0 :                             : () {
      90           0 :                                 showAlertDialog(context);
      91             :                               },
      92           0 :                         icon: Icon(CwtchIcons.leave_group),
      93           0 :                         label: Text(AppLocalizations.of(context)!.deleteBtn, style: settings.scaleFonts(defaultTextButtonStyle)),
      94             :                       ),
      95             :                     ),
      96             :                   ],
      97             :                 ),
      98           0 :                 Padding(padding: EdgeInsets.all(8), child: Text(AppLocalizations.of(context)!.groupsOnThisServerLabel)),
      99           0 :                 Expanded(child: _buildGroupsList(serverInfoState)),
     100             :               ],
     101             :             ),
     102             :           ),
     103             :         );
     104             :       },
     105             :     );
     106             :   }
     107             : 
     108           0 :   Widget _buildGroupsList(RemoteServerInfoState serverInfoState) {
     109           0 :     final tiles = serverInfoState.groups.map((ContactInfoState group) {
     110           0 :       return ChangeNotifierProvider<ContactInfoState>.value(
     111             :         value: group,
     112           0 :         builder: (context, child) => RepaintBoundary(child: _buildGroupRow(group)), // ServerRow()),
     113             :       );
     114             :     });
     115             : 
     116           0 :     final divided = ListTile.divideTiles(context: context, tiles: tiles).toList();
     117             : 
     118           0 :     var size = MediaQuery.of(context).size;
     119             : 
     120           0 :     int cols = ((size.width - 50) / 500).ceil();
     121             :     final double itemHeight = 60; // magic arbitary
     122           0 :     final double itemWidth = (size.width - 50 /* magic padding guess */ ) / cols;
     123             : 
     124           0 :     return GridView.count(crossAxisCount: cols, childAspectRatio: (itemWidth / itemHeight), children: divided);
     125             :   }
     126             : 
     127           0 :   Widget _buildGroupRow(ContactInfoState group) {
     128           0 :     return Padding(
     129             :       padding: const EdgeInsets.all(6.0), //border size
     130           0 :       child: Column(
     131           0 :         children: [
     132           0 :           Text(
     133           0 :             group.nickname,
     134           0 :             style: TextStyle(fontWeight: FontWeight.bold, color: Provider.of<Settings>(context).theme.portraitOnlineBorderColor),
     135             :             softWrap: true,
     136             :             overflow: TextOverflow.ellipsis,
     137             :           ),
     138           0 :           Visibility(
     139           0 :             visible: !Provider.of<Settings>(context).streamerMode,
     140           0 :             child: ExcludeSemantics(
     141           0 :               child: Text(
     142           0 :                 group.onion,
     143             :                 softWrap: true,
     144             :                 overflow: TextOverflow.ellipsis,
     145           0 :                 style: TextStyle(color: Provider.of<Settings>(context).theme.portraitOnlineBorderColor),
     146             :               ),
     147             :             ),
     148             :           ),
     149             :         ],
     150             :       ),
     151             :     );
     152             :   }
     153             : }
     154             : 
     155           0 : showAlertDialog(BuildContext context) {
     156             :   // set up the buttons
     157           0 :   Widget cancelButton = ElevatedButton(
     158           0 :     child: Text(AppLocalizations.of(context)!.cancel),
     159           0 :     onPressed: () {
     160           0 :       Navigator.of(context).pop(); // dismiss dialog
     161             :     },
     162             :   );
     163           0 :   Widget continueButton = ElevatedButton(
     164           0 :     style: ButtonStyle(padding: MaterialStateProperty.all(EdgeInsets.all(20))),
     165           0 :     child: Text(AppLocalizations.of(context)!.deleteServerConfirmBtn),
     166           0 :     onPressed: () {
     167           0 :       var profileOnion = Provider.of<ProfileInfoState>(context, listen: false).onion;
     168           0 :       var serverInfoState = Provider.of<RemoteServerInfoState>(context, listen: false);
     169           0 :       Provider.of<FlwtchState>(context, listen: false).cwtch.DeleteServerInfo(profileOnion, serverInfoState.onion);
     170           0 :       Navigator.popUntil(context, (route) => route.settings.name == "profileremoteservers");
     171             :     },
     172             :   );
     173             : 
     174             :   // set up the AlertDialog
     175           0 :   AlertDialog alert = AlertDialog(title: Text(AppLocalizations.of(context)!.deleteServerConfirmBtn), actions: [cancelButton, continueButton]);
     176             : 
     177             :   // show the dialog
     178           0 :   showDialog(
     179             :     context: context,
     180           0 :     builder: (BuildContext context) {
     181             :       return alert;
     182             :     },
     183             :   );
     184             : }

Generated by: LCOV version 1.14