2021-01-21 20:37:35 +00:00
|
|
|
import 'dart:convert';
|
2021-02-10 01:36:12 +00:00
|
|
|
|
2021-02-03 11:22:25 +00:00
|
|
|
import 'package:flutter/cupertino.dart';
|
2021-01-06 23:09:58 +00:00
|
|
|
import 'dart:async';
|
2021-01-07 19:38:06 +00:00
|
|
|
import 'dart:collection';
|
2021-01-06 23:09:58 +00:00
|
|
|
|
2021-01-12 06:21:18 +00:00
|
|
|
import 'cwtch/cwtch.dart';
|
|
|
|
|
2021-01-07 19:38:06 +00:00
|
|
|
////////////////////
|
|
|
|
/// UI State ///
|
|
|
|
////////////////////
|
2021-01-06 23:09:58 +00:00
|
|
|
|
2021-02-10 01:36:12 +00:00
|
|
|
//todo: delete
|
2021-01-07 19:38:06 +00:00
|
|
|
class ProfileModel {
|
|
|
|
String onion;
|
|
|
|
String nickname;
|
|
|
|
String creationDate;
|
2021-01-21 20:37:35 +00:00
|
|
|
String imagePath;
|
2021-01-07 19:38:06 +00:00
|
|
|
HashMap<String, ContactModel> contacts;
|
|
|
|
}
|
2021-01-06 23:09:58 +00:00
|
|
|
|
2021-02-10 01:36:12 +00:00
|
|
|
//todo: delete
|
2021-01-07 19:38:06 +00:00
|
|
|
class ContactModel {
|
|
|
|
String onion;
|
|
|
|
String nickname;
|
|
|
|
bool isGroup;
|
2021-01-21 20:37:35 +00:00
|
|
|
bool isInvitation;
|
2021-01-07 19:38:06 +00:00
|
|
|
bool isBlocked;
|
|
|
|
String status;
|
2021-01-21 20:37:35 +00:00
|
|
|
String imagePath;
|
2021-01-06 23:09:58 +00:00
|
|
|
|
2021-01-21 20:37:35 +00:00
|
|
|
ContactModel({this.onion, this.nickname, this.status, this.isInvitation, this.isBlocked, this.imagePath});
|
2021-01-07 19:38:06 +00:00
|
|
|
}
|
|
|
|
|
2021-02-10 01:36:12 +00:00
|
|
|
//todo: delete
|
2021-01-22 07:56:30 +00:00
|
|
|
class DanMessageModel {
|
2021-02-10 01:36:12 +00:00
|
|
|
// ignore: non_constant_identifier_names
|
2021-01-14 23:36:09 +00:00
|
|
|
String Timestamp;
|
2021-02-10 01:36:12 +00:00
|
|
|
// ignore: non_constant_identifier_names
|
2021-01-14 23:36:09 +00:00
|
|
|
bool Acknowledged;
|
2021-02-10 01:36:12 +00:00
|
|
|
// ignore: non_constant_identifier_names
|
2021-01-14 23:36:09 +00:00
|
|
|
String Message;
|
|
|
|
}
|
|
|
|
|
2021-01-21 20:37:35 +00:00
|
|
|
class ChatMessage {
|
|
|
|
final int o;
|
|
|
|
final String d;
|
|
|
|
|
|
|
|
ChatMessage({this.o, this.d});
|
|
|
|
|
|
|
|
ChatMessage.fromJson(Map<String, dynamic> json)
|
|
|
|
: o = json['o'],
|
|
|
|
d = json['d'];
|
|
|
|
|
|
|
|
Map<String, dynamic> toJson() =>
|
|
|
|
{
|
|
|
|
'o': o,
|
|
|
|
'd': d,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2021-02-03 11:22:25 +00:00
|
|
|
///////////////////
|
|
|
|
/// Providers ///
|
|
|
|
///////////////////
|
|
|
|
|
|
|
|
class ProfileListState extends ChangeNotifier {
|
|
|
|
List<ProfileInfoState> _onions = [];
|
|
|
|
int get num => _onions.length;
|
|
|
|
|
|
|
|
void addAll(Iterable<ProfileInfoState> newOnions) {
|
|
|
|
_onions.addAll(newOnions);
|
|
|
|
notifyListeners();
|
|
|
|
}
|
|
|
|
|
|
|
|
void add(ProfileInfoState newOnion) {
|
|
|
|
print("ProfileListState: adding " + newOnion.onion +" and notifying");
|
|
|
|
_onions.add(newOnion);
|
|
|
|
notifyListeners();
|
|
|
|
}
|
|
|
|
|
|
|
|
List<ProfileInfoState> get onions => _onions.sublist(0);//todo: copy?? dont want caller able to bypass changenotifier
|
|
|
|
}
|
|
|
|
|
|
|
|
class ContactListState extends ChangeNotifier {
|
|
|
|
List<ContactInfoState> _onions = [];
|
|
|
|
int get num => _onions.length;
|
|
|
|
|
2021-02-10 01:36:12 +00:00
|
|
|
ContactListState(Cwtch cwtch, String profileOnion) {
|
|
|
|
cwtch.GetContacts(profileOnion).then((jsonStr) {
|
2021-02-10 22:04:07 +00:00
|
|
|
if (jsonStr == null) return;
|
|
|
|
|
2021-02-10 21:04:49 +00:00
|
|
|
print("contacts: " + jsonStr);
|
2021-02-10 01:36:12 +00:00
|
|
|
List<dynamic> contacts = jsonDecode(jsonStr);
|
2021-02-10 21:04:49 +00:00
|
|
|
contacts.forEach((c) {
|
2021-02-10 01:36:12 +00:00
|
|
|
add(ContactInfoState(
|
|
|
|
profileOnion: profileOnion,
|
2021-02-10 21:04:49 +00:00
|
|
|
onion: c["onion"],
|
|
|
|
nickname: c["name"],
|
2021-02-10 01:36:12 +00:00
|
|
|
isGroup: false,
|
|
|
|
isInvitation: false,
|
|
|
|
isBlocked: false,
|
2021-02-10 21:04:49 +00:00
|
|
|
status: c["status"],
|
2021-02-10 01:36:12 +00:00
|
|
|
imagePath: "",
|
|
|
|
));
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2021-02-03 11:22:25 +00:00
|
|
|
void addAll(Iterable<ContactInfoState> newOnions) {
|
|
|
|
_onions.addAll(newOnions);
|
|
|
|
notifyListeners();
|
|
|
|
}
|
|
|
|
|
|
|
|
void add(ContactInfoState newOnion) {
|
|
|
|
_onions.add(newOnion);
|
|
|
|
notifyListeners();
|
|
|
|
}
|
|
|
|
|
|
|
|
void updateUnreadMessages(String forOnion, int newVal) {
|
|
|
|
_onions.sort((ContactInfoState a, ContactInfoState b) { return b.unreadMessages - a.unreadMessages; });
|
|
|
|
//<todo> if(changed) {
|
|
|
|
notifyListeners();
|
|
|
|
//} </todo>
|
|
|
|
}
|
|
|
|
|
|
|
|
List<ContactInfoState> get onions => _onions.sublist(0);//todo: copy?? dont want caller able to bypass changenotifier
|
|
|
|
}
|
|
|
|
|
|
|
|
class ProfileInfoState extends ChangeNotifier {
|
|
|
|
final String onion;
|
|
|
|
String _nickname = "";
|
|
|
|
String _imagePath = "";
|
|
|
|
int _unreadMessages = 0;
|
|
|
|
|
|
|
|
ProfileInfoState({this.onion, nickname = "", imagePath = "", unreadMessages = 0,}){
|
|
|
|
this._nickname = nickname;
|
|
|
|
this._imagePath = imagePath;
|
|
|
|
this._unreadMessages = unreadMessages;
|
|
|
|
}
|
|
|
|
|
|
|
|
String get nickname => this._nickname;
|
|
|
|
set nickname(String newValue) {
|
|
|
|
this.nickname = newValue;
|
|
|
|
notifyListeners();
|
|
|
|
}
|
|
|
|
|
|
|
|
String get imagePath => this._imagePath;
|
|
|
|
set imagePath(String newVal) {
|
|
|
|
this._imagePath = newVal;
|
|
|
|
notifyListeners();
|
|
|
|
}
|
|
|
|
|
|
|
|
int get unreadMessages => this._unreadMessages;
|
|
|
|
set unreadMessages(int newVal) {
|
|
|
|
this._unreadMessages = newVal;
|
|
|
|
notifyListeners();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class ContactInfoState extends ChangeNotifier {
|
|
|
|
final String profileOnion;
|
|
|
|
final String onion;
|
|
|
|
String _nickname;
|
|
|
|
bool _isGroup;
|
|
|
|
bool _isInvitation;
|
|
|
|
bool _isBlocked;
|
|
|
|
String _status;
|
|
|
|
String _imagePath;
|
|
|
|
int _unreadMessages = 0;
|
|
|
|
|
|
|
|
ContactInfoState({this.profileOnion, this.onion, nickname = "", isGroup = false, isInvitation = false, isBlocked = false, status = "", imagePath = "",}) {
|
|
|
|
this._nickname = nickname;
|
|
|
|
this._isGroup = isGroup;
|
|
|
|
this._isInvitation = isInvitation;
|
|
|
|
this._isBlocked = isBlocked;
|
|
|
|
this._status = status;
|
|
|
|
this._imagePath = imagePath;
|
|
|
|
}
|
|
|
|
|
|
|
|
get nickname => this._nickname;
|
|
|
|
set nickname(String newVal) {
|
|
|
|
this._nickname = newVal;
|
|
|
|
notifyListeners();
|
|
|
|
}
|
|
|
|
|
2021-02-10 01:36:12 +00:00
|
|
|
get isInvitation => this._isInvitation;
|
|
|
|
set isInvitation(bool newVal) {
|
|
|
|
this._isInvitation = newVal;
|
|
|
|
notifyListeners();
|
|
|
|
}
|
|
|
|
|
|
|
|
get status => this._status;
|
|
|
|
set status(String newVal) {
|
|
|
|
this._status = newVal;
|
|
|
|
notifyListeners();
|
|
|
|
}
|
|
|
|
|
2021-02-03 11:22:25 +00:00
|
|
|
get unreadMessages => this._unreadMessages;
|
|
|
|
set unreadMessages(int newVal) {
|
|
|
|
this._unreadMessages = newVal;
|
|
|
|
notifyListeners();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-07 19:38:06 +00:00
|
|
|
/////////////
|
|
|
|
/// ACN ///
|
|
|
|
/////////////
|
2021-01-06 23:09:58 +00:00
|
|
|
|
2021-01-12 06:21:18 +00:00
|
|
|
|
2021-01-07 19:38:06 +00:00
|
|
|
|
|
|
|
class AppModel {
|
2021-01-12 06:21:18 +00:00
|
|
|
final Cwtch cwtch;
|
|
|
|
AppModel({this.cwtch});
|
2021-01-06 23:09:58 +00:00
|
|
|
|
|
|
|
Stream<String> contactEvents() async* {
|
|
|
|
while (true) {
|
2021-01-14 23:36:09 +00:00
|
|
|
String event = await cwtch.ContactEvents();
|
2021-01-06 23:09:58 +00:00
|
|
|
if (event != "") {
|
|
|
|
print(event);
|
|
|
|
yield event;
|
|
|
|
} else {
|
2021-02-03 11:22:25 +00:00
|
|
|
print("TEST TEST FAIL TEST FAIL 123");
|
2021-01-06 23:09:58 +00:00
|
|
|
await Future.delayed(Duration(seconds: 1));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Stream<String> torStatus() async* {
|
|
|
|
while (true) {
|
2021-01-14 23:36:09 +00:00
|
|
|
String event = await cwtch.ACNEvents();
|
2021-01-06 23:09:58 +00:00
|
|
|
if (event != "") {
|
|
|
|
yield event;
|
|
|
|
} else {
|
2021-02-03 11:22:25 +00:00
|
|
|
print("TOR TEST TEST FAIL TEST FAIL 123");
|
2021-01-06 23:09:58 +00:00
|
|
|
await Future.delayed(Duration(seconds: 1));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-01-07 19:38:06 +00:00
|
|
|
}
|