-
Notifications
You must be signed in to change notification settings - Fork 553
[NEW] Send dynamicLinks with invites; Support the handling of dynamicLinks in the app. #2196
[NEW] Send dynamicLinks with invites; Support the handling of dynamicLinks in the app. #2196
Conversation
…amicLinks manager and resolve imports
…ing the widechat google-services and appName for testing.
…DM from dynamicLinks
…ndroid into ear_develop_w_share_and_dynamic_links
@filipedelimabrito I can fix the conflicts in this PR, but I would prefer to wait until you are ready to review so that we don't keep going around in circles. This is our Phase 1 to support the Contact Sync feature. Do you think we'll get that feature in the next milestone? We are prepared to make all the PRs and present a design doc if needed. Thanks... |
@filipedelimabrito can we give this PR some visibility on what is missing for it to get merged if the conflicts are resolved? |
|
||
}.addOnFailureListener { | ||
// Error | ||
Toast.makeText(context, "Error dynamic link", Toast.LENGTH_SHORT).show() |
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.
Hard-coded string! 🛑
Please remove and make use of the strings.xml!
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.
These toast messages were just for debugging. I will remove them and replace with timber logging without string translations. If you would rather we do it a different way please let me know.
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.
Timber is enough but if it is there because you are still debugging it I'll make this as a WIP PR, ok?
Anyway, I think that showing an error message to the user when there is a failure would be better. In this case make sure to implement the MessageView
on the fragment (if needed) and make use of our ext. function showToast(resId)
and/or showToast(message)
plus log it with timber.
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.
Is it supposed to show the deeplink url on the toast in this line (on the addOnSuccessListener
):
Toast.makeText(context, newDeepLink, Toast.LENGTH_SHORT).show()
?
Only a toast with the deeplink url? 🤔
If so, better to add more context on the message.
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.
My thought is this.... I don't think we want to show any info to the user about the deepLink. Users have no idea what a deepLink is, and there is no requirement that they do. I added the logging with Timber just to have a record in the server logs for admins as needed. If the deepLink creation fails, then it uses the default message, and the user has not been affected. Thoughts?
FYI - I did push a bunch of updates to the PR and the Toast messages are now removed.
app/src/play/java/chat/rocket/android/dynamiclinks/DynamicLinksForFirebase.kt
Outdated
Show resolved
Hide resolved
app/src/play/java/chat/rocket/android/dynamiclinks/DynamicLinksForFirebase.kt
Outdated
Show resolved
Hide resolved
app/src/play/java/chat/rocket/android/dynamiclinks/DynamicLinksForFirebase.kt
Outdated
Show resolved
Hide resolved
app/src/play/java/chat/rocket/android/dynamiclinks/DynamicLinksForFirebase.kt
Outdated
Show resolved
Hide resolved
app/src/main/java/chat/rocket/android/authentication/presentation/AuthenticationNavigator.kt
Outdated
Show resolved
Hide resolved
@@ -181,7 +181,7 @@ class LoginOptionsFragment : Fragment(), LoginOptionsView { | |||
totalSocialAccountsEnabled = getInt(TOTAL_SOCIAL_ACCOUNTS) | |||
isLoginFormEnabled = getBoolean(IS_LOGIN_FORM_ENABLED) | |||
isNewAccountCreationEnabled = getBoolean(IS_NEW_ACCOUNT_CREATION_ENABLED) | |||
deepLinkInfo = getParcelable(DEEP_LINK_INFO) | |||
deepLinkInfo = getParcelable(Constants.DEEP_LINK_INFO) |
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.
Remove the Constants object please (a comment was left on it).
@@ -115,7 +115,7 @@ fun newInstance( | |||
putInt(TOTAL_SOCIAL_ACCOUNTS, totalSocialAccountsEnabled) | |||
putBoolean(IS_LOGIN_FORM_ENABLED, isLoginFormEnabled) | |||
putBoolean(IS_NEW_ACCOUNT_CREATION_ENABLED, isNewAccountCreationEnabled) | |||
putParcelable(DEEP_LINK_INFO, deepLinkInfo) | |||
putParcelable(Constants.DEEP_LINK_INFO, deepLinkInfo) |
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.
Remove the Constants object please (a comment was left on it).
app/src/main/java/chat/rocket/android/authentication/domain/model/DeepLinkInfo.kt
Outdated
Show resolved
Hide resolved
app/src/foss/java/chat/rocket/android/dynamiclinks/DynamicLinksForFirebase.kt
Show resolved
Hide resolved
Hi Filipe..... I did manage to test this end to end using our Firebase dynamic links... I'm pretty much done with this PR, unless you have some suggestion about how to best handle the Constants.kt file (I posed the question in the thread)... Thanks. Let me know if there are other issues you would like resolved before merge... |
@ear-dev It is not ready to be merged yet. There is still some hard-coded strings on this PR making it unready to be integrated here - for instance. |
Thanks Filipe. I see that there are new conflicting files.... I'll fix those. That const you pointed out is fixed.... let me know if you have any thoughts about the Constants.kt file question I posed.... |
app/src/main/java/chat/rocket/android/authentication/domain/model/DeepLinkInfo.kt
Show resolved
Hide resolved
app/src/main/java/chat/rocket/android/authentication/domain/model/DeepLinkInfo.kt
Outdated
Show resolved
Hide resolved
app/src/main/java/chat/rocket/android/authentication/domain/model/DeepLinkInfo.kt
Outdated
Show resolved
Hide resolved
private inline fun Uri.isWebSchemeRoomLink(): Boolean { | ||
val roomType = path.split("/")[1] | ||
if (scheme.startsWith("http") && | ||
(roomType == "channel" || roomType == "group" || roomType == "direct")) |
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.
You can make use of roomTypeOf(roomType)
here to check is the room type is channel, group, etc.
Ex.:
... roomTypeOf(roomType) is RoomType.DirectMessage
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.
@filipedelimabrito will roomTypeOf() just accept the lower case strings we've parsed from the path? Or does it need to be converted into some object or capitalized string? It's not clear to me right away. Thanks.
allowStateLoss = true | ||
) { | ||
chat.rocket.android.authentication.server.ui.newInstance() | ||
private fun routeNoLink() { |
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.
@ear-dev Can you add a comment to make it clear to anyone reading that code or change the function name to something more meaningful? It will help us a lot here.
@@ -0,0 +1,5 @@ | |||
package chat.rocket.android.helper | |||
|
|||
object Constants { |
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.
Let me take a look in a deep way here. But since we are going to use a Constant class with, well... our constants we will need to move all the stuffs declared on our code here to avoid people declaring it in multiple places of our code for instance.
Thanks for thinking about the constants.kt issue..... I honestly do not know what the best practice should be in this case. Most of your constants are scoped to just a single class I believe. Are there any other examples of a constant like this one that is shared among multiple classes and activities? |
…ndroid into ear_develop_w_share_and_dynamic_links
* | ||
* @param inviteType The method of invite to log, currently only 'share' using the share intent. | ||
*/ | ||
fun logInviteSent(inviteType: String, inviteSucceeded: Boolean) {} |
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 can make the inviteType an enum here.
fun saveDeepLinkInfo(deepLinkInfo: DeepLinkInfo) { | ||
savedDeepLinkInfo = deepLinkInfo | ||
} | ||
fun toOnBoarding() { |
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.
Missing white line above function.
|
||
private const val DEEP_LINK_INFO = "DeepLinkInfo" | ||
fun newInstance(deepLinkInfo: DeepLinkInfo?): ServerFragment { | ||
val fragment = ServerFragment() |
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.
Code can be improved here. I'll work on it.
putExtra(Intent.EXTRA_TEXT, getString(R.string.play_store_link)) | ||
startActivity(Intent.createChooser(this, getString(R.string.msg_share_using))) | ||
} | ||
// We can't know for sure at this point that the invitation was sent successfully since they will now be outside our app |
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.
Right. But having it logged by our analytic tool will let us know how many people do this action even though the invitation was not sent successfully as explained on your comment above (thanks for adding it). This way I'll remove the inviteSucceeded which indicate if the invitation was sent successfully or not - since we don't know about it.
DeepLinkInfo(url, userId, token, null, null, null) | ||
} catch (ex: Exception) { | ||
Timber.d(ex, "Error parsing auth deeplink") |
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 error used the proper Timber function: e
.
/** | ||
* Logs the invitation sent event. | ||
* | ||
* @param inviteType The method of invite to log, currently only 'share' using the share intent. |
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.
Where is the inviteSucceeded
param?
@@ -73,6 +73,13 @@ class GoogleAnalyticsForFirebase @Inject constructor(val context: Context) : | |||
}) | |||
} | |||
|
|||
override fun logInviteSent(inviteType: String, inviteSucceeded: Boolean) { |
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.
You forgot to log it on AnswersAnalytics
too...
import chat.rocket.android.main.ui.MainActivity | ||
import chat.rocket.android.server.ui.changeServerIntent | ||
import chat.rocket.android.util.extensions.addFragmentBackStack | ||
import chat.rocket.android.util.extensions.toPreviousView | ||
import chat.rocket.android.webview.ui.webViewIntent | ||
|
||
class AuthenticationNavigator(internal val activity: AuthenticationActivity) { | ||
var savedDeepLinkInfo: DeepLinkInfo? = 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.
Variable can be private.
intent?.let { | ||
val deepLinkInfo = it.getParcelableExtra<DeepLinkInfo>(Constants.DEEP_LINK_INFO) | ||
if (deepLinkInfo != null) { | ||
val chatRoomsFragment = supportFragmentManager.findFragmentByTag(TAG_CHAT_ROOMS_FRAGMENT) as ChatRoomsFragment |
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.
Please, respect our code style.
fun saveDeepLinkInfo(deepLinkInfo: DeepLinkInfo) { | ||
savedDeepLinkInfo = deepLinkInfo | ||
} | ||
fun toOnBoarding() { |
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.
Also, where is this function being called?
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.
@ear-dev I have fixed some issues here. Thanks for sending this PR!
@filipedelimabrito Awesome!! Thanks!! |
@RocketChat/android
Changes:
Video Demo here: https://drive.google.com/file/d/1t244q_G4Kls_iWzb4EMqA8eBCg94j1bq/view?usp=sharing