Basic Group Implementation
continuous-integration/drone/pr Build is failing
Details
continuous-integration/drone/pr Build is failing
Details
This commit is contained in:
parent
9edae601a9
commit
484f8a4b77
|
@ -25,7 +25,8 @@ class CwtchNotifier {
|
|||
void handleMessage(String type, dynamic data) {
|
||||
switch (type) {
|
||||
case "NewPeer":
|
||||
profileCN.add(ProfileInfoState(onion: data["Identity"], nickname: data["name"], imagePath: data["picture"], contactsJson: data["ContactsJson"], online: data["Online"] == "true"));
|
||||
profileCN.add(ProfileInfoState(
|
||||
onion: data["Identity"], nickname: data["name"], imagePath: data["picture"], contactsJson: data["ContactsJson"], serversJson: data["ServerList"], online: data["Online"] == "true"));
|
||||
break;
|
||||
case "PeerCreated":
|
||||
profileCN.getProfile(data["ProfileOnion"]).contactList.add(ContactInfoState(
|
||||
|
@ -39,6 +40,7 @@ class CwtchNotifier {
|
|||
savePeerHistory: data["saveConversationHistory"],
|
||||
numMessages: int.parse(data["numMessages"]),
|
||||
numUnread: int.parse(data["unread"]),
|
||||
isGroup: data["isGroup"],
|
||||
lastMessageTime: DateTime.now(), //show at the top of the contact list even if no messages yet
|
||||
));
|
||||
break;
|
||||
|
@ -81,6 +83,9 @@ class CwtchNotifier {
|
|||
print("acn status: $data");
|
||||
torStatus.handleUpdate(int.parse(data["Progress"]), data["Status"]);
|
||||
break;
|
||||
case "UpdateServerInfo":
|
||||
profileCN.getProfile(data["ProfileOnion"]).replaceServers(data["ServerList"]);
|
||||
break;
|
||||
default:
|
||||
print("unhandled event: $type");
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
"dateLastMonth": "",
|
||||
"dateLastYear": "",
|
||||
"dateMinutesAgo": "",
|
||||
"dateMonthsAgo": "",
|
||||
"dateNever": "",
|
||||
"dateRightNow": "",
|
||||
"dateWeeksAgo": "",
|
||||
|
@ -138,6 +139,7 @@
|
|||
"themeLight": "Licht",
|
||||
"titleManageContacts": "",
|
||||
"titleManageProfiles": "",
|
||||
"titleManageServers": "",
|
||||
"titlePlaceholder": "Titel...",
|
||||
"todoPlaceholder": "noch zu erledigen",
|
||||
"tooltipAddContact": "",
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
"dateLastMonth": "Last Month",
|
||||
"dateLastYear": "Last Year",
|
||||
"dateMinutesAgo": "Minutes Ago",
|
||||
"dateMonthsAgo": "Months Ago",
|
||||
"dateNever": "Never",
|
||||
"dateRightNow": "Right Now",
|
||||
"dateWeeksAgo": "Weeks Ago",
|
||||
|
@ -138,6 +139,7 @@
|
|||
"themeLight": "Light",
|
||||
"titleManageContacts": "Manage Contacts",
|
||||
"titleManageProfiles": "Manage Cwtch Profiles",
|
||||
"titleManageServers": "Manage Servers",
|
||||
"titlePlaceholder": "title...",
|
||||
"todoPlaceholder": "Todo...",
|
||||
"tooltipAddContact": "Add a new contact",
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
"dateLastMonth": "",
|
||||
"dateLastYear": "",
|
||||
"dateMinutesAgo": "",
|
||||
"dateMonthsAgo": "",
|
||||
"dateNever": "",
|
||||
"dateRightNow": "",
|
||||
"dateWeeksAgo": "",
|
||||
|
@ -138,6 +139,7 @@
|
|||
"themeLight": "Claro",
|
||||
"titleManageContacts": "",
|
||||
"titleManageProfiles": "",
|
||||
"titleManageServers": "",
|
||||
"titlePlaceholder": "título...",
|
||||
"todoPlaceholder": "Por hacer...",
|
||||
"tooltipAddContact": "",
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
"dateLastMonth": "",
|
||||
"dateLastYear": "",
|
||||
"dateMinutesAgo": "",
|
||||
"dateMonthsAgo": "",
|
||||
"dateNever": "",
|
||||
"dateRightNow": "",
|
||||
"dateWeeksAgo": "",
|
||||
|
@ -138,6 +139,7 @@
|
|||
"themeLight": "",
|
||||
"titleManageContacts": "",
|
||||
"titleManageProfiles": "",
|
||||
"titleManageServers": "",
|
||||
"titlePlaceholder": "titre...",
|
||||
"todoPlaceholder": "A faire...",
|
||||
"tooltipAddContact": "",
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
"dateLastMonth": "",
|
||||
"dateLastYear": "",
|
||||
"dateMinutesAgo": "",
|
||||
"dateMonthsAgo": "",
|
||||
"dateNever": "",
|
||||
"dateRightNow": "",
|
||||
"dateWeeksAgo": "",
|
||||
|
@ -138,6 +139,7 @@
|
|||
"themeLight": "Chiaro",
|
||||
"titleManageContacts": "",
|
||||
"titleManageProfiles": "",
|
||||
"titleManageServers": "",
|
||||
"titlePlaceholder": "titolo...",
|
||||
"todoPlaceholder": "Da fare...",
|
||||
"tooltipAddContact": "",
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
"dateLastMonth": "",
|
||||
"dateLastYear": "",
|
||||
"dateMinutesAgo": "",
|
||||
"dateMonthsAgo": "",
|
||||
"dateNever": "",
|
||||
"dateRightNow": "",
|
||||
"dateWeeksAgo": "",
|
||||
|
@ -138,6 +139,7 @@
|
|||
"themeLight": "",
|
||||
"titleManageContacts": "",
|
||||
"titleManageProfiles": "",
|
||||
"titleManageServers": "",
|
||||
"titlePlaceholder": "título…",
|
||||
"todoPlaceholder": "Afazer…",
|
||||
"tooltipAddContact": "",
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter_app/models/servers.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'dart:async';
|
||||
import 'dart:collection';
|
||||
|
@ -34,16 +35,6 @@ class ContactModel {
|
|||
ContactModel({this.onion, this.nickname, this.status, this.isInvitation, this.isBlocked, this.imagePath});
|
||||
}
|
||||
|
||||
//todo: delete
|
||||
class DanMessageModel {
|
||||
// ignore: non_constant_identifier_names
|
||||
String Timestamp;
|
||||
// ignore: non_constant_identifier_names
|
||||
bool Acknowledged;
|
||||
// ignore: non_constant_identifier_names
|
||||
String Message;
|
||||
}
|
||||
|
||||
class ChatMessage {
|
||||
final int o;
|
||||
final String d;
|
||||
|
@ -123,6 +114,7 @@ class ContactListState extends ChangeNotifier {
|
|||
|
||||
class ProfileInfoState extends ChangeNotifier {
|
||||
ContactListState _contacts = ContactListState();
|
||||
ServerListState _servers = ServerListState();
|
||||
final String onion;
|
||||
String _nickname = "";
|
||||
String _imagePath = "";
|
||||
|
@ -135,6 +127,7 @@ class ProfileInfoState extends ChangeNotifier {
|
|||
imagePath = "",
|
||||
unreadMessages = 0,
|
||||
contactsJson = "",
|
||||
serversJson = "",
|
||||
online = false,
|
||||
}) {
|
||||
this._nickname = nickname;
|
||||
|
@ -164,6 +157,20 @@ class ProfileInfoState extends ChangeNotifier {
|
|||
this._contacts.updateLastMessageTime(this._contacts._contacts.first.onion, this._contacts._contacts.first.lastMessageTime);
|
||||
}
|
||||
}
|
||||
|
||||
this.replaceServers(serversJson);
|
||||
}
|
||||
|
||||
// Parse out the server list json into our server info state struct...
|
||||
void replaceServers(String serversJson) {
|
||||
if (serversJson != null && serversJson != "" && serversJson != "null") {
|
||||
print("got servers $serversJson");
|
||||
List<dynamic> servers = jsonDecode(serversJson);
|
||||
this._servers.replace(servers.map((server) {
|
||||
// TODO Keys...
|
||||
return ServerInfoState(onion: server["onion"], status: server["status"]);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
// Getters and Setters for Online Status
|
||||
|
@ -192,6 +199,7 @@ class ProfileInfoState extends ChangeNotifier {
|
|||
}
|
||||
|
||||
ContactListState get contactList => this._contacts;
|
||||
ServerListState get serverList => this._servers;
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
class ServerListState extends ChangeNotifier {
|
||||
List<ServerInfoState> _servers = [];
|
||||
|
||||
void replace(Iterable<ServerInfoState> newServers) {
|
||||
_servers.clear();
|
||||
_servers.addAll(newServers);
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
ServerInfoState getServer(String onion) {
|
||||
int idx = _servers.indexWhere((element) => element.onion == onion);
|
||||
return idx >= 0 ? _servers[idx] : null;
|
||||
}
|
||||
|
||||
List<ServerInfoState> get servers => _servers.sublist(0); //todo: copy?? dont want caller able to bypass changenotifier
|
||||
|
||||
}
|
||||
|
||||
class ServerInfoState extends ChangeNotifier {
|
||||
final String onion;
|
||||
final String status;
|
||||
|
||||
ServerInfoState({this.onion, this.status});
|
||||
}
|
|
@ -3,6 +3,7 @@ import 'dart:convert';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_app/errorHandler.dart';
|
||||
import 'package:flutter_app/models/servers.dart';
|
||||
import 'package:flutter_app/settings.dart';
|
||||
import 'package:flutter_app/widgets/buttontextfield.dart';
|
||||
import 'package:flutter_app/widgets/cwtchlabel.dart';
|
||||
|
@ -24,8 +25,11 @@ class AddContactView extends StatefulWidget {
|
|||
|
||||
class _AddContactViewState extends State<AddContactView> {
|
||||
final _formKey = GlobalKey<FormState>();
|
||||
final _createGroupFormKey = GlobalKey<FormState>();
|
||||
final ctrlrOnion = TextEditingController(text: "");
|
||||
final ctrlrContact = TextEditingController(text: "");
|
||||
final ctrlrGroupName = TextEditingController(text: "");
|
||||
String server = "";
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -49,7 +53,7 @@ class _AddContactViewState extends State<AddContactView> {
|
|||
(groupsEnabled ? getTabBarWithGroups() : getTabBarWithAddPeerOnly()),
|
||||
Expanded(
|
||||
child: TabBarView(
|
||||
children: (groupsEnabled ? [addPeerTab(), addGroupTab(), joinGroupTab()] : [addPeerTab()]),
|
||||
children: (groupsEnabled ? [addPeerTab(), manageServersTab(), addGroupTab(), joinGroupTab()] : [addPeerTab()]),
|
||||
)),
|
||||
]));
|
||||
});
|
||||
|
@ -81,6 +85,7 @@ class _AddContactViewState extends State<AddContactView> {
|
|||
icon: Icon(Icons.person_add_rounded),
|
||||
text: AppLocalizations.of(context).addPeer,
|
||||
),
|
||||
Tab(icon: Icon(Icons.backup), text: AppLocalizations.of(context).titleManageServers),
|
||||
Tab(icon: Icon(Icons.group), text: AppLocalizations.of(context).createGroup),
|
||||
Tab(icon: Icon(Icons.group_add), text: AppLocalizations.of(context).joinGroup),
|
||||
],
|
||||
|
@ -150,11 +155,78 @@ class _AddContactViewState extends State<AddContactView> {
|
|||
|
||||
/// TODO Add Group Pane
|
||||
Widget addGroupTab() {
|
||||
return Icon(Icons.group_add);
|
||||
// TODO We should replace with with a "Paste in Server Key Bundle"
|
||||
if (Provider.of<ProfileInfoState>(context).serverList.servers.isEmpty) {
|
||||
return Text("You need to add a server before you can create a group.");
|
||||
}
|
||||
|
||||
// if we haven't picked a server yet, pick the first one in the list...
|
||||
if (server.isEmpty) {
|
||||
server = Provider.of<ProfileInfoState>(context).serverList.servers.first.onion;
|
||||
}
|
||||
|
||||
return Container(
|
||||
margin: EdgeInsets.all(30),
|
||||
padding: EdgeInsets.all(20),
|
||||
child: Form(
|
||||
autovalidateMode: AutovalidateMode.always,
|
||||
key: _createGroupFormKey,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
CwtchLabel(label: AppLocalizations.of(context).server),
|
||||
SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
DropdownButton(
|
||||
onChanged: (newServer) {
|
||||
server = newServer;
|
||||
},
|
||||
value: server,
|
||||
items: Provider.of<ProfileInfoState>(context).serverList.servers.map<DropdownMenuItem<String>>((ServerInfoState serverInfo) {
|
||||
return DropdownMenuItem<String>(
|
||||
value: serverInfo.onion,
|
||||
child: Text(serverInfo.onion),
|
||||
);
|
||||
}).toList()),
|
||||
SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
CwtchLabel(label: AppLocalizations.of(context).groupName),
|
||||
SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
CwtchTextField(controller: ctrlrGroupName, labelText: AppLocalizations.of(context).groupNameLabel, onChanged: (newValue) {}),
|
||||
SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
ElevatedButton(
|
||||
onPressed: () {},
|
||||
child: Text(AppLocalizations.of(context).createGroupBtn),
|
||||
),
|
||||
],
|
||||
)));
|
||||
}
|
||||
|
||||
/// TODO Join Group Pane
|
||||
Widget joinGroupTab() {
|
||||
return Icon(Icons.group);
|
||||
}
|
||||
|
||||
/// TODO Manage Servers Tab
|
||||
Widget manageServersTab() {
|
||||
final tiles = Provider.of<ProfileInfoState>(context).serverList.servers.map((ServerInfoState server) {
|
||||
return ChangeNotifierProvider<ServerInfoState>.value(
|
||||
value: server,
|
||||
child: ListTile(
|
||||
title: Text(server.onion),
|
||||
));
|
||||
});
|
||||
final divided = ListTile.divideTiles(
|
||||
context: context,
|
||||
tiles: tiles,
|
||||
).toList();
|
||||
return ListView(children: divided);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ class _ContactRowState extends State<ContactRow> {
|
|||
badgeTextColor: Provider.of<Settings>(context).theme.portraitContactBadgeTextColor(),
|
||||
diameter: 64.0,
|
||||
imagePath: contact.imagePath,
|
||||
maskOut: contact.status != "Authenticated",
|
||||
maskOut: contact.isGroup ? false : contact.status != "Authenticated",
|
||||
border: contact.status == "Authenticated" ? Provider.of<Settings>(context).theme.portraitOnlineBorderColor() : Provider.of<Settings>(context).theme.portraitOfflineBorderColor()),
|
||||
),
|
||||
Expanded(
|
||||
|
|
|
@ -135,7 +135,7 @@ packages:
|
|||
name: integration_test
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.2+2"
|
||||
version: "1.0.2+3"
|
||||
intl:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
|
@ -85,6 +85,7 @@ flutter:
|
|||
- assets/
|
||||
- assets/core/
|
||||
- assets/profiles/
|
||||
- assets/servers/
|
||||
|
||||
# To add custom fonts to your application, add a fonts section here,
|
||||
# in this "flutter" section. Each entry in this list should have a
|
||||
|
|
Loading…
Reference in New Issue