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:flutter_gen/gen_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>(builder: (context, profile, serverInfoState, settings, child) {
46 0 : return Scaffold(
47 0 : backgroundColor: Provider.of<Settings>(context).theme.backgroundMainColor,
48 0 : appBar: AppBar(title: Text(ctrlrDesc.text.isNotEmpty ? ctrlrDesc.text : serverInfoState.onion)),
49 0 : body: Container(
50 0 : margin: EdgeInsets.fromLTRB(30, 0, 30, 10),
51 0 : padding: EdgeInsets.fromLTRB(20, 0, 20, 10),
52 0 : child: Column(mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [
53 0 : SizedBox(
54 : height: 20,
55 : ),
56 0 : CwtchLabel(label: AppLocalizations.of(context)!.serverAddress),
57 0 : SizedBox(
58 : height: 20,
59 : ),
60 0 : SelectableText(serverInfoState.onion),
61 :
62 : // Description
63 0 : SizedBox(
64 : height: 20,
65 : ),
66 0 : CwtchLabel(label: AppLocalizations.of(context)!.serverDescriptionLabel),
67 0 : Text(AppLocalizations.of(context)!.serverDescriptionDescription),
68 0 : SizedBox(
69 : height: 20,
70 : ),
71 0 : CwtchButtonTextField(
72 0 : controller: ctrlrDesc,
73 : readonly: false,
74 0 : tooltip: AppLocalizations.of(context)!.saveBtn,
75 0 : labelText: AppLocalizations.of(context)!.fieldDescriptionLabel,
76 0 : icon: Icon(Icons.save),
77 0 : onPressed: () {
78 0 : Provider.of<FlwtchState>(context, listen: false).cwtch.SetConversationAttribute(profile.onion, serverInfoState.identifier, "server.description", ctrlrDesc.text);
79 0 : serverInfoState.updateDescription(ctrlrDesc.text);
80 : },
81 : ),
82 :
83 0 : SizedBox(
84 : height: 20,
85 : ),
86 0 : Row(crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.end, children: [
87 0 : Tooltip(
88 0 : message: serverInfoState.groups.isNotEmpty ? AppLocalizations.of(context)!.cannotDeleteServerIfActiveGroups : AppLocalizations.of(context)!.leaveConversation,
89 0 : child: ElevatedButton.icon(
90 0 : onPressed: serverInfoState.groups.isNotEmpty
91 : ? null
92 0 : : () {
93 0 : showAlertDialog(context);
94 : },
95 0 : icon: Icon(CwtchIcons.leave_group),
96 0 : label: Text(
97 0 : AppLocalizations.of(context)!.deleteBtn,
98 0 : style: settings.scaleFonts(defaultTextButtonStyle),
99 : ),
100 : ))
101 : ]),
102 0 : Padding(
103 0 : padding: EdgeInsets.all(8),
104 0 : child: Text(AppLocalizations.of(context)!.groupsOnThisServerLabel),
105 : ),
106 0 : Expanded(child: _buildGroupsList(serverInfoState)),
107 : ])));
108 : });
109 : }
110 :
111 0 : Widget _buildGroupsList(RemoteServerInfoState serverInfoState) {
112 0 : final tiles = serverInfoState.groups.map(
113 0 : (ContactInfoState group) {
114 0 : return ChangeNotifierProvider<ContactInfoState>.value(
115 : value: group,
116 0 : builder: (context, child) => RepaintBoundary(child: _buildGroupRow(group)), // ServerRow()),
117 : );
118 : },
119 : );
120 :
121 0 : final divided = ListTile.divideTiles(
122 0 : context: context,
123 : tiles: tiles,
124 0 : ).toList();
125 :
126 0 : var size = MediaQuery.of(context).size;
127 :
128 0 : int cols = ((size.width - 50) / 500).ceil();
129 : final double itemHeight = 60; // magic arbitary
130 0 : final double itemWidth = (size.width - 50 /* magic padding guess */) / cols;
131 :
132 0 : return GridView.count(crossAxisCount: cols, childAspectRatio: (itemWidth / itemHeight), children: divided);
133 : }
134 :
135 0 : Widget _buildGroupRow(ContactInfoState group) {
136 0 : return Padding(
137 : padding: const EdgeInsets.all(6.0), //border size
138 0 : child: Column(children: [
139 0 : Text(
140 0 : group.nickname,
141 0 : style: TextStyle(fontWeight: FontWeight.bold, color: Provider.of<Settings>(context).theme.portraitOnlineBorderColor),
142 : softWrap: true,
143 : overflow: TextOverflow.ellipsis,
144 : ),
145 0 : Visibility(
146 0 : visible: !Provider.of<Settings>(context).streamerMode,
147 0 : child: ExcludeSemantics(
148 0 : child: Text(
149 0 : group.onion,
150 : softWrap: true,
151 : overflow: TextOverflow.ellipsis,
152 0 : style: TextStyle(color: Provider.of<Settings>(context).theme.portraitOnlineBorderColor),
153 : )))
154 : ]));
155 : }
156 : }
157 :
158 0 : showAlertDialog(BuildContext context) {
159 : // set up the buttons
160 0 : Widget cancelButton = ElevatedButton(
161 0 : child: Text(AppLocalizations.of(context)!.cancel),
162 0 : onPressed: () {
163 0 : Navigator.of(context).pop(); // dismiss dialog
164 : },
165 : );
166 0 : Widget continueButton = ElevatedButton(
167 0 : style: ButtonStyle(padding: MaterialStateProperty.all(EdgeInsets.all(20))),
168 0 : child: Text(AppLocalizations.of(context)!.deleteServerConfirmBtn),
169 0 : onPressed: () {
170 0 : var profileOnion = Provider.of<ProfileInfoState>(context, listen: false).onion;
171 0 : var serverInfoState = Provider.of<RemoteServerInfoState>(context, listen: false);
172 0 : Provider.of<FlwtchState>(context, listen: false).cwtch.DeleteServerInfo(profileOnion, serverInfoState.onion);
173 0 : Navigator.popUntil(context, (route) => route.settings.name == "profileremoteservers");
174 : },
175 : );
176 :
177 : // set up the AlertDialog
178 0 : AlertDialog alert = AlertDialog(
179 0 : title: Text(AppLocalizations.of(context)!.deleteServerConfirmBtn),
180 0 : actions: [
181 : cancelButton,
182 : continueButton,
183 : ],
184 : );
185 :
186 : // show the dialog
187 0 : showDialog(
188 : context: context,
189 0 : builder: (BuildContext context) {
190 : return alert;
191 : },
192 : );
193 : }
|