Line data Source code
1 : import 'package:cwtch/cwtch_icons_icons.dart';
2 : import 'package:cwtch/models/appstate.dart';
3 : import 'package:cwtch/models/contact.dart';
4 : import 'package:cwtch/models/profile.dart';
5 : import 'package:cwtch/themes/opaque.dart';
6 : import 'package:flutter/services.dart';
7 : import 'package:cwtch/widgets/buttontextfield.dart';
8 : import 'package:cwtch/widgets/cwtchlabel.dart';
9 : import 'package:flutter/material.dart';
10 : import 'package:cwtch/settings.dart';
11 : import 'package:cwtch/widgets/textfield.dart';
12 : import 'package:provider/provider.dart';
13 : import 'package:cwtch/l10n/app_localizations.dart';
14 :
15 : import '../main.dart';
16 :
17 : /// Group Settings View Provides way to Configure group settings
18 : class GroupSettingsView extends StatefulWidget {
19 0 : @override
20 0 : _GroupSettingsViewState createState() => _GroupSettingsViewState();
21 : }
22 :
23 : class _GroupSettingsViewState extends State<GroupSettingsView> {
24 0 : @override
25 : void dispose() {
26 0 : super.dispose();
27 : }
28 :
29 : final ctrlrNick = TextEditingController(text: "");
30 : final ctrlrGroupAddr = TextEditingController(text: "");
31 : ScrollController groupSettingsScrollController = ScrollController();
32 :
33 0 : @override
34 : void initState() {
35 0 : super.initState();
36 0 : final nickname = Provider.of<ContactInfoState>(context, listen: false).nickname;
37 0 : if (nickname.isNotEmpty) {
38 0 : ctrlrNick.text = nickname;
39 : }
40 0 : final groupAddr = Provider.of<ContactInfoState>(context, listen: false).onion;
41 0 : if (groupAddr.isNotEmpty) {
42 0 : ctrlrGroupAddr.text = groupAddr;
43 : }
44 : }
45 :
46 0 : @override
47 : Widget build(BuildContext context) {
48 0 : return Scaffold(
49 0 : appBar: AppBar(
50 0 : title: Container(
51 0 : height: Provider.of<Settings>(context).fontScaling * 24.0,
52 : clipBehavior: Clip.hardEdge,
53 0 : decoration: BoxDecoration(),
54 0 : child: Text(Provider.of<ContactInfoState>(context).nickname + " " + AppLocalizations.of(context)!.conversationSettings),
55 : ),
56 : ),
57 0 : body: _buildSettingsList(),
58 : );
59 : }
60 :
61 0 : Widget _buildSettingsList() {
62 0 : return Consumer<Settings>(
63 0 : builder: (context, settings, child) {
64 0 : return LayoutBuilder(
65 0 : builder: (BuildContext context, BoxConstraints viewportConstraints) {
66 0 : return Scrollbar(
67 : trackVisibility: true,
68 0 : controller: groupSettingsScrollController,
69 0 : child: SingleChildScrollView(
70 : clipBehavior: Clip.antiAlias,
71 0 : controller: groupSettingsScrollController,
72 0 : child: ConstrainedBox(
73 0 : constraints: BoxConstraints(minHeight: viewportConstraints.maxHeight),
74 0 : child: Container(
75 0 : color: settings.theme.backgroundPaneColor,
76 0 : padding: EdgeInsets.all(12),
77 0 : child: Column(
78 : mainAxisAlignment: MainAxisAlignment.start,
79 : crossAxisAlignment: CrossAxisAlignment.stretch,
80 0 : children: [
81 : // Nickname Save Button
82 0 : Column(
83 : mainAxisAlignment: MainAxisAlignment.start,
84 : crossAxisAlignment: CrossAxisAlignment.start,
85 0 : children: [
86 0 : SizedBox(height: 20),
87 0 : CwtchLabel(label: AppLocalizations.of(context)!.displayNameLabel),
88 0 : SizedBox(height: 20),
89 0 : CwtchButtonTextField(
90 0 : controller: ctrlrNick,
91 : readonly: false,
92 0 : onPressed: () {
93 0 : var profileOnion = Provider.of<ContactInfoState>(context, listen: false).profileOnion;
94 0 : var handle = Provider.of<ContactInfoState>(context, listen: false).identifier;
95 0 : Provider.of<ContactInfoState>(context, listen: false).nickname = ctrlrNick.text;
96 0 : Provider.of<FlwtchState>(context, listen: false).cwtch.SetConversationAttribute(profileOnion, handle, "profile.name", ctrlrNick.text);
97 : // todo translations
98 0 : final snackBar = SnackBar(content: Text("Group Nickname changed successfully"));
99 0 : ScaffoldMessenger.of(context).showSnackBar(snackBar);
100 : },
101 0 : icon: Icon(Icons.save),
102 0 : tooltip: AppLocalizations.of(context)!.saveBtn,
103 : ),
104 : ],
105 : ),
106 0 : Column(
107 : mainAxisAlignment: MainAxisAlignment.start,
108 : crossAxisAlignment: CrossAxisAlignment.start,
109 0 : children: [
110 0 : SizedBox(height: 20),
111 0 : CwtchLabel(label: AppLocalizations.of(context)!.server),
112 0 : SizedBox(height: 20),
113 0 : CwtchTextField(
114 0 : controller: TextEditingController(text: Provider.of<ContactInfoState>(context, listen: false).server),
115 0 : validator: (value) {
116 : return null;
117 : },
118 : hintText: '',
119 : ),
120 : ],
121 : ),
122 :
123 0 : Column(
124 : mainAxisAlignment: MainAxisAlignment.start,
125 : crossAxisAlignment: CrossAxisAlignment.start,
126 0 : children: [
127 0 : SizedBox(height: 20),
128 0 : CwtchLabel(label: AppLocalizations.of(context)!.conversationSettings),
129 0 : SizedBox(height: 20),
130 0 : ListTile(
131 0 : title: Text(AppLocalizations.of(context)!.conversationNotificationPolicySettingLabel, style: TextStyle(color: settings.current().mainTextColor)),
132 0 : subtitle: Text(AppLocalizations.of(context)!.conversationNotificationPolicySettingDescription),
133 0 : leading: Icon(CwtchIcons.chat_bubble_empty_24px, color: settings.current().mainTextColor),
134 0 : trailing: DropdownButton(
135 0 : value: Provider.of<ContactInfoState>(context).notificationsPolicy,
136 0 : items: ConversationNotificationPolicy.values.map<DropdownMenuItem<ConversationNotificationPolicy>>((ConversationNotificationPolicy value) {
137 0 : return DropdownMenuItem<ConversationNotificationPolicy>(
138 : value: value,
139 0 : child: Text(value.toName(context), style: settings.scaleFonts(defaultDropDownMenuItemTextStyle)),
140 : );
141 0 : }).toList(),
142 0 : onChanged: (ConversationNotificationPolicy? newVal) {
143 0 : Provider.of<ContactInfoState>(context, listen: false).notificationsPolicy = newVal!;
144 0 : var profileOnion = Provider.of<ContactInfoState>(context, listen: false).profileOnion;
145 0 : var identifier = Provider.of<ContactInfoState>(context, listen: false).identifier;
146 : const NotificationPolicyKey = "profile.notification-policy";
147 0 : Provider.of<FlwtchState>(context, listen: false).cwtch.SetConversationAttribute(profileOnion, identifier, NotificationPolicyKey, newVal.toString());
148 : },
149 : ),
150 : ),
151 : ],
152 : ),
153 :
154 0 : Column(
155 : mainAxisAlignment: MainAxisAlignment.start,
156 : crossAxisAlignment: CrossAxisAlignment.end,
157 0 : children: [
158 0 : SizedBox(height: 20),
159 0 : Tooltip(
160 0 : message: AppLocalizations.of(context)!.archiveConversation,
161 0 : child: OutlinedButton.icon(
162 0 : onPressed: () {
163 0 : var profileOnion = Provider.of<ContactInfoState>(context, listen: false).profileOnion;
164 0 : var handle = Provider.of<ContactInfoState>(context, listen: false).identifier;
165 : // locally update cache...
166 0 : Provider.of<ContactInfoState>(context, listen: false).isArchived = true;
167 0 : Provider.of<FlwtchState>(context, listen: false).cwtch.ArchiveConversation(profileOnion, handle);
168 0 : Future.delayed(Duration(milliseconds: 500), () {
169 0 : Provider.of<AppState>(context, listen: false).selectedConversation = null;
170 0 : Navigator.of(context).popUntil((route) => route.settings.name == "conversations"); // dismiss dialog
171 : });
172 : },
173 0 : icon: Icon(CwtchIcons.leave_chat),
174 0 : label: Text(AppLocalizations.of(context)!.archiveConversation),
175 : ),
176 : ),
177 0 : SizedBox(height: 20),
178 0 : Row(
179 : crossAxisAlignment: CrossAxisAlignment.center,
180 : mainAxisAlignment: MainAxisAlignment.end,
181 0 : children: [
182 0 : Tooltip(
183 0 : message: AppLocalizations.of(context)!.leaveConversation,
184 0 : child: OutlinedButton.icon(
185 0 : onPressed: () {
186 0 : showAlertDialog(context);
187 : },
188 0 : icon: Icon(CwtchIcons.leave_group),
189 0 : label: Text(AppLocalizations.of(context)!.leaveConversation),
190 : ),
191 : ),
192 : ],
193 : ),
194 : ],
195 : ),
196 : ],
197 : ),
198 : ),
199 : ),
200 : ),
201 : );
202 : },
203 : );
204 : },
205 : );
206 : }
207 :
208 0 : void _copyOnion() {
209 0 : Clipboard.setData(new ClipboardData(text: Provider.of<ContactInfoState>(context, listen: false).onion));
210 0 : final snackBar = SnackBar(content: Text(AppLocalizations.of(context)!.copiedToClipboardNotification));
211 0 : ScaffoldMessenger.of(context).showSnackBar(snackBar);
212 : }
213 :
214 0 : showAlertDialog(BuildContext context) {
215 : // set up the buttons
216 0 : Widget cancelButton = ElevatedButton(
217 0 : child: Text(AppLocalizations.of(context)!.cancel),
218 0 : onPressed: () {
219 0 : Navigator.of(context).pop(); // dismiss dialog
220 : },
221 : );
222 0 : Widget continueButton = ElevatedButton(
223 0 : style: ButtonStyle(padding: MaterialStateProperty.all(EdgeInsets.all(20))),
224 0 : child: Text(AppLocalizations.of(context)!.yesLeave),
225 0 : onPressed: () {
226 0 : var profileOnion = Provider.of<ContactInfoState>(context, listen: false).profileOnion;
227 0 : var identifier = Provider.of<ContactInfoState>(context, listen: false).identifier;
228 : // locally update cache...
229 0 : Provider.of<ContactInfoState>(context, listen: false).isArchived = true;
230 0 : Provider.of<ProfileInfoState>(context, listen: false).contactList.removeContact(identifier);
231 0 : Provider.of<FlwtchState>(context, listen: false).cwtch.DeleteContact(profileOnion, identifier);
232 0 : Future.delayed(Duration(milliseconds: 500), () {
233 0 : Provider.of<AppState>(context, listen: false).selectedConversation = null;
234 0 : Navigator.of(context).popUntil((route) => route.settings.name == "conversations"); // dismiss dialog
235 : });
236 : },
237 : );
238 :
239 : // set up the AlertDialog
240 0 : AlertDialog alert = AlertDialog(title: Text(AppLocalizations.of(context)!.reallyLeaveThisGroupPrompt), actions: [cancelButton, continueButton]);
241 :
242 : // show the dialog
243 0 : showDialog(
244 : context: context,
245 0 : builder: (BuildContext context) {
246 : return alert;
247 : },
248 : );
249 : }
250 : }
|