-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
QR code scanning improvements and PR feedback #314
Conversation
oxtoacart
commented
Aug 17, 2021
- If you refactored existing code, have you tested the refactored functionality against the old version to make sure you didn't break anything?
- Do the tests pass? Consistently?
- Did this change improve test coverage?
- Is the code in question being linted? If not, consider adding a linter step to CI. If yes, make sure the linter is happy.
- Have you logged tickets for related technical debt with the label “techdebt”?
android/app/build.gradle
Outdated
@@ -417,7 +417,7 @@ dependencies { | |||
implementation(name:'opuslib-release', ext: 'aar') | |||
implementation 'com.github.getlantern:secrets-android:3ac588e' | |||
implementation 'com.github.getlantern:db-android:4d13d81641' | |||
implementation 'com.github.getlantern:messaging-android:6c54447c7a' | |||
implementation 'com.github.getlantern:messaging-android:fa0be640a1' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This pulls in changes from this PR, which includes both QR code scanning improvements as well as fixes related to introductions.
"addOrUpdateDirectContact" -> messaging.addOrUpdateDirectContact( | ||
call.argument("identityKey")!!, | ||
call.argument("displayName")!! | ||
"addProvisionalContact" -> messaging.addProvisionalContact( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When scanning QR codes, we now add provisional contacts rather than full contacts. That keeps us from getting contacts before the other side has completed their part of the scanning dance.
: unawaited(model.clearCurrentConversationContact()); | ||
return WillPopScope( | ||
onWillPop: () => Future<bool>.value(_keyboardState), | ||
child: BaseScreen( | ||
child: model.singleContactById(context, widget._contactId, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to subscribe to the contact so that we can observe changes that impact our conversation sticker (e.g. change to field hasReceivedMessage
).
.toList() | ||
.where((intro) => intro.value.contactId == contact.contactId) | ||
.isNotEmpty; | ||
final isPendingIntroduction = !contact.hasReceivedMessage && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An introduction is really only pending until we've received a message from the contact. This new hasReceivedMessage
field let's us know once we've gotten anything (even just a control message like disappearSettings
), which indicates to us that the other side must have added us as a contact.
introductions | ||
.toList() | ||
.where( | ||
(intro) => intro.value.introduction.to == contact.contactId) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This filter was wrong. We're interested in introductions made to this conversation's contact, not those made by this conversations' contact.
return ConversationSticker( | ||
contact: contact, | ||
noIntroductions: noIntroductions, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think noIntroductions
is necessary.
@@ -45,7 +45,7 @@ class _IntroduceState extends State<Introduce> { | |||
padding: const EdgeInsets.symmetric( | |||
horizontal: 24.0, vertical: 16.0), | |||
child: Text( | |||
'Select two or more contacts to introduce. They will be sent invitations to start messaging each other. ' | |||
'Select two or more contacts to introduce. They will be sent introductions to start messaging each other. ' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Invitation" means something different than "Introduction". Let's use "Introduction" consistently to avoid confusion.
@@ -102,7 +102,7 @@ class _IntroduceState extends State<Introduce> { | |||
}), | |||
)), | |||
), | |||
(selectedContactIds.isNotEmpty) | |||
(selectedContactIds.length >= 2) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should only display the button if we've selected 2 or more contacts, since we need at least 2 to make an introduction.
@@ -1,4 +1,3 @@ | |||
import 'package:lantern/core/router/router.gr.dart'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Linter drive-by
@@ -20,7 +20,8 @@ class _AddViaQRState extends State<AddViaQR> { | |||
QRViewController? qrController; | |||
|
|||
bool scanning = false; | |||
Contact? scannedContact; | |||
String? scannedContactId; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changes in this file are to accommodate the switch to using provisional contacts for QR code scanning.
@@ -21,8 +20,6 @@ class _AddViaUsernameState extends State<AddViaUsername> { | |||
|
|||
@override | |||
Widget build(BuildContext context) { | |||
var model = context.watch<MessagingModel>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Drive-by, unused
? _fullyAddedIcon() | ||
: _partiallyAddedIcon(), | ||
child: | ||
!isPendingIntroduction ? _fullyAddedIcon() : _partiallyAddedIcon(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This logic was backwards. We should only show the fully added state if we're NOT pending introduction.
@@ -62,45 +61,39 @@ class ContactConnectionCard extends StatelessWidget { | |||
color: outbound | |||
? outboundMsgColor | |||
: inboundMsgColor), | |||
IconButton( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Having only the tiny icon as a click target seemed inconvenient, so I changed this to make the whole message bubble clickable.
@@ -146,7 +139,7 @@ class ContactConnectionCard extends StatelessWidget { | |||
dense: true, | |||
leading: | |||
const Icon(Icons.check_circle, color: Colors.black), | |||
title: Text('Accept'.i18n), | |||
title: Text('Accept'.i18n, style: tsAlertDialogTitle), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needed the style to look the same as the Reject button.
@@ -161,6 +154,7 @@ class ContactConnectionCard extends StatelessWidget { | |||
icon: ImagePaths.alert_icon, | |||
buttonText: 'OK'.i18n); | |||
} finally { | |||
await context.router.pop(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For now, let's just close the bottom sheet until we figure out what else to do.
@@ -66,12 +66,6 @@ class AudioController extends ValueNotifier<AudioValue> { | |||
}); | |||
} | |||
|
|||
void _setThumbnail(Uint8List thumbnail) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Drive-by, unused
* [error] if loading fails, this contains the error encountered | ||
* | ||
*/ | ||
/// An asynchronously loaded value cached in an LRU cache. CachedValues are |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Drive-by, comment style
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the bug fixes @oxtoacart 👍
In terms of the QR side of this - I am getting an error when I exit the scanning view without the other phone having scanned my code.
I/GoLog (28038): Aug 17 15:19:21.860 - 1m41s ERROR lantern: logger.go:8 BaseModel: Unexpected error calling deleteProvisionalContact: java.lang.NullPointerException [error=%s: %s error_location=github.com/getlantern/android-lantern/internalsdk.Error (logger.go:8) error_text=BaseModel: Unexpected error calling deleteProvisionalContact: java.lang.NullPointerException error_type=errors.Error]
I/GoLog (28038): ERROR lantern: logger.go:8 at github.com/getlantern/android-lantern/internalsdk.Error (logger.go:8)
I/GoLog (28038): ERROR lantern: logger.go:8 at main.proxyinternalsdk__Error (go_internalsdkmain.go:1434)
I/GoLog (28038): ERROR lantern: logger.go:8 at _cgoexp_6a4be5f45433_proxyinternalsdk__Error (_cgo_gotypes.go:1647)
I/GoLog (28038): ERROR lantern: logger.go:8 at runtime.cgocallbackg1 (cgocall.go:292)
I/GoLog (28038): ERROR lantern: logger.go:8 at runtime.cgocallbackg (cgocall.go:228)
I/GoLog (28038): ERROR lantern: logger.go:8 at runtime.cgocallback (asm_arm64.s:1055)
I/GoLog (28038): ERROR lantern: logger.go:8 at runtime.goexit (asm_arm64.s:1130)
Oops! I've fixed that now. |
subscription = qrController?.scannedDataStream.listen((scanData) async { | ||
try { | ||
if (scannedContact != null) { | ||
if (scannedContactId != null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we be providing some UX feedback here? (sorry, should have pointed this out way earlier!)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, that's just a guard because we can get the same event multiple times prior to shutting off the camera.
// immediately invoke listener in case the contactNotifier already has | ||
// a contact. | ||
listener(); | ||
} | ||
} catch (e) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm getting a "Failed assertion: boolean expression must not be null"
error when scanning the QR code of an existing contact in the catch
statement here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not seeing this anymore @oxtoacart, I was one commit behind when I added it.
This works well for me now @oxtoacart, not getting that error after exiting QR screen. |
7851e6b
to
7a8550d
Compare