Basic Group Implementation
continuous-integration/drone/pr Build is failing Details

This commit is contained in:
Sarah Jamie Lewis 2021-04-20 16:54:47 -07:00
parent 9edae601a9
commit 484f8a4b77
13 changed files with 139 additions and 15 deletions

View File

@ -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");
}

View File

@ -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": "",

View File

@ -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",

View File

@ -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": "",

View File

@ -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": "",

View File

@ -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": "",

View File

@ -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": "",

View File

@ -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() {

26
lib/models/servers.dart Normal file
View File

@ -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});
}

View File

@ -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);
}
}

View File

@ -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(

View File

@ -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:

View File

@ -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