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 : }
|