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