Line data Source code
1 : import 'package:cwtch/models/profile.dart';
2 : import 'package:cwtch/models/profileservers.dart';
3 : import 'package:cwtch/models/remoteserver.dart';
4 : import 'package:cwtch/models/servers.dart';
5 : import 'package:cwtch/widgets/remoteserverrow.dart';
6 : import 'package:flutter/material.dart';
7 : import 'package:cwtch/l10n/app_localizations.dart';
8 : import 'package:provider/provider.dart';
9 :
10 : import '../cwtch_icons_icons.dart';
11 : import '../main.dart';
12 : import '../settings.dart';
13 :
14 : class ProfileServersView extends StatefulWidget {
15 0 : @override
16 0 : _ProfileServersView createState() => _ProfileServersView();
17 : }
18 :
19 : class _ProfileServersView extends State<ProfileServersView> {
20 0 : @override
21 : void dispose() {
22 0 : super.dispose();
23 : }
24 :
25 0 : @override
26 : Widget build(BuildContext context) {
27 0 : var knownServers = Provider.of<ProfileInfoState>(context).serverList.servers.map<String>((RemoteServerInfoState remoteServer) {
28 0 : return remoteServer.onion + ".onion";
29 0 : }).toSet();
30 0 : var importServerList = Provider.of<ServerListState>(context).servers.where((server) => !knownServers.contains(server.onion)).map<DropdownMenuItem<String>>((ServerInfoState serverInfo) {
31 0 : return DropdownMenuItem<String>(
32 0 : value: serverInfo.onion,
33 0 : child: Text(serverInfo.description.isNotEmpty ? serverInfo.description : serverInfo.onion, overflow: TextOverflow.ellipsis),
34 : );
35 0 : }).toList();
36 :
37 0 : importServerList.insert(0, DropdownMenuItem<String>(value: "", child: Text(AppLocalizations.of(context)!.importLocalServerSelectText)));
38 :
39 0 : return Scaffold(
40 0 : backgroundColor: Provider.of<Settings>(context, listen: false).theme.backgroundMainColor,
41 0 : appBar: AppBar(title: Text(MediaQuery.of(context).size.width > 600 ? AppLocalizations.of(context)!.manageKnownServersLong : AppLocalizations.of(context)!.manageKnownServersShort)),
42 0 : body: Consumer<ProfileInfoState>(
43 0 : builder: (context, profile, child) {
44 0 : ProfileServerListState servers = profile.serverList;
45 0 : final tiles = servers.servers.map((RemoteServerInfoState server) {
46 0 : return ChangeNotifierProvider<RemoteServerInfoState>.value(value: server, builder: (context, child) => RemoteServerRow());
47 : });
48 :
49 0 : final divided = ListTile.divideTiles(context: context, tiles: tiles).toList();
50 :
51 0 : final importCard = Card(
52 0 : child: ListTile(
53 0 : title: Text(AppLocalizations.of(context)!.importLocalServerLabel),
54 0 : leading: Icon(CwtchIcons.add_circle_24px, color: Provider.of<Settings>(context).current().mainTextColor),
55 0 : trailing: DropdownButton(
56 0 : onChanged: (String? importServer) {
57 0 : if (importServer!.isNotEmpty) {
58 0 : var server = Provider.of<ServerListState>(context).getServer(importServer)!;
59 0 : showImportConfirm(context, profile.onion, server.onion, server.description, server.serverBundle);
60 : }
61 : },
62 : value: "",
63 : items: importServerList,
64 : ),
65 : ),
66 : );
67 :
68 0 : return LayoutBuilder(
69 0 : builder: (BuildContext context, BoxConstraints viewportConstraints) {
70 0 : ScrollController controller = ScrollController();
71 0 : return Scrollbar(
72 : trackVisibility: true,
73 : controller: controller,
74 0 : child: SingleChildScrollView(
75 : clipBehavior: Clip.antiAlias,
76 : controller: controller,
77 0 : child: Container(
78 0 : margin: EdgeInsets.fromLTRB(5, 0, 5, 10),
79 0 : padding: EdgeInsets.fromLTRB(5, 0, 5, 10),
80 0 : child: Column(
81 0 : children: [
82 0 : if (importServerList.length > 1) importCard,
83 0 : Column(children: divided),
84 : ],
85 : ),
86 : ),
87 : ),
88 : );
89 : },
90 : );
91 :
92 : return ListView(children: divided);
93 : },
94 : ),
95 : );
96 : }
97 :
98 0 : showImportConfirm(BuildContext context, String profileHandle, String serverHandle, String serverDesc, String bundle) {
99 0 : var serverLabel = serverDesc.isNotEmpty ? serverDesc : serverHandle;
100 0 : serverHandle = serverHandle.substring(0, serverHandle.length - 6); // remove '.onion'
101 : // set up the buttons
102 0 : Widget cancelButton = ElevatedButton(
103 0 : child: Text(AppLocalizations.of(context)!.cancel),
104 0 : onPressed: () {
105 0 : Navigator.of(context).pop(); // dismiss dialog
106 : },
107 : );
108 0 : Widget continueButton = ElevatedButton(
109 0 : child: Text(AppLocalizations.of(context)!.importLocalServerButton.replaceAll("%1", serverLabel)),
110 0 : onPressed: () {
111 0 : Provider.of<FlwtchState>(context, listen: false).cwtch.ImportBundle(profileHandle, bundle);
112 : // Wait 500ms and hope the server is imported and add it's description in the UI and as an attribute
113 0 : Future.delayed(const Duration(milliseconds: 500), () {
114 0 : var profile = Provider.of<ProfileInfoState>(context);
115 0 : if (profile.serverList.getServer(serverHandle) != null) {
116 0 : profile.serverList.getServer(serverHandle)?.updateDescription(serverDesc);
117 :
118 0 : Provider.of<FlwtchState>(context, listen: false).cwtch.SetConversationAttribute(profile.onion, profile.serverList.getServer(serverHandle)!.identifier, "server.description", serverDesc);
119 : }
120 : });
121 0 : Navigator.of(context).pop();
122 : },
123 : );
124 :
125 : // set up the AlertDialog
126 0 : AlertDialog alert = AlertDialog(title: Text(AppLocalizations.of(context)!.importLocalServerButton.replaceAll("%1", serverLabel)), actions: [cancelButton, continueButton]);
127 :
128 : // show the dialog
129 0 : showDialog(
130 : context: context,
131 0 : builder: (BuildContext context) {
132 : return alert;
133 : },
134 : );
135 : }
136 : }
|