Merge branch 'trunk' into settings-pane
This commit is contained in:
commit
26637af08d
|
@ -23,13 +23,38 @@ class CwtchNotifier {
|
||||||
profileCN.add(ProfileInfoState(
|
profileCN.add(ProfileInfoState(
|
||||||
onion: data["Identity"],
|
onion: data["Identity"],
|
||||||
nickname: data["name"],
|
nickname: data["name"],
|
||||||
imagePath: data["picture"]));
|
imagePath: data["picture"],
|
||||||
|
contactsJson: data["ContactsJson"],
|
||||||
|
));
|
||||||
|
break;
|
||||||
|
case "PeerCreated":
|
||||||
|
print("xx peercreated");
|
||||||
|
profileCN.getProfile(data["ProfileOnion"]).contactList.add(ContactInfoState(
|
||||||
|
profileOnion: data["ProfileOnion"],
|
||||||
|
onion: data["RemotePeer"],
|
||||||
|
nickname: data["nick"],
|
||||||
|
status: data["status"],
|
||||||
|
));
|
||||||
|
break;
|
||||||
|
case "PeerStateChange":
|
||||||
|
ContactInfoState contact = profileCN.getProfile(data["ProfileOnion"]).contactList.getContact(data["RemotePeer"]);
|
||||||
|
if (contact == null) {//todo: stopgap, as lc-g is supposed to handle this
|
||||||
|
print("PSC -> adding "+data["ProfileOnion"]+" :: " + data["RemotePeer"]);
|
||||||
|
profileCN.getProfile(data["ProfileOnion"]).contactList.add(ContactInfoState(
|
||||||
|
profileOnion: data["ProfileOnion"],
|
||||||
|
onion: data["RemotePeer"],
|
||||||
|
nickname: data["nick"],
|
||||||
|
status: data["ConnectionState"],
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
contact.status = data["ConnectionState"];
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case "UpdateGlobalSettings":
|
case "UpdateGlobalSettings":
|
||||||
settings.handleUpdate(jsonDecode(data["Data"]));
|
settings.handleUpdate(jsonDecode(data["Data"]));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
print("unhandled gomobile appbus event: ${type}");
|
print("unhandled event: $type");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,6 @@ class CwtchGomobile implements Cwtch {
|
||||||
Future<void> _handleAppbusEvent(MethodCall call) async {
|
Future<void> _handleAppbusEvent(MethodCall call) async {
|
||||||
final String json = call.arguments;
|
final String json = call.arguments;
|
||||||
var obj = jsonDecode(json);
|
var obj = jsonDecode(json);
|
||||||
|
|
||||||
cwtchNotifier.handleMessage(call.method, obj);
|
cwtchNotifier.handleMessage(call.method, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -69,87 +69,84 @@ class ChatMessage {
|
||||||
///////////////////
|
///////////////////
|
||||||
|
|
||||||
class ProfileListState extends ChangeNotifier {
|
class ProfileListState extends ChangeNotifier {
|
||||||
List<ProfileInfoState> _onions = [];
|
List<ProfileInfoState> _profiles = [];
|
||||||
int get num => _onions.length;
|
int get num => _profiles.length;
|
||||||
|
|
||||||
void addAll(Iterable<ProfileInfoState> newOnions) {
|
void addAll(Iterable<ProfileInfoState> newProfiles) {
|
||||||
_onions.addAll(newOnions);
|
_profiles.addAll(newProfiles);
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
void add(ProfileInfoState newOnion) {
|
void add(ProfileInfoState newProfile) {
|
||||||
print("ProfileListState: adding " + newOnion.onion + " and notifying");
|
print("ProfileListState: adding " + newProfile.onion +" and notifying");
|
||||||
_onions.add(newOnion);
|
_profiles.add(newProfile);
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
List<ProfileInfoState> get onions => _onions
|
List<ProfileInfoState> get profiles => _profiles.sublist(0);//todo: copy?? dont want caller able to bypass changenotifier
|
||||||
.sublist(0); //todo: copy?? dont want caller able to bypass changenotifier
|
|
||||||
|
ProfileInfoState getProfile(String onion) {
|
||||||
|
int idx = _profiles.indexWhere((element) => element.onion == onion);
|
||||||
|
return idx >= 0 ? _profiles[idx] : null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ContactListState extends ChangeNotifier {
|
class ContactListState extends ChangeNotifier {
|
||||||
List<ContactInfoState> _onions = [];
|
List<ContactInfoState> _contacts = [];
|
||||||
int get num => _onions.length;
|
int get num => _contacts.length;
|
||||||
|
|
||||||
ContactListState(Cwtch cwtch, String profileOnion) {
|
void addAll(Iterable<ContactInfoState> newContacts) {
|
||||||
cwtch.GetContacts(profileOnion).then((jsonStr) {
|
_contacts.addAll(newContacts);
|
||||||
if (jsonStr == null) return;
|
|
||||||
|
|
||||||
print("contacts: " + jsonStr);
|
|
||||||
List<dynamic> contacts = jsonDecode(jsonStr);
|
|
||||||
contacts.forEach((c) {
|
|
||||||
add(ContactInfoState(
|
|
||||||
profileOnion: profileOnion,
|
|
||||||
onion: c["onion"],
|
|
||||||
nickname: c["name"],
|
|
||||||
isGroup: false,
|
|
||||||
isInvitation: false,
|
|
||||||
isBlocked: false,
|
|
||||||
status: c["status"],
|
|
||||||
imagePath: "",
|
|
||||||
));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void addAll(Iterable<ContactInfoState> newOnions) {
|
|
||||||
_onions.addAll(newOnions);
|
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
void add(ContactInfoState newOnion) {
|
void add(ContactInfoState newContact) {
|
||||||
_onions.add(newOnion);
|
_contacts.add(newContact);
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateUnreadMessages(String forOnion, int newVal) {
|
void updateUnreadMessages(String forOnion, int newVal) {
|
||||||
_onions.sort((ContactInfoState a, ContactInfoState b) {
|
_contacts.sort((ContactInfoState a, ContactInfoState b) { return b.unreadMessages - a.unreadMessages; });
|
||||||
return b.unreadMessages - a.unreadMessages;
|
|
||||||
});
|
|
||||||
//<todo> if(changed) {
|
//<todo> if(changed) {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
//} </todo>
|
//} </todo>
|
||||||
}
|
}
|
||||||
|
|
||||||
List<ContactInfoState> get onions => _onions
|
List<ContactInfoState> get contacts => _contacts.sublist(0);//todo: copy?? dont want caller able to bypass changenotifier
|
||||||
.sublist(0); //todo: copy?? dont want caller able to bypass changenotifier
|
|
||||||
|
ContactInfoState getContact(String onion) {
|
||||||
|
int idx = _contacts.indexWhere((element) => element.onion == onion);
|
||||||
|
return idx >= 0 ? _contacts[idx] : null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ProfileInfoState extends ChangeNotifier {
|
class ProfileInfoState extends ChangeNotifier {
|
||||||
|
ContactListState _contacts = ContactListState();
|
||||||
final String onion;
|
final String onion;
|
||||||
String _nickname = "";
|
String _nickname = "";
|
||||||
String _imagePath = "";
|
String _imagePath = "";
|
||||||
int _unreadMessages = 0;
|
int _unreadMessages = 0;
|
||||||
|
|
||||||
ProfileInfoState({
|
ProfileInfoState({this.onion, nickname = "", imagePath = "", unreadMessages = 0, contactsJson = "",}){
|
||||||
this.onion,
|
|
||||||
nickname = "",
|
|
||||||
imagePath = "",
|
|
||||||
unreadMessages = 0,
|
|
||||||
}) {
|
|
||||||
this._nickname = nickname;
|
this._nickname = nickname;
|
||||||
this._imagePath = imagePath;
|
this._imagePath = imagePath;
|
||||||
this._unreadMessages = unreadMessages;
|
this._unreadMessages = unreadMessages;
|
||||||
|
|
||||||
|
if (contactsJson != null && contactsJson != "" && contactsJson != "null") {
|
||||||
|
print("decoding " + contactsJson);
|
||||||
|
List<dynamic> contacts = jsonDecode(contactsJson);
|
||||||
|
this._contacts.addAll(
|
||||||
|
contacts.map((contact){
|
||||||
|
return ContactInfoState(
|
||||||
|
profileOnion: this.onion,
|
||||||
|
onion: contact["onion"],
|
||||||
|
nickname: contact["name"],
|
||||||
|
status: contact["status"],
|
||||||
|
imagePath: contact["picture"],
|
||||||
|
);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String get nickname => this._nickname;
|
String get nickname => this._nickname;
|
||||||
|
@ -170,6 +167,8 @@ class ProfileInfoState extends ChangeNotifier {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ContactListState get contactList => this._contacts;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
super.dispose();
|
super.dispose();
|
||||||
|
@ -229,6 +228,12 @@ class ContactInfoState extends ChangeNotifier {
|
||||||
this._unreadMessages = newVal;
|
this._unreadMessages = newVal;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get imagePath => this._imagePath;
|
||||||
|
set imagePath(String newVal) {
|
||||||
|
this._imagePath = newVal;
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////
|
/////////////
|
||||||
|
|
|
@ -14,27 +14,6 @@ class ContactsView extends StatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _ContactsViewState extends State<ContactsView> {
|
class _ContactsViewState extends State<ContactsView> {
|
||||||
_ContactsViewState();
|
|
||||||
// Map<String, ContactModel> _contacts = new HashMap<String, ContactModel>();
|
|
||||||
|
|
||||||
// @override
|
|
||||||
// void didChangeDependencies() {
|
|
||||||
// super.didChangeDependencies();
|
|
||||||
//
|
|
||||||
// Provider.of<ContactListState>(context).onions.forEach((contact) {
|
|
||||||
// _contacts.putIfAbsent(contact.onion, () => ContactModel(contact);
|
|
||||||
// });
|
|
||||||
// .cwtch.GetContacts(widget.profile.onion).then((jsonContacts) {
|
|
||||||
// print("got contact: $jsonContacts");
|
|
||||||
// setState(() {
|
|
||||||
// List<dynamic> contacts = jsonDecode(jsonContacts);
|
|
||||||
// contacts.forEach((onion) {
|
|
||||||
// _contacts.putIfAbsent(onion['onion'], () => ContactModel(onion: onion['onion'], nickname: onion['name'], status: onion['status']));
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
|
@ -61,26 +40,11 @@ class _ContactsViewState extends State<ContactsView> {
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildContactList() {
|
Widget _buildContactList() {
|
||||||
return StreamBuilder<String>(
|
final tiles = Provider.of<ContactListState>(context).contacts.map((ContactInfoState contact) {
|
||||||
stream: Provider.of<FlwtchState>(context).appStatus.contactEvents(),
|
return ChangeNotifierProvider<ContactInfoState>.value(value: contact, child: ContactRow());
|
||||||
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
|
});
|
||||||
final tiles = Provider.of<ContactListState>(context).onions.map(
|
final divided = ListTile.divideTiles(context: context, tiles: tiles, ).toList();
|
||||||
(ContactInfoState contact) {
|
return ListView(children: divided);
|
||||||
return ChangeNotifierProvider<ContactInfoState>(
|
|
||||||
create: (context) => contact,
|
|
||||||
builder: (context, child) => ContactRow(),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
final divided = ListTile.divideTiles(
|
|
||||||
context: context,
|
|
||||||
tiles: tiles,
|
|
||||||
).toList();
|
|
||||||
|
|
||||||
return ListView(children: divided);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _pushAddContact() {
|
void _pushAddContact() {
|
||||||
|
|
|
@ -50,7 +50,7 @@ class _ProfileMgrViewState extends State<ProfileMgrView> {
|
||||||
}
|
}
|
||||||
|
|
||||||
void _testChangingContactInfo() {
|
void _testChangingContactInfo() {
|
||||||
Provider.of<ProfileListState>(context, listen: false).notifyListeners();
|
Provider.of<ProfileListState>(context, listen:false).profiles.first.nickname = "yay!";
|
||||||
}
|
}
|
||||||
|
|
||||||
void _pushGlobalSettings() {
|
void _pushGlobalSettings() {
|
||||||
|
@ -116,7 +116,7 @@ class _ProfileMgrViewState extends State<ProfileMgrView> {
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildProfileManager() {
|
Widget _buildProfileManager() {
|
||||||
final tiles = Provider.of<ProfileListState>(context).onions.map(
|
final tiles = Provider.of<ProfileListState>(context).profiles.map(
|
||||||
(ProfileInfoState profile) {
|
(ProfileInfoState profile) {
|
||||||
return ChangeNotifierProvider<ProfileInfoState>.value(
|
return ChangeNotifierProvider<ProfileInfoState>.value(
|
||||||
value: profile,
|
value: profile,
|
||||||
|
|
|
@ -20,19 +20,7 @@ class _ContactRowState extends State<ContactRow> {
|
||||||
width: 60,
|
width: 60,
|
||||||
height: 60,
|
height: 60,
|
||||||
child: ClipOval(
|
child: ClipOval(
|
||||||
child: SizedBox(
|
child: SizedBox(width:60, height:60, child:Container(color:Colors.white, width: 60, height: 60, child: Image(image: AssetImage("assets/"+contact.imagePath), width:50,height:50,))),
|
||||||
width: 60,
|
|
||||||
height: 60,
|
|
||||||
child: Container(
|
|
||||||
color: Colors.white,
|
|
||||||
width: 60,
|
|
||||||
height: 60,
|
|
||||||
child: Image(
|
|
||||||
image: AssetImage("assets/profiles/001-centaur.png"),
|
|
||||||
width: 50,
|
|
||||||
height: 50,
|
|
||||||
))),
|
|
||||||
//child: SizedBox(width:60, height:60, child:Container(color:Colors.white, width: 60, height: 60, child: Image(image: AssetImage(contact.imagePath), width:50,height:50,))),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
trailing: contact.isInvitation != null && contact.isInvitation
|
trailing: contact.isInvitation != null && contact.isInvitation
|
||||||
|
|
|
@ -80,11 +80,7 @@ class _ProfileRowState extends State<ProfileRow> {
|
||||||
return MultiProvider(
|
return MultiProvider(
|
||||||
providers: [
|
providers: [
|
||||||
ChangeNotifierProvider<ProfileInfoState>.value(value: profile),
|
ChangeNotifierProvider<ProfileInfoState>.value(value: profile),
|
||||||
ChangeNotifierProvider<ContactListState>(
|
ChangeNotifierProvider<ContactListState>.value(value: profile.contactList),
|
||||||
create: (_) => ContactListState(
|
|
||||||
Provider.of<FlwtchState>(buildcontext).cwtch,
|
|
||||||
profile.onion),
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
builder: (context, widget) =>
|
builder: (context, widget) =>
|
||||||
includeDoublePane ? DoubleColumnView() : ContactsView(),
|
includeDoublePane ? DoubleColumnView() : ContactsView(),
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
// Generated file. Do not edit.
|
// Generated file. Do not edit.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
|
||||||
#include "generated_plugin_registrant.h"
|
#include "generated_plugin_registrant.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
// Generated file. Do not edit.
|
// Generated file. Do not edit.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
|
||||||
#ifndef GENERATED_PLUGIN_REGISTRANT_
|
#ifndef GENERATED_PLUGIN_REGISTRANT_
|
||||||
#define GENERATED_PLUGIN_REGISTRANT_
|
#define GENERATED_PLUGIN_REGISTRANT_
|
||||||
|
|
||||||
|
|
19
pubspec.lock
19
pubspec.lock
|
@ -115,7 +115,7 @@ packages:
|
||||||
name: flutter_lokalise
|
name: flutter_lokalise
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.1.3"
|
version: "0.1.4"
|
||||||
flutter_test:
|
flutter_test:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description: flutter
|
description: flutter
|
||||||
|
@ -132,7 +132,7 @@ packages:
|
||||||
name: freezed_annotation
|
name: freezed_annotation
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.7.1"
|
version: "0.12.0"
|
||||||
http:
|
http:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -195,7 +195,7 @@ packages:
|
||||||
name: nested
|
name: nested
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.0.4"
|
version: "1.0.0"
|
||||||
package_info_plus:
|
package_info_plus:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -286,7 +286,7 @@ packages:
|
||||||
name: pedantic
|
name: pedantic
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.10.0"
|
version: "1.11.0"
|
||||||
platform:
|
platform:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -355,13 +355,6 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0"
|
version: "1.1.0"
|
||||||
string_unescape:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: string_unescape
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.5.1"
|
|
||||||
term_glyph:
|
term_glyph:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -396,7 +389,7 @@ packages:
|
||||||
name: win32
|
name: win32
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.0"
|
version: "2.0.4"
|
||||||
xdg_directories:
|
xdg_directories:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -412,5 +405,5 @@ packages:
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.1"
|
version: "2.2.1"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=2.12.0-259.9.beta <3.0.0"
|
dart: ">=2.12.0 <3.0.0"
|
||||||
flutter: ">=1.20.0"
|
flutter: ">=1.20.0"
|
||||||
|
|
Loading…
Reference in New Issue