forked from cwtch.im/cwtch-ui
server manager
This commit is contained in:
parent
d4b9f1dc55
commit
9789a42e94
|
@ -314,7 +314,9 @@ class FlwtchWorker(context: Context, parameters: WorkerParameters) :
|
|||
}
|
||||
"CreateServer" -> {
|
||||
val password = (a.get("Password") as? String) ?: ""
|
||||
Cwtch.createServer(password)
|
||||
val desc = (a.get("Description") as? String) ?: ""
|
||||
val autostart = (a.get("Autostart") as? Byte) ?: ""
|
||||
Cwtch.createServer(password, desc, autostart)
|
||||
}
|
||||
"DeleteServer" -> {
|
||||
val serverOnion = (a.get("ServerOnion") as? String) ?: ""
|
||||
|
@ -335,6 +337,12 @@ class FlwtchWorker(context: Context, parameters: WorkerParameters) :
|
|||
"ShutdownServers" -> {
|
||||
Cwtch.shutdownServers()
|
||||
}
|
||||
"SetServerAttribute" -> {
|
||||
val serverOnion = (a.get("ServerOnion") as? String) ?: ""
|
||||
val key = (a.get("Key") as? String) ?: ""
|
||||
val v = (a.get("Val") as? String) ?: ""
|
||||
Cwtch.setServerAttribute(serverOnion, key, v)
|
||||
}
|
||||
else -> return Result.failure()
|
||||
}
|
||||
return Result.success()
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import 'package:flutter/src/services/text_input.dart';
|
||||
|
||||
const DefaultPassword = "be gay do crime";
|
||||
|
||||
abstract class Cwtch {
|
||||
// ignore: non_constant_identifier_names
|
||||
Future<void> Start();
|
||||
|
@ -71,7 +73,7 @@ abstract class Cwtch {
|
|||
// ignore: non_constant_identifier_names
|
||||
void LoadServers(String password);
|
||||
// ignore: non_constant_identifier_names
|
||||
void CreateServer(String password);
|
||||
void CreateServer(String password, String description, bool autostart);
|
||||
// ignore: non_constant_identifier_names
|
||||
void DeleteServer(String serverOnion, String password);
|
||||
// ignore: non_constant_identifier_names
|
||||
|
@ -82,6 +84,8 @@ abstract class Cwtch {
|
|||
void ShutdownServer(String serverOnion);
|
||||
// ignore: non_constant_identifier_names
|
||||
void ShutdownServers();
|
||||
// ignore: non_constant_identifier_names
|
||||
void SetServerAttribute(String serverOnion, String key, String val);
|
||||
|
||||
// ignore: non_constant_identifier_names
|
||||
void Shutdown();
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import 'dart:convert';
|
||||
import 'package:cwtch/models/message.dart';
|
||||
import 'package:cwtch/models/profileservers.dart';
|
||||
import 'package:cwtch/models/servers.dart';
|
||||
import 'package:cwtch/notification_manager.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
@ -20,17 +21,20 @@ class CwtchNotifier {
|
|||
late TorStatus torStatus;
|
||||
late NotificationsManager notificationManager;
|
||||
late AppState appState;
|
||||
late ServerListState serverListState;
|
||||
|
||||
CwtchNotifier(ProfileListState pcn, Settings settingsCN, ErrorHandler errorCN, TorStatus torStatusCN, NotificationsManager notificationManagerP, AppState appStateCN) {
|
||||
CwtchNotifier(ProfileListState pcn, Settings settingsCN, ErrorHandler errorCN, TorStatus torStatusCN, NotificationsManager notificationManagerP, AppState appStateCN, ServerListState serverListStateCN) {
|
||||
profileCN = pcn;
|
||||
settings = settingsCN;
|
||||
error = errorCN;
|
||||
torStatus = torStatusCN;
|
||||
notificationManager = notificationManagerP;
|
||||
appState = appStateCN;
|
||||
serverListState = serverListStateCN;
|
||||
}
|
||||
|
||||
void handleMessage(String type, dynamic data) {
|
||||
print("EVENT $type $data");
|
||||
switch (type) {
|
||||
case "CwtchStarted":
|
||||
appState.SetCwtchInit();
|
||||
|
@ -59,11 +63,21 @@ class CwtchNotifier {
|
|||
lastMessageTime: DateTime.now(), //show at the top of the contact list even if no messages yet
|
||||
));
|
||||
break;
|
||||
case "NewServer":
|
||||
var serverData = jsonDecode(data["Data"]);
|
||||
serverListState.add(
|
||||
serverData["onion"],
|
||||
serverData["serverbundle"],
|
||||
serverData["enabled"] == "true",
|
||||
serverData["description"],
|
||||
serverData["autostart"] == "true",
|
||||
serverData["storageType"] == "storage-password");
|
||||
break;
|
||||
case "GroupCreated":
|
||||
|
||||
// Retrieve Server Status from Cache...
|
||||
String status = "";
|
||||
ServerInfoState? serverInfoState = profileCN.getProfile(data["ProfileOnion"])?.serverList.getServer(data["GroupServer"]);
|
||||
RemoteServerInfoState? serverInfoState = profileCN.getProfile(data["ProfileOnion"])?.serverList.getServer(data["GroupServer"]);
|
||||
if (serverInfoState != null) {
|
||||
status = serverInfoState.status;
|
||||
}
|
||||
|
@ -263,7 +277,7 @@ class CwtchNotifier {
|
|||
|
||||
// Retrieve Server Status from Cache...
|
||||
String status = "";
|
||||
ServerInfoState? serverInfoState = profileCN.getProfile(data["ProfileOnion"])!.serverList.getServer(groupInvite["ServerHost"]);
|
||||
RemoteServerInfoState? serverInfoState = profileCN.getProfile(data["ProfileOnion"])!.serverList.getServer(groupInvite["ServerHost"]);
|
||||
if (serverInfoState != null) {
|
||||
status = serverInfoState.status;
|
||||
}
|
||||
|
|
|
@ -42,6 +42,9 @@ typedef VoidFromStringStringStringStringStringFn = void Function(Pointer<Utf8>,
|
|||
typedef void_from_string_string_int_int_function = Void Function(Pointer<Utf8>, Int32, Pointer<Utf8>, Int32, Int64, Int64);
|
||||
typedef VoidFromStringStringIntIntFn = void Function(Pointer<Utf8>, int, Pointer<Utf8>, int, int, int);
|
||||
|
||||
typedef void_from_string_string_byte_function = Void Function(Pointer<Utf8>, Int32, Pointer<Utf8>, Int32, Int8);
|
||||
typedef VoidFromStringStringByteFn = void Function(Pointer<Utf8>, int, Pointer<Utf8>, int, int);
|
||||
|
||||
typedef string_to_void_function = Void Function(Pointer<Utf8> str, Int32 length);
|
||||
typedef StringFn = void Function(Pointer<Utf8> dir, int);
|
||||
|
||||
|
@ -575,13 +578,15 @@ class CwtchFfi implements Cwtch {
|
|||
|
||||
@override
|
||||
// ignore: non_constant_identifier_names
|
||||
void CreateServer(String password) {
|
||||
var createServer = library.lookup<NativeFunction<string_to_void_function>>("c_CreateServer");
|
||||
void CreateServer(String password, String description, bool autostart) {
|
||||
var createServer = library.lookup<NativeFunction<void_from_string_string_byte_function>>("c_CreateServer");
|
||||
// ignore: non_constant_identifier_names
|
||||
final CreateServer = createServer.asFunction<StringFn>();
|
||||
final CreateServer = createServer.asFunction<VoidFromStringStringByteFn>();
|
||||
final u1 = password.toNativeUtf8();
|
||||
CreateServer(u1, u1.length);
|
||||
final u2 = description.toNativeUtf8();
|
||||
CreateServer(u1, u1.length, u2, u2.length, autostart ? 1 : 0);
|
||||
malloc.free(u1);
|
||||
malloc.free(u2);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -637,6 +642,21 @@ class CwtchFfi implements Cwtch {
|
|||
ShutdownServers();
|
||||
}
|
||||
|
||||
@override
|
||||
// ignore: non_constant_identifier_names
|
||||
void SetServerAttribute(String serverOnion, String key, String val) {
|
||||
var setServerAttribute = library.lookup<NativeFunction<void_from_string_string_string_function>>("c_SetServerAttribute");
|
||||
// ignore: non_constant_identifier_names
|
||||
final SetServerAttribute = setServerAttribute.asFunction<VoidFromStringStringStringFn>();
|
||||
final u1 = serverOnion.toNativeUtf8();
|
||||
final u2 = key.toNativeUtf8();
|
||||
final u3 = val.toNativeUtf8();
|
||||
SetServerAttribute(u1, u1.length, u2, u2.length, u3, u3.length);
|
||||
malloc.free(u1);
|
||||
malloc.free(u2);
|
||||
malloc.free(u3);
|
||||
}
|
||||
|
||||
@override
|
||||
// ignore: non_constant_identifier_names
|
||||
Future<void> Shutdown() async {
|
||||
|
|
|
@ -221,8 +221,8 @@ class CwtchGomobile implements Cwtch {
|
|||
|
||||
@override
|
||||
// ignore: non_constant_identifier_names
|
||||
void CreateServer(String password) {
|
||||
cwtchPlatform.invokeMethod("CreateServer", {"Password": password});
|
||||
void CreateServer(String password, String description, bool autostart) {
|
||||
cwtchPlatform.invokeMethod("CreateServer", {"Password": password, "Description": description, "Autostart": autostart ? 1 : 0});
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -255,6 +255,12 @@ class CwtchGomobile implements Cwtch {
|
|||
cwtchPlatform.invokeMethod("ShutdownServers", {});
|
||||
}
|
||||
|
||||
@override
|
||||
// ignore: non_constant_identifier_names
|
||||
void SetServerAttribute(String serverOnion, String key, String val) {
|
||||
cwtchPlatform.invokeMethod("SetServerAttribute", {"ServerOnion": serverOnion, "Key": key, "Val": val});
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> Shutdown() async {
|
||||
print("gomobile.dart Shutdown");
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
{
|
||||
"@@locale": "de",
|
||||
"@@last_modified": "2021-09-21T23:09:19+02:00",
|
||||
"@@last_modified": "2021-10-15T20:45:29+02:00",
|
||||
"titleManageProfilesShort": "Profiles",
|
||||
"descriptionStreamerMode": "If turned on, this option makes the app more visually private for streaming or presenting with, for example, hiding profile and contact addresses",
|
||||
"descriptionFileSharing": "The file sharing experiment allows you to send and receive files from Cwtch contacts and groups. Note that sharing a file with a group will result in members of that group connecting with you directly over Cwtch to download it.",
|
||||
"settingFileSharing": "File Sharing",
|
||||
"tooltipSendFile": "Send File",
|
||||
|
@ -12,7 +14,6 @@
|
|||
"downloadFileButton": "Download",
|
||||
"openFolderButton": "Open Folder",
|
||||
"retrievingManifestMessage": "Retrieving file information...",
|
||||
"descriptionStreamerMode": "If turned on, this option makes the app more visually private for streaming or presenting with, for example, hiding profile and contact onions",
|
||||
"streamerModeLabel": "Streamer\/Presentation Mode",
|
||||
"archiveConversation": "Archive this Conversation",
|
||||
"profileOnionLabel": "Senden Sie diese Adresse an Peers, mit denen Sie sich verbinden möchten",
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
{
|
||||
"@@locale": "en",
|
||||
"@@last_modified": "2021-09-21T23:09:19+02:00",
|
||||
"@@last_modified": "2021-10-15T20:45:29+02:00",
|
||||
"titleManageProfilesShort": "Profiles",
|
||||
"descriptionStreamerMode": "If turned on, this option makes the app more visually private for streaming or presenting with, for example, hiding profile and contact addresses",
|
||||
"descriptionFileSharing": "The file sharing experiment allows you to send and receive files from Cwtch contacts and groups. Note that sharing a file with a group will result in members of that group connecting with you directly over Cwtch to download it.",
|
||||
"settingFileSharing": "File Sharing",
|
||||
"tooltipSendFile": "Send File",
|
||||
|
@ -12,7 +14,6 @@
|
|||
"downloadFileButton": "Download",
|
||||
"openFolderButton": "Open Folder",
|
||||
"retrievingManifestMessage": "Retrieving file information...",
|
||||
"descriptionStreamerMode": "If turned on, this option makes the app more visually private for streaming or presenting with, for example, hiding profile and contact onions",
|
||||
"streamerModeLabel": "Streamer\/Presentation Mode",
|
||||
"archiveConversation": "Archive this Conversation",
|
||||
"profileOnionLabel": "Send this address to people you want to connect with",
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
{
|
||||
"@@locale": "es",
|
||||
"@@last_modified": "2021-09-21T23:09:19+02:00",
|
||||
"@@last_modified": "2021-10-15T20:45:29+02:00",
|
||||
"titleManageProfilesShort": "Profiles",
|
||||
"descriptionStreamerMode": "If turned on, this option makes the app more visually private for streaming or presenting with, for example, hiding profile and contact addresses",
|
||||
"descriptionFileSharing": "The file sharing experiment allows you to send and receive files from Cwtch contacts and groups. Note that sharing a file with a group will result in members of that group connecting with you directly over Cwtch to download it.",
|
||||
"settingFileSharing": "File Sharing",
|
||||
"tooltipSendFile": "Send File",
|
||||
|
@ -12,7 +14,6 @@
|
|||
"downloadFileButton": "Download",
|
||||
"openFolderButton": "Open Folder",
|
||||
"retrievingManifestMessage": "Retrieving file information...",
|
||||
"descriptionStreamerMode": "If turned on, this option makes the app more visually private for streaming or presenting with, for example, hiding profile and contact onions",
|
||||
"streamerModeLabel": "Streamer\/Presentation Mode",
|
||||
"archiveConversation": "Archive this Conversation",
|
||||
"profileOnionLabel": "Envía esta dirección a los contactos con los que quieras conectarte",
|
||||
|
|
|
@ -1,18 +1,19 @@
|
|||
{
|
||||
"@@locale": "fr",
|
||||
"@@last_modified": "2021-09-21T23:09:19+02:00",
|
||||
"descriptionFileSharing": "The file sharing experiment allows you to send and receive files from Cwtch contacts and groups. Note that sharing a file with a group will result in members of that group connecting with you directly over Cwtch to download it.",
|
||||
"settingFileSharing": "File Sharing",
|
||||
"tooltipSendFile": "Send File",
|
||||
"messageFileOffered": "Contact is offering to send you a file",
|
||||
"messageFileSent": "You sent a file",
|
||||
"messageEnableFileSharing": "Enable the file sharing experiment to view this message.",
|
||||
"labelFilesize": "Size",
|
||||
"labelFilename": "Filename",
|
||||
"downloadFileButton": "Download",
|
||||
"openFolderButton": "Open Folder",
|
||||
"retrievingManifestMessage": "Retrieving file information...",
|
||||
"descriptionStreamerMode": "Si elle est activée, cette option donne un rendu visuel plus privé à l'application pour la diffusion ou la présentation, par exemple en masquant les profils et les contacts.",
|
||||
"@@last_modified": "2021-10-15T20:45:29+02:00",
|
||||
"titleManageProfilesShort": "Profiles",
|
||||
"descriptionStreamerMode": "Si elle est activée, cette option donne un rendu visuel plus privé à l'application pour la diffusion en direct ou la présentation, par exemple, en masquant profil et adresses de contacts.",
|
||||
"descriptionFileSharing": "L'expérience de partage de fichiers vous permet d'envoyer et de recevoir des fichiers à partir de contacts et de groupes Cwtch. Notez que si vous partagez un fichier avec un groupe, les membres de ce groupe se connecteront avec vous directement via Cwtch pour le télécharger.",
|
||||
"settingFileSharing": "Partage de fichiers",
|
||||
"tooltipSendFile": "Envoyer le fichier",
|
||||
"messageFileOffered": "Contact vous propose de vous envoyer un fichier",
|
||||
"messageFileSent": "Vous avez envoyé un fichier",
|
||||
"messageEnableFileSharing": "Activez l'expérience de partage de fichiers pour afficher ce message.",
|
||||
"labelFilesize": "Taille",
|
||||
"labelFilename": "Nom de fichier",
|
||||
"downloadFileButton": "Télécharger",
|
||||
"openFolderButton": "Ouvrir le dossier",
|
||||
"retrievingManifestMessage": "Récupération des informations sur le fichier...",
|
||||
"streamerModeLabel": "Mode Streamer\/Présentation",
|
||||
"archiveConversation": "Archiver cette conversation",
|
||||
"profileOnionLabel": "Envoyez cette adresse aux personnes avec lesquelles vous souhaitez entrer en contact.",
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
{
|
||||
"@@locale": "it",
|
||||
"@@last_modified": "2021-09-21T23:09:19+02:00",
|
||||
"descriptionFileSharing": "The file sharing experiment allows you to send and receive files from Cwtch contacts and groups. Note that sharing a file with a group will result in members of that group connecting with you directly over Cwtch to download it.",
|
||||
"settingFileSharing": "File Sharing",
|
||||
"tooltipSendFile": "Send File",
|
||||
"messageFileOffered": "Contact is offering to send you a file",
|
||||
"@@last_modified": "2021-10-15T20:45:29+02:00",
|
||||
"titleManageProfilesShort": "Profiles",
|
||||
"descriptionStreamerMode": "If turned on, this option makes the app more visually private for streaming or presenting with, for example, hiding profile and contact addresses",
|
||||
"descriptionFileSharing": "L'esperimento di condivisione dei file ti consente di inviare e ricevere file dai contatti e dai gruppi di Cwtch. Tieni presente che la condivisione di un file con un gruppo farà sì che i membri di quel gruppo si colleghino con te direttamente su Cwtch per scaricarlo.",
|
||||
"settingFileSharing": "Condivisione file",
|
||||
"tooltipSendFile": "Invia file",
|
||||
"messageFileOffered": "Il contatto offre l'invio di un file",
|
||||
"messageFileSent": "You sent a file",
|
||||
"messageEnableFileSharing": "Enable the file sharing experiment to view this message.",
|
||||
"labelFilesize": "Size",
|
||||
|
@ -12,7 +14,6 @@
|
|||
"downloadFileButton": "Download",
|
||||
"openFolderButton": "Open Folder",
|
||||
"retrievingManifestMessage": "Retrieving file information...",
|
||||
"descriptionStreamerMode": "If turned on, this option makes the app more visually private for streaming or presenting with, for example, hiding profile and contact onions",
|
||||
"streamerModeLabel": "Streamer\/Presentation Mode",
|
||||
"archiveConversation": "Archive this Conversation",
|
||||
"profileOnionLabel": "Inviare questo indirizzo ai peer con cui si desidera connettersi",
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
{
|
||||
"@@locale": "pl",
|
||||
"@@last_modified": "2021-09-21T23:09:19+02:00",
|
||||
"@@last_modified": "2021-10-15T20:45:29+02:00",
|
||||
"titleManageProfilesShort": "Profiles",
|
||||
"descriptionStreamerMode": "If turned on, this option makes the app more visually private for streaming or presenting with, for example, hiding profile and contact addresses",
|
||||
"descriptionFileSharing": "The file sharing experiment allows you to send and receive files from Cwtch contacts and groups. Note that sharing a file with a group will result in members of that group connecting with you directly over Cwtch to download it.",
|
||||
"settingFileSharing": "File Sharing",
|
||||
"tooltipSendFile": "Send File",
|
||||
|
@ -12,7 +14,6 @@
|
|||
"downloadFileButton": "Download",
|
||||
"openFolderButton": "Open Folder",
|
||||
"retrievingManifestMessage": "Retrieving file information...",
|
||||
"descriptionStreamerMode": "If turned on, this option makes the app more visually private for streaming or presenting with, for example, hiding profile and contact onions",
|
||||
"streamerModeLabel": "Streamer\/Presentation Mode",
|
||||
"archiveConversation": "Archive this Conversation",
|
||||
"profileOnionLabel": "Send this address to contacts you want to connect with",
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
{
|
||||
"@@locale": "pt",
|
||||
"@@last_modified": "2021-09-21T23:09:19+02:00",
|
||||
"@@last_modified": "2021-10-15T20:45:29+02:00",
|
||||
"titleManageProfilesShort": "Profiles",
|
||||
"descriptionStreamerMode": "If turned on, this option makes the app more visually private for streaming or presenting with, for example, hiding profile and contact addresses",
|
||||
"descriptionFileSharing": "The file sharing experiment allows you to send and receive files from Cwtch contacts and groups. Note that sharing a file with a group will result in members of that group connecting with you directly over Cwtch to download it.",
|
||||
"settingFileSharing": "File Sharing",
|
||||
"tooltipSendFile": "Send File",
|
||||
|
@ -12,7 +14,6 @@
|
|||
"downloadFileButton": "Download",
|
||||
"openFolderButton": "Open Folder",
|
||||
"retrievingManifestMessage": "Retrieving file information...",
|
||||
"descriptionStreamerMode": "If turned on, this option makes the app more visually private for streaming or presenting with, for example, hiding profile and contact onions",
|
||||
"streamerModeLabel": "Streamer\/Presentation Mode",
|
||||
"archiveConversation": "Archive this Conversation",
|
||||
"profileOnionLabel": "Send this address to contacts you want to connect with",
|
||||
|
|
|
@ -17,6 +17,7 @@ import 'cwtch/cwtch.dart';
|
|||
import 'cwtch/cwtchNotifier.dart';
|
||||
import 'licenses.dart';
|
||||
import 'model.dart';
|
||||
import 'models/servers.dart';
|
||||
import 'views/profilemgrview.dart';
|
||||
import 'views/splashView.dart';
|
||||
import 'dart:io' show Platform, exit;
|
||||
|
@ -27,6 +28,7 @@ var globalSettings = Settings(Locale("en", ''), OpaqueDark());
|
|||
var globalErrorHandler = ErrorHandler();
|
||||
var globalTorStatus = TorStatus();
|
||||
var globalAppState = AppState();
|
||||
var globalServersList = ServerListState();
|
||||
|
||||
void main() {
|
||||
print("Cwtch version: ${EnvironmentConfig.BUILD_VER} built on: ${EnvironmentConfig.BUILD_DATE}");
|
||||
|
@ -62,13 +64,13 @@ class FlwtchState extends State<Flwtch> {
|
|||
shutdownMethodChannel.setMethodCallHandler(modalShutdown);
|
||||
print("initState: creating cwtchnotifier, ffi");
|
||||
if (Platform.isAndroid) {
|
||||
var cwtchNotifier = new CwtchNotifier(profs, globalSettings, globalErrorHandler, globalTorStatus, NullNotificationsManager(), globalAppState);
|
||||
var cwtchNotifier = new CwtchNotifier(profs, globalSettings, globalErrorHandler, globalTorStatus, NullNotificationsManager(), globalAppState, globalServersList);
|
||||
cwtch = CwtchGomobile(cwtchNotifier);
|
||||
} else if (Platform.isLinux) {
|
||||
var cwtchNotifier = new CwtchNotifier(profs, globalSettings, globalErrorHandler, globalTorStatus, newDesktopNotificationsManager(), globalAppState);
|
||||
var cwtchNotifier = new CwtchNotifier(profs, globalSettings, globalErrorHandler, globalTorStatus, newDesktopNotificationsManager(), globalAppState, globalServersList);
|
||||
cwtch = CwtchFfi(cwtchNotifier);
|
||||
} else {
|
||||
var cwtchNotifier = new CwtchNotifier(profs, globalSettings, globalErrorHandler, globalTorStatus, NullNotificationsManager(), globalAppState);
|
||||
var cwtchNotifier = new CwtchNotifier(profs, globalSettings, globalErrorHandler, globalTorStatus, NullNotificationsManager(), globalAppState, globalServersList);
|
||||
cwtch = CwtchFfi(cwtchNotifier);
|
||||
}
|
||||
print("initState: invoking cwtch.Start()");
|
||||
|
@ -82,6 +84,7 @@ class FlwtchState extends State<Flwtch> {
|
|||
ChangeNotifierProvider<AppState> getAppStateProvider() => ChangeNotifierProvider.value(value: globalAppState);
|
||||
Provider<FlwtchState> getFlwtchStateProvider() => Provider<FlwtchState>(create: (_) => this);
|
||||
ChangeNotifierProvider<ProfileListState> getProfileListProvider() => ChangeNotifierProvider(create: (context) => profs);
|
||||
ChangeNotifierProvider<ServerListState> getServerListStateProvider() => ChangeNotifierProvider.value(value: globalServersList);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -94,6 +97,7 @@ class FlwtchState extends State<Flwtch> {
|
|||
getErrorHandlerProvider(),
|
||||
getTorStatusProvider(),
|
||||
getAppStateProvider(),
|
||||
getServerListStateProvider(),
|
||||
],
|
||||
builder: (context, widget) {
|
||||
return Consumer2<Settings, AppState>(
|
||||
|
|
|
@ -2,7 +2,7 @@ import 'dart:convert';
|
|||
|
||||
import 'package:cwtch/widgets/messagerow.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:cwtch/models/servers.dart';
|
||||
import 'package:cwtch/models/profileservers.dart';
|
||||
|
||||
////////////////////
|
||||
/// UI State ///
|
||||
|
@ -207,7 +207,7 @@ class ContactListState extends ChangeNotifier {
|
|||
|
||||
class ProfileInfoState extends ChangeNotifier {
|
||||
ContactListState _contacts = ContactListState();
|
||||
ServerListState _servers = ServerListState();
|
||||
ProfileServerListState _servers = ProfileServerListState();
|
||||
final String onion;
|
||||
String _nickname = "";
|
||||
String _imagePath = "";
|
||||
|
@ -267,7 +267,7 @@ class ProfileInfoState extends ChangeNotifier {
|
|||
List<dynamic> servers = jsonDecode(serversJson);
|
||||
this._servers.replace(servers.map((server) {
|
||||
// TODO Keys...
|
||||
return ServerInfoState(onion: server["onion"], status: server["status"]);
|
||||
return RemoteServerInfoState(onion: server["onion"], status: server["status"]);
|
||||
}));
|
||||
notifyListeners();
|
||||
}
|
||||
|
@ -316,7 +316,7 @@ class ProfileInfoState extends ChangeNotifier {
|
|||
}
|
||||
|
||||
ContactListState get contactList => this._contacts;
|
||||
ServerListState get serverList => this._servers;
|
||||
ProfileServerListState get serverList => this._servers;
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
class ServerListState extends ChangeNotifier {
|
||||
List<ServerInfoState> _servers = [];
|
||||
class ProfileServerListState extends ChangeNotifier {
|
||||
List<RemoteServerInfoState> _servers = [];
|
||||
|
||||
void replace(Iterable<ServerInfoState> newServers) {
|
||||
void replace(Iterable<RemoteServerInfoState> newServers) {
|
||||
_servers.clear();
|
||||
_servers.addAll(newServers);
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
ServerInfoState? getServer(String onion) {
|
||||
RemoteServerInfoState? getServer(String onion) {
|
||||
int idx = _servers.indexWhere((element) => element.onion == onion);
|
||||
return idx >= 0 ? _servers[idx] : null;
|
||||
}
|
||||
|
@ -17,20 +17,20 @@ class ServerListState extends ChangeNotifier {
|
|||
void updateServerCache(String onion, String status) {
|
||||
int idx = _servers.indexWhere((element) => element.onion == onion);
|
||||
if (idx >= 0) {
|
||||
_servers[idx] = ServerInfoState(onion: onion, status: status);
|
||||
_servers[idx] = RemoteServerInfoState(onion: onion, status: status);
|
||||
} else {
|
||||
print("Tried to update server cache without a starting state...this is probably an error");
|
||||
}
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
List<ServerInfoState> get servers => _servers.sublist(0); //todo: copy?? dont want caller able to bypass changenotifier
|
||||
List<RemoteServerInfoState> get servers => _servers.sublist(0); //todo: copy?? dont want caller able to bypass changenotifier
|
||||
|
||||
}
|
||||
|
||||
class ServerInfoState extends ChangeNotifier {
|
||||
class RemoteServerInfoState extends ChangeNotifier {
|
||||
final String onion;
|
||||
final String status;
|
||||
|
||||
ServerInfoState({required this.onion, required this.status});
|
||||
RemoteServerInfoState({required this.onion, required this.status});
|
||||
}
|
|
@ -9,6 +9,7 @@ import 'opaque.dart';
|
|||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
|
||||
const TapirGroupsExperiment = "tapir-groups-experiment";
|
||||
const ServerManagementExperiment = "servers-experiment";
|
||||
const FileSharingExperiment = "filesharing";
|
||||
|
||||
enum DualpaneMode {
|
||||
|
|
|
@ -4,7 +4,7 @@ import 'package:cwtch/cwtch_icons_icons.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:cwtch/errorHandler.dart';
|
||||
import 'package:cwtch/models/servers.dart';
|
||||
import 'package:cwtch/models/profileservers.dart';
|
||||
import 'package:cwtch/settings.dart';
|
||||
import 'package:cwtch/widgets/buttontextfield.dart';
|
||||
import 'package:cwtch/widgets/cwtchlabel.dart';
|
||||
|
@ -197,7 +197,7 @@ class _AddContactViewState extends State<AddContactView> {
|
|||
},
|
||||
isExpanded: true, // magic property
|
||||
value: server,
|
||||
items: Provider.of<ProfileInfoState>(context).serverList.servers.map<DropdownMenuItem<String>>((ServerInfoState serverInfo) {
|
||||
items: Provider.of<ProfileInfoState>(context).serverList.servers.map<DropdownMenuItem<String>>((RemoteServerInfoState serverInfo) {
|
||||
return DropdownMenuItem<String>(
|
||||
value: serverInfo.onion,
|
||||
child: Text(
|
||||
|
@ -240,8 +240,8 @@ class _AddContactViewState extends State<AddContactView> {
|
|||
|
||||
/// TODO Manage Servers Tab
|
||||
Widget manageServersTab() {
|
||||
final tiles = Provider.of<ProfileInfoState>(context).serverList.servers.map((ServerInfoState server) {
|
||||
return ChangeNotifierProvider<ServerInfoState>.value(
|
||||
final tiles = Provider.of<ProfileInfoState>(context).serverList.servers.map((RemoteServerInfoState server) {
|
||||
return ChangeNotifierProvider<RemoteServerInfoState>.value(
|
||||
value: server,
|
||||
child: ListTile(
|
||||
title: Text(server.onion),
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:cwtch/cwtch/cwtch.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:cwtch/model.dart';
|
||||
|
@ -106,6 +107,7 @@ class _AddEditProfileViewState extends State<AddEditProfileView> {
|
|||
labelText: AppLocalizations.of(context)!.yourDisplayName,
|
||||
validator: (value) {
|
||||
if (value.isEmpty) {
|
||||
// TODO l10n ize
|
||||
return "Please enter a display name";
|
||||
}
|
||||
return null;
|
||||
|
@ -287,32 +289,19 @@ class _AddEditProfileViewState extends State<AddEditProfileView> {
|
|||
Provider.of<FlwtchState>(context, listen: false).cwtch.CreateProfile(ctrlrNick.value.text, ctrlrPass.value.text);
|
||||
Navigator.of(context).pop();
|
||||
} else {
|
||||
Provider.of<FlwtchState>(context, listen: false).cwtch.CreateProfile(ctrlrNick.value.text, "be gay do crime");
|
||||
Provider.of<FlwtchState>(context, listen: false).cwtch.CreateProfile(ctrlrNick.value.text, DefaultPassword);
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
} else {
|
||||
// Profile Editing
|
||||
if (ctrlrPass.value.text.isEmpty) {
|
||||
// Don't update password, only update name
|
||||
final event = {
|
||||
"EventType": "SetAttribute",
|
||||
"Data": {"Key": "public.name", "Data": ctrlrNick.value.text}
|
||||
};
|
||||
final json = jsonEncode(event);
|
||||
|
||||
Provider.of<FlwtchState>(context, listen: false).cwtch.SendProfileEvent(Provider.of<ProfileInfoState>(context, listen: false).onion, json);
|
||||
Provider.of<FlwtchState>(context, listen: false).cwtch.SetProfileAttribute(Provider.of<ProfileInfoState>(context, listen: false).onion, "public.name", ctrlrNick.value.text);
|
||||
Navigator.of(context).pop();
|
||||
} else {
|
||||
// At this points passwords have been validated to be the same and not empty
|
||||
// Update both password and name, even if name hasn't been changed...
|
||||
final updateNameEvent = {
|
||||
"EventType": "SetAttribute",
|
||||
"Data": {"Key": "public.name", "Data": ctrlrNick.value.text}
|
||||
};
|
||||
final updateNameEventJson = jsonEncode(updateNameEvent);
|
||||
|
||||
Provider.of<FlwtchState>(context, listen: false).cwtch.SendProfileEvent(Provider.of<ProfileInfoState>(context, listen: false).onion, updateNameEventJson);
|
||||
|
||||
Provider.of<FlwtchState>(context, listen: false).cwtch.SetProfileAttribute(Provider.of<ProfileInfoState>(context, listen: false).onion, "public.name", ctrlrNick.value.text);
|
||||
final updatePasswordEvent = {
|
||||
"EventType": "ChangePassword",
|
||||
"Data": {"Password": ctrlrOldPass.text, "NewPassword": ctrlrPass.text}
|
||||
|
|
|
@ -103,9 +103,10 @@ class _ContactsViewState extends State<ContactsView> {
|
|||
if (Provider.of<Settings>(context).blockUnknownConnections) {
|
||||
actions.add(Tooltip(message: AppLocalizations.of(context)!.blockUnknownConnectionsEnabledDescription, child: Icon(CwtchIcons.block_unknown)));
|
||||
}
|
||||
actions.add(
|
||||
IconButton(icon: TorIcon(), onPressed: _pushTorStatus),
|
||||
);
|
||||
|
||||
// TODO copy ID
|
||||
// TODO servers
|
||||
|
||||
actions.add(IconButton(
|
||||
// need both conditions for displaying initial empty textfield and also allowing filters to be cleared if this widget gets lost/reset
|
||||
icon: Icon(showSearchBar || Provider.of<ContactListState>(context).isFiltered ? Icons.search_off : Icons.search),
|
||||
|
|
|
@ -188,6 +188,23 @@ class _GlobalSettingsViewState extends State<GlobalSettingsView> {
|
|||
inactiveTrackColor: settings.theme.defaultButtonDisabledColor(),
|
||||
secondary: Icon(CwtchIcons.enable_groups, color: settings.current().mainTextColor()),
|
||||
),
|
||||
SwitchListTile(
|
||||
title: Text("Enable Servers", /*AppLocalizations.of(context)!.enableGroups,*/ style: TextStyle(color: settings.current().mainTextColor())),
|
||||
subtitle: Text("Enable Servers"), //AppLocalizations.of(context)!.descriptionExperimentsGroups),
|
||||
value: settings.isExperimentEnabled(ServerManagementExperiment),
|
||||
onChanged: (bool value) {
|
||||
if (value) {
|
||||
settings.enableExperiment(ServerManagementExperiment);
|
||||
} else {
|
||||
settings.disableExperiment(ServerManagementExperiment);
|
||||
}
|
||||
// Save Settings...
|
||||
saveSettings(context);
|
||||
},
|
||||
activeTrackColor: settings.theme.defaultButtonActiveColor(),
|
||||
inactiveTrackColor: settings.theme.defaultButtonDisabledColor(),
|
||||
secondary: Icon(CwtchIcons.dns_24px, color: settings.current().mainTextColor()),
|
||||
),
|
||||
SwitchListTile(
|
||||
title: Text(AppLocalizations.of(context)!.settingFileSharing, style: TextStyle(color: settings.current().mainTextColor())),
|
||||
subtitle: Text(AppLocalizations.of(context)!.descriptionFileSharing),
|
||||
|
|
|
@ -17,6 +17,7 @@ import '../model.dart';
|
|||
import '../torstatus.dart';
|
||||
import 'addeditprofileview.dart';
|
||||
import 'globalsettingsview.dart';
|
||||
import 'serversview.dart';
|
||||
|
||||
class ProfileMgrView extends StatefulWidget {
|
||||
ProfileMgrView();
|
||||
|
@ -56,12 +57,14 @@ class _ProfileMgrViewState extends State<ProfileMgrView> {
|
|||
SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Expanded(child: Text(AppLocalizations.of(context)!.titleManageProfiles, style: TextStyle(color: settings.current().mainTextColor())))
|
||||
Expanded(child: Text(MediaQuery.of(context).size.width > 600 ?
|
||||
AppLocalizations.of(context)!.titleManageProfiles : AppLocalizations.of(context)!.titleManageProfilesShort,
|
||||
style: TextStyle(color: settings.current().mainTextColor())))
|
||||
]),
|
||||
actions: getActions(),
|
||||
),
|
||||
floatingActionButton: FloatingActionButton(
|
||||
onPressed: _pushAddEditProfile,
|
||||
onPressed: _pushAddProfile,
|
||||
tooltip: AppLocalizations.of(context)!.addNewProfileBtn,
|
||||
child: Icon(
|
||||
Icons.add,
|
||||
|
@ -95,6 +98,11 @@ class _ProfileMgrViewState extends State<ProfileMgrView> {
|
|||
onPressed: _modalUnlockProfiles,
|
||||
));
|
||||
|
||||
// Servers
|
||||
if (Provider.of<Settings>(context).isExperimentEnabled(ServerManagementExperiment)) {
|
||||
actions.add(IconButton(icon: Icon(CwtchIcons.dns_black_24dp), tooltip: "Servers", onPressed: _pushServers));
|
||||
}
|
||||
|
||||
// Global Settings
|
||||
actions.add(IconButton(icon: Icon(Icons.settings), tooltip: AppLocalizations.of(context)!.tooltipOpenSettings, onPressed: _pushGlobalSettings));
|
||||
|
||||
|
@ -119,6 +127,17 @@ class _ProfileMgrViewState extends State<ProfileMgrView> {
|
|||
));
|
||||
}
|
||||
|
||||
void _pushServers() {
|
||||
Navigator.of(context).push(MaterialPageRoute<void>(
|
||||
builder: (BuildContext context) {
|
||||
return MultiProvider(
|
||||
providers: [Provider.value(value: Provider.of<FlwtchState>(context))],
|
||||
child: ServersView(),
|
||||
);
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
void _pushTorStatus() {
|
||||
Navigator.of(context).push(MaterialPageRoute<void>(
|
||||
builder: (BuildContext context) {
|
||||
|
@ -130,7 +149,7 @@ class _ProfileMgrViewState extends State<ProfileMgrView> {
|
|||
));
|
||||
}
|
||||
|
||||
void _pushAddEditProfile({onion: ""}) {
|
||||
void _pushAddProfile({onion: ""}) {
|
||||
Navigator.of(context).push(MaterialPageRoute<void>(
|
||||
builder: (BuildContext context) {
|
||||
return MultiProvider(
|
||||
|
|
|
@ -61,7 +61,7 @@ class _ProfileRowState extends State<ProfileRow> {
|
|||
tooltip: AppLocalizations.of(context)!.editProfile + " " + profile.nickname,
|
||||
icon: Icon(Icons.create, color: Provider.of<Settings>(context).current().mainTextColor()),
|
||||
onPressed: () {
|
||||
_pushAddEditProfile(onion: profile.onion, displayName: profile.nickname, profileImage: profile.imagePath, encrypted: profile.isEncrypted);
|
||||
_pushEditProfile(onion: profile.onion, displayName: profile.nickname, profileImage: profile.imagePath, encrypted: profile.isEncrypted);
|
||||
},
|
||||
)
|
||||
],
|
||||
|
@ -100,7 +100,7 @@ class _ProfileRowState extends State<ProfileRow> {
|
|||
);
|
||||
}
|
||||
|
||||
void _pushAddEditProfile({onion: "", displayName: "", profileImage: "", encrypted: true}) {
|
||||
void _pushEditProfile({onion: "", displayName: "", profileImage: "", encrypted: true}) {
|
||||
Navigator.of(context).push(MaterialPageRoute<void>(
|
||||
builder: (BuildContext context) {
|
||||
return MultiProvider(
|
||||
|
|
Loading…
Reference in New Issue