forked from cwtch.im/cwtch-ui
Fix Change Password for Unencrypted Profiles / Handle TokenUpdates with No Tokens / Format
This commit is contained in:
parent
7ee619f1a6
commit
27a729d09a
|
@ -72,7 +72,8 @@ class CwtchNotifier {
|
||||||
}
|
}
|
||||||
EnvironmentConfig.debugLog("NewPeer $data");
|
EnvironmentConfig.debugLog("NewPeer $data");
|
||||||
// if tag != v1-defaultPassword then it is either encrypted OR it is an unencrypted account created during pre-beta...
|
// if tag != v1-defaultPassword then it is either encrypted OR it is an unencrypted account created during pre-beta...
|
||||||
profileCN.add(data["Identity"], data["name"], data["picture"], data["defaultPicture"], data["ContactsJson"], data["ServerList"], data["Online"] == "true", data["autostart"] == "true", data["tag"] != "v1-defaultPassword");
|
profileCN.add(data["Identity"], data["name"], data["picture"], data["defaultPicture"], data["ContactsJson"], data["ServerList"], data["Online"] == "true", data["autostart"] == "true",
|
||||||
|
data["tag"] != "v1-defaultPassword");
|
||||||
break;
|
break;
|
||||||
case "ContactCreated":
|
case "ContactCreated":
|
||||||
EnvironmentConfig.debugLog("ContactCreated $data");
|
EnvironmentConfig.debugLog("ContactCreated $data");
|
||||||
|
@ -310,12 +311,16 @@ class CwtchNotifier {
|
||||||
profileCN.getProfile(data["ProfileOnion"])?.replaceServers(data["ServerList"]);
|
profileCN.getProfile(data["ProfileOnion"])?.replaceServers(data["ServerList"]);
|
||||||
break;
|
break;
|
||||||
case "TokenManagerInfo":
|
case "TokenManagerInfo":
|
||||||
List<dynamic> associatedGroups = jsonDecode(data["Data"]);
|
try {
|
||||||
int count = int.parse(data["ServerTokenCount"]);
|
List<dynamic> associatedGroups = jsonDecode(data["Data"]);
|
||||||
associatedGroups.forEach((identifier) {
|
int count = int.parse(data["ServerTokenCount"]);
|
||||||
profileCN.getProfile(data["ProfileOnion"])?.contactList.getContact(int.parse(identifier.toString()))!.antispamTickets = count;
|
associatedGroups.forEach((identifier) {
|
||||||
});
|
profileCN.getProfile(data["ProfileOnion"])?.contactList.getContact(int.parse(identifier.toString()))!.antispamTickets = count;
|
||||||
EnvironmentConfig.debugLog("update server token count for ${associatedGroups}, $count");
|
});
|
||||||
|
EnvironmentConfig.debugLog("update server token count for ${associatedGroups}, $count");
|
||||||
|
} catch (e) {
|
||||||
|
// No tokens in data...
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case "NewGroup":
|
case "NewGroup":
|
||||||
String invite = data["GroupInvite"].toString();
|
String invite = data["GroupInvite"].toString();
|
||||||
|
|
|
@ -124,6 +124,10 @@ class ProfileInfoState extends ChangeNotifier {
|
||||||
|
|
||||||
// Check encrypted status for profile info screen
|
// Check encrypted status for profile info screen
|
||||||
bool get isEncrypted => this._encrypted;
|
bool get isEncrypted => this._encrypted;
|
||||||
|
set isEncrypted(bool newValue) {
|
||||||
|
this._encrypted = newValue;
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
String get nickname => this._nickname;
|
String get nickname => this._nickname;
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,15 @@ class ProfileListState extends ChangeNotifier {
|
||||||
var idx = _profiles.indexWhere((element) => element.onion == onion);
|
var idx = _profiles.indexWhere((element) => element.onion == onion);
|
||||||
if (idx == -1) {
|
if (idx == -1) {
|
||||||
_profiles.add(ProfileInfoState(
|
_profiles.add(ProfileInfoState(
|
||||||
onion: onion, nickname: name, imagePath: picture, defaultImagePath: defaultPicture, contactsJson: contactsJson, serversJson: serverJson, online: online, autostart: autostart, encrypted: encrypted));
|
onion: onion,
|
||||||
|
nickname: name,
|
||||||
|
imagePath: picture,
|
||||||
|
defaultImagePath: defaultPicture,
|
||||||
|
contactsJson: contactsJson,
|
||||||
|
serversJson: serverJson,
|
||||||
|
online: online,
|
||||||
|
autostart: autostart,
|
||||||
|
encrypted: encrypted));
|
||||||
} else {
|
} else {
|
||||||
_profiles[idx].updateFrom(onion, name, picture, contactsJson, serverJson, online);
|
_profiles[idx].updateFrom(onion, name, picture, contactsJson, serverJson, online);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ class GhostDark extends CwtchDark {
|
||||||
static final Color peerBubble = darkBlue;
|
static final Color peerBubble = darkBlue;
|
||||||
static final Color font = Colors.white;
|
static final Color font = Colors.white;
|
||||||
static final Color settings = Color(0xFFFDFFFD);
|
static final Color settings = Color(0xFFFDFFFD);
|
||||||
static final Color accent = lightBlue;//Color(0xFFD20070);
|
static final Color accent = lightBlue; //Color(0xFFD20070);
|
||||||
|
|
||||||
get theme => ghost_theme;
|
get theme => ghost_theme;
|
||||||
get mode => mode_dark;
|
get mode => mode_dark;
|
||||||
|
|
|
@ -49,7 +49,7 @@ class MidnightDark extends CwtchDark {
|
||||||
}
|
}
|
||||||
|
|
||||||
class MidnightLight extends CwtchLight {
|
class MidnightLight extends CwtchLight {
|
||||||
static final Color background = Color(0xFFFBFBFB);//Color(0xFFFFFDFF);
|
static final Color background = Color(0xFFFBFBFB); //Color(0xFFFFFDFF);
|
||||||
static final Color header = Color(0xFFE0E0E0);
|
static final Color header = Color(0xFFE0E0E0);
|
||||||
static final Color userBubble = Color(0xFFE0E0E0);
|
static final Color userBubble = Color(0xFFE0E0E0);
|
||||||
static final Color peerBubble = Color(0xFFBABDBE);
|
static final Color peerBubble = Color(0xFFBABDBE);
|
||||||
|
|
|
@ -199,7 +199,9 @@ class _AddEditProfileViewState extends State<AddEditProfileView> {
|
||||||
Provider.of<ProfileInfoState>(context).autostart = value;
|
Provider.of<ProfileInfoState>(context).autostart = value;
|
||||||
|
|
||||||
if (!Provider.of<ProfileInfoState>(context).onion.isEmpty) {
|
if (!Provider.of<ProfileInfoState>(context).onion.isEmpty) {
|
||||||
Provider.of<FlwtchState>(context, listen: false).cwtch.SetProfileAttribute(Provider.of<ProfileInfoState>(context).onion, "profile.autostart", value ? "true" : "false");
|
Provider.of<FlwtchState>(context, listen: false)
|
||||||
|
.cwtch
|
||||||
|
.SetProfileAttribute(Provider.of<ProfileInfoState>(context).onion, "profile.autostart", value ? "true" : "false");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
activeTrackColor: Provider.of<Settings>(context).theme.defaultButtonColor,
|
activeTrackColor: Provider.of<Settings>(context).theme.defaultButtonColor,
|
||||||
|
@ -207,7 +209,6 @@ class _AddEditProfileViewState extends State<AddEditProfileView> {
|
||||||
secondary: Icon(CwtchIcons.favorite_24dp, color: Provider.of<Settings>(context).current().mainTextColor),
|
secondary: Icon(CwtchIcons.favorite_24dp, color: Provider.of<Settings>(context).current().mainTextColor),
|
||||||
),
|
),
|
||||||
|
|
||||||
|
|
||||||
Visibility(
|
Visibility(
|
||||||
visible: Provider.of<ProfileInfoState>(context).onion.isEmpty,
|
visible: Provider.of<ProfileInfoState>(context).onion.isEmpty,
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
|
@ -418,7 +419,9 @@ class _AddEditProfileViewState extends State<AddEditProfileView> {
|
||||||
var profile = Provider.of<ProfileInfoState>(context, listen: false).onion;
|
var profile = Provider.of<ProfileInfoState>(context, listen: false).onion;
|
||||||
Provider.of<ProfileInfoState>(context, listen: false).nickname = ctrlrNick.value.text;
|
Provider.of<ProfileInfoState>(context, listen: false).nickname = ctrlrNick.value.text;
|
||||||
Provider.of<FlwtchState>(context, listen: false).cwtch.SetProfileAttribute(profile, "profile.name", ctrlrNick.value.text);
|
Provider.of<FlwtchState>(context, listen: false).cwtch.SetProfileAttribute(profile, "profile.name", ctrlrNick.value.text);
|
||||||
Provider.of<FlwtchState>(context, listen: false).cwtch.ChangePassword(profile, ctrlrOldPass.text, ctrlrPass.text, ctrlrPass2.text);
|
// Use default password if the profile is unencrypted
|
||||||
|
var password = Provider.of<ProfileInfoState>(context, listen: false).isEncrypted ? ctrlrOldPass.text : DefaultPassword;
|
||||||
|
Provider.of<FlwtchState>(context, listen: false).cwtch.ChangePassword(profile, password, ctrlrPass.text, ctrlrPass2.text);
|
||||||
|
|
||||||
EnvironmentConfig.debugLog("waiting for change password response");
|
EnvironmentConfig.debugLog("waiting for change password response");
|
||||||
Future.delayed(const Duration(milliseconds: 500), () {
|
Future.delayed(const Duration(milliseconds: 500), () {
|
||||||
|
@ -434,6 +437,8 @@ class _AddEditProfileViewState extends State<AddEditProfileView> {
|
||||||
}
|
}
|
||||||
}).whenComplete(() {
|
}).whenComplete(() {
|
||||||
if (globalErrorHandler.explicitChangePasswordSuccess) {
|
if (globalErrorHandler.explicitChangePasswordSuccess) {
|
||||||
|
// we need to set the local encrypted status to display correct password forms on this run...
|
||||||
|
Provider.of<ProfileInfoState>(context, listen: false).isEncrypted = true;
|
||||||
final snackBar = SnackBar(content: Text(AppLocalizations.of(context)!.newPassword));
|
final snackBar = SnackBar(content: Text(AppLocalizations.of(context)!.newPassword));
|
||||||
ScaffoldMessenger.of(context).showSnackBar(snackBar);
|
ScaffoldMessenger.of(context).showSnackBar(snackBar);
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
|
|
|
@ -95,70 +95,73 @@ class _ContactsViewState extends State<ContactsView> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return ScaffoldMessenger(key: scaffoldKey, child: Scaffold(
|
return ScaffoldMessenger(
|
||||||
endDrawerEnableOpenDragGesture: false,
|
key: scaffoldKey,
|
||||||
drawerEnableOpenDragGesture: false,
|
child: Scaffold(
|
||||||
appBar: AppBar(
|
endDrawerEnableOpenDragGesture: false,
|
||||||
leading: Stack(children: [
|
drawerEnableOpenDragGesture: false,
|
||||||
Align(
|
appBar: AppBar(
|
||||||
alignment: Alignment.center,
|
leading: Stack(children: [
|
||||||
child: IconButton(
|
Align(
|
||||||
icon: Icon(Icons.arrow_back),
|
alignment: Alignment.center,
|
||||||
tooltip: MaterialLocalizations.of(context).backButtonTooltip,
|
child: IconButton(
|
||||||
onPressed: () {
|
icon: Icon(Icons.arrow_back),
|
||||||
Provider.of<ProfileInfoState>(context, listen: false).recountUnread();
|
tooltip: MaterialLocalizations.of(context).backButtonTooltip,
|
||||||
Provider.of<AppState>(context, listen: false).selectedProfile = "";
|
onPressed: () {
|
||||||
Navigator.of(context).pop();
|
Provider.of<ProfileInfoState>(context, listen: false).recountUnread();
|
||||||
},
|
Provider.of<AppState>(context, listen: false).selectedProfile = "";
|
||||||
)),
|
Navigator.of(context).pop();
|
||||||
Positioned(
|
},
|
||||||
bottom: 5.0,
|
)),
|
||||||
right: 5.0,
|
Positioned(
|
||||||
child: StreamBuilder<bool>(
|
bottom: 5.0,
|
||||||
stream: Provider.of<AppState>(context).getUnreadProfileNotifyStream(),
|
right: 5.0,
|
||||||
builder: (BuildContext context, AsyncSnapshot<bool> unreadCountSnapshot) {
|
child: StreamBuilder<bool>(
|
||||||
int unreadCount = Provider.of<ProfileListState>(context).generateUnreadCount(Provider.of<AppState>(context).selectedProfile ?? "");
|
stream: Provider.of<AppState>(context).getUnreadProfileNotifyStream(),
|
||||||
|
builder: (BuildContext context, AsyncSnapshot<bool> unreadCountSnapshot) {
|
||||||
|
int unreadCount = Provider.of<ProfileListState>(context).generateUnreadCount(Provider.of<AppState>(context).selectedProfile ?? "");
|
||||||
|
|
||||||
return Visibility(
|
return Visibility(
|
||||||
visible: unreadCount > 0,
|
visible: unreadCount > 0,
|
||||||
child: CircleAvatar(
|
child: CircleAvatar(
|
||||||
radius: 10.0,
|
radius: 10.0,
|
||||||
backgroundColor: Provider.of<Settings>(context).theme.portraitProfileBadgeColor,
|
backgroundColor: Provider.of<Settings>(context).theme.portraitProfileBadgeColor,
|
||||||
child: Text(unreadCount > 99 ? "99+" : unreadCount.toString(), style: TextStyle(color: Provider.of<Settings>(context).theme.portraitProfileBadgeTextColor, fontSize: 8.0)),
|
child:
|
||||||
));
|
Text(unreadCount > 99 ? "99+" : unreadCount.toString(), style: TextStyle(color: Provider.of<Settings>(context).theme.portraitProfileBadgeTextColor, fontSize: 8.0)),
|
||||||
}),
|
));
|
||||||
)
|
}),
|
||||||
]),
|
)
|
||||||
title: Row(children: [
|
]),
|
||||||
ProfileImage(
|
title: Row(children: [
|
||||||
imagePath: Provider.of<Settings>(context).isExperimentEnabled(ImagePreviewsExperiment)
|
ProfileImage(
|
||||||
? Provider.of<ProfileInfoState>(context).imagePath
|
imagePath: Provider.of<Settings>(context).isExperimentEnabled(ImagePreviewsExperiment)
|
||||||
: Provider.of<ProfileInfoState>(context).defaultImagePath,
|
? Provider.of<ProfileInfoState>(context).imagePath
|
||||||
diameter: 42,
|
: Provider.of<ProfileInfoState>(context).defaultImagePath,
|
||||||
border: Provider.of<ProfileInfoState>(context).isOnline
|
diameter: 42,
|
||||||
? Provider.of<Settings>(context).current().portraitOnlineBorderColor
|
border: Provider.of<ProfileInfoState>(context).isOnline
|
||||||
: Provider.of<Settings>(context).current().portraitOfflineBorderColor,
|
? Provider.of<Settings>(context).current().portraitOnlineBorderColor
|
||||||
badgeTextColor: Colors.red,
|
: Provider.of<Settings>(context).current().portraitOfflineBorderColor,
|
||||||
badgeColor: Colors.red,
|
badgeTextColor: Colors.red,
|
||||||
|
badgeColor: Colors.red,
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 10,
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Text("%1 » %2".replaceAll("%1", Provider.of<ProfileInfoState>(context).nickname).replaceAll("%2", AppLocalizations.of(context)!.titleManageContacts),
|
||||||
|
overflow: TextOverflow.ellipsis, style: TextStyle(color: Provider.of<Settings>(context).current().mainTextColor))),
|
||||||
|
]),
|
||||||
|
actions: getActions(context),
|
||||||
),
|
),
|
||||||
SizedBox(
|
floatingActionButton: FloatingActionButton(
|
||||||
width: 10,
|
onPressed: _modalAddImportChoice,
|
||||||
|
tooltip: AppLocalizations.of(context)!.tooltipAddContact,
|
||||||
|
child: Icon(
|
||||||
|
CwtchIcons.person_add_alt_1_24px,
|
||||||
|
color: Provider.of<Settings>(context).theme.defaultButtonTextColor,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
Expanded(
|
body: showSearchBar || Provider.of<ContactListState>(context).isFiltered ? _buildFilterable() : _buildContactList()));
|
||||||
child: Text("%1 » %2".replaceAll("%1", Provider.of<ProfileInfoState>(context).nickname).replaceAll("%2", AppLocalizations.of(context)!.titleManageContacts),
|
|
||||||
overflow: TextOverflow.ellipsis, style: TextStyle(color: Provider.of<Settings>(context).current().mainTextColor))),
|
|
||||||
]),
|
|
||||||
actions: getActions(context),
|
|
||||||
),
|
|
||||||
floatingActionButton: FloatingActionButton(
|
|
||||||
onPressed: _modalAddImportChoice,
|
|
||||||
tooltip: AppLocalizations.of(context)!.tooltipAddContact,
|
|
||||||
child: Icon(
|
|
||||||
CwtchIcons.person_add_alt_1_24px,
|
|
||||||
color: Provider.of<Settings>(context).theme.defaultButtonTextColor,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
body: showSearchBar || Provider.of<ContactListState>(context).isFiltered ? _buildFilterable() : _buildContactList()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Widget> getActions(context) {
|
List<Widget> getActions(context) {
|
||||||
|
|
|
@ -82,15 +82,17 @@ class _ProfileImageState extends State<ProfileImage> {
|
||||||
width: widget.diameter,
|
width: widget.diameter,
|
||||||
height: widget.diameter,
|
height: widget.diameter,
|
||||||
color: widget.border,
|
color: widget.border,
|
||||||
foregroundDecoration: widget.disabled ? BoxDecoration(
|
foregroundDecoration: widget.disabled
|
||||||
color: Provider.of<Settings>(context).theme.portraitBackgroundColor, //Colors.grey,
|
? BoxDecoration(
|
||||||
backgroundBlendMode: BlendMode.color, //saturation,
|
color: Provider.of<Settings>(context).theme.portraitBackgroundColor, //Colors.grey,
|
||||||
) : null,
|
backgroundBlendMode: BlendMode.color, //saturation,
|
||||||
|
)
|
||||||
|
: null,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(2.0), //border size
|
padding: const EdgeInsets.all(2.0), //border size
|
||||||
child: ClipOval(clipBehavior: Clip.antiAlias, child: widget.tooltip == "" ? image : Tooltip(message: widget.tooltip, child: image))))),
|
child: ClipOval(clipBehavior: Clip.antiAlias, child: widget.tooltip == "" ? image : Tooltip(message: widget.tooltip, child: image))))),
|
||||||
// badge
|
// badge
|
||||||
Visibility(
|
Visibility(
|
||||||
visible: widget.badgeIcon != null || widget.badgeEdit || widget.badgeCount > 0,
|
visible: widget.badgeIcon != null || widget.badgeEdit || widget.badgeCount > 0,
|
||||||
child: Positioned(
|
child: Positioned(
|
||||||
bottom: 0.0,
|
bottom: 0.0,
|
||||||
|
@ -107,22 +109,17 @@ class _ProfileImageState extends State<ProfileImage> {
|
||||||
),
|
),
|
||||||
)),
|
)),
|
||||||
// disabled center icon
|
// disabled center icon
|
||||||
Visibility(
|
Visibility(
|
||||||
visible: widget.disabled,
|
visible: widget.disabled,
|
||||||
child: Container(
|
child: Container(
|
||||||
width: widget.diameter,
|
width: widget.diameter,
|
||||||
height: widget.diameter,
|
height: widget.diameter,
|
||||||
child:
|
child: Center(
|
||||||
Center(
|
child: Icon(
|
||||||
|
CwtchIcons.negative_heart_24px,
|
||||||
|
size: widget.diameter / 1.5,
|
||||||
child: Icon(
|
color: Provider.of<Settings>(context).theme.portraitOfflineBorderColor,
|
||||||
CwtchIcons.negative_heart_24px,
|
)))),
|
||||||
size: widget.diameter / 1.5,
|
|
||||||
color: Provider.of<Settings>(context).theme.portraitOfflineBorderColor,
|
|
||||||
)
|
|
||||||
|
|
||||||
))),
|
|
||||||
]));
|
]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue