Commit 30a02575 authored by Filipe de Lima Brito's avatar Filipe de Lima Brito

Merge branch 'v3.0.0' into redesignOnboarding

parents 8c74508e 93d43d3b
...@@ -6,6 +6,7 @@ if (isPlay) { apply plugin: 'io.fabric' } ...@@ -6,6 +6,7 @@ if (isPlay) { apply plugin: 'io.fabric' }
apply plugin: 'kotlin-android' apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions' apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt' apply plugin: 'kotlin-kapt'
apply plugin: "com.github.ben-manes.versions"
android { android {
compileSdkVersion versions.compileSdk compileSdkVersion versions.compileSdk
...@@ -15,8 +16,8 @@ android { ...@@ -15,8 +16,8 @@ android {
applicationId "chat.rocket.android" applicationId "chat.rocket.android"
minSdkVersion versions.minSdk minSdkVersion versions.minSdk
targetSdkVersion versions.targetSdk targetSdkVersion versions.targetSdk
versionCode 2036 versionCode 2042
versionName "2.5.1" versionName "2.6.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
multiDexEnabled true multiDexEnabled true
...@@ -104,6 +105,7 @@ dependencies { ...@@ -104,6 +105,7 @@ dependencies {
implementation libraries.browser implementation libraries.browser
implementation libraries.androidKtx implementation libraries.androidKtx
implementation libraries.fragmentsKtx
implementation libraries.dagger implementation libraries.dagger
implementation libraries.daggerSupport implementation libraries.daggerSupport
...@@ -117,6 +119,8 @@ dependencies { ...@@ -117,6 +119,8 @@ dependencies {
kapt libraries.roomProcessor kapt libraries.roomProcessor
implementation libraries.lifecycleExtensions implementation libraries.lifecycleExtensions
kapt libraries.lifecycleCompiler kapt libraries.lifecycleCompiler
implementation libraries.viewmodelKtx
implementation libraries.workmanager
implementation libraries.rxKotlin implementation libraries.rxKotlin
implementation libraries.rxAndroid implementation libraries.rxAndroid
...@@ -145,14 +149,14 @@ dependencies { ...@@ -145,14 +149,14 @@ dependencies {
implementation libraries.aVLoadingIndicatorView implementation libraries.aVLoadingIndicatorView
implementation "com.github.luciofm:livedata-ktx:b1e8bbc25a" implementation libraries.livedataKtx
// Proprietary libraries // Proprietary libraries
playImplementation libraries.fcm playImplementation libraries.fcm
playImplementation libraries.firebaseAnalytics playImplementation libraries.firebaseAnalytics
playImplementation libraries.playServicesAuth playImplementation libraries.playServicesAuth
playImplementation('com.crashlytics.sdk.android:crashlytics:2.9.4@aar') { transitive = true } playImplementation('com.crashlytics.sdk.android:crashlytics:2.9.5@aar') { transitive = true }
playImplementation('com.crashlytics.sdk.android:answers:1.4.2@aar') { transitive = true } playImplementation('com.crashlytics.sdk.android:answers:1.4.3@aar') { transitive = true }
testImplementation libraries.junit testImplementation libraries.junit
testImplementation libraries.truth testImplementation libraries.truth
......
package chat.rocket.android.util.helper.analytics package chat.rocket.android.analytics
import chat.rocket.android.util.helper.analytics.event.AuthenticationEvent import chat.rocket.android.analytics.event.AuthenticationEvent
import chat.rocket.android.util.helper.analytics.event.ScreenViewEvent import chat.rocket.android.analytics.event.ScreenViewEvent
import chat.rocket.android.util.helper.analytics.event.SubscriptionTypeEvent import chat.rocket.android.analytics.event.SubscriptionTypeEvent
object AnalyticsManager : Analytics { class AnswersAnalytics : Analytics {
override fun logLogin(event: AuthenticationEvent, loginSucceeded: Boolean) { override fun logLogin(event: AuthenticationEvent, loginSucceeded: Boolean) {
// Do absolutely nothing // Do absolutely nothing
......
package chat.rocket.android.analytics
import android.content.Context
import chat.rocket.android.analytics.event.AuthenticationEvent
import chat.rocket.android.analytics.event.ScreenViewEvent
import chat.rocket.android.analytics.event.SubscriptionTypeEvent
import javax.inject.Inject
class GoogleAnalyticsForFirebase @Inject constructor(val context: Context) :
Analytics {
override fun logLogin(event: AuthenticationEvent, loginSucceeded: Boolean) {
// Do absolutely nothing
}
override fun logSignUp(event: AuthenticationEvent, signUpSucceeded: Boolean) {
// Do absolutely nothing
}
override fun logScreenView(event: ScreenViewEvent) {
// Do absolutely nothing
}
override fun logMessageSent(event: SubscriptionTypeEvent, serverUrl: String) {
// Do absolutely nothing
}
override fun logMediaUploaded(event: SubscriptionTypeEvent, mimeType: String) {
// Do absolutely nothing
}
override fun logReaction(event: SubscriptionTypeEvent) {
// Do absolutely nothing
}
override fun logServerSwitch(serverUrl: String, serverCount: Int) {
// Do absolutely nothing
}
}
package chat.rocket.android.push package chat.rocket.android.push
class FirebaseTokenService { fun refreshPushToken() {
}
}
\ No newline at end of file
package chat.rocket.android.util package chat.rocket.android.util
import chat.rocket.android.main.presentation.MainPresenter
fun refreshFCMToken(presenter: MainPresenter) {
//Do absolutely nothing
}
fun invalidateFirebaseToken(token: String) { fun invalidateFirebaseToken(token: String) {
//Do absolutely nothing //Do absolutely nothing
} }
\ No newline at end of file
app/src/main/ic_launcher-web.png

39.1 KB | W: | H:

app/src/main/ic_launcher-web.png

63.8 KB | W: | H:

app/src/main/ic_launcher-web.png
app/src/main/ic_launcher-web.png
app/src/main/ic_launcher-web.png
app/src/main/ic_launcher-web.png
  • 2-up
  • Swipe
  • Onion skin
package chat.rocket.android.about.di
import chat.rocket.android.about.ui.AboutFragment
import dagger.Module
import dagger.android.ContributesAndroidInjector
@Module
abstract class AboutFragmentProvider {
@ContributesAndroidInjector()
abstract fun provideAboutFragment(): AboutFragment
}
...@@ -7,10 +7,10 @@ import android.view.ViewGroup ...@@ -7,10 +7,10 @@ import android.view.ViewGroup
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import chat.rocket.android.BuildConfig import chat.rocket.android.BuildConfig
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.analytics.AnalyticsManager
import chat.rocket.android.analytics.event.ScreenViewEvent
import chat.rocket.android.main.ui.MainActivity import chat.rocket.android.main.ui.MainActivity
import chat.rocket.android.server.domain.AnalyticsTrackingInteractor import dagger.android.support.AndroidSupportInjection
import chat.rocket.android.util.helper.analytics.AnalyticsManager
import chat.rocket.android.util.helper.analytics.event.ScreenViewEvent
import kotlinx.android.synthetic.main.app_bar.* import kotlinx.android.synthetic.main.app_bar.*
import kotlinx.android.synthetic.main.fragment_about.* import kotlinx.android.synthetic.main.fragment_about.*
import javax.inject.Inject import javax.inject.Inject
...@@ -19,7 +19,12 @@ internal const val TAG_ABOUT_FRAGMENT = "AboutFragment" ...@@ -19,7 +19,12 @@ internal const val TAG_ABOUT_FRAGMENT = "AboutFragment"
class AboutFragment : Fragment() { class AboutFragment : Fragment() {
@Inject @Inject
lateinit var analyticsTrackingInteractor: AnalyticsTrackingInteractor lateinit var analyticsManager: AnalyticsManager
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
AndroidSupportInjection.inject(this)
}
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, inflater: LayoutInflater,
...@@ -32,15 +37,15 @@ class AboutFragment : Fragment() { ...@@ -32,15 +37,15 @@ class AboutFragment : Fragment() {
setupToolbar() setupToolbar()
setupViews() setupViews()
if (analyticsTrackingInteractor.get()) { analyticsManager.logScreenView(ScreenViewEvent.About)
AnalyticsManager.logScreenView(ScreenViewEvent.About)
}
} }
private fun setupViews() { private fun setupViews() {
text_version_name.text = BuildConfig.VERSION_NAME text_version_name.text = BuildConfig.VERSION_NAME
text_build_number.text = getString(R.string.msg_build, BuildConfig.VERSION_CODE, text_build_number.text = getString(
BuildConfig.GIT_SHA, BuildConfig.FLAVOR) R.string.msg_build, BuildConfig.VERSION_CODE,
BuildConfig.GIT_SHA, BuildConfig.FLAVOR
)
} }
private fun setupToolbar() { private fun setupToolbar() {
......
package chat.rocket.android.util.helper.analytics package chat.rocket.android.analytics
import chat.rocket.android.util.helper.analytics.event.AuthenticationEvent import chat.rocket.android.analytics.event.AuthenticationEvent
import chat.rocket.android.util.helper.analytics.event.ScreenViewEvent import chat.rocket.android.analytics.event.ScreenViewEvent
import chat.rocket.android.util.helper.analytics.event.SubscriptionTypeEvent import chat.rocket.android.analytics.event.SubscriptionTypeEvent
interface Analytics { interface Analytics {
......
package chat.rocket.android.analytics
import chat.rocket.android.analytics.event.AuthenticationEvent
import chat.rocket.android.analytics.event.ScreenViewEvent
import chat.rocket.android.analytics.event.SubscriptionTypeEvent
import chat.rocket.android.server.domain.AnalyticsTrackingInteractor
import chat.rocket.android.server.domain.GetAccountsInteractor
import chat.rocket.android.server.domain.GetCurrentServerInteractor
import javax.inject.Inject
class AnalyticsManager @Inject constructor(
private val analyticsTrackingInteractor: AnalyticsTrackingInteractor,
getCurrentServerInteractor: GetCurrentServerInteractor,
getAccountsInteractor: GetAccountsInteractor,
private val analytics: List<Analytics>
) {
val serverUrl = getCurrentServerInteractor.get()
val accounts = getAccountsInteractor.get()
fun logLogin(
event: AuthenticationEvent,
loginSucceeded: Boolean
) {
if (analyticsTrackingInteractor.get()) {
analytics.forEach { it.logLogin(event, loginSucceeded) }
}
}
fun logSignUp(
event: AuthenticationEvent,
signUpSucceeded: Boolean
) {
if (analyticsTrackingInteractor.get()) {
analytics.forEach { it.logSignUp(event, signUpSucceeded) }
}
}
fun logScreenView(event: ScreenViewEvent) {
if (analyticsTrackingInteractor.get()) {
analytics.forEach { it.logScreenView(event) }
}
}
fun logMessageSent(event: SubscriptionTypeEvent) {
if (analyticsTrackingInteractor.get() && serverUrl != null) {
analytics.forEach { it.logMessageSent(event, serverUrl) }
}
}
fun logMediaUploaded(event: SubscriptionTypeEvent, mimeType: String) {
if (analyticsTrackingInteractor.get()) {
analytics.forEach { it.logMediaUploaded(event, mimeType) }
}
}
fun logReaction(event: SubscriptionTypeEvent) {
if (analyticsTrackingInteractor.get()) {
analytics.forEach { it.logReaction(event) }
}
}
fun logServerSwitch() {
if (analyticsTrackingInteractor.get() && serverUrl != null) {
analytics.forEach { it.logServerSwitch(serverUrl, accounts.size) }
}
}
}
package chat.rocket.android.util.helper.analytics.event package chat.rocket.android.analytics.event
sealed class AuthenticationEvent(val methodName: String) { sealed class AuthenticationEvent(val methodName: String) {
object AuthenticationWithUserAndPassword : AuthenticationEvent("User and password") object AuthenticationWithUserAndPassword : AuthenticationEvent("User and password")
object AuthenticationWithCas : AuthenticationEvent("CAS") object AuthenticationWithCas : AuthenticationEvent("CAS")
object AuthenticationWithSaml : AuthenticationEvent("SAML") object AuthenticationWithSaml : AuthenticationEvent("SAML")
object AuthenticationWithOauth : AuthenticationEvent("Oauth") object AuthenticationWithOauth : AuthenticationEvent("Oauth")
object AuthenticationWithDeeplink : AuthenticationEvent("Deep link") object AuthenticationWithDeeplink : AuthenticationEvent("Deep link")
} }
package chat.rocket.android.util.helper.analytics.event package chat.rocket.android.analytics.event
sealed class ScreenViewEvent(val screenName: String) { sealed class ScreenViewEvent(val screenName: String) {
...@@ -23,4 +23,4 @@ sealed class ScreenViewEvent(val screenName: String) { ...@@ -23,4 +23,4 @@ sealed class ScreenViewEvent(val screenName: String) {
object Settings : ScreenViewEvent("SettingsFragment") object Settings : ScreenViewEvent("SettingsFragment")
object SignUp : ScreenViewEvent("SignupFragment") object SignUp : ScreenViewEvent("SignupFragment")
object TwoFa : ScreenViewEvent("TwoFAFragment") object TwoFa : ScreenViewEvent("TwoFAFragment")
} }
\ No newline at end of file
package chat.rocket.android.util.helper.analytics.event package chat.rocket.android.analytics.event
sealed class SubscriptionTypeEvent(val subscriptionTypeName: String) { sealed class SubscriptionTypeEvent(val subscriptionTypeName: String) {
object DirectMessage : SubscriptionTypeEvent("Direct Message") object DirectMessage : SubscriptionTypeEvent("Direct Message")
object Channel : SubscriptionTypeEvent("Channel") object Channel : SubscriptionTypeEvent("Channel")
object Group : SubscriptionTypeEvent("Group") object Group : SubscriptionTypeEvent("Group")
} }
\ No newline at end of file
...@@ -8,9 +8,15 @@ import android.content.Context ...@@ -8,9 +8,15 @@ import android.content.Context
import android.content.SharedPreferences import android.content.SharedPreferences
import androidx.core.content.edit import androidx.core.content.edit
import androidx.lifecycle.ProcessLifecycleOwner import androidx.lifecycle.ProcessLifecycleOwner
import androidx.work.Worker
import chat.rocket.android.BuildConfig import chat.rocket.android.BuildConfig
import chat.rocket.android.dagger.DaggerAppComponent import chat.rocket.android.dagger.DaggerAppComponent
import chat.rocket.android.dagger.injector.HasWorkerInjector
import chat.rocket.android.dagger.qualifier.ForMessages import chat.rocket.android.dagger.qualifier.ForMessages
import chat.rocket.android.emoji.Emoji
import chat.rocket.android.emoji.EmojiRepository
import chat.rocket.android.emoji.Fitzpatrick
import chat.rocket.android.emoji.internal.EmojiCategory
import chat.rocket.android.helper.CrashlyticsTree import chat.rocket.android.helper.CrashlyticsTree
import chat.rocket.android.infrastructure.LocalRepository import chat.rocket.android.infrastructure.LocalRepository
import chat.rocket.android.server.domain.AccountsRepository import chat.rocket.android.server.domain.AccountsRepository
...@@ -18,22 +24,26 @@ import chat.rocket.android.server.domain.GetCurrentServerInteractor ...@@ -18,22 +24,26 @@ import chat.rocket.android.server.domain.GetCurrentServerInteractor
import chat.rocket.android.server.domain.GetSettingsInteractor import chat.rocket.android.server.domain.GetSettingsInteractor
import chat.rocket.android.server.domain.SITE_URL import chat.rocket.android.server.domain.SITE_URL
import chat.rocket.android.server.domain.TokenRepository import chat.rocket.android.server.domain.TokenRepository
import chat.rocket.android.server.infraestructure.RocketChatClientFactory
import chat.rocket.android.util.retryIO
import chat.rocket.android.util.setupFabric import chat.rocket.android.util.setupFabric
import chat.rocket.common.RocketChatException
import chat.rocket.core.internal.rest.getCustomEmojis
import com.facebook.drawee.backends.pipeline.DraweeConfig import com.facebook.drawee.backends.pipeline.DraweeConfig
import com.facebook.drawee.backends.pipeline.Fresco import com.facebook.drawee.backends.pipeline.Fresco
import com.facebook.imagepipeline.core.ImagePipelineConfig import com.facebook.imagepipeline.core.ImagePipelineConfig
import com.jakewharton.threetenabp.AndroidThreeTen import com.jakewharton.threetenabp.AndroidThreeTen
import dagger.android.AndroidInjector
import dagger.android.DispatchingAndroidInjector import dagger.android.DispatchingAndroidInjector
import dagger.android.HasActivityInjector import dagger.android.HasActivityInjector
import dagger.android.HasBroadcastReceiverInjector import dagger.android.HasBroadcastReceiverInjector
import dagger.android.HasServiceInjector import dagger.android.HasServiceInjector
import kotlinx.coroutines.experimental.launch
import timber.log.Timber import timber.log.Timber
import java.lang.ref.WeakReference import java.lang.ref.WeakReference
import javax.inject.Inject import javax.inject.Inject
class RocketChatApplication : Application(), HasActivityInjector, HasServiceInjector, class RocketChatApplication : Application(), HasActivityInjector, HasServiceInjector,
HasBroadcastReceiverInjector { HasBroadcastReceiverInjector, HasWorkerInjector {
@Inject @Inject
lateinit var appLifecycleObserver: AppLifecycleObserver lateinit var appLifecycleObserver: AppLifecycleObserver
...@@ -47,6 +57,9 @@ class RocketChatApplication : Application(), HasActivityInjector, HasServiceInje ...@@ -47,6 +57,9 @@ class RocketChatApplication : Application(), HasActivityInjector, HasServiceInje
@Inject @Inject
lateinit var broadcastReceiverInjector: DispatchingAndroidInjector<BroadcastReceiver> lateinit var broadcastReceiverInjector: DispatchingAndroidInjector<BroadcastReceiver>
@Inject
lateinit var workerInjector: DispatchingAndroidInjector<Worker>
@Inject @Inject
lateinit var imagePipelineConfig: ImagePipelineConfig lateinit var imagePipelineConfig: ImagePipelineConfig
@Inject @Inject
...@@ -63,6 +76,8 @@ class RocketChatApplication : Application(), HasActivityInjector, HasServiceInje ...@@ -63,6 +76,8 @@ class RocketChatApplication : Application(), HasActivityInjector, HasServiceInje
lateinit var localRepository: LocalRepository lateinit var localRepository: LocalRepository
@Inject @Inject
lateinit var accountRepository: AccountsRepository lateinit var accountRepository: AccountsRepository
@Inject
lateinit var factory: RocketChatClientFactory
@Inject @Inject
@field:ForMessages @field:ForMessages
...@@ -98,6 +113,9 @@ class RocketChatApplication : Application(), HasActivityInjector, HasServiceInje ...@@ -98,6 +113,9 @@ class RocketChatApplication : Application(), HasActivityInjector, HasServiceInje
// TODO - remove REALM files. // TODO - remove REALM files.
// TODO - remove this // TODO - remove this
checkCurrentServer() checkCurrentServer()
// TODO - FIXME - we need to proper inject the EmojiRepository and initialize it properly
loadEmojis()
} }
private fun checkCurrentServer() { private fun checkCurrentServer() {
...@@ -132,17 +150,13 @@ class RocketChatApplication : Application(), HasActivityInjector, HasServiceInje ...@@ -132,17 +150,13 @@ class RocketChatApplication : Application(), HasActivityInjector, HasServiceInje
} }
} }
override fun activityInjector(): AndroidInjector<Activity> { override fun activityInjector() = activityDispatchingAndroidInjector
return activityDispatchingAndroidInjector
}
override fun serviceInjector(): AndroidInjector<Service> { override fun serviceInjector() = serviceDispatchingAndroidInjector
return serviceDispatchingAndroidInjector
}
override fun broadcastReceiverInjector(): AndroidInjector<BroadcastReceiver> { override fun broadcastReceiverInjector() = broadcastReceiverInjector
return broadcastReceiverInjector
} override fun workerInjector() = workerInjector
companion object { companion object {
var context: WeakReference<Context>? = null var context: WeakReference<Context>? = null
...@@ -150,6 +164,44 @@ class RocketChatApplication : Application(), HasActivityInjector, HasServiceInje ...@@ -150,6 +164,44 @@ class RocketChatApplication : Application(), HasActivityInjector, HasServiceInje
return context?.get() return context?.get()
} }
} }
// TODO - FIXME - This is a big Workaround
/**
* Load all emojis for the current server. Simple emojis are always the same for every server,
* but custom emojis vary according to the its url.
*/
fun loadEmojis() {
EmojiRepository.init(this)
val currentServer = getCurrentServerInteractor.get()
currentServer?.let { server ->
launch {
val client = factory.create(server)
EmojiRepository.setCurrentServerUrl(server)
val customEmojiList = mutableListOf<Emoji>()
try {
for (customEmoji in retryIO("getCustomEmojis()") { client.getCustomEmojis() }) {
customEmojiList.add(Emoji(
shortname = ":${customEmoji.name}:",
category = EmojiCategory.CUSTOM.name,
url = "$currentServer/emoji-custom/${customEmoji.name}.${customEmoji.extension}",
count = 0,
fitzpatrick = Fitzpatrick.Default.type,
keywords = customEmoji.aliases,
shortnameAlternates = customEmoji.aliases,
siblings = mutableListOf(),
unicode = "",
isDefault = true
))
}
EmojiRepository.load(this@RocketChatApplication, customEmojis = customEmojiList)
} catch (ex: RocketChatException) {
Timber.e(ex)
EmojiRepository.load(this@RocketChatApplication as Context)
}
}
}
}
} }
private fun LocalRepository.needOldMessagesCleanUp() = getBoolean(CLEANUP_OLD_MESSAGES_NEEDED, true) private fun LocalRepository.needOldMessagesCleanUp() = getBoolean(CLEANUP_OLD_MESSAGES_NEEDED, true)
......
package chat.rocket.android.authentication.login.presentation package chat.rocket.android.authentication.login.presentation
import chat.rocket.android.analytics.AnalyticsManager
import chat.rocket.android.analytics.event.AuthenticationEvent
import chat.rocket.android.authentication.domain.model.LoginDeepLinkInfo import chat.rocket.android.authentication.domain.model.LoginDeepLinkInfo
import chat.rocket.android.authentication.presentation.AuthenticationNavigator import chat.rocket.android.authentication.presentation.AuthenticationNavigator
import chat.rocket.android.core.lifecycle.CancelStrategy import chat.rocket.android.core.lifecycle.CancelStrategy
import chat.rocket.android.helper.OauthHelper import chat.rocket.android.helper.OauthHelper
import chat.rocket.android.infrastructure.LocalRepository import chat.rocket.android.infrastructure.LocalRepository
import chat.rocket.android.server.domain.* import chat.rocket.android.server.domain.GetConnectingServerInteractor
import chat.rocket.android.server.domain.GetSettingsInteractor
import chat.rocket.android.server.domain.PublicSettings
import chat.rocket.android.server.domain.SaveAccountInteractor
import chat.rocket.android.server.domain.SaveCurrentServerInteractor
import chat.rocket.android.server.domain.TokenRepository
import chat.rocket.android.server.domain.casLoginUrl
import chat.rocket.android.server.domain.favicon
import chat.rocket.android.server.domain.gitlabUrl
import chat.rocket.android.server.domain.isCasAuthenticationEnabled
import chat.rocket.android.server.domain.isFacebookAuthenticationEnabled
import chat.rocket.android.server.domain.isGithubAuthenticationEnabled
import chat.rocket.android.server.domain.isGitlabAuthenticationEnabled
import chat.rocket.android.server.domain.isGoogleAuthenticationEnabled
import chat.rocket.android.server.domain.isLdapAuthenticationEnabled
import chat.rocket.android.server.domain.isLinkedinAuthenticationEnabled
import chat.rocket.android.server.domain.isLoginFormEnabled
import chat.rocket.android.server.domain.isPasswordResetEnabled
import chat.rocket.android.server.domain.isRegistrationEnabledForNewUsers
import chat.rocket.android.server.domain.isWordpressAuthenticationEnabled
import chat.rocket.android.server.domain.model.Account import chat.rocket.android.server.domain.model.Account
import chat.rocket.android.server.domain.wideTile
import chat.rocket.android.server.domain.wordpressUrl
import chat.rocket.android.server.infraestructure.RocketChatClientFactory import chat.rocket.android.server.infraestructure.RocketChatClientFactory
import chat.rocket.android.util.extension.launchUI import chat.rocket.android.util.extension.launchUI
import chat.rocket.android.util.extensions.avatarUrl import chat.rocket.android.util.extensions.avatarUrl
...@@ -15,11 +38,8 @@ import chat.rocket.android.util.extensions.encodeToBase64 ...@@ -15,11 +38,8 @@ import chat.rocket.android.util.extensions.encodeToBase64
import chat.rocket.android.util.extensions.generateRandomString import chat.rocket.android.util.extensions.generateRandomString
import chat.rocket.android.util.extensions.isEmail import chat.rocket.android.util.extensions.isEmail
import chat.rocket.android.util.extensions.parseColor import chat.rocket.android.util.extensions.parseColor
import chat.rocket.android.util.extensions.registerPushToken
import chat.rocket.android.util.extensions.samlUrl import chat.rocket.android.util.extensions.samlUrl
import chat.rocket.android.util.extensions.serverLogoUrl import chat.rocket.android.util.extensions.serverLogoUrl
import chat.rocket.android.util.helper.analytics.AnalyticsManager
import chat.rocket.android.util.helper.analytics.event.AuthenticationEvent
import chat.rocket.android.util.retryIO import chat.rocket.android.util.retryIO
import chat.rocket.common.RocketChatAuthException import chat.rocket.common.RocketChatAuthException
import chat.rocket.common.RocketChatException import chat.rocket.common.RocketChatException
...@@ -60,9 +80,8 @@ class LoginPresenter @Inject constructor( ...@@ -60,9 +80,8 @@ class LoginPresenter @Inject constructor(
private val navigator: AuthenticationNavigator, private val navigator: AuthenticationNavigator,
private val tokenRepository: TokenRepository, private val tokenRepository: TokenRepository,
private val localRepository: LocalRepository, private val localRepository: LocalRepository,
private val getAccountsInteractor: GetAccountsInteractor,
private val settingsInteractor: GetSettingsInteractor, private val settingsInteractor: GetSettingsInteractor,
private val analyticsTrackingInteractor: AnalyticsTrackingInteractor, private val analyticsManager: AnalyticsManager,
serverInteractor: GetConnectingServerInteractor, serverInteractor: GetConnectingServerInteractor,
private val saveCurrentServer: SaveCurrentServerInteractor, private val saveCurrentServer: SaveCurrentServerInteractor,
private val saveAccountInteractor: SaveAccountInteractor, private val saveAccountInteractor: SaveAccountInteractor,
...@@ -312,12 +331,10 @@ class LoginPresenter @Inject constructor( ...@@ -312,12 +331,10 @@ class LoginPresenter @Inject constructor(
) )
localRepository.saveCurrentUser(currentServer, user) localRepository.saveCurrentUser(currentServer, user)
saveCurrentServer.save(currentServer) saveCurrentServer.save(currentServer)
localRepository.save(LocalRepository.CURRENT_USERNAME_KEY, myself.username)
saveAccount(myself.username!!) saveAccount(myself.username!!)
saveToken(token) saveToken(token)
registerPushToken() analyticsManager.logLogin(loginMethod, true)
if (analyticsTrackingInteractor.get()) {
AnalyticsManager.logLogin(loginMethod, true)
}
if (loginType == TYPE_LOGIN_USER_EMAIL) { if (loginType == TYPE_LOGIN_USER_EMAIL) {
view.saveSmartLockCredentials(usernameOrEmail, password) view.saveSmartLockCredentials(usernameOrEmail, password)
} }
...@@ -331,9 +348,7 @@ class LoginPresenter @Inject constructor( ...@@ -331,9 +348,7 @@ class LoginPresenter @Inject constructor(
navigator.toTwoFA(usernameOrEmail, password) navigator.toTwoFA(usernameOrEmail, password)
} }
else -> { else -> {
if (analyticsTrackingInteractor.get()) { analyticsManager.logLogin(loginMethod, false)
AnalyticsManager.logLogin(loginMethod, false)
}
exception.message?.let { exception.message?.let {
view.showMessage(it) view.showMessage(it)
}.ifNull { }.ifNull {
...@@ -472,12 +487,4 @@ class LoginPresenter @Inject constructor( ...@@ -472,12 +487,4 @@ class LoginPresenter @Inject constructor(
private fun saveToken(token: Token) { private fun saveToken(token: Token) {
tokenRepository.save(currentServer, token) tokenRepository.save(currentServer, token)
} }
private suspend fun registerPushToken() {
localRepository.get(LocalRepository.KEY_PUSH_TOKEN)?.let {
client.registerPushToken(it, getAccountsInteractor.get(), factory)
}
// TODO: When the push token is null, at some point we should receive it with
// onTokenRefresh() on FirebaseTokenService, we need to confirm it.
}
} }
\ No newline at end of file
...@@ -6,7 +6,6 @@ import android.content.Intent ...@@ -6,7 +6,6 @@ import android.content.Intent
import android.graphics.PorterDuff import android.graphics.PorterDuff
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import androidx.fragment.app.Fragment
import android.text.style.ClickableSpan import android.text.style.ClickableSpan
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
...@@ -18,20 +17,30 @@ import android.widget.LinearLayout ...@@ -18,20 +17,30 @@ import android.widget.LinearLayout
import android.widget.ScrollView import android.widget.ScrollView
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.core.view.postDelayed import androidx.core.view.postDelayed
import androidx.fragment.app.Fragment
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.analytics.AnalyticsManager
import chat.rocket.android.analytics.event.ScreenViewEvent
import chat.rocket.android.authentication.domain.model.LoginDeepLinkInfo import chat.rocket.android.authentication.domain.model.LoginDeepLinkInfo
import chat.rocket.android.authentication.login.presentation.LoginPresenter import chat.rocket.android.authentication.login.presentation.LoginPresenter
import chat.rocket.android.authentication.login.presentation.LoginView import chat.rocket.android.authentication.login.presentation.LoginView
import chat.rocket.android.helper.* import chat.rocket.android.helper.KeyboardHelper
import chat.rocket.android.server.domain.AnalyticsTrackingInteractor import chat.rocket.android.helper.TextHelper
import chat.rocket.android.util.extensions.* import chat.rocket.android.helper.getCredentials
import chat.rocket.android.util.helper.analytics.AnalyticsManager import chat.rocket.android.helper.hasCredentialsSupport
import chat.rocket.android.util.helper.analytics.event.ScreenViewEvent import chat.rocket.android.helper.requestStoredCredentials
import chat.rocket.android.webview.sso.ui.INTENT_SSO_TOKEN import chat.rocket.android.helper.saveCredentials
import chat.rocket.android.webview.sso.ui.ssoWebViewIntent import chat.rocket.android.util.extensions.inflate
import chat.rocket.android.util.extensions.shake
import chat.rocket.android.util.extensions.showToast
import chat.rocket.android.util.extensions.textContent
import chat.rocket.android.util.extensions.ui
import chat.rocket.android.util.extensions.vibrateSmartPhone
import chat.rocket.android.webview.oauth.ui.INTENT_OAUTH_CREDENTIAL_SECRET import chat.rocket.android.webview.oauth.ui.INTENT_OAUTH_CREDENTIAL_SECRET
import chat.rocket.android.webview.oauth.ui.INTENT_OAUTH_CREDENTIAL_TOKEN import chat.rocket.android.webview.oauth.ui.INTENT_OAUTH_CREDENTIAL_TOKEN
import chat.rocket.android.webview.oauth.ui.oauthWebViewIntent import chat.rocket.android.webview.oauth.ui.oauthWebViewIntent
import chat.rocket.android.webview.sso.ui.INTENT_SSO_TOKEN
import chat.rocket.android.webview.sso.ui.ssoWebViewIntent
import chat.rocket.common.util.ifNull import chat.rocket.common.util.ifNull
import dagger.android.support.AndroidSupportInjection import dagger.android.support.AndroidSupportInjection
import kotlinx.android.synthetic.main.fragment_authentication_log_in.* import kotlinx.android.synthetic.main.fragment_authentication_log_in.*
...@@ -49,7 +58,7 @@ class LoginFragment : Fragment(), LoginView { ...@@ -49,7 +58,7 @@ class LoginFragment : Fragment(), LoginView {
@Inject @Inject
lateinit var presenter: LoginPresenter lateinit var presenter: LoginPresenter
@Inject @Inject
lateinit var analyticsTrackingInteractor: AnalyticsTrackingInteractor lateinit var analyticsManager: AnalyticsManager
private var isOauthViewEnable = false private var isOauthViewEnable = false
private var deepLinkInfo: LoginDeepLinkInfo? = null private var deepLinkInfo: LoginDeepLinkInfo? = null
...@@ -93,9 +102,7 @@ class LoginFragment : Fragment(), LoginView { ...@@ -93,9 +102,7 @@ class LoginFragment : Fragment(), LoginView {
image_key.isVisible = false image_key.isVisible = false
} }
if (analyticsTrackingInteractor.get()) { analyticsManager.logScreenView(ScreenViewEvent.Login)
AnalyticsManager.logScreenView(ScreenViewEvent.Login)
}
} }
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
......
package chat.rocket.android.authentication.loginoptions.presentation package chat.rocket.android.authentication.loginoptions.presentation
import chat.rocket.android.analytics.AnalyticsManager
import chat.rocket.android.analytics.event.AuthenticationEvent
import chat.rocket.android.authentication.login.presentation.* import chat.rocket.android.authentication.login.presentation.*
import chat.rocket.android.authentication.presentation.AuthenticationNavigator import chat.rocket.android.authentication.presentation.AuthenticationNavigator
import chat.rocket.android.core.lifecycle.CancelStrategy import chat.rocket.android.core.lifecycle.CancelStrategy
...@@ -33,17 +35,17 @@ private const val SERVICE_NAME_LINKEDIN = "linkedin" ...@@ -33,17 +35,17 @@ private const val SERVICE_NAME_LINKEDIN = "linkedin"
private const val SERVICE_NAME_GILAB = "gitlab" private const val SERVICE_NAME_GILAB = "gitlab"
class LoginOptionsPresenter @Inject constructor( class LoginOptionsPresenter @Inject constructor(
private val view: LoginOptionsView, private val view: LoginOptionsView,
private val strategy: CancelStrategy, private val strategy: CancelStrategy,
private val factory: RocketChatClientFactory, private val factory: RocketChatClientFactory,
private val navigator: AuthenticationNavigator, private val navigator: AuthenticationNavigator,
private val settingsInteractor: GetSettingsInteractor, private val settingsInteractor: GetSettingsInteractor,
private val localRepository: LocalRepository, private val localRepository: LocalRepository,
private val saveCurrentServer: SaveCurrentServerInteractor, private val saveCurrentServer: SaveCurrentServerInteractor,
private val saveAccountInteractor: SaveAccountInteractor, private val saveAccountInteractor: SaveAccountInteractor,
private val getAccountsInteractor: GetAccountsInteractor, private val analyticsManager: AnalyticsManager,
private val tokenRepository: TokenRepository, private val tokenRepository: TokenRepository,
serverInteractor: GetConnectingServerInteractor serverInteractor: GetConnectingServerInteractor
) { ) {
// TODO - we should validate the current server when opening the app, and have a nonnull get() // TODO - we should validate the current server when opening the app, and have a nonnull get()
private var currentServer = serverInteractor.get()!! private var currentServer = serverInteractor.get()!!
...@@ -245,7 +247,11 @@ class LoginOptionsPresenter @Inject constructor( ...@@ -245,7 +247,11 @@ class LoginOptionsPresenter @Inject constructor(
saveCurrentServer.save(currentServer) saveCurrentServer.save(currentServer)
saveAccount(myself.username!!) saveAccount(myself.username!!)
saveToken(token) saveToken(token)
registerPushToken() // TODO
// analyticsManager.logSignUp(
// AuthenticationEvent.AuthenticationWithOauth,
// true
// )
navigator.toChatList() navigator.toChatList()
} else if (loginType == TYPE_LOGIN_OAUTH) { } else if (loginType == TYPE_LOGIN_OAUTH) {
navigator.toRegisterUsername(token.userId, token.authToken) navigator.toRegisterUsername(token.userId, token.authToken)
...@@ -284,14 +290,6 @@ class LoginOptionsPresenter @Inject constructor( ...@@ -284,14 +290,6 @@ class LoginOptionsPresenter @Inject constructor(
tokenRepository.save(currentServer, token) tokenRepository.save(currentServer, token)
} }
private suspend fun registerPushToken() {
localRepository.get(LocalRepository.KEY_PUSH_TOKEN)?.let {
client.registerPushToken(it, getAccountsInteractor.get(), factory)
}
// TODO: When the push token is null, at some point we should receive it with
// onTokenRefresh() on FirebaseTokenService, we need to confirm it.
}
fun toCreateAccount() { fun toCreateAccount() {
navigator.toCreateAccount() navigator.toCreateAccount()
} }
......
package chat.rocket.android.authentication.registerusername.presentation package chat.rocket.android.authentication.registerusername.presentation
import chat.rocket.android.analytics.AnalyticsManager
import chat.rocket.android.analytics.event.AuthenticationEvent
import chat.rocket.android.authentication.presentation.AuthenticationNavigator import chat.rocket.android.authentication.presentation.AuthenticationNavigator
import chat.rocket.android.core.lifecycle.CancelStrategy import chat.rocket.android.core.lifecycle.CancelStrategy
import chat.rocket.android.infrastructure.LocalRepository
import chat.rocket.android.server.domain.AnalyticsTrackingInteractor
import chat.rocket.android.server.domain.GetAccountsInteractor
import chat.rocket.android.server.domain.GetConnectingServerInteractor import chat.rocket.android.server.domain.GetConnectingServerInteractor
import chat.rocket.android.server.domain.GetSettingsInteractor import chat.rocket.android.server.domain.GetSettingsInteractor
import chat.rocket.android.server.domain.PublicSettings import chat.rocket.android.server.domain.PublicSettings
...@@ -17,10 +16,7 @@ import chat.rocket.android.server.domain.wideTile ...@@ -17,10 +16,7 @@ import chat.rocket.android.server.domain.wideTile
import chat.rocket.android.server.infraestructure.RocketChatClientFactory import chat.rocket.android.server.infraestructure.RocketChatClientFactory
import chat.rocket.android.util.extension.launchUI import chat.rocket.android.util.extension.launchUI
import chat.rocket.android.util.extensions.avatarUrl import chat.rocket.android.util.extensions.avatarUrl
import chat.rocket.android.util.extensions.registerPushToken
import chat.rocket.android.util.extensions.serverLogoUrl import chat.rocket.android.util.extensions.serverLogoUrl
import chat.rocket.android.util.helper.analytics.AnalyticsManager
import chat.rocket.android.util.helper.analytics.event.AuthenticationEvent
import chat.rocket.android.util.retryIO import chat.rocket.android.util.retryIO
import chat.rocket.common.RocketChatException import chat.rocket.common.RocketChatException
import chat.rocket.common.model.Token import chat.rocket.common.model.Token
...@@ -34,11 +30,9 @@ class RegisterUsernamePresenter @Inject constructor( ...@@ -34,11 +30,9 @@ class RegisterUsernamePresenter @Inject constructor(
private val strategy: CancelStrategy, private val strategy: CancelStrategy,
private val navigator: AuthenticationNavigator, private val navigator: AuthenticationNavigator,
private val tokenRepository: TokenRepository, private val tokenRepository: TokenRepository,
private val localRepository: LocalRepository, factory: RocketChatClientFactory,
private val factory: RocketChatClientFactory,
private val saveAccountInteractor: SaveAccountInteractor, private val saveAccountInteractor: SaveAccountInteractor,
private val getAccountsInteractor: GetAccountsInteractor, private val analyticsManager: AnalyticsManager,
private val analyticsTrackingInteractor: AnalyticsTrackingInteractor,
serverInteractor: GetConnectingServerInteractor, serverInteractor: GetConnectingServerInteractor,
private val saveCurrentServer: SaveCurrentServerInteractor, private val saveCurrentServer: SaveCurrentServerInteractor,
settingsInteractor: GetSettingsInteractor settingsInteractor: GetSettingsInteractor
...@@ -62,16 +56,14 @@ class RegisterUsernamePresenter @Inject constructor( ...@@ -62,16 +56,14 @@ class RegisterUsernamePresenter @Inject constructor(
saveAccount(registeredUsername) saveAccount(registeredUsername)
saveCurrentServer.save(currentServer) saveCurrentServer.save(currentServer)
tokenRepository.save(currentServer, Token(userId, authToken)) tokenRepository.save(currentServer, Token(userId, authToken))
registerPushToken() analyticsManager.logSignUp(
if (analyticsTrackingInteractor.get()) { AuthenticationEvent.AuthenticationWithOauth,
AnalyticsManager.logSignUp(AuthenticationEvent.AuthenticationWithOauth, true) true
} )
navigator.toChatList() navigator.toChatList()
} }
} catch (exception: RocketChatException) { } catch (exception: RocketChatException) {
if (analyticsTrackingInteractor.get()) { analyticsManager.logSignUp(AuthenticationEvent.AuthenticationWithOauth, false)
AnalyticsManager.logSignUp(AuthenticationEvent.AuthenticationWithOauth, false)
}
exception.message?.let { exception.message?.let {
view.showMessage(it) view.showMessage(it)
}.ifNull { }.ifNull {
...@@ -84,14 +76,6 @@ class RegisterUsernamePresenter @Inject constructor( ...@@ -84,14 +76,6 @@ class RegisterUsernamePresenter @Inject constructor(
} }
} }
private suspend fun registerPushToken() {
localRepository.get(LocalRepository.KEY_PUSH_TOKEN)?.let {
client.registerPushToken(it, getAccountsInteractor.get(), factory)
}
// TODO: When the push token is null, at some point we should receive it with
// onTokenRefresh() on FirebaseTokenService, we need to confirm it.
}
private suspend fun saveAccount(username: String) { private suspend fun saveAccount(username: String) {
val icon = settings.favicon()?.let { val icon = settings.favicon()?.let {
currentServer.serverLogoUrl(it) currentServer.serverLogoUrl(it)
......
...@@ -3,17 +3,23 @@ package chat.rocket.android.authentication.registerusername.ui ...@@ -3,17 +3,23 @@ package chat.rocket.android.authentication.registerusername.ui
import DrawableHelper import DrawableHelper
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.Fragment
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.analytics.AnalyticsManager
import chat.rocket.android.analytics.event.ScreenViewEvent
import chat.rocket.android.authentication.registerusername.presentation.RegisterUsernamePresenter import chat.rocket.android.authentication.registerusername.presentation.RegisterUsernamePresenter
import chat.rocket.android.authentication.registerusername.presentation.RegisterUsernameView import chat.rocket.android.authentication.registerusername.presentation.RegisterUsernameView
import chat.rocket.android.server.domain.AnalyticsTrackingInteractor import chat.rocket.android.util.extensions.inflate
import chat.rocket.android.util.extensions.* import chat.rocket.android.util.extensions.setVisible
import chat.rocket.android.util.helper.analytics.AnalyticsManager import chat.rocket.android.util.extensions.shake
import chat.rocket.android.util.helper.analytics.event.ScreenViewEvent import chat.rocket.android.util.extensions.showKeyboard
import chat.rocket.android.util.extensions.showToast
import chat.rocket.android.util.extensions.textContent
import chat.rocket.android.util.extensions.ui
import chat.rocket.android.util.extensions.vibrateSmartPhone
import dagger.android.support.AndroidSupportInjection import dagger.android.support.AndroidSupportInjection
import kotlinx.android.synthetic.main.fragment_authentication_register_username.* import kotlinx.android.synthetic.main.fragment_authentication_register_username.*
import javax.inject.Inject import javax.inject.Inject
...@@ -24,7 +30,7 @@ class RegisterUsernameFragment : Fragment(), RegisterUsernameView { ...@@ -24,7 +30,7 @@ class RegisterUsernameFragment : Fragment(), RegisterUsernameView {
@Inject @Inject
lateinit var presenter: RegisterUsernamePresenter lateinit var presenter: RegisterUsernamePresenter
@Inject @Inject
lateinit var analyticsTrackingInteractor: AnalyticsTrackingInteractor lateinit var analyticsManager: AnalyticsManager
private lateinit var userId: String private lateinit var userId: String
private lateinit var authToken: String private lateinit var authToken: String
...@@ -69,9 +75,7 @@ class RegisterUsernameFragment : Fragment(), RegisterUsernameView { ...@@ -69,9 +75,7 @@ class RegisterUsernameFragment : Fragment(), RegisterUsernameView {
setupOnClickListener() setupOnClickListener()
if (analyticsTrackingInteractor.get()) { analyticsManager.logScreenView(ScreenViewEvent.RegisterUsername)
AnalyticsManager.logScreenView(ScreenViewEvent.RegisterUsername)
}
} }
override fun alertBlankUsername() { override fun alertBlankUsername() {
......
...@@ -3,18 +3,24 @@ package chat.rocket.android.authentication.resetpassword.ui ...@@ -3,18 +3,24 @@ package chat.rocket.android.authentication.resetpassword.ui
import DrawableHelper import DrawableHelper
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.Toast import android.widget.Toast
import androidx.fragment.app.Fragment
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.analytics.AnalyticsManager
import chat.rocket.android.analytics.event.ScreenViewEvent
import chat.rocket.android.authentication.resetpassword.presentation.ResetPasswordPresenter import chat.rocket.android.authentication.resetpassword.presentation.ResetPasswordPresenter
import chat.rocket.android.authentication.resetpassword.presentation.ResetPasswordView import chat.rocket.android.authentication.resetpassword.presentation.ResetPasswordView
import chat.rocket.android.server.domain.AnalyticsTrackingInteractor import chat.rocket.android.util.extensions.inflate
import chat.rocket.android.util.extensions.* import chat.rocket.android.util.extensions.setVisible
import chat.rocket.android.util.helper.analytics.AnalyticsManager import chat.rocket.android.util.extensions.shake
import chat.rocket.android.util.helper.analytics.event.ScreenViewEvent import chat.rocket.android.util.extensions.showKeyboard
import chat.rocket.android.util.extensions.showToast
import chat.rocket.android.util.extensions.textContent
import chat.rocket.android.util.extensions.ui
import chat.rocket.android.util.extensions.vibrateSmartPhone
import dagger.android.support.AndroidSupportInjection import dagger.android.support.AndroidSupportInjection
import kotlinx.android.synthetic.main.fragment_authentication_reset_password.* import kotlinx.android.synthetic.main.fragment_authentication_reset_password.*
import javax.inject.Inject import javax.inject.Inject
...@@ -25,7 +31,7 @@ class ResetPasswordFragment : Fragment(), ResetPasswordView { ...@@ -25,7 +31,7 @@ class ResetPasswordFragment : Fragment(), ResetPasswordView {
@Inject @Inject
lateinit var presenter: ResetPasswordPresenter lateinit var presenter: ResetPasswordPresenter
@Inject @Inject
lateinit var analyticsTrackingInteractor: AnalyticsTrackingInteractor lateinit var analyticsManager: AnalyticsManager
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
...@@ -52,9 +58,7 @@ class ResetPasswordFragment : Fragment(), ResetPasswordView { ...@@ -52,9 +58,7 @@ class ResetPasswordFragment : Fragment(), ResetPasswordView {
setupOnClickListener() setupOnClickListener()
if (analyticsTrackingInteractor.get()) { analyticsManager.logScreenView(ScreenViewEvent.ResetPassword)
AnalyticsManager.logScreenView(ScreenViewEvent.ResetPassword)
}
} }
override fun alertBlankEmail() { override fun alertBlankEmail() {
......
...@@ -3,7 +3,6 @@ package chat.rocket.android.authentication.server.ui ...@@ -3,7 +3,6 @@ package chat.rocket.android.authentication.server.ui
import android.app.AlertDialog import android.app.AlertDialog
import android.net.Uri import android.net.Uri
import android.os.Bundle import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
...@@ -11,17 +10,25 @@ import android.view.ViewTreeObserver ...@@ -11,17 +10,25 @@ import android.view.ViewTreeObserver
import android.widget.AdapterView import android.widget.AdapterView
import android.widget.ArrayAdapter import android.widget.ArrayAdapter
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import chat.rocket.android.BuildConfig import chat.rocket.android.BuildConfig
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.analytics.AnalyticsManager
import chat.rocket.android.analytics.event.ScreenViewEvent
import chat.rocket.android.authentication.domain.model.LoginDeepLinkInfo import chat.rocket.android.authentication.domain.model.LoginDeepLinkInfo
import chat.rocket.android.authentication.server.presentation.ServerPresenter import chat.rocket.android.authentication.server.presentation.ServerPresenter
import chat.rocket.android.authentication.server.presentation.ServerView import chat.rocket.android.authentication.server.presentation.ServerView
import chat.rocket.android.authentication.ui.AuthenticationActivity import chat.rocket.android.authentication.ui.AuthenticationActivity
import chat.rocket.android.helper.KeyboardHelper import chat.rocket.android.helper.KeyboardHelper
import chat.rocket.android.server.domain.AnalyticsTrackingInteractor import chat.rocket.android.util.extensions.hintContent
import chat.rocket.android.util.extensions.* import chat.rocket.android.util.extensions.ifEmpty
import chat.rocket.android.util.helper.analytics.AnalyticsManager import chat.rocket.android.util.extensions.inflate
import chat.rocket.android.util.helper.analytics.event.ScreenViewEvent import chat.rocket.android.util.extensions.sanitize
import chat.rocket.android.util.extensions.setLightStatusBar
import chat.rocket.android.util.extensions.setVisible
import chat.rocket.android.util.extensions.showToast
import chat.rocket.android.util.extensions.textContent
import chat.rocket.android.util.extensions.ui
import chat.rocket.common.util.ifNull import chat.rocket.common.util.ifNull
import dagger.android.support.AndroidSupportInjection import dagger.android.support.AndroidSupportInjection
import kotlinx.android.synthetic.main.app_bar_chat_room.* import kotlinx.android.synthetic.main.app_bar_chat_room.*
...@@ -35,10 +42,11 @@ class ServerFragment : Fragment(), ServerView { ...@@ -35,10 +42,11 @@ class ServerFragment : Fragment(), ServerView {
@Inject @Inject
lateinit var presenter: ServerPresenter lateinit var presenter: ServerPresenter
@Inject @Inject
lateinit var analyticsTrackingInteractor: AnalyticsTrackingInteractor lateinit var analyticsManager: AnalyticsManager
private var deepLinkInfo: LoginDeepLinkInfo? = null private var deepLinkInfo: LoginDeepLinkInfo? = null
private val layoutListener = ViewTreeObserver.OnGlobalLayoutListener { private val layoutListener = ViewTreeObserver.OnGlobalLayoutListener {
text_server_url.isCursorVisible = KeyboardHelper.isSoftKeyboardShown(constraint_layout.rootView) text_server_url.isCursorVisible =
KeyboardHelper.isSoftKeyboardShown(constraint_layout.rootView)
} }
private var protocol = "https://" private var protocol = "https://"
private var ignoreChange = false private var ignoreChange = false
...@@ -50,7 +58,11 @@ class ServerFragment : Fragment(), ServerView { ...@@ -50,7 +58,11 @@ class ServerFragment : Fragment(), ServerView {
deepLinkInfo = arguments?.getParcelable(DEEP_LINK_INFO) deepLinkInfo = arguments?.getParcelable(DEEP_LINK_INFO)
} }
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? = override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? =
container?.inflate(R.layout.fragment_authentication_server) container?.inflate(R.layout.fragment_authentication_server)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
...@@ -65,45 +77,51 @@ class ServerFragment : Fragment(), ServerView { ...@@ -65,45 +77,51 @@ class ServerFragment : Fragment(), ServerView {
presenter.deepLink(it) presenter.deepLink(it)
} }
spinner_server_protocol.adapter = ArrayAdapter<String>(activity, spinner_server_protocol.adapter = ArrayAdapter<String>(
android.R.layout.simple_dropdown_item_1line, arrayOf("https://", "http://")) activity,
spinner_server_protocol.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { android.R.layout.simple_dropdown_item_1line, arrayOf("https://", "http://")
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { )
when(position) { spinner_server_protocol.onItemSelectedListener =
0 -> { object : AdapterView.OnItemSelectedListener {
protocol = "https://" override fun onItemSelected(
} parent: AdapterView<*>?,
1 -> { view: View?,
if (ignoreChange) { position: Int,
protocol = "http://" id: Long
} else { ) {
ui { when (position) {
AlertDialog.Builder(it) 0 -> {
.setTitle(R.string.msg_warning) protocol = "https://"
.setMessage(R.string.msg_http_insecure) }
.setPositiveButton(R.string.msg_proceed) { _, _ -> 1 -> {
protocol = "http://" if (ignoreChange) {
} protocol = "http://"
.setNegativeButton(R.string.msg_cancel) { _, _ -> } else {
spinner_server_protocol.setSelection(0) ui {
} AlertDialog.Builder(it)
.setCancelable(false) .setTitle(R.string.msg_warning)
.create() .setMessage(R.string.msg_http_insecure)
.show() .setPositiveButton(R.string.msg_proceed) { _, _ ->
protocol = "http://"
}
.setNegativeButton(R.string.msg_cancel) { _, _ ->
spinner_server_protocol.setSelection(0)
}
.setCancelable(false)
.create()
.show()
}
}
} }
} }
ignoreChange = false
} }
}
ignoreChange = false
}
override fun onNothingSelected(parent: AdapterView<*>?) { override fun onNothingSelected(parent: AdapterView<*>?) {
} }
} }
if (analyticsTrackingInteractor.get()) { analyticsManager.logScreenView(ScreenViewEvent.Server)
AnalyticsManager.logScreenView(ScreenViewEvent.Server)
}
} }
private fun setupToobar() { private fun setupToobar() {
...@@ -121,7 +139,8 @@ class ServerFragment : Fragment(), ServerView { ...@@ -121,7 +139,8 @@ class ServerFragment : Fragment(), ServerView {
constraint_layout.viewTreeObserver.removeOnGlobalLayoutListener(layoutListener) constraint_layout.viewTreeObserver.removeOnGlobalLayoutListener(layoutListener)
} }
override fun showInvalidServerUrlMessage() = showMessage(getString(R.string.msg_invalid_server_url)) override fun showInvalidServerUrlMessage() =
showMessage(getString(R.string.msg_invalid_server_url))
override fun showLoading() { override fun showLoading() {
ui { ui {
...@@ -157,7 +176,12 @@ class ServerFragment : Fragment(), ServerView { ...@@ -157,7 +176,12 @@ class ServerFragment : Fragment(), ServerView {
ui { ui {
hideLoading() hideLoading()
AlertDialog.Builder(it) AlertDialog.Builder(it)
.setMessage(getString(R.string.msg_ver_not_recommended, BuildConfig.RECOMMENDED_SERVER_VERSION)) .setMessage(
getString(
R.string.msg_ver_not_recommended,
BuildConfig.RECOMMENDED_SERVER_VERSION
)
)
.setPositiveButton(R.string.msg_ok) { _, _ -> .setPositiveButton(R.string.msg_ok) { _, _ ->
performConnect() performConnect()
} }
...@@ -170,7 +194,12 @@ class ServerFragment : Fragment(), ServerView { ...@@ -170,7 +194,12 @@ class ServerFragment : Fragment(), ServerView {
ui { ui {
hideLoading() hideLoading()
AlertDialog.Builder(it) AlertDialog.Builder(it)
.setMessage(getString(R.string.msg_ver_not_minimum, BuildConfig.REQUIRED_SERVER_VERSION)) .setMessage(
getString(
R.string.msg_ver_not_minimum,
BuildConfig.REQUIRED_SERVER_VERSION
)
)
.setPositiveButton(R.string.msg_ok, null) .setPositiveButton(R.string.msg_ok, null)
.setOnDismissListener { .setOnDismissListener {
// reset the deeplink info, so the user can log to another server... // reset the deeplink info, so the user can log to another server...
...@@ -197,7 +226,9 @@ class ServerFragment : Fragment(), ServerView { ...@@ -197,7 +226,9 @@ class ServerFragment : Fragment(), ServerView {
override fun updateServerUrl(url: HttpUrl) { override fun updateServerUrl(url: HttpUrl) {
if (activity != null && view != null) { if (activity != null && view != null) {
if (url.scheme() == "https") spinner_server_protocol.setSelection(0) else spinner_server_protocol.setSelection(1) if (url.scheme() == "https") spinner_server_protocol.setSelection(0) else spinner_server_protocol.setSelection(
1
)
protocol = "${url.scheme()}://" protocol = "${url.scheme()}://"
val serverUrl = url.toString().removePrefix("${url.scheme()}://") val serverUrl = url.toString().removePrefix("${url.scheme()}://")
......
package chat.rocket.android.authentication.signup.presentation package chat.rocket.android.authentication.signup.presentation
import chat.rocket.android.analytics.AnalyticsManager
import chat.rocket.android.analytics.event.AuthenticationEvent
import chat.rocket.android.authentication.presentation.AuthenticationNavigator import chat.rocket.android.authentication.presentation.AuthenticationNavigator
import chat.rocket.android.core.lifecycle.CancelStrategy import chat.rocket.android.core.lifecycle.CancelStrategy
import chat.rocket.android.infrastructure.LocalRepository import chat.rocket.android.infrastructure.LocalRepository
import chat.rocket.android.server.domain.AnalyticsTrackingInteractor
import chat.rocket.android.server.domain.GetAccountsInteractor
import chat.rocket.android.server.domain.GetConnectingServerInteractor import chat.rocket.android.server.domain.GetConnectingServerInteractor
import chat.rocket.android.server.domain.GetSettingsInteractor import chat.rocket.android.server.domain.GetSettingsInteractor
import chat.rocket.android.server.domain.PublicSettings import chat.rocket.android.server.domain.PublicSettings
...@@ -17,15 +17,11 @@ import chat.rocket.android.server.infraestructure.RocketChatClientFactory ...@@ -17,15 +17,11 @@ import chat.rocket.android.server.infraestructure.RocketChatClientFactory
import chat.rocket.android.util.extension.launchUI import chat.rocket.android.util.extension.launchUI
import chat.rocket.android.util.extensions.avatarUrl import chat.rocket.android.util.extensions.avatarUrl
import chat.rocket.android.util.extensions.privacyPolicyUrl import chat.rocket.android.util.extensions.privacyPolicyUrl
import chat.rocket.android.util.extensions.registerPushToken
import chat.rocket.android.util.extensions.serverLogoUrl import chat.rocket.android.util.extensions.serverLogoUrl
import chat.rocket.android.util.extensions.termsOfServiceUrl import chat.rocket.android.util.extensions.termsOfServiceUrl
import chat.rocket.android.util.helper.analytics.AnalyticsManager
import chat.rocket.android.util.helper.analytics.event.AuthenticationEvent
import chat.rocket.android.util.retryIO import chat.rocket.android.util.retryIO
import chat.rocket.common.RocketChatException import chat.rocket.common.RocketChatException
import chat.rocket.common.util.ifNull import chat.rocket.common.util.ifNull
import chat.rocket.core.RocketChatClient
import chat.rocket.core.internal.rest.login import chat.rocket.core.internal.rest.login
import chat.rocket.core.internal.rest.me import chat.rocket.core.internal.rest.me
import chat.rocket.core.internal.rest.signup import chat.rocket.core.internal.rest.signup
...@@ -39,14 +35,12 @@ class SignupPresenter @Inject constructor( ...@@ -39,14 +35,12 @@ class SignupPresenter @Inject constructor(
private val localRepository: LocalRepository, private val localRepository: LocalRepository,
private val serverInteractor: GetConnectingServerInteractor, private val serverInteractor: GetConnectingServerInteractor,
private val saveCurrentServerInteractor: SaveCurrentServerInteractor, private val saveCurrentServerInteractor: SaveCurrentServerInteractor,
private val analyticsTrackingInteractor: AnalyticsTrackingInteractor, private val analyticsManager: AnalyticsManager,
private val factory: RocketChatClientFactory, private val factory: RocketChatClientFactory,
private val saveAccountInteractor: SaveAccountInteractor, private val saveAccountInteractor: SaveAccountInteractor,
private val getAccountsInteractor: GetAccountsInteractor,
settingsInteractor: GetSettingsInteractor settingsInteractor: GetSettingsInteractor
) { ) {
private val currentServer = serverInteractor.get()!! private val currentServer = serverInteractor.get()!!
private val client: RocketChatClient = factory.create(currentServer)
private var settings: PublicSettings = settingsInteractor.get(serverInteractor.get()!!) private var settings: PublicSettings = settingsInteractor.get(serverInteractor.get()!!)
fun signup(name: String, username: String, password: String, email: String) { fun signup(name: String, username: String, password: String, email: String) {
...@@ -80,22 +74,17 @@ class SignupPresenter @Inject constructor( ...@@ -80,22 +74,17 @@ class SignupPresenter @Inject constructor(
saveCurrentServerInteractor.save(currentServer) saveCurrentServerInteractor.save(currentServer)
localRepository.save(LocalRepository.CURRENT_USERNAME_KEY, me.username) localRepository.save(LocalRepository.CURRENT_USERNAME_KEY, me.username)
saveAccount(me) saveAccount(me)
registerPushToken() analyticsManager.logSignUp(
if (analyticsTrackingInteractor.get()) { AuthenticationEvent.AuthenticationWithUserAndPassword,
AnalyticsManager.logSignUp( true
AuthenticationEvent.AuthenticationWithUserAndPassword, )
true
)
}
view.saveSmartLockCredentials(username, password) view.saveSmartLockCredentials(username, password)
navigator.toChatList() navigator.toChatList()
} catch (exception: RocketChatException) { } catch (exception: RocketChatException) {
if (analyticsTrackingInteractor.get()) { analyticsManager.logSignUp(
AnalyticsManager.logSignUp( AuthenticationEvent.AuthenticationWithUserAndPassword,
AuthenticationEvent.AuthenticationWithUserAndPassword, false
false )
)
}
exception.message?.let { exception.message?.let {
view.showMessage(it) view.showMessage(it)
}.ifNull { }.ifNull {
...@@ -122,14 +111,6 @@ class SignupPresenter @Inject constructor( ...@@ -122,14 +111,6 @@ class SignupPresenter @Inject constructor(
} }
} }
private suspend fun registerPushToken() {
localRepository.get(LocalRepository.KEY_PUSH_TOKEN)?.let {
client.registerPushToken(it, getAccountsInteractor.get(), factory)
}
// TODO: When the push token is null, at some point we should receive it with
// onTokenRefresh() on FirebaseTokenService, we need to confirm it.
}
private suspend fun saveAccount(me: Myself) { private suspend fun saveAccount(me: Myself) {
val icon = settings.favicon()?.let { val icon = settings.favicon()?.let {
currentServer.serverLogoUrl(it) currentServer.serverLogoUrl(it)
......
...@@ -13,20 +13,19 @@ import android.view.ViewTreeObserver ...@@ -13,20 +13,19 @@ import android.view.ViewTreeObserver
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.R.string.message_credentials_saved_successfully import chat.rocket.android.R.string.message_credentials_saved_successfully
import chat.rocket.android.analytics.AnalyticsManager
import chat.rocket.android.analytics.event.ScreenViewEvent
import chat.rocket.android.authentication.signup.presentation.SignupPresenter import chat.rocket.android.authentication.signup.presentation.SignupPresenter
import chat.rocket.android.authentication.signup.presentation.SignupView import chat.rocket.android.authentication.signup.presentation.SignupView
import chat.rocket.android.helper.KeyboardHelper import chat.rocket.android.helper.KeyboardHelper
import chat.rocket.android.helper.TextHelper import chat.rocket.android.helper.TextHelper
import chat.rocket.android.helper.saveCredentials import chat.rocket.android.helper.saveCredentials
import chat.rocket.android.server.domain.AnalyticsTrackingInteractor
import chat.rocket.android.util.extensions.setVisible import chat.rocket.android.util.extensions.setVisible
import chat.rocket.android.util.extensions.shake import chat.rocket.android.util.extensions.shake
import chat.rocket.android.util.extensions.showToast import chat.rocket.android.util.extensions.showToast
import chat.rocket.android.util.extensions.textContent import chat.rocket.android.util.extensions.textContent
import chat.rocket.android.util.extensions.ui import chat.rocket.android.util.extensions.ui
import chat.rocket.android.util.extensions.vibrateSmartPhone import chat.rocket.android.util.extensions.vibrateSmartPhone
import chat.rocket.android.util.helper.analytics.AnalyticsManager
import chat.rocket.android.util.helper.analytics.event.ScreenViewEvent
import dagger.android.support.AndroidSupportInjection import dagger.android.support.AndroidSupportInjection
import kotlinx.android.synthetic.main.fragment_authentication_sign_up.* import kotlinx.android.synthetic.main.fragment_authentication_sign_up.*
import javax.inject.Inject import javax.inject.Inject
...@@ -38,7 +37,7 @@ class SignupFragment : Fragment(), SignupView { ...@@ -38,7 +37,7 @@ class SignupFragment : Fragment(), SignupView {
@Inject @Inject
lateinit var presenter: SignupPresenter lateinit var presenter: SignupPresenter
@Inject @Inject
lateinit var analyticsTrackingInteractor: AnalyticsTrackingInteractor lateinit var analyticsManager: AnalyticsManager
private val layoutListener = ViewTreeObserver.OnGlobalLayoutListener { private val layoutListener = ViewTreeObserver.OnGlobalLayoutListener {
if (KeyboardHelper.isSoftKeyboardShown(constraint_layout.rootView)) { if (KeyboardHelper.isSoftKeyboardShown(constraint_layout.rootView)) {
text_new_user_agreement.setVisible(false) text_new_user_agreement.setVisible(false)
...@@ -82,9 +81,7 @@ class SignupFragment : Fragment(), SignupView { ...@@ -82,9 +81,7 @@ class SignupFragment : Fragment(), SignupView {
) )
} }
if (analyticsTrackingInteractor.get()) { analyticsManager.logScreenView(ScreenViewEvent.SignUp)
AnalyticsManager.logScreenView(ScreenViewEvent.SignUp)
}
} }
override fun onDestroyView() { override fun onDestroyView() {
......
package chat.rocket.android.authentication.twofactor.presentation package chat.rocket.android.authentication.twofactor.presentation
import chat.rocket.android.analytics.AnalyticsManager
import chat.rocket.android.analytics.event.AuthenticationEvent
import chat.rocket.android.authentication.presentation.AuthenticationNavigator import chat.rocket.android.authentication.presentation.AuthenticationNavigator
import chat.rocket.android.core.lifecycle.CancelStrategy import chat.rocket.android.core.lifecycle.CancelStrategy
import chat.rocket.android.infrastructure.LocalRepository import chat.rocket.android.infrastructure.LocalRepository
import chat.rocket.android.server.domain.* import chat.rocket.android.server.domain.GetConnectingServerInteractor
import chat.rocket.android.server.domain.GetSettingsInteractor
import chat.rocket.android.server.domain.PublicSettings
import chat.rocket.android.server.domain.SaveAccountInteractor
import chat.rocket.android.server.domain.SaveCurrentServerInteractor
import chat.rocket.android.server.domain.TokenRepository
import chat.rocket.android.server.domain.favicon
import chat.rocket.android.server.domain.model.Account import chat.rocket.android.server.domain.model.Account
import chat.rocket.android.server.domain.wideTile
import chat.rocket.android.server.infraestructure.RocketChatClientFactory import chat.rocket.android.server.infraestructure.RocketChatClientFactory
import chat.rocket.android.util.extension.launchUI import chat.rocket.android.util.extension.launchUI
import chat.rocket.android.util.extensions.avatarUrl import chat.rocket.android.util.extensions.avatarUrl
import chat.rocket.android.util.extensions.registerPushToken
import chat.rocket.android.util.extensions.serverLogoUrl import chat.rocket.android.util.extensions.serverLogoUrl
import chat.rocket.android.util.helper.analytics.AnalyticsManager
import chat.rocket.android.util.helper.analytics.event.AuthenticationEvent
import chat.rocket.android.util.retryIO import chat.rocket.android.util.retryIO
import chat.rocket.common.RocketChatAuthException import chat.rocket.common.RocketChatAuthException
import chat.rocket.common.RocketChatException import chat.rocket.common.RocketChatException
import chat.rocket.common.util.ifNull import chat.rocket.common.util.ifNull
import chat.rocket.core.RocketChatClient
import chat.rocket.core.internal.rest.login import chat.rocket.core.internal.rest.login
import chat.rocket.core.internal.rest.me import chat.rocket.core.internal.rest.me
import chat.rocket.core.model.Myself import chat.rocket.core.model.Myself
...@@ -30,14 +35,12 @@ class TwoFAPresenter @Inject constructor( ...@@ -30,14 +35,12 @@ class TwoFAPresenter @Inject constructor(
private val localRepository: LocalRepository, private val localRepository: LocalRepository,
private val serverInteractor: GetConnectingServerInteractor, private val serverInteractor: GetConnectingServerInteractor,
private val saveCurrentServerInteractor: SaveCurrentServerInteractor, private val saveCurrentServerInteractor: SaveCurrentServerInteractor,
private val analyticsTrackingInteractor: AnalyticsTrackingInteractor, private val analyticsManager: AnalyticsManager,
private val factory: RocketChatClientFactory, private val factory: RocketChatClientFactory,
private val saveAccountInteractor: SaveAccountInteractor, private val saveAccountInteractor: SaveAccountInteractor,
private val getAccountsInteractor: GetAccountsInteractor,
settingsInteractor: GetSettingsInteractor settingsInteractor: GetSettingsInteractor
) { ) {
private val currentServer = serverInteractor.get()!! private val currentServer = serverInteractor.get()!!
private val client: RocketChatClient = factory.create(currentServer)
private var settings: PublicSettings = settingsInteractor.get(serverInteractor.get()!!) private var settings: PublicSettings = settingsInteractor.get(serverInteractor.get()!!)
// TODO: If the usernameOrEmail and password was informed by the user on the previous screen, then we should pass only the pin, like this: fun authenticate(pin: EditText) // TODO: If the usernameOrEmail and password was informed by the user on the previous screen, then we should pass only the pin, like this: fun authenticate(pin: EditText)
...@@ -67,24 +70,20 @@ class TwoFAPresenter @Inject constructor( ...@@ -67,24 +70,20 @@ class TwoFAPresenter @Inject constructor(
saveAccount(me) saveAccount(me)
saveCurrentServerInteractor.save(currentServer) saveCurrentServerInteractor.save(currentServer)
tokenRepository.save(server, token) tokenRepository.save(server, token)
registerPushToken() localRepository.save(LocalRepository.CURRENT_USERNAME_KEY, me.username)
if (analyticsTrackingInteractor.get()) { analyticsManager.logLogin(
AnalyticsManager.logLogin( AuthenticationEvent.AuthenticationWithUserAndPassword,
AuthenticationEvent.AuthenticationWithUserAndPassword, true
true )
)
}
navigator.toChatList() navigator.toChatList()
} catch (exception: RocketChatException) { } catch (exception: RocketChatException) {
if (exception is RocketChatAuthException) { if (exception is RocketChatAuthException) {
view.alertInvalidTwoFactorAuthenticationCode() view.alertInvalidTwoFactorAuthenticationCode()
} else { } else {
if (analyticsTrackingInteractor.get()) { analyticsManager.logLogin(
AnalyticsManager.logLogin( AuthenticationEvent.AuthenticationWithUserAndPassword,
AuthenticationEvent.AuthenticationWithUserAndPassword, false
false )
)
}
exception.message?.let { exception.message?.let {
view.showMessage(it) view.showMessage(it)
}.ifNull { }.ifNull {
...@@ -101,14 +100,6 @@ class TwoFAPresenter @Inject constructor( ...@@ -101,14 +100,6 @@ class TwoFAPresenter @Inject constructor(
fun signup() = navigator.toSignUp() fun signup() = navigator.toSignUp()
private suspend fun registerPushToken() {
localRepository.get(LocalRepository.KEY_PUSH_TOKEN)?.let {
client.registerPushToken(it, getAccountsInteractor.get(), factory)
}
// TODO: When the push token is null, at some point we should receive it with
// onTokenRefresh() on FirebaseTokenService, we need to confirm it.
}
private suspend fun saveAccount(me: Myself) { private suspend fun saveAccount(me: Myself) {
val icon = settings.favicon()?.let { val icon = settings.favicon()?.let {
currentServer.serverLogoUrl(it) currentServer.serverLogoUrl(it)
......
...@@ -10,9 +10,10 @@ import android.view.ViewGroup ...@@ -10,9 +10,10 @@ import android.view.ViewGroup
import android.view.inputmethod.InputMethodManager import android.view.inputmethod.InputMethodManager
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.analytics.AnalyticsManager
import chat.rocket.android.analytics.event.ScreenViewEvent
import chat.rocket.android.authentication.twofactor.presentation.TwoFAPresenter import chat.rocket.android.authentication.twofactor.presentation.TwoFAPresenter
import chat.rocket.android.authentication.twofactor.presentation.TwoFAView import chat.rocket.android.authentication.twofactor.presentation.TwoFAView
import chat.rocket.android.server.domain.AnalyticsTrackingInteractor
import chat.rocket.android.util.extensions.inflate import chat.rocket.android.util.extensions.inflate
import chat.rocket.android.util.extensions.setVisible import chat.rocket.android.util.extensions.setVisible
import chat.rocket.android.util.extensions.shake import chat.rocket.android.util.extensions.shake
...@@ -20,8 +21,6 @@ import chat.rocket.android.util.extensions.showToast ...@@ -20,8 +21,6 @@ import chat.rocket.android.util.extensions.showToast
import chat.rocket.android.util.extensions.textContent import chat.rocket.android.util.extensions.textContent
import chat.rocket.android.util.extensions.ui import chat.rocket.android.util.extensions.ui
import chat.rocket.android.util.extensions.vibrateSmartPhone import chat.rocket.android.util.extensions.vibrateSmartPhone
import chat.rocket.android.util.helper.analytics.AnalyticsManager
import chat.rocket.android.util.helper.analytics.event.ScreenViewEvent
import dagger.android.support.AndroidSupportInjection import dagger.android.support.AndroidSupportInjection
import kotlinx.android.synthetic.main.fragment_authentication_two_fa.* import kotlinx.android.synthetic.main.fragment_authentication_two_fa.*
import javax.inject.Inject import javax.inject.Inject
...@@ -32,7 +31,7 @@ class TwoFAFragment : Fragment(), TwoFAView { ...@@ -32,7 +31,7 @@ class TwoFAFragment : Fragment(), TwoFAView {
@Inject @Inject
lateinit var presenter: TwoFAPresenter lateinit var presenter: TwoFAPresenter
@Inject @Inject
lateinit var analyticsTrackingInteractor: AnalyticsTrackingInteractor lateinit var analyticsManager: AnalyticsManager
lateinit var username: String lateinit var username: String
lateinit var password: String lateinit var password: String
...@@ -66,9 +65,7 @@ class TwoFAFragment : Fragment(), TwoFAView { ...@@ -66,9 +65,7 @@ class TwoFAFragment : Fragment(), TwoFAView {
setupOnClickListener() setupOnClickListener()
if (analyticsTrackingInteractor.get()) { analyticsManager.logScreenView(ScreenViewEvent.TwoFa)
AnalyticsManager.logScreenView(ScreenViewEvent.TwoFa)
}
} }
override fun alertBlankTwoFactorAuthenticationCode() { override fun alertBlankTwoFactorAuthenticationCode() {
......
...@@ -9,15 +9,14 @@ import androidx.recyclerview.widget.DefaultItemAnimator ...@@ -9,15 +9,14 @@ import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.analytics.AnalyticsManager
import chat.rocket.android.analytics.event.ScreenViewEvent
import chat.rocket.android.chatinformation.adapter.ReadReceiptAdapter import chat.rocket.android.chatinformation.adapter.ReadReceiptAdapter
import chat.rocket.android.chatinformation.presentation.MessageInfoPresenter import chat.rocket.android.chatinformation.presentation.MessageInfoPresenter
import chat.rocket.android.chatinformation.presentation.MessageInfoView import chat.rocket.android.chatinformation.presentation.MessageInfoView
import chat.rocket.android.chatinformation.viewmodel.ReadReceiptViewModel import chat.rocket.android.chatinformation.viewmodel.ReadReceiptViewModel
import chat.rocket.android.server.domain.AnalyticsTrackingInteractor
import chat.rocket.android.util.extensions.setVisible import chat.rocket.android.util.extensions.setVisible
import chat.rocket.android.util.extensions.showToast import chat.rocket.android.util.extensions.showToast
import chat.rocket.android.util.helper.analytics.AnalyticsManager
import chat.rocket.android.util.helper.analytics.event.ScreenViewEvent
import dagger.android.support.AndroidSupportInjection import dagger.android.support.AndroidSupportInjection
import kotlinx.android.synthetic.main.fragment_message_info.* import kotlinx.android.synthetic.main.fragment_message_info.*
import javax.inject.Inject import javax.inject.Inject
...@@ -37,7 +36,7 @@ class MessageInfoFragment : Fragment(), MessageInfoView { ...@@ -37,7 +36,7 @@ class MessageInfoFragment : Fragment(), MessageInfoView {
@Inject @Inject
lateinit var presenter: MessageInfoPresenter lateinit var presenter: MessageInfoPresenter
@Inject @Inject
lateinit var analyticsTrackingInteractor: AnalyticsTrackingInteractor lateinit var analyticsManager: AnalyticsManager
private lateinit var adapter: ReadReceiptAdapter private lateinit var adapter: ReadReceiptAdapter
private lateinit var messageId: String private lateinit var messageId: String
...@@ -67,9 +66,7 @@ class MessageInfoFragment : Fragment(), MessageInfoView { ...@@ -67,9 +66,7 @@ class MessageInfoFragment : Fragment(), MessageInfoView {
setupRecyclerView() setupRecyclerView()
presenter.loadReadReceipts(messageId = messageId) presenter.loadReadReceipts(messageId = messageId)
if (analyticsTrackingInteractor.get()) { analyticsManager.logScreenView(ScreenViewEvent.MessageInfo)
AnalyticsManager.logScreenView(ScreenViewEvent.MessageInfo)
}
} }
private fun setupRecyclerView() { private fun setupRecyclerView() {
......
...@@ -158,23 +158,36 @@ class ChatRoomAdapter( ...@@ -158,23 +158,36 @@ class ChatRoomAdapter(
} }
fun prependData(dataSet: List<BaseUiModel<*>>) { fun prependData(dataSet: List<BaseUiModel<*>>) {
val item = dataSet.indexOfFirst { newItem -> //---At first we will update all already saved elements with received updated ones
this.dataSet.indexOfFirst { it.messageId == newItem.messageId && it.viewType == newItem.viewType } > -1 val filteredDataSet = dataSet.filter { newItem ->
} val matchedIndex = this.dataSet.indexOfFirst { it.messageId == newItem.messageId && it.viewType == newItem.viewType }
if (item == -1) { if (matchedIndex > -1) {
this.dataSet.addAll(0, dataSet) this.dataSet[matchedIndex] = newItem
notifyItemRangeInserted(0, dataSet.size) notifyItemChanged(matchedIndex)
} else {
dataSet.forEach { item ->
val index = this.dataSet.indexOfFirst {
item.messageId == it.messageId && item.viewType == it.viewType
}
if (index > -1) {
this.dataSet[index] = item
notifyItemChanged(index)
}
} }
return@filter (matchedIndex < 0)
}
val minAdditionDate = filteredDataSet.minBy { it.message.timestamp } ?: return
//---In the most cases we will just add new elements to the top of messages heap
if (this.dataSet.isEmpty() || minAdditionDate.message.timestamp > this.dataSet[0].message.timestamp) {
this.dataSet.addAll(0, filteredDataSet)
notifyItemRangeInserted(0, filteredDataSet.size)
return
} }
//---Else branch: merging messages---
//---We are inserting new received elements into set. Sort them by time+type and show
if (filteredDataSet.isEmpty()) return
this.dataSet.addAll(0, filteredDataSet)
val tmp = this.dataSet.sortedWith(Comparator { t, t2 ->
val timeComparison = t.message.timestamp.compareTo(t2.message.timestamp)
if (timeComparison == 0) {
return@Comparator t.viewType.compareTo(t2.viewType)
}
timeComparison
}).reversed()
this.dataSet.clear()
this.dataSet.addAll(tmp)
notifyDataSetChanged()
} }
fun updateItem(message: BaseUiModel<*>) { fun updateItem(message: BaseUiModel<*>) {
......
...@@ -5,7 +5,6 @@ import android.app.job.JobService ...@@ -5,7 +5,6 @@ import android.app.job.JobService
import chat.rocket.android.server.domain.CurrentServerRepository import chat.rocket.android.server.domain.CurrentServerRepository
import chat.rocket.android.server.domain.MessagesRepository import chat.rocket.android.server.domain.MessagesRepository
import chat.rocket.android.server.infraestructure.ConnectionManagerFactory import chat.rocket.android.server.infraestructure.ConnectionManagerFactory
import chat.rocket.common.RocketChatException
import chat.rocket.core.internal.rest.sendMessage import chat.rocket.core.internal.rest.sendMessage
import chat.rocket.core.model.Message import chat.rocket.core.model.Message
import dagger.android.AndroidInjection import dagger.android.AndroidInjection
......
...@@ -33,6 +33,8 @@ import androidx.recyclerview.widget.DefaultItemAnimator ...@@ -33,6 +33,8 @@ import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.analytics.AnalyticsManager
import chat.rocket.android.analytics.event.ScreenViewEvent
import chat.rocket.android.chatroom.adapter.ChatRoomAdapter import chat.rocket.android.chatroom.adapter.ChatRoomAdapter
import chat.rocket.android.chatroom.adapter.CommandSuggestionsAdapter import chat.rocket.android.chatroom.adapter.CommandSuggestionsAdapter
import chat.rocket.android.chatroom.adapter.PEOPLE import chat.rocket.android.chatroom.adapter.PEOPLE
...@@ -60,7 +62,6 @@ import chat.rocket.android.helper.EndlessRecyclerViewScrollListener ...@@ -60,7 +62,6 @@ import chat.rocket.android.helper.EndlessRecyclerViewScrollListener
import chat.rocket.android.helper.ImageHelper import chat.rocket.android.helper.ImageHelper
import chat.rocket.android.helper.KeyboardHelper import chat.rocket.android.helper.KeyboardHelper
import chat.rocket.android.helper.MessageParser import chat.rocket.android.helper.MessageParser
import chat.rocket.android.server.domain.AnalyticsTrackingInteractor
import chat.rocket.android.util.extension.asObservable import chat.rocket.android.util.extension.asObservable
import chat.rocket.android.util.extension.launchUI import chat.rocket.android.util.extension.launchUI
import chat.rocket.android.util.extensions.circularRevealOrUnreveal import chat.rocket.android.util.extensions.circularRevealOrUnreveal
...@@ -72,8 +73,6 @@ import chat.rocket.android.util.extensions.rotateBy ...@@ -72,8 +73,6 @@ import chat.rocket.android.util.extensions.rotateBy
import chat.rocket.android.util.extensions.showToast import chat.rocket.android.util.extensions.showToast
import chat.rocket.android.util.extensions.textContent import chat.rocket.android.util.extensions.textContent
import chat.rocket.android.util.extensions.ui import chat.rocket.android.util.extensions.ui
import chat.rocket.android.util.helper.analytics.AnalyticsManager
import chat.rocket.android.util.helper.analytics.event.ScreenViewEvent
import chat.rocket.common.model.RoomType import chat.rocket.common.model.RoomType
import chat.rocket.common.model.roomTypeOf import chat.rocket.common.model.roomTypeOf
import chat.rocket.core.internal.realtime.socket.model.State import chat.rocket.core.internal.realtime.socket.model.State
...@@ -148,7 +147,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -148,7 +147,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
@Inject @Inject
lateinit var parser: MessageParser lateinit var parser: MessageParser
@Inject @Inject
lateinit var analyticsTrackingInteractor: AnalyticsTrackingInteractor lateinit var analyticsManager: AnalyticsManager
private lateinit var adapter: ChatRoomAdapter private lateinit var adapter: ChatRoomAdapter
internal lateinit var chatRoomId: String internal lateinit var chatRoomId: String
private lateinit var chatRoomName: String private lateinit var chatRoomName: String
...@@ -219,8 +218,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -219,8 +218,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
requireNotNull(bundle) { "no arguments supplied when the fragment was instantiated" } requireNotNull(bundle) { "no arguments supplied when the fragment was instantiated" }
} }
adapter = ChatRoomAdapter(chatRoomId, chatRoomType, chatRoomName, this, adapter = ChatRoomAdapter(chatRoomId, chatRoomType, chatRoomName, this, reactionListener = this)
reactionListener = this)
} }
override fun onCreateView( override fun onCreateView(
...@@ -246,9 +244,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -246,9 +244,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
it.showToolbarChatRoomIcon(chatRoomType) it.showToolbarChatRoomIcon(chatRoomType)
} }
if (analyticsTrackingInteractor.get()) { analyticsManager.logScreenView(ScreenViewEvent.ChatRoom)
AnalyticsManager.logScreenView(ScreenViewEvent.ChatRoom)
}
} }
override fun onActivityCreated(savedInstanceState: Bundle?) { override fun onActivityCreated(savedInstanceState: Bundle?) {
...@@ -480,23 +476,18 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -480,23 +476,18 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
override fun showTypingStatus(usernameList: List<String>) { override fun showTypingStatus(usernameList: List<String>) {
ui { ui {
when (usernameList.size) { when (usernameList.size) {
1 -> { 1 -> text_typing_status.text =
text_typing_status.text =
SpannableStringBuilder() SpannableStringBuilder()
.bold { append(usernameList[0]) } .bold { append(usernameList[0]) }
.append(getString(R.string.msg_is_typing)) .append(getString(R.string.msg_is_typing))
} 2 -> text_typing_status.text =
2 -> {
text_typing_status.text =
SpannableStringBuilder() SpannableStringBuilder()
.bold { append(usernameList[0]) } .bold { append(usernameList[0]) }
.append(getString(R.string.msg_and)) .append(getString(R.string.msg_and))
.bold { append(usernameList[1]) } .bold { append(usernameList[1]) }
.append(getString(R.string.msg_are_typing)) .append(getString(R.string.msg_are_typing))
}
else -> { else -> text_typing_status.text = getString(R.string.msg_several_users_are_typing)
text_typing_status.text = getString(R.string.msg_several_users_are_typing)
}
} }
text_typing_status.isVisible = true text_typing_status.isVisible = true
} }
...@@ -720,16 +711,16 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -720,16 +711,16 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
text_connection_status.text = getString(R.string.status_connected) text_connection_status.text = getString(R.string.status_connected)
handler.postDelayed(dismissStatus, 2000) handler.postDelayed(dismissStatus, 2000)
} }
is State.Disconnected -> text_connection_status.text = is State.Disconnected ->
getString(R.string.status_disconnected) text_connection_status.text = getString(R.string.status_disconnected)
is State.Connecting -> text_connection_status.text = is State.Connecting ->
getString(R.string.status_connecting) text_connection_status.text = getString(R.string.status_connecting)
is State.Authenticating -> text_connection_status.text = is State.Authenticating ->
getString(R.string.status_authenticating) text_connection_status.text = getString(R.string.status_authenticating)
is State.Disconnecting -> text_connection_status.text = is State.Disconnecting ->
getString(R.string.status_disconnecting) text_connection_status.text = getString(R.string.status_disconnecting)
is State.Waiting -> text_connection_status.text = is State.Waiting ->
getString(R.string.status_waiting, state.seconds) text_connection_status.text = getString(R.string.status_waiting, state.seconds)
} }
} }
} }
...@@ -791,7 +782,11 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -791,7 +782,11 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
activity?.supportFragmentManager?.registerFragmentLifecycleCallbacks( activity?.supportFragmentManager?.registerFragmentLifecycleCallbacks(
object : FragmentManager.FragmentLifecycleCallbacks() { object : FragmentManager.FragmentLifecycleCallbacks() {
override fun onFragmentAttached(fm: FragmentManager, f: Fragment, context: Context) { override fun onFragmentAttached(
fm: FragmentManager,
f: Fragment,
context: Context
) {
if (f is MessageActionsBottomSheet) { if (f is MessageActionsBottomSheet) {
setReactionButtonIcon(R.drawable.ic_reaction_24dp) setReactionButtonIcon(R.drawable.ic_reaction_24dp)
emojiKeyboardPopup.dismiss() emojiKeyboardPopup.dismiss()
...@@ -802,12 +797,10 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -802,12 +797,10 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
) )
subscribeComposeTextMessage() subscribeComposeTextMessage()
emojiKeyboardPopup = emojiKeyboardPopup = EmojiKeyboardPopup(activity!!, activity!!.findViewById(R.id.fragment_container))
EmojiKeyboardPopup(activity!!, activity!!.findViewById(R.id.fragment_container))
emojiKeyboardPopup.listener = this emojiKeyboardPopup.listener = this
text_message.listener = object : ComposerEditText.ComposerEditTextListener { text_message.listener = object : ComposerEditText.ComposerEditTextListener {
override fun onKeyboardOpened() { override fun onKeyboardOpened() {}
}
override fun onKeyboardClosed() { override fun onKeyboardClosed() {
activity?.let { activity?.let {
...@@ -1005,7 +998,12 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -1005,7 +998,12 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
presenter.messageInfo(id) presenter.messageInfo(id)
} }
override fun citeMessage(roomName: String, roomType: String, messageId: String, mentionAuthor: Boolean) { override fun citeMessage(
roomName: String,
roomType: String,
messageId: String,
mentionAuthor: Boolean
) {
presenter.citeMessage(roomName, roomType, messageId, mentionAuthor) presenter.citeMessage(roomName, roomType, messageId, mentionAuthor)
} }
...@@ -1037,10 +1035,15 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -1037,10 +1035,15 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
ui { ui {
val builder = AlertDialog.Builder(it) val builder = AlertDialog.Builder(it)
builder.setTitle(it.getString(R.string.msg_delete_message)) builder.setTitle(it.getString(R.string.msg_delete_message))
.setMessage(it.getString(R.string.msg_delete_description)) .setMessage(it.getString(R.string.msg_delete_description))
.setPositiveButton(it.getString(R.string.msg_ok)) { _, _ -> presenter.deleteMessage(roomId, id) } .setPositiveButton(it.getString(R.string.msg_ok)) { _, _ ->
.setNegativeButton(it.getString(R.string.msg_cancel)) { _, _ -> } presenter.deleteMessage(
.show() roomId,
id
)
}
.setNegativeButton(it.getString(R.string.msg_cancel)) { _, _ -> }
.show()
} }
} }
......
package chat.rocket.android.chatroom.ui package chat.rocket.android.chatroom.ui
import android.graphics.Bitmap
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.net.Uri import android.net.Uri
import androidx.core.view.isVisible import androidx.core.view.isVisible
import chat.rocket.android.emoji.internal.GlideApp
import chat.rocket.android.util.extensions.getFileName import chat.rocket.android.util.extensions.getFileName
import chat.rocket.android.util.extensions.getMimeType import chat.rocket.android.util.extensions.getMimeType
import com.bumptech.glide.request.target.SimpleTarget
import com.bumptech.glide.request.transition.Transition
fun ChatRoomFragment.showFileAttachmentDialog(uri: Uri) { fun ChatRoomFragment.showFileAttachmentDialog(uri: Uri) {
activity?.let { fragmentActivity -> imagePreview.isVisible = false
uri.getMimeType(fragmentActivity).let { mimeType -> audioVideoAttachment.isVisible = false
textFile.isVisible = false
var bitmap: Bitmap? = null
activity?.let { context ->
uri.getMimeType(context).let { mimeType ->
description.text.clear() description.text.clear()
when { when {
mimeType.startsWith("image") -> { mimeType.startsWith("image") -> {
imagePreview.isVisible = true GlideApp
imagePreview.setImageURI(uri) .with(context)
} .asBitmap()
mimeType.startsWith("video") -> { .load(uri)
audioVideoAttachment.isVisible = true .override(imagePreview.width, imagePreview.height)
.fitCenter()
.into(object : SimpleTarget<Bitmap>() {
override fun onResourceReady(
resource: Bitmap,
transition: Transition<in Bitmap>?
) {
bitmap = resource
imagePreview.setImageBitmap(resource)
imagePreview.isVisible = true
}
})
} }
mimeType.startsWith("video") -> audioVideoAttachment.isVisible = true
else -> { else -> {
textFile.isVisible = true textFile.isVisible = true
textFile.text = uri.getFileName(fragmentActivity) textFile.text = uri.getFileName(context)
} }
} }
} }
} }
sendButton.setOnClickListener { sendButton.setOnClickListener {
presenter.uploadFile(chatRoomId, uri, (citation ?: "") + description.text.toString()) presenter.uploadFile(
chatRoomId,
uri,
(citation ?: "") + description.text.toString(),
bitmap
)
alertDialog.dismiss() alertDialog.dismiss()
} }
cancelButton.setOnClickListener { alertDialog.dismiss() } cancelButton.setOnClickListener { alertDialog.dismiss() }
......
...@@ -21,6 +21,8 @@ import androidx.lifecycle.ViewModelProviders ...@@ -21,6 +21,8 @@ import androidx.lifecycle.ViewModelProviders
import androidx.recyclerview.widget.DefaultItemAnimator import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.analytics.AnalyticsManager
import chat.rocket.android.analytics.event.ScreenViewEvent
import chat.rocket.android.chatrooms.adapter.RoomsAdapter import chat.rocket.android.chatrooms.adapter.RoomsAdapter
import chat.rocket.android.chatrooms.presentation.ChatRoomsPresenter import chat.rocket.android.chatrooms.presentation.ChatRoomsPresenter
import chat.rocket.android.chatrooms.presentation.ChatRoomsView import chat.rocket.android.chatrooms.presentation.ChatRoomsView
...@@ -32,15 +34,12 @@ import chat.rocket.android.db.DatabaseManager ...@@ -32,15 +34,12 @@ import chat.rocket.android.db.DatabaseManager
import chat.rocket.android.helper.ChatRoomsSortOrder import chat.rocket.android.helper.ChatRoomsSortOrder
import chat.rocket.android.helper.Constants import chat.rocket.android.helper.Constants
import chat.rocket.android.helper.SharedPreferenceHelper import chat.rocket.android.helper.SharedPreferenceHelper
import chat.rocket.android.server.domain.AnalyticsTrackingInteractor
import chat.rocket.android.util.extension.onQueryTextListener import chat.rocket.android.util.extension.onQueryTextListener
import chat.rocket.android.util.extensions.fadeIn import chat.rocket.android.util.extensions.fadeIn
import chat.rocket.android.util.extensions.fadeOut import chat.rocket.android.util.extensions.fadeOut
import chat.rocket.android.util.extensions.inflate import chat.rocket.android.util.extensions.inflate
import chat.rocket.android.util.extensions.showToast import chat.rocket.android.util.extensions.showToast
import chat.rocket.android.util.extensions.ui import chat.rocket.android.util.extensions.ui
import chat.rocket.android.util.helper.analytics.AnalyticsManager
import chat.rocket.android.util.helper.analytics.event.ScreenViewEvent
import chat.rocket.android.widget.DividerItemDecoration import chat.rocket.android.widget.DividerItemDecoration
import chat.rocket.core.internal.realtime.socket.model.State import chat.rocket.core.internal.realtime.socket.model.State
import dagger.android.support.AndroidSupportInjection import dagger.android.support.AndroidSupportInjection
...@@ -60,7 +59,7 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView { ...@@ -60,7 +59,7 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
@Inject @Inject
lateinit var dbManager: DatabaseManager // TODO - remove when moving ChatRoom screen to DB lateinit var dbManager: DatabaseManager // TODO - remove when moving ChatRoom screen to DB
@Inject @Inject
lateinit var analyticsTrackingInteractor: AnalyticsTrackingInteractor lateinit var analyticsManager: AnalyticsManager
lateinit var viewModel: ChatRoomsViewModel lateinit var viewModel: ChatRoomsViewModel
private var searchView: SearchView? = null private var searchView: SearchView? = null
private var sortView: MenuItem? = null private var sortView: MenuItem? = null
...@@ -112,9 +111,7 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView { ...@@ -112,9 +111,7 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
setupToolbar() setupToolbar()
if (analyticsTrackingInteractor.get()) { analyticsManager.logScreenView(ScreenViewEvent.ChatRooms)
AnalyticsManager.logScreenView(ScreenViewEvent.ChatRooms)
}
} }
private fun subscribeUi() { private fun subscribeUi() {
...@@ -124,9 +121,13 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView { ...@@ -124,9 +121,13 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
} }
recycler_view.layoutManager = LinearLayoutManager(it) recycler_view.layoutManager = LinearLayoutManager(it)
recycler_view.addItemDecoration(DividerItemDecoration(it, recycler_view.addItemDecoration(
DividerItemDecoration(
it,
resources.getDimensionPixelSize(R.dimen.divider_item_decorator_bound_start), resources.getDimensionPixelSize(R.dimen.divider_item_decorator_bound_start),
resources.getDimensionPixelSize(R.dimen.divider_item_decorator_bound_end))) resources.getDimensionPixelSize(R.dimen.divider_item_decorator_bound_end)
)
)
recycler_view.itemAnimator = DefaultItemAnimator() recycler_view.itemAnimator = DefaultItemAnimator()
recycler_view.adapter = adapter recycler_view.adapter = adapter
...@@ -141,7 +142,7 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView { ...@@ -141,7 +142,7 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
}) })
viewModel.loadingState.observe(viewLifecycleOwner, Observer { state -> viewModel.loadingState.observe(viewLifecycleOwner, Observer { state ->
when(state) { when (state) {
is LoadingState.Loading -> if (state.count == 0L) showLoading() is LoadingState.Loading -> if (state.count == 0L) showLoading()
is LoadingState.Loaded -> { is LoadingState.Loaded -> {
hideLoading() hideLoading()
...@@ -195,29 +196,41 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView { ...@@ -195,29 +196,41 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
// TODO - simplify this // TODO - simplify this
R.id.action_sort -> { R.id.action_sort -> {
val dialogLayout = layoutInflater.inflate(R.layout.chatroom_sort_dialog, null) val dialogLayout = layoutInflater.inflate(R.layout.chatroom_sort_dialog, null)
val sortType = SharedPreferenceHelper.getInt(Constants.CHATROOM_SORT_TYPE_KEY, ChatRoomsSortOrder.ACTIVITY) val sortType = SharedPreferenceHelper.getInt(
val groupByType = SharedPreferenceHelper.getBoolean(Constants.CHATROOM_GROUP_BY_TYPE_KEY, false) Constants.CHATROOM_SORT_TYPE_KEY,
ChatRoomsSortOrder.ACTIVITY
)
val groupByType =
SharedPreferenceHelper.getBoolean(Constants.CHATROOM_GROUP_BY_TYPE_KEY, false)
val radioGroup = dialogLayout.findViewById<RadioGroup>(R.id.radio_group_sort) val radioGroup = dialogLayout.findViewById<RadioGroup>(R.id.radio_group_sort)
val groupByTypeCheckBox = dialogLayout.findViewById<CheckBox>(R.id.checkbox_group_by_type) val groupByTypeCheckBox =
dialogLayout.findViewById<CheckBox>(R.id.checkbox_group_by_type)
radioGroup.check(when (sortType) { radioGroup.check(
0 -> R.id.radio_sort_alphabetical when (sortType) {
else -> R.id.radio_sort_activity 0 -> R.id.radio_sort_alphabetical
}) else -> R.id.radio_sort_activity
}
)
radioGroup.setOnCheckedChangeListener { _, checkedId -> radioGroup.setOnCheckedChangeListener { _, checkedId ->
run { run {
SharedPreferenceHelper.putInt(Constants.CHATROOM_SORT_TYPE_KEY, when (checkedId) { SharedPreferenceHelper.putInt(
R.id.radio_sort_alphabetical -> 0 Constants.CHATROOM_SORT_TYPE_KEY, when (checkedId) {
R.id.radio_sort_activity -> 1 R.id.radio_sort_alphabetical -> 0
else -> 1 R.id.radio_sort_activity -> 1
}) else -> 1
}
)
} }
} }
groupByTypeCheckBox.isChecked = groupByType groupByTypeCheckBox.isChecked = groupByType
groupByTypeCheckBox.setOnCheckedChangeListener { _, isChecked -> groupByTypeCheckBox.setOnCheckedChangeListener { _, isChecked ->
SharedPreferenceHelper.putBoolean(Constants.CHATROOM_GROUP_BY_TYPE_KEY, isChecked) SharedPreferenceHelper.putBoolean(
Constants.CHATROOM_GROUP_BY_TYPE_KEY,
isChecked
)
} }
AlertDialog.Builder(context) AlertDialog.Builder(context)
...@@ -234,10 +247,13 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView { ...@@ -234,10 +247,13 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
} }
private fun updateSort() { private fun updateSort() {
val sortType = SharedPreferenceHelper.getInt(Constants.CHATROOM_SORT_TYPE_KEY, ChatRoomsSortOrder.ACTIVITY) val sortType = SharedPreferenceHelper.getInt(
Constants.CHATROOM_SORT_TYPE_KEY,
ChatRoomsSortOrder.ACTIVITY
)
val grouped = SharedPreferenceHelper.getBoolean(Constants.CHATROOM_GROUP_BY_TYPE_KEY, false) val grouped = SharedPreferenceHelper.getBoolean(Constants.CHATROOM_GROUP_BY_TYPE_KEY, false)
val query = when(sortType) { val query = when (sortType) {
ChatRoomsSortOrder.ALPHABETICAL -> { ChatRoomsSortOrder.ALPHABETICAL -> {
Query.ByName(grouped) Query.ByName(grouped)
} }
...@@ -304,11 +320,16 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView { ...@@ -304,11 +320,16 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
text_connection_status.text = getString(R.string.status_connected) text_connection_status.text = getString(R.string.status_connected)
handler.postDelayed(dismissStatus, 2000) handler.postDelayed(dismissStatus, 2000)
} }
is State.Disconnected -> text_connection_status.text = getString(R.string.status_disconnected) is State.Disconnected -> text_connection_status.text =
is State.Connecting -> text_connection_status.text = getString(R.string.status_connecting) getString(R.string.status_disconnected)
is State.Authenticating -> text_connection_status.text = getString(R.string.status_authenticating) is State.Connecting -> text_connection_status.text =
is State.Disconnecting -> text_connection_status.text = getString(R.string.status_disconnecting) getString(R.string.status_connecting)
is State.Waiting -> text_connection_status.text = getString(R.string.status_waiting, state.seconds) is State.Authenticating -> text_connection_status.text =
getString(R.string.status_authenticating)
is State.Disconnecting -> text_connection_status.text =
getString(R.string.status_disconnecting)
is State.Waiting -> text_connection_status.text =
getString(R.string.status_waiting, state.seconds)
} }
} }
} }
......
...@@ -17,15 +17,15 @@ import chat.rocket.common.util.ifNull ...@@ -17,15 +17,15 @@ import chat.rocket.common.util.ifNull
import chat.rocket.core.internal.realtime.socket.model.State import chat.rocket.core.internal.realtime.socket.model.State
import chat.rocket.core.internal.rest.spotlight import chat.rocket.core.internal.rest.spotlight
import chat.rocket.core.model.SpotlightResult import chat.rocket.core.model.SpotlightResult
import com.shopify.livedataktx.distinct
import com.shopify.livedataktx.map
import com.shopify.livedataktx.nonNull
import kotlinx.coroutines.experimental.android.UI import kotlinx.coroutines.experimental.android.UI
import kotlinx.coroutines.experimental.delay import kotlinx.coroutines.experimental.delay
import kotlinx.coroutines.experimental.isActive import kotlinx.coroutines.experimental.isActive
import kotlinx.coroutines.experimental.launch import kotlinx.coroutines.experimental.launch
import kotlinx.coroutines.experimental.newSingleThreadContext import kotlinx.coroutines.experimental.newSingleThreadContext
import kotlinx.coroutines.experimental.withContext import kotlinx.coroutines.experimental.withContext
import me.henrytao.livedataktx.distinct
import me.henrytao.livedataktx.map
import me.henrytao.livedataktx.nonNull
import timber.log.Timber import timber.log.Timber
import java.security.InvalidParameterException import java.security.InvalidParameterException
import kotlin.coroutines.experimental.coroutineContext import kotlin.coroutines.experimental.coroutineContext
......
...@@ -15,18 +15,17 @@ import androidx.recyclerview.widget.DividerItemDecoration ...@@ -15,18 +15,17 @@ import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.analytics.AnalyticsManager
import chat.rocket.android.analytics.event.ScreenViewEvent
import chat.rocket.android.createchannel.presentation.CreateChannelPresenter import chat.rocket.android.createchannel.presentation.CreateChannelPresenter
import chat.rocket.android.createchannel.presentation.CreateChannelView import chat.rocket.android.createchannel.presentation.CreateChannelView
import chat.rocket.android.main.ui.MainActivity import chat.rocket.android.main.ui.MainActivity
import chat.rocket.android.members.adapter.MembersAdapter import chat.rocket.android.members.adapter.MembersAdapter
import chat.rocket.android.members.uimodel.MemberUiModel import chat.rocket.android.members.uimodel.MemberUiModel
import chat.rocket.android.server.domain.AnalyticsTrackingInteractor
import chat.rocket.android.util.extension.asObservable import chat.rocket.android.util.extension.asObservable
import chat.rocket.android.util.extensions.inflate import chat.rocket.android.util.extensions.inflate
import chat.rocket.android.util.extensions.showToast import chat.rocket.android.util.extensions.showToast
import chat.rocket.android.util.extensions.ui import chat.rocket.android.util.extensions.ui
import chat.rocket.android.util.helper.analytics.AnalyticsManager
import chat.rocket.android.util.helper.analytics.event.ScreenViewEvent
import chat.rocket.common.model.RoomType import chat.rocket.common.model.RoomType
import chat.rocket.common.model.roomTypeOf import chat.rocket.common.model.roomTypeOf
import com.google.android.material.chip.Chip import com.google.android.material.chip.Chip
...@@ -43,7 +42,7 @@ class CreateChannelFragment : Fragment(), CreateChannelView, ActionMode.Callback ...@@ -43,7 +42,7 @@ class CreateChannelFragment : Fragment(), CreateChannelView, ActionMode.Callback
@Inject @Inject
lateinit var createChannelPresenter: CreateChannelPresenter lateinit var createChannelPresenter: CreateChannelPresenter
@Inject @Inject
lateinit var analyticsTrackingInteractor: AnalyticsTrackingInteractor lateinit var analyticsManager: AnalyticsManager
private var actionMode: ActionMode? = null private var actionMode: ActionMode? = null
private val adapter: MembersAdapter = MembersAdapter { private val adapter: MembersAdapter = MembersAdapter {
if (it.username != null) { if (it.username != null) {
...@@ -77,9 +76,7 @@ class CreateChannelFragment : Fragment(), CreateChannelView, ActionMode.Callback ...@@ -77,9 +76,7 @@ class CreateChannelFragment : Fragment(), CreateChannelView, ActionMode.Callback
setupRecyclerView() setupRecyclerView()
subscribeEditTexts() subscribeEditTexts()
if (analyticsTrackingInteractor.get()) { analyticsManager.logScreenView(ScreenViewEvent.CreateChannel)
AnalyticsManager.logScreenView(ScreenViewEvent.CreateChannel)
}
} }
override fun onDestroyView() { override fun onDestroyView() {
......
package chat.rocket.android.dagger package chat.rocket.android.dagger
import android.app.Application import android.app.Application
import chat.rocket.android.app.AppLifecycleObserver
import chat.rocket.android.app.RocketChatApplication import chat.rocket.android.app.RocketChatApplication
import chat.rocket.android.chatroom.service.MessageService import chat.rocket.android.chatroom.service.MessageService
import chat.rocket.android.dagger.module.ActivityBuilder import chat.rocket.android.dagger.module.ActivityBuilder
import chat.rocket.android.dagger.module.AndroidWorkerInjectionModule
import chat.rocket.android.dagger.module.AppModule import chat.rocket.android.dagger.module.AppModule
import chat.rocket.android.dagger.module.ReceiverBuilder import chat.rocket.android.dagger.module.ReceiverBuilder
import chat.rocket.android.dagger.module.ServiceBuilder import chat.rocket.android.dagger.module.ServiceBuilder
import chat.rocket.android.push.FirebaseTokenService
import dagger.BindsInstance import dagger.BindsInstance
import dagger.Component import dagger.Component
import dagger.android.support.AndroidSupportInjectionModule import dagger.android.support.AndroidSupportInjectionModule
...@@ -16,7 +15,8 @@ import javax.inject.Singleton ...@@ -16,7 +15,8 @@ import javax.inject.Singleton
@Singleton @Singleton
@Component(modules = [AndroidSupportInjectionModule::class, @Component(modules = [AndroidSupportInjectionModule::class,
AppModule::class, ActivityBuilder::class, ServiceBuilder::class, ReceiverBuilder::class]) AppModule::class, ActivityBuilder::class, ServiceBuilder::class, ReceiverBuilder::class,
AndroidWorkerInjectionModule::class])
interface AppComponent { interface AppComponent {
@Component.Builder @Component.Builder
...@@ -29,10 +29,5 @@ interface AppComponent { ...@@ -29,10 +29,5 @@ interface AppComponent {
fun inject(app: RocketChatApplication) fun inject(app: RocketChatApplication)
fun inject(service: FirebaseTokenService)
fun inject(service: MessageService) fun inject(service: MessageService)
/*@Component.Builder
abstract class Builder : AndroidInjector.Builder<RocketChatApplication>()*/
} }
package chat.rocket.android.dagger.injector
import androidx.work.Worker
object AndroidWorkerInjection {
fun inject(worker: Worker) {
val application = worker.applicationContext
if (application !is HasWorkerInjector) {
throw RuntimeException("${application.javaClass.canonicalName} does not implement ${HasWorkerInjector::class.java.canonicalName}")
}
val workerInjector = (application as HasWorkerInjector).workerInjector()
checkNotNull(workerInjector) { "${application.javaClass}.workerInjector() return null" }
workerInjector.inject(worker)
}
}
\ No newline at end of file
package chat.rocket.android.dagger.injector
import androidx.work.Worker
import dagger.android.AndroidInjector
interface HasWorkerInjector {
fun workerInjector(): AndroidInjector<Worker>
}
\ No newline at end of file
package chat.rocket.android.dagger.module package chat.rocket.android.dagger.module
import chat.rocket.android.about.di.AboutFragmentProvider
import chat.rocket.android.authentication.di.AuthenticationModule import chat.rocket.android.authentication.di.AuthenticationModule
import chat.rocket.android.authentication.login.di.LoginFragmentProvider import chat.rocket.android.authentication.login.di.LoginFragmentProvider
import chat.rocket.android.authentication.loginoptions.di.LoginOptionsFragmentProvider import chat.rocket.android.authentication.loginoptions.di.LoginOptionsFragmentProvider
...@@ -62,6 +63,7 @@ abstract class ActivityBuilder { ...@@ -62,6 +63,7 @@ abstract class ActivityBuilder {
CreateChannelProvider::class, CreateChannelProvider::class,
ProfileFragmentProvider::class, ProfileFragmentProvider::class,
SettingsFragmentProvider::class, SettingsFragmentProvider::class,
AboutFragmentProvider::class,
PreferencesFragmentProvider::class PreferencesFragmentProvider::class
] ]
) )
......
package chat.rocket.android.dagger.module
import androidx.work.Worker
import dagger.Module
import dagger.android.AndroidInjector
import dagger.multibindings.Multibinds
@Module
abstract class AndroidWorkerInjectionModule {
@Multibinds
abstract fun workerInjectorFactories(): Map<Class<out Worker>, AndroidInjector.Factory<out Worker>>
}
\ No newline at end of file
...@@ -9,6 +9,10 @@ import android.content.Context ...@@ -9,6 +9,10 @@ import android.content.Context
import android.content.SharedPreferences import android.content.SharedPreferences
import chat.rocket.android.BuildConfig import chat.rocket.android.BuildConfig
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.analytics.Analytics
import chat.rocket.android.analytics.AnalyticsManager
import chat.rocket.android.analytics.AnswersAnalytics
import chat.rocket.android.analytics.GoogleAnalyticsForFirebase
import chat.rocket.android.authentication.infraestructure.SharedPreferencesMultiServerTokenRepository import chat.rocket.android.authentication.infraestructure.SharedPreferencesMultiServerTokenRepository
import chat.rocket.android.authentication.infraestructure.SharedPreferencesTokenRepository import chat.rocket.android.authentication.infraestructure.SharedPreferencesTokenRepository
import chat.rocket.android.chatroom.service.MessageService import chat.rocket.android.chatroom.service.MessageService
...@@ -23,10 +27,12 @@ import chat.rocket.android.push.GroupedPush ...@@ -23,10 +27,12 @@ import chat.rocket.android.push.GroupedPush
import chat.rocket.android.push.PushManager import chat.rocket.android.push.PushManager
import chat.rocket.android.server.domain.AccountsRepository import chat.rocket.android.server.domain.AccountsRepository
import chat.rocket.android.server.domain.ActiveUsersRepository import chat.rocket.android.server.domain.ActiveUsersRepository
import chat.rocket.android.server.domain.AnalyticsTrackingInteractor
import chat.rocket.android.server.domain.AnalyticsTrackingRepository import chat.rocket.android.server.domain.AnalyticsTrackingRepository
import chat.rocket.android.server.domain.ChatRoomsRepository import chat.rocket.android.server.domain.ChatRoomsRepository
import chat.rocket.android.server.domain.CurrentServerRepository import chat.rocket.android.server.domain.CurrentServerRepository
import chat.rocket.android.server.domain.GetAccountInteractor import chat.rocket.android.server.domain.GetAccountInteractor
import chat.rocket.android.server.domain.GetAccountsInteractor
import chat.rocket.android.server.domain.GetCurrentServerInteractor import chat.rocket.android.server.domain.GetCurrentServerInteractor
import chat.rocket.android.server.domain.GetSettingsInteractor import chat.rocket.android.server.domain.GetSettingsInteractor
import chat.rocket.android.server.domain.JobSchedulerInteractor import chat.rocket.android.server.domain.JobSchedulerInteractor
...@@ -115,7 +121,10 @@ class AppModule { ...@@ -115,7 +121,10 @@ class AppModule {
@Provides @Provides
@Singleton @Singleton
fun provideImagePipelineConfig(context: Context, okHttpClient: OkHttpClient): ImagePipelineConfig { fun provideImagePipelineConfig(
context: Context,
okHttpClient: OkHttpClient
): ImagePipelineConfig {
val listeners = setOf(RequestLoggingListener()) val listeners = setOf(RequestLoggingListener())
return OkHttpImagePipelineConfigFactory.newBuilder(context, okHttpClient) return OkHttpImagePipelineConfigFactory.newBuilder(context, okHttpClient)
...@@ -185,7 +194,10 @@ class AppModule { ...@@ -185,7 +194,10 @@ class AppModule {
@Provides @Provides
@Singleton @Singleton
fun providePermissionsRepository(localRepository: LocalRepository, moshi: Moshi): PermissionsRepository { fun providePermissionsRepository(
localRepository: LocalRepository,
moshi: Moshi
): PermissionsRepository {
return SharedPreferencesPermissionsRepository(localRepository, moshi) return SharedPreferencesPermissionsRepository(localRepository, moshi)
} }
...@@ -234,15 +246,20 @@ class AppModule { ...@@ -234,15 +246,20 @@ class AppModule {
@Provides @Provides
@Singleton @Singleton
fun provideMultiServerTokenRepository(repository: LocalRepository, moshi: Moshi): MultiServerTokenRepository { fun provideMultiServerTokenRepository(
repository: LocalRepository,
moshi: Moshi
): MultiServerTokenRepository {
return SharedPreferencesMultiServerTokenRepository(repository, moshi) return SharedPreferencesMultiServerTokenRepository(repository, moshi)
} }
@Provides @Provides
@Singleton @Singleton
fun provideMessageRepository(@ForMessages preferences: SharedPreferences, fun provideMessageRepository(
moshi: Moshi, @ForMessages preferences: SharedPreferences,
currentServerInteractor: GetCurrentServerInteractor): MessagesRepository { moshi: Moshi,
currentServerInteractor: GetCurrentServerInteractor
): MessagesRepository {
return SharedPreferencesMessagesRepository(preferences, moshi, currentServerInteractor) return SharedPreferencesMessagesRepository(preferences, moshi, currentServerInteractor)
} }
...@@ -257,10 +274,12 @@ class AppModule { ...@@ -257,10 +274,12 @@ class AppModule {
fun provideConfiguration(context: Application): SpannableConfiguration { fun provideConfiguration(context: Application): SpannableConfiguration {
val res = context.resources val res = context.resources
return SpannableConfiguration.builder(context) return SpannableConfiguration.builder(context)
.theme(SpannableTheme.builder() .theme(
.blockMargin(0) SpannableTheme.builder()
.linkColor(res.getColor(R.color.colorAccent)) .blockMargin(0)
.build()) .linkColor(res.getColor(R.color.colorAccent))
.build()
)
.build() .build()
} }
...@@ -277,7 +296,10 @@ class AppModule { ...@@ -277,7 +296,10 @@ class AppModule {
@Provides @Provides
@Singleton @Singleton
fun provideAccountsRepository(preferences: SharedPreferences, moshi: Moshi): AccountsRepository = fun provideAccountsRepository(
preferences: SharedPreferences,
moshi: Moshi
): AccountsRepository =
SharedPreferencesAccountsRepository(preferences, moshi) SharedPreferencesAccountsRepository(preferences, moshi)
@Provides @Provides
...@@ -296,8 +318,16 @@ class AppModule { ...@@ -296,8 +318,16 @@ class AppModule {
manager: NotificationManager, manager: NotificationManager,
moshi: Moshi, moshi: Moshi,
getAccountInteractor: GetAccountInteractor, getAccountInteractor: GetAccountInteractor,
getSettingsInteractor: GetSettingsInteractor): PushManager { getSettingsInteractor: GetSettingsInteractor
return PushManager(groupedPushes, manager, moshi, getAccountInteractor, getSettingsInteractor, context) ): PushManager {
return PushManager(
groupedPushes,
manager,
moshi,
getAccountInteractor,
getSettingsInteractor,
context
)
} }
@Provides @Provides
...@@ -307,14 +337,19 @@ class AppModule { ...@@ -307,14 +337,19 @@ class AppModule {
@Provides @Provides
fun provideSendMessageJob(context: Application): JobInfo { fun provideSendMessageJob(context: Application): JobInfo {
return JobInfo.Builder(MessageService.RETRY_SEND_MESSAGE_ID, return JobInfo.Builder(
ComponentName(context, MessageService::class.java)) MessageService.RETRY_SEND_MESSAGE_ID,
ComponentName(context, MessageService::class.java)
)
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY) .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
.build() .build()
} }
@Provides @Provides
fun provideJobSchedulerInteractor(jobScheduler: JobScheduler, jobInfo: JobInfo): JobSchedulerInteractor { fun provideJobSchedulerInteractor(
jobScheduler: JobScheduler,
jobInfo: JobInfo
): JobSchedulerInteractor {
return JobSchedulerInteractorImpl(jobScheduler, jobInfo) return JobSchedulerInteractorImpl(jobScheduler, jobInfo)
} }
...@@ -331,4 +366,33 @@ class AppModule { ...@@ -331,4 +366,33 @@ class AppModule {
): DatabaseManager { ): DatabaseManager {
return factory.create(currentServer) return factory.create(currentServer)
} }
@Provides
@Singleton
fun provideAnswersAnalytics(): AnswersAnalytics {
return AnswersAnalytics()
}
@Provides
@Singleton
fun provideGoogleAnalyticsForFirebase(context: Application): GoogleAnalyticsForFirebase {
return GoogleAnalyticsForFirebase(context)
}
@Provides
@Singleton
fun provideAnalyticsManager(
analyticsTrackingInteractor: AnalyticsTrackingInteractor,
getCurrentServerInteractor: GetCurrentServerInteractor,
getAccountsInteractor: GetAccountsInteractor,
answersAnalytics: AnswersAnalytics,
googleAnalyticsForFirebase: GoogleAnalyticsForFirebase
): AnalyticsManager {
return AnalyticsManager(
analyticsTrackingInteractor,
getCurrentServerInteractor,
getAccountsInteractor,
listOf(answersAnalytics, googleAnalyticsForFirebase)
)
}
} }
package chat.rocket.android.dagger.qualifier
import androidx.work.Worker
import dagger.MapKey
import kotlin.reflect.KClass
@MapKey
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.FUNCTION)
annotation class WorkerKey(val value: KClass<out Worker>)
...@@ -10,18 +10,17 @@ import androidx.recyclerview.widget.DefaultItemAnimator ...@@ -10,18 +10,17 @@ import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.analytics.AnalyticsManager
import chat.rocket.android.analytics.event.ScreenViewEvent
import chat.rocket.android.chatroom.adapter.ChatRoomAdapter import chat.rocket.android.chatroom.adapter.ChatRoomAdapter
import chat.rocket.android.chatroom.ui.ChatRoomActivity import chat.rocket.android.chatroom.ui.ChatRoomActivity
import chat.rocket.android.chatroom.uimodel.BaseUiModel import chat.rocket.android.chatroom.uimodel.BaseUiModel
import chat.rocket.android.favoritemessages.presentation.FavoriteMessagesPresenter import chat.rocket.android.favoritemessages.presentation.FavoriteMessagesPresenter
import chat.rocket.android.favoritemessages.presentation.FavoriteMessagesView import chat.rocket.android.favoritemessages.presentation.FavoriteMessagesView
import chat.rocket.android.helper.EndlessRecyclerViewScrollListener import chat.rocket.android.helper.EndlessRecyclerViewScrollListener
import chat.rocket.android.server.domain.AnalyticsTrackingInteractor
import chat.rocket.android.util.extensions.inflate import chat.rocket.android.util.extensions.inflate
import chat.rocket.android.util.extensions.showToast import chat.rocket.android.util.extensions.showToast
import chat.rocket.android.util.extensions.ui import chat.rocket.android.util.extensions.ui
import chat.rocket.android.util.helper.analytics.AnalyticsManager
import chat.rocket.android.util.helper.analytics.event.ScreenViewEvent
import dagger.android.support.AndroidSupportInjection import dagger.android.support.AndroidSupportInjection
import kotlinx.android.synthetic.main.fragment_favorite_messages.* import kotlinx.android.synthetic.main.fragment_favorite_messages.*
import javax.inject.Inject import javax.inject.Inject
...@@ -41,7 +40,7 @@ class FavoriteMessagesFragment : Fragment(), FavoriteMessagesView { ...@@ -41,7 +40,7 @@ class FavoriteMessagesFragment : Fragment(), FavoriteMessagesView {
@Inject @Inject
lateinit var presenter: FavoriteMessagesPresenter lateinit var presenter: FavoriteMessagesPresenter
@Inject @Inject
lateinit var analyticsTrackingInteractor: AnalyticsTrackingInteractor lateinit var analyticsManager: AnalyticsManager
private lateinit var chatRoomId: String private lateinit var chatRoomId: String
private val adapter = ChatRoomAdapter(enableActions = false) private val adapter = ChatRoomAdapter(enableActions = false)
...@@ -68,9 +67,7 @@ class FavoriteMessagesFragment : Fragment(), FavoriteMessagesView { ...@@ -68,9 +67,7 @@ class FavoriteMessagesFragment : Fragment(), FavoriteMessagesView {
setupToolbar() setupToolbar()
presenter.loadFavoriteMessages(chatRoomId) presenter.loadFavoriteMessages(chatRoomId)
if (analyticsTrackingInteractor.get()) { analyticsManager.logScreenView(ScreenViewEvent.FavoriteMessages)
AnalyticsManager.logScreenView(ScreenViewEvent.FavoriteMessages)
}
} }
override fun showFavoriteMessages(favoriteMessages: List<BaseUiModel<*>>) { override fun showFavoriteMessages(favoriteMessages: List<BaseUiModel<*>>) {
......
...@@ -13,6 +13,8 @@ import androidx.recyclerview.widget.DividerItemDecoration.HORIZONTAL ...@@ -13,6 +13,8 @@ import androidx.recyclerview.widget.DividerItemDecoration.HORIZONTAL
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.analytics.AnalyticsManager
import chat.rocket.android.analytics.event.ScreenViewEvent
import chat.rocket.android.chatroom.ui.ChatRoomActivity import chat.rocket.android.chatroom.ui.ChatRoomActivity
import chat.rocket.android.files.adapter.FilesAdapter import chat.rocket.android.files.adapter.FilesAdapter
import chat.rocket.android.files.presentation.FilesPresenter import chat.rocket.android.files.presentation.FilesPresenter
...@@ -21,12 +23,9 @@ import chat.rocket.android.files.uimodel.FileUiModel ...@@ -21,12 +23,9 @@ import chat.rocket.android.files.uimodel.FileUiModel
import chat.rocket.android.helper.EndlessRecyclerViewScrollListener import chat.rocket.android.helper.EndlessRecyclerViewScrollListener
import chat.rocket.android.helper.ImageHelper import chat.rocket.android.helper.ImageHelper
import chat.rocket.android.player.PlayerActivity import chat.rocket.android.player.PlayerActivity
import chat.rocket.android.server.domain.AnalyticsTrackingInteractor
import chat.rocket.android.util.extensions.inflate import chat.rocket.android.util.extensions.inflate
import chat.rocket.android.util.extensions.showToast import chat.rocket.android.util.extensions.showToast
import chat.rocket.android.util.extensions.ui import chat.rocket.android.util.extensions.ui
import chat.rocket.android.util.helper.analytics.AnalyticsManager
import chat.rocket.android.util.helper.analytics.event.ScreenViewEvent
import dagger.android.support.AndroidSupportInjection import dagger.android.support.AndroidSupportInjection
import kotlinx.android.synthetic.main.fragment_files.* import kotlinx.android.synthetic.main.fragment_files.*
import javax.inject.Inject import javax.inject.Inject
...@@ -46,7 +45,7 @@ class FilesFragment : Fragment(), FilesView { ...@@ -46,7 +45,7 @@ class FilesFragment : Fragment(), FilesView {
@Inject @Inject
lateinit var presenter: FilesPresenter lateinit var presenter: FilesPresenter
@Inject @Inject
lateinit var analyticsTrackingInteractor: AnalyticsTrackingInteractor lateinit var analyticsManager: AnalyticsManager
private val adapter: FilesAdapter = private val adapter: FilesAdapter =
FilesAdapter { fileUiModel -> presenter.openFile(fileUiModel) } FilesAdapter { fileUiModel -> presenter.openFile(fileUiModel) }
private val linearLayoutManager = LinearLayoutManager(context) private val linearLayoutManager = LinearLayoutManager(context)
...@@ -75,31 +74,30 @@ class FilesFragment : Fragment(), FilesView { ...@@ -75,31 +74,30 @@ class FilesFragment : Fragment(), FilesView {
setupRecyclerView() setupRecyclerView()
presenter.loadFiles(chatRoomId) presenter.loadFiles(chatRoomId)
if (analyticsTrackingInteractor.get()) { analyticsManager.logScreenView(ScreenViewEvent.Files)
AnalyticsManager.logScreenView(ScreenViewEvent.Files)
}
} }
override fun showFiles(dataSet: List<FileUiModel>, total: Long) { override fun showFiles(dataSet: List<FileUiModel>, total: Long) {
setupToolbar(total) ui {
if (adapter.itemCount == 0) { setupToolbar(total)
adapter.prependData(dataSet) if (adapter.itemCount == 0) {
if (dataSet.size >= 30) { adapter.prependData(dataSet)
recycler_view.addOnScrollListener(object : if (dataSet.size >= 30) {
EndlessRecyclerViewScrollListener(linearLayoutManager) { recycler_view.addOnScrollListener(object :
override fun onLoadMore( EndlessRecyclerViewScrollListener(linearLayoutManager) {
page: Int, override fun onLoadMore(
totalItemsCount: Int, page: Int,
recyclerView: RecyclerView totalItemsCount: Int,
) { recyclerView: RecyclerView
presenter.loadFiles(chatRoomId) ) {
} presenter.loadFiles(chatRoomId)
}) }
})
}
group_no_file.isVisible = dataSet.isEmpty()
} else {
adapter.appendData(dataSet)
} }
group_no_file.isVisible = dataSet.isEmpty()
} else {
adapter.appendData(dataSet)
} }
} }
......
...@@ -34,8 +34,8 @@ class FileUiModel( ...@@ -34,8 +34,8 @@ class FileUiModel(
} }
private fun getUserDisplayName(): String { private fun getUserDisplayName(): String {
val username = "@${genericAttachment.user?.username}" val username = "@${genericAttachment.user.username}"
val realName = genericAttachment.user?.name val realName = genericAttachment.user.name
val uploaderName = if (settings.useRealName()) realName else username val uploaderName = if (settings.useRealName()) realName else username
return uploaderName ?: username return uploaderName ?: username
} }
......
...@@ -131,7 +131,7 @@ class MessageParser @Inject constructor( ...@@ -131,7 +131,7 @@ class MessageParser @Inject constructor(
private val builder: SpannableBuilder private val builder: SpannableBuilder
) : SpannableMarkdownVisitor(configuration, builder) { ) : SpannableMarkdownVisitor(configuration, builder) {
private val emojiSize = context.resources.getDimensionPixelSize(R.dimen.radius_mention) private val emojiSize = context.resources.getDimensionPixelSize(R.dimen.custom_emoji_small)
override fun visit(document: Document) { override fun visit(document: Document) {
val spannable = EmojiParser.parse(context, builder.text()) val spannable = EmojiParser.parse(context, builder.text())
......
...@@ -27,7 +27,6 @@ import chat.rocket.android.server.infraestructure.RocketChatClientFactory ...@@ -27,7 +27,6 @@ import chat.rocket.android.server.infraestructure.RocketChatClientFactory
import chat.rocket.android.server.presentation.CheckServerPresenter import chat.rocket.android.server.presentation.CheckServerPresenter
import chat.rocket.android.util.extension.launchUI import chat.rocket.android.util.extension.launchUI
import chat.rocket.android.util.extensions.adminPanelUrl import chat.rocket.android.util.extensions.adminPanelUrl
import chat.rocket.android.util.extensions.registerPushToken
import chat.rocket.android.util.extensions.serverLogoUrl import chat.rocket.android.util.extensions.serverLogoUrl
import chat.rocket.android.util.retryIO import chat.rocket.android.util.retryIO
import chat.rocket.common.RocketChatAuthException import chat.rocket.common.RocketChatAuthException
...@@ -59,7 +58,7 @@ class MainPresenter @Inject constructor( ...@@ -59,7 +58,7 @@ class MainPresenter @Inject constructor(
private val saveAccountInteractor: SaveAccountInteractor, private val saveAccountInteractor: SaveAccountInteractor,
private val getAccountsInteractor: GetAccountsInteractor, private val getAccountsInteractor: GetAccountsInteractor,
private val removeAccountInteractor: RemoveAccountInteractor, private val removeAccountInteractor: RemoveAccountInteractor,
private val factory: RocketChatClientFactory, factory: RocketChatClientFactory,
private val groupedPush: GroupedPush, private val groupedPush: GroupedPush,
dbManagerFactory: DatabaseManagerFactory, dbManagerFactory: DatabaseManagerFactory,
getSettingsInteractor: GetSettingsInteractor, getSettingsInteractor: GetSettingsInteractor,
...@@ -233,13 +232,6 @@ class MainPresenter @Inject constructor( ...@@ -233,13 +232,6 @@ class MainPresenter @Inject constructor(
} }
} }
suspend fun refreshToken(token: String?) {
token?.let {
localRepository.save(LocalRepository.KEY_PUSH_TOKEN, token)
client.registerPushToken(token, getAccountsInteractor.get(), factory)
}
}
private suspend fun saveAccount(uiModel: NavHeaderUiModel) { private suspend fun saveAccount(uiModel: NavHeaderUiModel) {
val icon = settings.favicon()?.let { val icon = settings.favicon()?.let {
currentServer.serverLogoUrl(it) currentServer.serverLogoUrl(it)
......
...@@ -18,6 +18,7 @@ import chat.rocket.android.main.adapter.Selector ...@@ -18,6 +18,7 @@ import chat.rocket.android.main.adapter.Selector
import chat.rocket.android.main.presentation.MainPresenter import chat.rocket.android.main.presentation.MainPresenter
import chat.rocket.android.main.presentation.MainView import chat.rocket.android.main.presentation.MainView
import chat.rocket.android.main.uimodel.NavHeaderUiModel import chat.rocket.android.main.uimodel.NavHeaderUiModel
import chat.rocket.android.push.refreshPushToken
import chat.rocket.android.server.domain.PermissionsInteractor import chat.rocket.android.server.domain.PermissionsInteractor
import chat.rocket.android.server.domain.model.Account import chat.rocket.android.server.domain.model.Account
import chat.rocket.android.server.ui.INTENT_CHAT_ROOM_ID import chat.rocket.android.server.ui.INTENT_CHAT_ROOM_ID
...@@ -26,7 +27,6 @@ import chat.rocket.android.util.extensions.fadeOut ...@@ -26,7 +27,6 @@ import chat.rocket.android.util.extensions.fadeOut
import chat.rocket.android.util.extensions.rotateBy import chat.rocket.android.util.extensions.rotateBy
import chat.rocket.android.util.extensions.showToast import chat.rocket.android.util.extensions.showToast
import chat.rocket.android.util.invalidateFirebaseToken import chat.rocket.android.util.invalidateFirebaseToken
import chat.rocket.android.util.refreshFCMToken
import chat.rocket.common.model.UserStatus import chat.rocket.common.model.UserStatus
import dagger.android.AndroidInjection import dagger.android.AndroidInjection
import dagger.android.AndroidInjector import dagger.android.AndroidInjector
...@@ -36,9 +36,6 @@ import dagger.android.support.HasSupportFragmentInjector ...@@ -36,9 +36,6 @@ import dagger.android.support.HasSupportFragmentInjector
import kotlinx.android.synthetic.main.activity_main.* import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.app_bar.* import kotlinx.android.synthetic.main.app_bar.*
import kotlinx.android.synthetic.main.nav_header.view.* import kotlinx.android.synthetic.main.nav_header.view.*
import kotlinx.coroutines.experimental.CommonPool
import kotlinx.coroutines.experimental.launch
import timber.log.Timber
import javax.inject.Inject import javax.inject.Inject
private const val CURRENT_STATE = "current_state" private const val CURRENT_STATE = "current_state"
...@@ -64,9 +61,7 @@ class MainActivity : AppCompatActivity(), MainView, HasActivityInjector, ...@@ -64,9 +61,7 @@ class MainActivity : AppCompatActivity(), MainView, HasActivityInjector,
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main) setContentView(R.layout.activity_main)
launch(CommonPool) { refreshPushToken()
refreshFCMToken(presenter)
}
chatRoomId = intent.getStringExtra(INTENT_CHAT_ROOM_ID) chatRoomId = intent.getStringExtra(INTENT_CHAT_ROOM_ID)
......
...@@ -2,6 +2,7 @@ package chat.rocket.android.members.di ...@@ -2,6 +2,7 @@ package chat.rocket.android.members.di
import chat.rocket.android.members.ui.MembersFragment import chat.rocket.android.members.ui.MembersFragment
import chat.rocket.android.dagger.scope.PerFragment import chat.rocket.android.dagger.scope.PerFragment
import chat.rocket.android.members.ui.MemberBottomSheetFragment
import dagger.Module import dagger.Module
import dagger.android.ContributesAndroidInjector import dagger.android.ContributesAndroidInjector
...@@ -11,4 +12,9 @@ abstract class MembersFragmentProvider { ...@@ -11,4 +12,9 @@ abstract class MembersFragmentProvider {
@ContributesAndroidInjector(modules = [MembersFragmentModule::class]) @ContributesAndroidInjector(modules = [MembersFragmentModule::class])
@PerFragment @PerFragment
abstract fun provideMembersFragment(): MembersFragment abstract fun provideMembersFragment(): MembersFragment
@ContributesAndroidInjector()
@PerFragment
abstract fun provideMemberBottomSheetFragment(): MemberBottomSheetFragment
} }
\ No newline at end of file
...@@ -6,12 +6,12 @@ import android.view.View ...@@ -6,12 +6,12 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.core.view.isVisible import androidx.core.view.isVisible
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.server.domain.AnalyticsTrackingInteractor import chat.rocket.android.analytics.AnalyticsManager
import chat.rocket.android.analytics.event.ScreenViewEvent
import chat.rocket.android.util.extensions.content import chat.rocket.android.util.extensions.content
import chat.rocket.android.util.extensions.textContent import chat.rocket.android.util.extensions.textContent
import chat.rocket.android.util.helper.analytics.AnalyticsManager
import chat.rocket.android.util.helper.analytics.event.ScreenViewEvent
import com.google.android.material.bottomsheet.BottomSheetDialogFragment import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import dagger.android.support.AndroidSupportInjection
import kotlinx.android.synthetic.main.fragment_member_bottom_sheet.* import kotlinx.android.synthetic.main.fragment_member_bottom_sheet.*
import javax.inject.Inject import javax.inject.Inject
...@@ -43,7 +43,7 @@ private const val BUNDLE_UTC_OFFSET = "utc_offset" ...@@ -43,7 +43,7 @@ private const val BUNDLE_UTC_OFFSET = "utc_offset"
class MemberBottomSheetFragment : BottomSheetDialogFragment() { class MemberBottomSheetFragment : BottomSheetDialogFragment() {
@Inject @Inject
lateinit var analyticsTrackingInteractor: AnalyticsTrackingInteractor lateinit var analyticsManager: AnalyticsManager
private lateinit var avatarUri: String private lateinit var avatarUri: String
private lateinit var realName: String private lateinit var realName: String
private lateinit var username: String private lateinit var username: String
...@@ -52,6 +52,7 @@ class MemberBottomSheetFragment : BottomSheetDialogFragment() { ...@@ -52,6 +52,7 @@ class MemberBottomSheetFragment : BottomSheetDialogFragment() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
AndroidSupportInjection.inject(this)
val bundle = arguments val bundle = arguments
if (bundle != null) { if (bundle != null) {
...@@ -76,9 +77,7 @@ class MemberBottomSheetFragment : BottomSheetDialogFragment() { ...@@ -76,9 +77,7 @@ class MemberBottomSheetFragment : BottomSheetDialogFragment() {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
showMemberDetails() showMemberDetails()
if (analyticsTrackingInteractor.get()) { analyticsManager.logScreenView(ScreenViewEvent.MemberBottomSheet)
AnalyticsManager.logScreenView(ScreenViewEvent.MemberBottomSheet)
}
} }
private fun showMemberDetails() { private fun showMemberDetails() {
......
package chat.rocket.android.members.ui package chat.rocket.android.members.ui
import android.os.Bundle import android.os.Bundle
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.analytics.AnalyticsManager
import chat.rocket.android.analytics.event.ScreenViewEvent
import chat.rocket.android.chatroom.ui.ChatRoomActivity import chat.rocket.android.chatroom.ui.ChatRoomActivity
import chat.rocket.android.helper.EndlessRecyclerViewScrollListener import chat.rocket.android.helper.EndlessRecyclerViewScrollListener
import chat.rocket.android.members.adapter.MembersAdapter import chat.rocket.android.members.adapter.MembersAdapter
import chat.rocket.android.members.presentation.MembersPresenter import chat.rocket.android.members.presentation.MembersPresenter
import chat.rocket.android.members.presentation.MembersView import chat.rocket.android.members.presentation.MembersView
import chat.rocket.android.members.uimodel.MemberUiModel import chat.rocket.android.members.uimodel.MemberUiModel
import chat.rocket.android.server.domain.AnalyticsTrackingInteractor
import chat.rocket.android.util.extensions.inflate import chat.rocket.android.util.extensions.inflate
import chat.rocket.android.util.extensions.showToast import chat.rocket.android.util.extensions.showToast
import chat.rocket.android.util.extensions.ui import chat.rocket.android.util.extensions.ui
import chat.rocket.android.util.helper.analytics.AnalyticsManager
import chat.rocket.android.util.helper.analytics.event.ScreenViewEvent
import dagger.android.support.AndroidSupportInjection import dagger.android.support.AndroidSupportInjection
import kotlinx.android.synthetic.main.fragment_members.* import kotlinx.android.synthetic.main.fragment_members.*
import javax.inject.Inject import javax.inject.Inject
...@@ -41,7 +40,7 @@ class MembersFragment : Fragment(), MembersView { ...@@ -41,7 +40,7 @@ class MembersFragment : Fragment(), MembersView {
@Inject @Inject
lateinit var presenter: MembersPresenter lateinit var presenter: MembersPresenter
@Inject @Inject
lateinit var analyticsTrackingInteractor: AnalyticsTrackingInteractor lateinit var analyticsManager: AnalyticsManager
private val adapter: MembersAdapter = private val adapter: MembersAdapter =
MembersAdapter { memberUiModel -> presenter.toMemberDetails(memberUiModel) } MembersAdapter { memberUiModel -> presenter.toMemberDetails(memberUiModel) }
private val linearLayoutManager = LinearLayoutManager(context) private val linearLayoutManager = LinearLayoutManager(context)
...@@ -70,9 +69,7 @@ class MembersFragment : Fragment(), MembersView { ...@@ -70,9 +69,7 @@ class MembersFragment : Fragment(), MembersView {
setupRecyclerView() setupRecyclerView()
presenter.loadChatRoomsMembers(chatRoomId) presenter.loadChatRoomsMembers(chatRoomId)
if (analyticsTrackingInteractor.get()) { analyticsManager.logScreenView(ScreenViewEvent.Members)
AnalyticsManager.logScreenView(ScreenViewEvent.Members)
}
} }
override fun showMembers(dataSet: List<MemberUiModel>, total: Long) { override fun showMembers(dataSet: List<MemberUiModel>, total: Long) {
......
...@@ -10,18 +10,17 @@ import androidx.recyclerview.widget.DefaultItemAnimator ...@@ -10,18 +10,17 @@ import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.analytics.AnalyticsManager
import chat.rocket.android.analytics.event.ScreenViewEvent
import chat.rocket.android.chatroom.adapter.ChatRoomAdapter import chat.rocket.android.chatroom.adapter.ChatRoomAdapter
import chat.rocket.android.chatroom.ui.ChatRoomActivity import chat.rocket.android.chatroom.ui.ChatRoomActivity
import chat.rocket.android.chatroom.uimodel.BaseUiModel import chat.rocket.android.chatroom.uimodel.BaseUiModel
import chat.rocket.android.helper.EndlessRecyclerViewScrollListener import chat.rocket.android.helper.EndlessRecyclerViewScrollListener
import chat.rocket.android.mentions.presentention.MentionsPresenter import chat.rocket.android.mentions.presentention.MentionsPresenter
import chat.rocket.android.mentions.presentention.MentionsView import chat.rocket.android.mentions.presentention.MentionsView
import chat.rocket.android.server.domain.AnalyticsTrackingInteractor
import chat.rocket.android.util.extensions.inflate import chat.rocket.android.util.extensions.inflate
import chat.rocket.android.util.extensions.showToast import chat.rocket.android.util.extensions.showToast
import chat.rocket.android.util.extensions.ui import chat.rocket.android.util.extensions.ui
import chat.rocket.android.util.helper.analytics.AnalyticsManager
import chat.rocket.android.util.helper.analytics.event.ScreenViewEvent
import dagger.android.support.AndroidSupportInjection import dagger.android.support.AndroidSupportInjection
import kotlinx.android.synthetic.main.fragment_mentions.* import kotlinx.android.synthetic.main.fragment_mentions.*
import javax.inject.Inject import javax.inject.Inject
...@@ -44,7 +43,7 @@ class MentionsFragment : Fragment(), MentionsView { ...@@ -44,7 +43,7 @@ class MentionsFragment : Fragment(), MentionsView {
@Inject @Inject
lateinit var presenter: MentionsPresenter lateinit var presenter: MentionsPresenter
@Inject @Inject
lateinit var analyticsTrackingInteractor: AnalyticsTrackingInteractor lateinit var analyticsManager: AnalyticsManager
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
...@@ -70,9 +69,7 @@ class MentionsFragment : Fragment(), MentionsView { ...@@ -70,9 +69,7 @@ class MentionsFragment : Fragment(), MentionsView {
setupToolbar() setupToolbar()
presenter.loadMentions(chatRoomId) presenter.loadMentions(chatRoomId)
if (analyticsTrackingInteractor.get()) { analyticsManager.logScreenView(ScreenViewEvent.Mentions)
AnalyticsManager.logScreenView(ScreenViewEvent.Mentions)
}
} }
override fun showMentions(mentions: List<BaseUiModel<*>>) { override fun showMentions(mentions: List<BaseUiModel<*>>) {
......
...@@ -10,6 +10,8 @@ import androidx.recyclerview.widget.DefaultItemAnimator ...@@ -10,6 +10,8 @@ import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.analytics.AnalyticsManager
import chat.rocket.android.analytics.event.ScreenViewEvent
import chat.rocket.android.chatroom.adapter.ChatRoomAdapter import chat.rocket.android.chatroom.adapter.ChatRoomAdapter
import chat.rocket.android.chatroom.ui.ChatRoomActivity import chat.rocket.android.chatroom.ui.ChatRoomActivity
import chat.rocket.android.chatroom.uimodel.BaseUiModel import chat.rocket.android.chatroom.uimodel.BaseUiModel
...@@ -20,8 +22,6 @@ import chat.rocket.android.server.domain.AnalyticsTrackingInteractor ...@@ -20,8 +22,6 @@ import chat.rocket.android.server.domain.AnalyticsTrackingInteractor
import chat.rocket.android.util.extensions.inflate import chat.rocket.android.util.extensions.inflate
import chat.rocket.android.util.extensions.showToast import chat.rocket.android.util.extensions.showToast
import chat.rocket.android.util.extensions.ui import chat.rocket.android.util.extensions.ui
import chat.rocket.android.util.helper.analytics.AnalyticsManager
import chat.rocket.android.util.helper.analytics.event.ScreenViewEvent
import dagger.android.support.AndroidSupportInjection import dagger.android.support.AndroidSupportInjection
import kotlinx.android.synthetic.main.fragment_pinned_messages.* import kotlinx.android.synthetic.main.fragment_pinned_messages.*
import javax.inject.Inject import javax.inject.Inject
...@@ -41,7 +41,7 @@ class PinnedMessagesFragment : Fragment(), PinnedMessagesView { ...@@ -41,7 +41,7 @@ class PinnedMessagesFragment : Fragment(), PinnedMessagesView {
@Inject @Inject
lateinit var presenter: PinnedMessagesPresenter lateinit var presenter: PinnedMessagesPresenter
@Inject @Inject
lateinit var analyticsTrackingInteractor: AnalyticsTrackingInteractor lateinit var analyticsManager: AnalyticsManager
private lateinit var chatRoomId: String private lateinit var chatRoomId: String
private val adapter = ChatRoomAdapter(enableActions = false) private val adapter = ChatRoomAdapter(enableActions = false)
...@@ -69,9 +69,7 @@ class PinnedMessagesFragment : Fragment(), PinnedMessagesView { ...@@ -69,9 +69,7 @@ class PinnedMessagesFragment : Fragment(), PinnedMessagesView {
setupToolbar() setupToolbar()
presenter.loadPinnedMessages(chatRoomId) presenter.loadPinnedMessages(chatRoomId)
if (analyticsTrackingInteractor.get()) { analyticsManager.logScreenView(ScreenViewEvent.PinnedMessages)
AnalyticsManager.logScreenView(ScreenViewEvent.PinnedMessages)
}
} }
override fun showPinnedMessages(pinnedMessages: List<BaseUiModel<*>>) { override fun showPinnedMessages(pinnedMessages: List<BaseUiModel<*>>) {
......
...@@ -7,12 +7,11 @@ import android.view.ViewGroup ...@@ -7,12 +7,11 @@ import android.view.ViewGroup
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import chat.rocket.android.BuildConfig import chat.rocket.android.BuildConfig
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.analytics.AnalyticsManager
import chat.rocket.android.analytics.event.ScreenViewEvent
import chat.rocket.android.main.ui.MainActivity import chat.rocket.android.main.ui.MainActivity
import chat.rocket.android.preferences.presentation.PreferencesPresenter import chat.rocket.android.preferences.presentation.PreferencesPresenter
import chat.rocket.android.preferences.presentation.PreferencesView import chat.rocket.android.preferences.presentation.PreferencesView
import chat.rocket.android.server.domain.AnalyticsTrackingInteractor
import chat.rocket.android.util.helper.analytics.AnalyticsManager
import chat.rocket.android.util.helper.analytics.event.ScreenViewEvent
import dagger.android.support.AndroidSupportInjection import dagger.android.support.AndroidSupportInjection
import kotlinx.android.synthetic.main.app_bar.* import kotlinx.android.synthetic.main.app_bar.*
import kotlinx.android.synthetic.main.fragment_preferences.* import kotlinx.android.synthetic.main.fragment_preferences.*
...@@ -24,7 +23,7 @@ class PreferencesFragment : Fragment(), PreferencesView { ...@@ -24,7 +23,7 @@ class PreferencesFragment : Fragment(), PreferencesView {
@Inject @Inject
lateinit var presenter: PreferencesPresenter lateinit var presenter: PreferencesPresenter
@Inject @Inject
lateinit var analyticsTrackingInteractor: AnalyticsTrackingInteractor lateinit var analyticsManager: AnalyticsManager
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
...@@ -43,17 +42,15 @@ class PreferencesFragment : Fragment(), PreferencesView { ...@@ -43,17 +42,15 @@ class PreferencesFragment : Fragment(), PreferencesView {
setupListeners() setupListeners()
presenter.loadAnalyticsTrackingInformation() presenter.loadAnalyticsTrackingInformation()
if (analyticsTrackingInteractor.get()) { analyticsManager.logScreenView(ScreenViewEvent.Preferences)
AnalyticsManager.logScreenView(ScreenViewEvent.Preferences)
}
} }
override fun setupAnalyticsTrackingView(isAnalyticsTrackingEnabled: Boolean) { override fun setupAnalyticsTrackingView(isAnalyticsTrackingEnabled: Boolean) {
if (BuildConfig.FLAVOR == "foss") { if (BuildConfig.FLAVOR == "foss") {
text_analytics_tracking_description.text =
getString(R.string.msg_not_applicable_since_it_is_a_foss_version)
switch_analytics_tracking.isChecked = false switch_analytics_tracking.isChecked = false
switch_analytics_tracking.isEnabled = false switch_analytics_tracking.isEnabled = false
text_analytics_tracking_description.text =
getString(R.string.msg_not_applicable_since_it_is_a_foss_version)
return return
} }
......
...@@ -17,10 +17,11 @@ import androidx.core.net.toUri ...@@ -17,10 +17,11 @@ import androidx.core.net.toUri
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.analytics.AnalyticsManager
import chat.rocket.android.analytics.event.ScreenViewEvent
import chat.rocket.android.main.ui.MainActivity import chat.rocket.android.main.ui.MainActivity
import chat.rocket.android.profile.presentation.ProfilePresenter import chat.rocket.android.profile.presentation.ProfilePresenter
import chat.rocket.android.profile.presentation.ProfileView import chat.rocket.android.profile.presentation.ProfileView
import chat.rocket.android.server.domain.AnalyticsTrackingInteractor
import chat.rocket.android.util.extension.asObservable import chat.rocket.android.util.extension.asObservable
import chat.rocket.android.util.extension.dispatchImageSelection import chat.rocket.android.util.extension.dispatchImageSelection
import chat.rocket.android.util.extension.dispatchTakePicture import chat.rocket.android.util.extension.dispatchTakePicture
...@@ -28,8 +29,6 @@ import chat.rocket.android.util.extensions.inflate ...@@ -28,8 +29,6 @@ import chat.rocket.android.util.extensions.inflate
import chat.rocket.android.util.extensions.showToast import chat.rocket.android.util.extensions.showToast
import chat.rocket.android.util.extensions.textContent import chat.rocket.android.util.extensions.textContent
import chat.rocket.android.util.extensions.ui import chat.rocket.android.util.extensions.ui
import chat.rocket.android.util.helper.analytics.AnalyticsManager
import chat.rocket.android.util.helper.analytics.event.ScreenViewEvent
import com.facebook.drawee.backends.pipeline.Fresco import com.facebook.drawee.backends.pipeline.Fresco
import dagger.android.support.AndroidSupportInjection import dagger.android.support.AndroidSupportInjection
import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.CompositeDisposable
...@@ -48,7 +47,7 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback { ...@@ -48,7 +47,7 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
@Inject @Inject
lateinit var presenter: ProfilePresenter lateinit var presenter: ProfilePresenter
@Inject @Inject
lateinit var analyticsTrackingInteractor: AnalyticsTrackingInteractor lateinit var analyticsManager: AnalyticsManager
private var currentName = "" private var currentName = ""
private var currentUsername = "" private var currentUsername = ""
private var currentEmail = "" private var currentEmail = ""
...@@ -81,9 +80,7 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback { ...@@ -81,9 +80,7 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
presenter.loadUserProfile() presenter.loadUserProfile()
subscribeEditTexts() subscribeEditTexts()
if (analyticsTrackingInteractor.get()) { analyticsManager.logScreenView(ScreenViewEvent.Profile)
AnalyticsManager.logScreenView(ScreenViewEvent.Profile)
}
} }
override fun onDestroyView() { override fun onDestroyView() {
......
...@@ -4,7 +4,6 @@ import android.app.NotificationManager ...@@ -4,7 +4,6 @@ import android.app.NotificationManager
import android.content.BroadcastReceiver import android.content.BroadcastReceiver
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import androidx.core.app.NotificationManagerCompat
import androidx.core.app.RemoteInput import androidx.core.app.RemoteInput
import android.widget.Toast import android.widget.Toast
import chat.rocket.android.R import chat.rocket.android.R
......
...@@ -3,7 +3,7 @@ package chat.rocket.android.server.domain ...@@ -3,7 +3,7 @@ package chat.rocket.android.server.domain
import chat.rocket.android.server.domain.model.Account import chat.rocket.android.server.domain.model.Account
interface AccountsRepository { interface AccountsRepository {
suspend fun save(account: Account) fun save(account: Account)
suspend fun load(): List<Account> fun load(): List<Account>
suspend fun remove(serverUrl: String) fun remove(serverUrl: String)
} }
\ No newline at end of file
...@@ -3,5 +3,5 @@ package chat.rocket.android.server.domain ...@@ -3,5 +3,5 @@ package chat.rocket.android.server.domain
import javax.inject.Inject import javax.inject.Inject
class GetAccountsInteractor @Inject constructor(val repository: AccountsRepository) { class GetAccountsInteractor @Inject constructor(val repository: AccountsRepository) {
suspend fun get() = repository.load() fun get() = repository.load()
} }
\ No newline at end of file
...@@ -72,4 +72,22 @@ interface MessagesRepository { ...@@ -72,4 +72,22 @@ interface MessagesRepository {
suspend fun getAllUnsent(): List<Message> suspend fun getAllUnsent(): List<Message>
suspend fun getUnsentByRoomId(roomId: String): List<Message> suspend fun getUnsentByRoomId(roomId: String): List<Message>
/**
* Save time of the latest room messages sync.
* Call this fun only when the latest messages list being received via /history or /messages network calls
*
* @param rid The id of the room the messages are.
* @param timeMillis time of room messages sync or the latest room message timestamp(which came with /history request)
*/
suspend fun saveLastSyncDate(rid: String, timeMillis: Long)
/**
* Get time when the room chat history has been loaded last time.
*
* @param rid The id of the room the messages are.
*
* @return Last Sync time or Null.
*/
suspend fun getLastSyncDate(rid: String): Long?
} }
\ No newline at end of file
...@@ -7,8 +7,16 @@ import kotlinx.coroutines.experimental.withContext ...@@ -7,8 +7,16 @@ import kotlinx.coroutines.experimental.withContext
class MemoryMessagesRepository : MessagesRepository { class MemoryMessagesRepository : MessagesRepository {
private var lastSyncDates: HashMap<String, Long> = HashMap()
private val messages: HashMap<String, Message> = HashMap() private val messages: HashMap<String, Message> = HashMap()
override suspend fun saveLastSyncDate(rid: String, timeMillis: Long) {
lastSyncDates[rid] = timeMillis
}
override suspend fun getLastSyncDate(rid: String) = lastSyncDates[rid]
override suspend fun getById(id: String): Message? = withContext(CommonPool) { override suspend fun getById(id: String): Message? = withContext(CommonPool) {
return@withContext messages[id] return@withContext messages[id]
} }
......
...@@ -6,41 +6,37 @@ import chat.rocket.android.server.domain.AccountsRepository ...@@ -6,41 +6,37 @@ import chat.rocket.android.server.domain.AccountsRepository
import chat.rocket.android.server.domain.model.Account import chat.rocket.android.server.domain.model.Account
import com.squareup.moshi.Moshi import com.squareup.moshi.Moshi
import com.squareup.moshi.Types import com.squareup.moshi.Types
import kotlinx.coroutines.experimental.CommonPool
import kotlinx.coroutines.experimental.withContext private const val ACCOUNTS_KEY = "ACCOUNTS_KEY"
class SharedPreferencesAccountsRepository( class SharedPreferencesAccountsRepository(
private val preferences: SharedPreferences, private val preferences: SharedPreferences,
private val moshi: Moshi private val moshi: Moshi
) : AccountsRepository { ) : AccountsRepository {
override suspend fun save(newAccount: Account) { override fun save(newAccount: Account) {
withContext(CommonPool) { val accounts = load()
val accounts = load()
val newList = accounts.filter { account -> newAccount.serverUrl != account.serverUrl } val newList = accounts.filter { account -> newAccount.serverUrl != account.serverUrl }
.toMutableList() .toMutableList()
newList.add(0, newAccount) newList.add(0, newAccount)
save(newList) save(newList)
}
} }
override suspend fun load(): List<Account> = withContext(CommonPool) { override fun load(): List<Account> {
val json = preferences.getString(ACCOUNTS_KEY, "[]") val json = preferences.getString(ACCOUNTS_KEY, "[]")
val type = Types.newParameterizedType(List::class.java, Account::class.java) val type = Types.newParameterizedType(List::class.java, Account::class.java)
val adapter = moshi.adapter<List<Account>>(type) val adapter = moshi.adapter<List<Account>>(type)
adapter.fromJson(json) ?: emptyList() return adapter.fromJson(json) ?: emptyList()
} }
override suspend fun remove(serverUrl: String) { override fun remove(serverUrl: String) {
withContext(CommonPool) { val accounts = load()
val accounts = load()
val newList = accounts.filter { account -> serverUrl != account.serverUrl } val newList = accounts.filter { account -> serverUrl != account.serverUrl }
.toMutableList() .toMutableList()
save(newList) save(newList)
}
} }
private fun save(accounts: List<Account>) { private fun save(accounts: List<Account>) {
...@@ -50,6 +46,4 @@ class SharedPreferencesAccountsRepository( ...@@ -50,6 +46,4 @@ class SharedPreferencesAccountsRepository(
putString(ACCOUNTS_KEY, adapter.toJson(accounts)) putString(ACCOUNTS_KEY, adapter.toJson(accounts))
} }
} }
} }
\ No newline at end of file
private const val ACCOUNTS_KEY = "ACCOUNTS_KEY"
\ No newline at end of file
...@@ -13,6 +13,27 @@ class SharedPreferencesMessagesRepository( ...@@ -13,6 +13,27 @@ class SharedPreferencesMessagesRepository(
private val moshi: Moshi, private val moshi: Moshi,
private val currentServerInteractor: GetCurrentServerInteractor private val currentServerInteractor: GetCurrentServerInteractor
) : MessagesRepository { ) : MessagesRepository {
private val KEY_LAST_SYNC_DATE = "KEY_LAST_SYNC_DATE"
override suspend fun saveLastSyncDate(rid: String, timeMillis: Long) {
withContext(CommonPool) {
currentServerInteractor.get()?.let {
prefs.edit().putLong(getSyncDateKey(it, rid), timeMillis).apply()
}
}
}
override suspend fun getLastSyncDate(rid: String): Long? = withContext(CommonPool) {
currentServerInteractor.get()?.also { server ->
if (!prefs.contains(getSyncDateKey(server, rid)))
return@withContext null
val time = prefs.getLong(getSyncDateKey(server, rid), -1)
return@withContext if (time == -1L) null else time
}
return@withContext null
}
private fun getSyncDateKey(server: String, rid: String) = "${KEY_LAST_SYNC_DATE}_$server $rid"
override suspend fun getById(id: String): Message? = withContext(CommonPool) { override suspend fun getById(id: String): Message? = withContext(CommonPool) {
currentServerInteractor.get()?.also { server -> currentServerInteractor.get()?.also { server ->
......
package chat.rocket.android.server.presentation package chat.rocket.android.server.presentation
import chat.rocket.android.analytics.AnalyticsManager
import chat.rocket.android.core.lifecycle.CancelStrategy import chat.rocket.android.core.lifecycle.CancelStrategy
import chat.rocket.android.infrastructure.LocalRepository import chat.rocket.android.infrastructure.LocalRepository
import chat.rocket.android.server.domain.AnalyticsTrackingInteractor
import chat.rocket.android.server.domain.GetAccountInteractor import chat.rocket.android.server.domain.GetAccountInteractor
import chat.rocket.android.server.domain.GetAccountsInteractor import chat.rocket.android.server.domain.GetAccountsInteractor
import chat.rocket.android.server.domain.GetCurrentServerInteractor import chat.rocket.android.server.domain.GetCurrentServerInteractor
...@@ -11,7 +11,6 @@ import chat.rocket.android.server.domain.SettingsRepository ...@@ -11,7 +11,6 @@ import chat.rocket.android.server.domain.SettingsRepository
import chat.rocket.android.server.domain.TokenRepository import chat.rocket.android.server.domain.TokenRepository
import chat.rocket.android.server.infraestructure.ConnectionManagerFactory import chat.rocket.android.server.infraestructure.ConnectionManagerFactory
import chat.rocket.android.util.extension.launchUI import chat.rocket.android.util.extension.launchUI
import chat.rocket.android.util.helper.analytics.AnalyticsManager
import chat.rocket.common.util.ifNull import chat.rocket.common.util.ifNull
import javax.inject.Inject import javax.inject.Inject
...@@ -23,7 +22,7 @@ class ChangeServerPresenter @Inject constructor( ...@@ -23,7 +22,7 @@ class ChangeServerPresenter @Inject constructor(
private val getCurrentServerInteractor: GetCurrentServerInteractor, private val getCurrentServerInteractor: GetCurrentServerInteractor,
private val getAccountInteractor: GetAccountInteractor, private val getAccountInteractor: GetAccountInteractor,
private val getAccountsInteractor: GetAccountsInteractor, private val getAccountsInteractor: GetAccountsInteractor,
private val analyticsTrackingInteractor: AnalyticsTrackingInteractor, private val analyticsManager: AnalyticsManager,
private val settingsRepository: SettingsRepository, private val settingsRepository: SettingsRepository,
private val tokenRepository: TokenRepository, private val tokenRepository: TokenRepository,
private val localRepository: LocalRepository, private val localRepository: LocalRepository,
...@@ -66,9 +65,7 @@ class ChangeServerPresenter @Inject constructor( ...@@ -66,9 +65,7 @@ class ChangeServerPresenter @Inject constructor(
saveCurrentServerInteractor.save(serverUrl) saveCurrentServerInteractor.save(serverUrl)
view.hideProgress() view.hideProgress()
if (analyticsTrackingInteractor.get()) { analyticsManager.logServerSwitch()
AnalyticsManager.logServerSwitch(serverUrl, accounts.size)
}
navigator.toChatRooms(chatRoomId) navigator.toChatRooms(chatRoomId)
}.ifNull { }.ifNull {
view.hideProgress() view.hideProgress()
......
...@@ -27,7 +27,7 @@ class PasswordPresenter @Inject constructor( ...@@ -27,7 +27,7 @@ class PasswordPresenter @Inject constructor(
val me = retryIO("me") { client.me() } val me = retryIO("me") { client.me() }
retryIO("updateProfile(${me.id})") { retryIO("updateProfile(${me.id})") {
client.updateProfile(me.id!!, null, null, password, null) client.updateProfile(me.id, null, null, password, null)
} }
view.showPasswordSuccessfullyUpdatedMessage() view.showPasswordSuccessfullyUpdatedMessage()
......
...@@ -10,15 +10,14 @@ import android.widget.Toast ...@@ -10,15 +10,14 @@ import android.widget.Toast
import androidx.appcompat.view.ActionMode import androidx.appcompat.view.ActionMode
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.server.domain.AnalyticsTrackingInteractor import chat.rocket.android.analytics.AnalyticsManager
import chat.rocket.android.analytics.event.ScreenViewEvent
import chat.rocket.android.settings.password.presentation.PasswordPresenter import chat.rocket.android.settings.password.presentation.PasswordPresenter
import chat.rocket.android.settings.password.presentation.PasswordView import chat.rocket.android.settings.password.presentation.PasswordView
import chat.rocket.android.util.extension.asObservable import chat.rocket.android.util.extension.asObservable
import chat.rocket.android.util.extensions.inflate import chat.rocket.android.util.extensions.inflate
import chat.rocket.android.util.extensions.textContent import chat.rocket.android.util.extensions.textContent
import chat.rocket.android.util.extensions.ui import chat.rocket.android.util.extensions.ui
import chat.rocket.android.util.helper.analytics.AnalyticsManager
import chat.rocket.android.util.helper.analytics.event.ScreenViewEvent
import dagger.android.support.AndroidSupportInjection import dagger.android.support.AndroidSupportInjection
import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.CompositeDisposable
import io.reactivex.disposables.Disposable import io.reactivex.disposables.Disposable
...@@ -32,7 +31,7 @@ class PasswordFragment : Fragment(), PasswordView, ActionMode.Callback { ...@@ -32,7 +31,7 @@ class PasswordFragment : Fragment(), PasswordView, ActionMode.Callback {
@Inject @Inject
lateinit var presenter: PasswordPresenter lateinit var presenter: PasswordPresenter
@Inject @Inject
lateinit var analyticsTrackingInteractor: AnalyticsTrackingInteractor lateinit var analyticsManager: AnalyticsManager
private var actionMode: ActionMode? = null private var actionMode: ActionMode? = null
private val disposables = CompositeDisposable() private val disposables = CompositeDisposable()
...@@ -56,9 +55,7 @@ class PasswordFragment : Fragment(), PasswordView, ActionMode.Callback { ...@@ -56,9 +55,7 @@ class PasswordFragment : Fragment(), PasswordView, ActionMode.Callback {
disposables.add(listenToChanges()) disposables.add(listenToChanges())
if (analyticsTrackingInteractor.get()) { analyticsManager.logScreenView(ScreenViewEvent.Password)
AnalyticsManager.logScreenView(ScreenViewEvent.Password)
}
} }
override fun onDestroyView() { override fun onDestroyView() {
......
...@@ -11,16 +11,16 @@ import androidx.fragment.app.Fragment ...@@ -11,16 +11,16 @@ import androidx.fragment.app.Fragment
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.about.ui.AboutFragment import chat.rocket.android.about.ui.AboutFragment
import chat.rocket.android.about.ui.TAG_ABOUT_FRAGMENT import chat.rocket.android.about.ui.TAG_ABOUT_FRAGMENT
import chat.rocket.android.analytics.AnalyticsManager
import chat.rocket.android.analytics.event.ScreenViewEvent
import chat.rocket.android.main.ui.MainActivity import chat.rocket.android.main.ui.MainActivity
import chat.rocket.android.preferences.ui.PreferencesFragment import chat.rocket.android.preferences.ui.PreferencesFragment
import chat.rocket.android.preferences.ui.TAG_PREFERENCES_FRAGMENT import chat.rocket.android.preferences.ui.TAG_PREFERENCES_FRAGMENT
import chat.rocket.android.server.domain.AnalyticsTrackingInteractor
import chat.rocket.android.settings.password.ui.PasswordActivity import chat.rocket.android.settings.password.ui.PasswordActivity
import chat.rocket.android.settings.presentation.SettingsView import chat.rocket.android.settings.presentation.SettingsView
import chat.rocket.android.util.extensions.addFragmentBackStack import chat.rocket.android.util.extensions.addFragmentBackStack
import chat.rocket.android.util.extensions.inflate import chat.rocket.android.util.extensions.inflate
import chat.rocket.android.util.helper.analytics.AnalyticsManager import dagger.android.support.AndroidSupportInjection
import chat.rocket.android.util.helper.analytics.event.ScreenViewEvent
import kotlinx.android.synthetic.main.fragment_settings.* import kotlinx.android.synthetic.main.fragment_settings.*
import javax.inject.Inject import javax.inject.Inject
import kotlin.reflect.KClass import kotlin.reflect.KClass
...@@ -29,7 +29,12 @@ internal const val TAG_SETTINGS_FRAGMENT = "SettingsFragment" ...@@ -29,7 +29,12 @@ internal const val TAG_SETTINGS_FRAGMENT = "SettingsFragment"
class SettingsFragment : Fragment(), SettingsView, AdapterView.OnItemClickListener { class SettingsFragment : Fragment(), SettingsView, AdapterView.OnItemClickListener {
@Inject @Inject
lateinit var analyticsTrackingInteractor: AnalyticsTrackingInteractor lateinit var analyticsManager: AnalyticsManager
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
AndroidSupportInjection.inject(this)
}
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, inflater: LayoutInflater,
...@@ -41,10 +46,7 @@ class SettingsFragment : Fragment(), SettingsView, AdapterView.OnItemClickListen ...@@ -41,10 +46,7 @@ class SettingsFragment : Fragment(), SettingsView, AdapterView.OnItemClickListen
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
setupToolbar() setupToolbar()
setupListView() setupListView()
analyticsManager.logScreenView(ScreenViewEvent.Settings)
if (analyticsTrackingInteractor.get()) {
AnalyticsManager.logScreenView(ScreenViewEvent.Settings)
}
} }
override fun onResume() { override fun onResume() {
......
...@@ -7,18 +7,18 @@ import chat.rocket.core.RocketChatClient ...@@ -7,18 +7,18 @@ import chat.rocket.core.RocketChatClient
import chat.rocket.core.internal.rest.registerPushToken import chat.rocket.core.internal.rest.registerPushToken
import kotlinx.coroutines.experimental.CommonPool import kotlinx.coroutines.experimental.CommonPool
import kotlinx.coroutines.experimental.launch import kotlinx.coroutines.experimental.launch
import kotlinx.coroutines.experimental.withContext
import timber.log.Timber import timber.log.Timber
suspend fun RocketChatClient.registerPushToken( suspend fun RocketChatClientFactory.registerPushToken(
token: String, token: String,
accounts: List<Account>, accounts: List<Account>
factory: RocketChatClientFactory
) { ) {
launch(CommonPool) { withContext(CommonPool) {
accounts.forEach { account -> accounts.forEach { account ->
try { try {
retryIO(description = "register push token: ${account.serverUrl}") { retryIO(description = "register push token: ${account.serverUrl}") {
factory.create(account.serverUrl).registerPushToken(token) create(account.serverUrl).registerPushToken(token)
} }
} catch (ex: Exception) { } catch (ex: Exception) {
Timber.d(ex, "Error registering Push token for ${account.serverUrl}") Timber.d(ex, "Error registering Push token for ${account.serverUrl}")
......
...@@ -10,15 +10,19 @@ import android.provider.DocumentsContract ...@@ -10,15 +10,19 @@ import android.provider.DocumentsContract
import android.provider.MediaStore import android.provider.MediaStore
import android.provider.OpenableColumns import android.provider.OpenableColumns
import android.webkit.MimeTypeMap import android.webkit.MimeTypeMap
import java.io.* import java.io.File
import java.io.FileInputStream
import java.io.FileNotFoundException
import java.io.IOException
import java.io.InputStream
fun Uri.getFileName(context: Context): String? { fun Uri.getFileName(context: Context): String? {
val cursor = context.contentResolver.query(this, null, null, null, null, null) val cursor = context.contentResolver.query(this, null, null, null, null, null)
var fileName: String? = null var fileName: String? = null
cursor.use { cursor -> cursor?.use {
if (cursor != null && cursor.moveToFirst()) { if (it.moveToFirst()) {
fileName = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)) fileName = it.getString(it.getColumnIndex(OpenableColumns.DISPLAY_NAME))
} }
} }
return fileName return fileName
...@@ -29,7 +33,7 @@ fun Uri.getFileSize(context: Context): Int { ...@@ -29,7 +33,7 @@ fun Uri.getFileSize(context: Context): Int {
if (scheme == ContentResolver.SCHEME_CONTENT) { if (scheme == ContentResolver.SCHEME_CONTENT) {
try { try {
val fileInputStream = context.contentResolver.openInputStream(this) val fileInputStream = context.contentResolver.openInputStream(this)
fileSize = fileInputStream.available().toString() fileSize = fileInputStream?.available().toString()
} catch (e: Exception) { } catch (e: Exception) {
e.printStackTrace() e.printStackTrace()
} }
...@@ -67,14 +71,17 @@ fun Uri.isVirtualFile(context: Context): Boolean { ...@@ -67,14 +71,17 @@ fun Uri.isVirtualFile(context: Context): Boolean {
val cursor = context.contentResolver.query( val cursor = context.contentResolver.query(
this, this,
arrayOf(DocumentsContract.Document.COLUMN_FLAGS), arrayOf(DocumentsContract.Document.COLUMN_FLAGS),
null, null, null null,
null,
null
) )
var flags = 0 var flags = 0
if (cursor.moveToFirst()) { cursor?.use {
flags = cursor.getInt(0) if (it.moveToFirst()) {
flags = it.getInt(0)
}
} }
cursor.close()
return flags and DocumentsContract.Document.FLAG_VIRTUAL_DOCUMENT != 0 return flags and DocumentsContract.Document.FLAG_VIRTUAL_DOCUMENT != 0
} }
...@@ -104,4 +111,4 @@ fun Uri.getInputStream(context: Context): InputStream? { ...@@ -104,4 +111,4 @@ fun Uri.getInputStream(context: Context): InputStream? {
fun Uri.getBitmpap(context: Context): Bitmap? { fun Uri.getBitmpap(context: Context): Bitmap? {
return MediaStore.Images.Media.getBitmap(context.contentResolver, this) return MediaStore.Images.Media.getBitmap(context.contentResolver, this)
} }
\ No newline at end of file
...@@ -4,11 +4,8 @@ import androidx.lifecycle.LiveData ...@@ -4,11 +4,8 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
import kotlinx.coroutines.experimental.CommonPool import kotlinx.coroutines.experimental.CommonPool
import kotlinx.coroutines.experimental.CoroutineScope
import kotlinx.coroutines.experimental.Job import kotlinx.coroutines.experimental.Job
import kotlinx.coroutines.experimental.android.UI
import kotlinx.coroutines.experimental.launch import kotlinx.coroutines.experimental.launch
import kotlinx.coroutines.experimental.withContext
import kotlin.coroutines.experimental.CoroutineContext import kotlin.coroutines.experimental.CoroutineContext
class WrappedLiveData<Source, Output>( class WrappedLiveData<Source, Output>(
......
...@@ -11,6 +11,7 @@ import androidx.appcompat.app.AppCompatActivity ...@@ -11,6 +11,7 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.util.extensions.inflate import chat.rocket.android.util.extensions.inflate
import chat.rocket.android.util.extensions.ui
import kotlinx.android.synthetic.main.fragment_admin_panel_web_view.* import kotlinx.android.synthetic.main.fragment_admin_panel_web_view.*
private const val BUNDLE_WEB_PAGE_URL = "web_page_url" private const val BUNDLE_WEB_PAGE_URL = "web_page_url"
...@@ -58,8 +59,10 @@ class AdminPanelWebViewFragment : Fragment() { ...@@ -58,8 +59,10 @@ class AdminPanelWebViewFragment : Fragment() {
web_view.webViewClient = object : WebViewClient() { web_view.webViewClient = object : WebViewClient() {
override fun onPageFinished(view: WebView, url: String) { override fun onPageFinished(view: WebView, url: String) {
super.onPageFinished(view, url) super.onPageFinished(view, url)
view_loading.hide() ui { _ ->
web_view.evaluateJavascript("Meteor.loginWithToken('$userToken', function() { })") {} view_loading.hide()
web_view.evaluateJavascript("Meteor.loginWithToken('$userToken', function() { })") {}
}
} }
} }
web_view.loadUrl(webPageUrl) web_view.loadUrl(webPageUrl)
......
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="20dp"
android:height="20dp"
android:viewportWidth="20"
android:viewportHeight="20">
<path
android:fillColor="#00000000"
android:fillType="evenOdd"
android:pathData="M11.286,6.143C11.286,7.087 11.136,7.797 10.838,8.273L16.354,13.615L17,15.709L15.708,17L13.62,16.358L13.21,15.949L13.21,14.474L11.735,14.474L11.105,13.844L11.105,12.368L9.629,12.368L8.063,10.796C7.481,11.123 6.84,11.286 6.143,11.286C4.7537,11.286 3.4234,10.7239 2.455,9.7277C1.4867,8.7314 0.9626,7.3858 1.002,5.997C1.077,3.313 3.314,1.077 5.997,1.002C7.3854,0.9628 8.7307,1.4869 9.7267,2.4551C10.7227,3.4232 11.2847,4.753 11.285,6.142L11.286,6.143Z"
android:strokeWidth="1.5"
android:strokeColor="#2F343D" />
<path
android:fillColor="#2F343D"
android:fillType="nonZero"
android:pathData="M5.5,5.5m1.5,0a1.5,1.5 0,1 0,-3 0a1.5,1.5 0,1 0,3 0"
android:strokeWidth="1"
android:strokeColor="#00000000" />
</vector>
...@@ -8,32 +8,19 @@ ...@@ -8,32 +8,19 @@
android:translateX="281.28394" android:translateX="281.28394"
android:translateY="271.51514"> android:translateY="271.51514">
<path <path
android:fillColor="#CC3333" android:fillColor="#FFDB2323"
android:pathData="M491.3,255.3c0,-24.1 -7.2,-47.2 -21.4,-68.7c-12.8,-19.3 -30.7,-36.4 -53.2,-50.7c-43.5,-27.8 -100.6,-43.1 -160.9,-43.1c-20.1,0 -40,1.7 -59.2,5.1c-11.9,-11.2 -25.9,-21.2 -40.7,-29.2c-79,-38.3 -144.6,-0.9 -144.6,-0.9s60.9,50.1 51,93.9c-27.3,27 -42,59.6 -42,93.6c0,0.1 0,0.2 0,0.3c0,0.1 0,0.2 0,0.3c0,33.9 14.8,66.6 42,93.6c9.9,43.9 -51,93.9 -51,93.9s65.5,37.4 144.6,-0.9c14.8,-8 28.8,-18 40.7,-29.2c19.2,3.4 39.1,5.1 59.2,5.1c60.3,0 117.4,-15.3 160.9,-43.1c22.5,-14.4 40.4,-31.5 53.2,-50.7c14.2,-21.5 21.4,-44.6 21.4,-68.7c0,-0.1 0,-0.2 0,-0.3C491.3,255.6 491.3,255.4 491.3,255.3z" /> android:pathData="M491.3,255.3c0,-24.1 -7.2,-47.2 -21.4,-68.7c-12.8,-19.3 -30.7,-36.4 -53.2,-50.7c-43.5,-27.8 -100.6,-43.1 -160.9,-43.1c-20.1,0 -40,1.7 -59.2,5.1c-11.9,-11.2 -25.9,-21.2 -40.7,-29.2c-79,-38.3 -144.6,-0.9 -144.6,-0.9s60.9,50.1 51,93.9c-27.3,27 -42,59.6 -42,93.6c0,0.1 0,0.2 0,0.3c0,0.1 0,0.2 0,0.3c0,33.9 14.8,66.6 42,93.6c9.9,43.9 -51,93.9 -51,93.9s65.5,37.4 144.6,-0.9c14.8,-8 28.8,-18 40.7,-29.2c19.2,3.4 39.1,5.1 59.2,5.1c60.3,0 117.4,-15.3 160.9,-43.1c22.5,-14.4 40.4,-31.5 53.2,-50.7c14.2,-21.5 21.4,-44.6 21.4,-68.7c0,-0.1 0,-0.2 0,-0.3C491.3,255.6 491.3,255.4 491.3,255.3z" />
<path <path
android:fillColor="#FFFFFF" android:fillColor="#FFFFFF"
android:pathData="M255.9,124.2c113.9,0 206.3,59 206.3,131.8c0,72.8 -92.4,131.8 -206.3,131.8c-25.4,0 -49.7,-2.9 -72.1,-8.3c-22.8,27.4 -73,65.6 -121.7,53.3c15.9,-17 39.4,-45.8 34.3,-93.2c-29.2,-22.7 -46.8,-51.8 -46.8,-83.5C49.6,183.2 142,124.2 255.9,124.2" /> android:pathData="M255.9,124.2c113.9,0 206.3,59 206.3,131.8c0,72.8 -92.4,131.8 -206.3,131.8c-25.4,0 -49.7,-2.9 -72.1,-8.3c-22.8,27.4 -73,65.6 -121.7,53.3c15.9,-17 39.4,-45.8 34.3,-93.2c-29.2,-22.7 -46.8,-51.8 -46.8,-83.5C49.6,183.2 142,124.2 255.9,124.2" />
<path <path
android:fillColor="#CC3333" android:fillColor="#FFDB2323"
android:pathData="M255.9,256m-27.4,0a27.4,27.4 0,1 1,54.8 0a27.4,27.4 0,1 1,-54.8 0" /> android:pathData="M255.9,256m-27.4,0a27.4,27.4 0,1 1,54.8 0a27.4,27.4 0,1 1,-54.8 0" />
<path <path
android:fillColor="#CC3333" android:fillColor="#FFDB2323"
android:pathData="M351.2,256m-27.4,0a27.4,27.4 0,1 1,54.8 0a27.4,27.4 0,1 1,-54.8 0" /> android:pathData="M351.2,256m-27.4,0a27.4,27.4 0,1 1,54.8 0a27.4,27.4 0,1 1,-54.8 0" />
<path <path
android:fillColor="#CC3333" android:fillColor="#FFDB2323"
android:pathData="M160.6,256m-27.4,0a27.4,27.4 0,1 1,54.8 0a27.4,27.4 0,1 1,-54.8 0" /> android:pathData="M160.6,256m-27.4,0a27.4,27.4 0,1 1,54.8 0a27.4,27.4 0,1 1,-54.8 0" />
<path
android:fillColor="#CCCCCC"
android:pathData="M255.8,372.8c-25.4,0 -56.2,-4.9 -78.7,-9.5c-20.1,21 -53.7,52.7 -99.6,50.3c-5.7,8.6 -10.2,13.5 -15.5,19.2c48.7,12.3 98.9,-25.8 121.7,-53.3c22.4,5.4 46.7,8.3 72.1,8.3c113,0 204.8,-58.1 206.3,-130C460.7,320.1 368.8,372.8 255.8,372.8z" />
<path
android:fillColor="#00000000"
android:pathData="M172,350.9"
android:strokeColor="#000000"
android:strokeWidth="1" />
<path
android:fillColor="#00000000"
android:pathData="M200.4,422.9"
android:strokeColor="#000000"
android:strokeWidth="1" />
</group> </group>
</vector> </vector>
\ No newline at end of file
...@@ -770,4 +770,4 @@ ...@@ -770,4 +770,4 @@
android:pathData="M89.876,190C88.289,190.003 87.003,191.286 87,192.87C87.004,193.159 87.053,193.445 87.144,193.719C87.639,193.823 88.14,193.916 88.648,194C88.193,193.513 88.073,192.802 88.341,192.193C88.609,191.584 89.215,191.192 89.882,191.196L107.855,191.196C108.586,190.843 109.305,190.466 110,190.066C109.803,190.023 109.602,190.001 109.401,190L89.876,190Z" android:pathData="M89.876,190C88.289,190.003 87.003,191.286 87,192.87C87.004,193.159 87.053,193.445 87.144,193.719C87.639,193.823 88.14,193.916 88.648,194C88.193,193.513 88.073,192.802 88.341,192.193C88.609,191.584 89.215,191.192 89.882,191.196L107.855,191.196C108.586,190.843 109.305,190.466 110,190.066C109.803,190.023 109.602,190.001 109.401,190L89.876,190Z"
android:strokeWidth="1" android:strokeWidth="1"
android:strokeColor="#00000000" /> android:strokeColor="#00000000" />
</vector> </vector>
\ No newline at end of file
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
<TextView <TextView
android:id="@+id/text_on_boarding_description" android:id="@+id/text_on_boarding_description"
style="@style/Authentication.Description.TextView" style="@style/Authentication.Description.TextView"
android:text="@string/msg_open_source_communication" android:text="@string/msg_team_communication"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text_on_boarding_title" /> app:layout_constraintTop_toBottomOf="@+id/text_on_boarding_title" />
......
<resources> <resources>
<!-- Titles --> <!-- Titles -->
<string name="title_sign_in_your_server">Anmelden am Server</string> <string name="title_sign_in_your_server">Anmelden am Server</string>
<string name="title_log_in">Anmelden</string> <string name="title_log_in">Anmelden</string>
...@@ -75,7 +76,6 @@ ...@@ -75,7 +76,6 @@
<string name="msg_invalid_email">Bitte eine korrekte E-Mail Adresse eingeben</string> <string name="msg_invalid_email">Bitte eine korrekte E-Mail Adresse eingeben</string>
<string name="msg_new_user_agreement">Beim weitergehen akzeptieren Sie usere\n%1$s und %2$s</string> <string name="msg_new_user_agreement">Beim weitergehen akzeptieren Sie usere\n%1$s und %2$s</string>
<string name="msg_2fa_code">2FA Code</string> <string name="msg_2fa_code">2FA Code</string>
<!-- <string name="msg_more_than_ninety_nine_unread_messages" translatable="false">99+</string> -->
<string name="msg_yesterday">Gestern</string> <string name="msg_yesterday">Gestern</string>
<string name="msg_today">Heute</string> <string name="msg_today">Heute</string>
<string name="msg_message">Nachricht</string> <string name="msg_message">Nachricht</string>
...@@ -109,11 +109,8 @@ ...@@ -109,11 +109,8 @@
<string name="msg_no_messages_yet">Noch keine Nachrichten</string> <string name="msg_no_messages_yet">Noch keine Nachrichten</string>
<string name="msg_ok">OK</string> <string name="msg_ok">OK</string>
<string name="msg_update_app_version_in_order_to_continue">Server Version veraltet. Bitte kontaktieren Sie ihren Server Administrator.</string> <string name="msg_update_app_version_in_order_to_continue">Server Version veraltet. Bitte kontaktieren Sie ihren Server Administrator.</string>
<string name="msg_ver_not_recommended"> <string name="msg_ver_not_recommended">Die Server Version scheint älter als die empfolene Version %1$s zu sein.\nSie können sich trotzdem einloggen, aber es kann zu einem unerwartetem Verhalten kommen.</string>
Die Server Version scheint älter als die empfolene Version %1$s zu sein.\nSie können sich trotzdem einloggen, aber es kann zu einem unerwartetem Verhalten kommen.</string> <string name="msg_ver_not_minimum">Die Server Version scheint älter als die minimale Version %1$s zu sein.\nBitte updaten Sie Ihren Server um sich einloggen zu können!</string>
<string name="msg_ver_not_minimum">
Die Server Version scheint älter als die minimale Version %1$s zu sein.\nBitte updaten Sie Ihren Server um sich einloggen zu können!
</string>
<string name="msg_no_chat_title">Keine Chat Nachrichten</string> <string name="msg_no_chat_title">Keine Chat Nachrichten</string>
<string name="msg_no_chat_description">Starte die Konversation um Ihre \nNachrichten hier zu sehen.</string> <string name="msg_no_chat_description">Starte die Konversation um Ihre \nNachrichten hier zu sehen.</string>
<string name="msg_proceed">WEITER</string> <string name="msg_proceed">WEITER</string>
...@@ -136,7 +133,7 @@ ...@@ -136,7 +133,7 @@
<string name="msg_send">Sende</string> <string name="msg_send">Sende</string>
<string name="msg_sent_attachment">Sende Anhang</string> <string name="msg_sent_attachment">Sende Anhang</string>
<string name="msg_welcome_to_rocket_chat">Welcome to Rocket.Chat</string> <!-- TODO Add translation --> <string name="msg_welcome_to_rocket_chat">Welcome to Rocket.Chat</string> <!-- TODO Add translation -->
<string name="msg_open_source_communication">Open Source Communication</string> <!-- TODO Add translation --> <string name="msg_team_communication">Open Source Communication</string> <!-- TODO Add translation -->
<string name="msg_login_with_email">Login with e-mail</string> <!-- TODO Add translation --> <string name="msg_login_with_email">Login with e-mail</string> <!-- TODO Add translation -->
<string name="msg_create_account">Create an account</string> <!-- TODO Add translation --> <string name="msg_create_account">Create an account</string> <!-- TODO Add translation -->
<string name="msg_continue_with_facebook">Continue with Facebook</string> <!-- TODO Add translation --> <string name="msg_continue_with_facebook">Continue with Facebook</string> <!-- TODO Add translation -->
......
...@@ -133,7 +133,7 @@ ...@@ -133,7 +133,7 @@
<string name="msg_delete_description">Seguro que quieres borrar este mensaje</string> <string name="msg_delete_description">Seguro que quieres borrar este mensaje</string>
<string name="msg_no_search_found">No se han encontrado resultados</string> <string name="msg_no_search_found">No se han encontrado resultados</string>
<string name="msg_welcome_to_rocket_chat">Welcome to Rocket.Chat</string> <!-- TODO Add translation --> <string name="msg_welcome_to_rocket_chat">Welcome to Rocket.Chat</string> <!-- TODO Add translation -->
<string name="msg_open_source_communication">Open Source Communication</string> <!-- TODO Add translation --> <string name="msg_team_communication">Open Source Communication</string> <!-- TODO Add translation -->
<string name="msg_login_with_email">Login with e-mail</string> <!-- TODO Add translation --> <string name="msg_login_with_email">Login with e-mail</string> <!-- TODO Add translation -->
<string name="msg_create_account">Create an account</string> <!-- TODO Add translation --> <string name="msg_create_account">Create an account</string> <!-- TODO Add translation -->
<string name="msg_continue_with_facebook">Continue with Facebook</string> <!-- TODO Add translation --> <string name="msg_continue_with_facebook">Continue with Facebook</string> <!-- TODO Add translation -->
......
This diff is collapsed.
...@@ -12,9 +12,9 @@ ...@@ -12,9 +12,9 @@
<string name="title_profile">प्रोफाइल</string> <string name="title_profile">प्रोफाइल</string>
<string name="title_members">सदस्य (%d)</string> <string name="title_members">सदस्य (%d)</string>
<string name="title_settings">सेटिंग्स</string> <string name="title_settings">सेटिंग्स</string>
<string name="title_preferences">Preferences</string> <!-- TODO Add translation --> <string name="title_preferences">प्राथमिकताएँ</string>
<string name="title_change_password">पासवर्ड बदलें</string> <string name="title_change_password">पासवर्ड बदलें</string>
<string name="title_admin_panel">Admin panel</string> <!-- TODO Add translation --> <string name="title_admin_panel">एडमिन पैनल</string>
<string name="title_password">पासवर्ड बदलें</string> <string name="title_password">पासवर्ड बदलें</string>
<string name="title_update_profile">प्रोफ़ाइल अपडेट करें</string> <string name="title_update_profile">प्रोफ़ाइल अपडेट करें</string>
<string name="title_about">परिचय</string> <string name="title_about">परिचय</string>
...@@ -42,9 +42,9 @@ ...@@ -42,9 +42,9 @@
<string name="action_invisible">अदृश्य</string> <string name="action_invisible">अदृश्य</string>
<string name="action_save_to_gallery">गैलरी में सहेजें</string> <string name="action_save_to_gallery">गैलरी में सहेजें</string>
<string name="action_drawing">चित्रकारी</string> <string name="action_drawing">चित्रकारी</string>
<string name="action_select_photo_from_gallery">Select photo from gallery</string> <!-- TODO Add translation --> <string name="action_select_photo_from_gallery">गैलरी से फोटो का चयन करें</string>
<string name="action_take_photo">Select photo from gallery</string> <!-- TODO Add translation --> <string name="action_take_photo">फोटो खेचिये</string>
<string name="action_reset_avatar">Reset avatar</string> <!-- TODO Add translation --> <string name="action_reset_avatar">अवतार रीसेट करें</string>
<string name="action_connect_server">सर्वर से कनेक्ट करें</string> <string name="action_connect_server">सर्वर से कनेक्ट करें</string>
<string name="action_join_community">समुदाय में शामिल हों</string> <string name="action_join_community">समुदाय में शामिल हों</string>
<string name="action_create_server">नया सर्वर बनाएं</string> <string name="action_create_server">नया सर्वर बनाएं</string>
...@@ -53,7 +53,7 @@ ...@@ -53,7 +53,7 @@
<!-- Settings List --> <!-- Settings List -->
<string-array name="settings_actions"> <string-array name="settings_actions">
<item name="item_preferences">Preferences</item> <!-- TODO Add translation --> <item name="item_preferences">प्राथमिकताएँ</item>
<item name="item_password">पासवर्ड बदलें</item> <item name="item_password">पासवर्ड बदलें</item>
<item name="item_password">परिचय</item> <item name="item_password">परिचय</item>
</string-array> </string-array>
...@@ -90,7 +90,7 @@ ...@@ -90,7 +90,7 @@
<string name="msg_content_description_log_in_using_meteor">Meteor द्वारा लॉगिन करें</string> <string name="msg_content_description_log_in_using_meteor">Meteor द्वारा लॉगिन करें</string>
<string name="msg_content_description_log_in_using_twitter">Twitter द्वारा लॉगिन करें</string> <string name="msg_content_description_log_in_using_twitter">Twitter द्वारा लॉगिन करें</string>
<string name="msg_content_description_log_in_using_gitlab">Gitlab द्वारा लॉगिन करें</string> <string name="msg_content_description_log_in_using_gitlab">Gitlab द्वारा लॉगिन करें</string>
<string name="msg_content_description_log_in_using_wordpress">Login using WordPress</string> <!-- TODO Translate--> <string name="msg_content_description_log_in_using_wordpress">WordPress द्वारा लॉगिन करें</string>
<string name="msg_content_description_send_message">मेसेज भेजें</string> <string name="msg_content_description_send_message">मेसेज भेजें</string>
<string name="msg_content_description_show_attachment_options">अटैचमेंट विकल्प दिखाएं</string> <string name="msg_content_description_show_attachment_options">अटैचमेंट विकल्प दिखाएं</string>
<string name="msg_you">आप</string> <string name="msg_you">आप</string>
...@@ -139,7 +139,7 @@ ...@@ -139,7 +139,7 @@
<string name="msg_delete_message">संदेश को हटाएं</string> <string name="msg_delete_message">संदेश को हटाएं</string>
<string name="msg_delete_description">क्या आप निश्चित रूप से यह संदेश हटाना चाहते हैं</string> <string name="msg_delete_description">क्या आप निश्चित रूप से यह संदेश हटाना चाहते हैं</string>
<string name="msg_welcome_to_rocket_chat">Rocket.Chat में आपका स्वागत है</string> <string name="msg_welcome_to_rocket_chat">Rocket.Chat में आपका स्वागत है</string>
<string name="msg_open_source_communication">ओपन सोर्स कम्युनिकेशन</string> <string name="msg_team_communication">ओपन सोर्स कम्युनिकेशन</string>
<string name="msg_login_with_email">ई-मेल के साथ लॉगिन करें</string> <string name="msg_login_with_email">ई-मेल के साथ लॉगिन करें</string>
<string name="msg_create_account">खाता बनाएं</string> <string name="msg_create_account">खाता बनाएं</string>
<string name="msg_continue_with_facebook">Facebook के साथ जारी रखें</string> <string name="msg_continue_with_facebook">Facebook के साथ जारी रखें</string>
...@@ -163,10 +163,10 @@ ...@@ -163,10 +163,10 @@
<string name="msg_channel_created_successfully">चैनल सफलतापूर्वक बनाया गया</string> <string name="msg_channel_created_successfully">चैनल सफलतापूर्वक बनाया गया</string>
<!-- Preferences messages --> <!-- Preferences messages -->
<string name="msg_analytics_tracking">Analytics tracking</string> <!-- TODO Add translation --> <string name="msg_analytics_tracking">एनालिटिक्स ट्रैकिंग</string>
<string name="msg_send_analytics_tracking">Send anonymous statics to help improving this app</string> <!-- TODO Add translation --> <string name="msg_send_analytics_tracking">इस ऐप को बेहतर बनाने में मदद के लिए अज्ञात स्टेटिक्स भेजें</string>
<string name="msg_do_not_send_analytics_tracking">Do not send anonymous statics to help improving this app</string> <!-- TODO Add translation --> <string name="msg_do_not_send_analytics_tracking">इस ऐप को बेहतर बनाने में मदद के लिए अनाम स्टेटिक न भेजें</string>
<string name="msg_not_applicable_since_it_is_a_foss_version">Not applicable since it is a FOSS version</string> <!-- TODO Add translation --> <string name="msg_not_applicable_since_it_is_a_foss_version">लागू नहीं है क्योंकि यह एक FOSS संस्करण है</string>
<!-- System messages --> <!-- System messages -->
<string name="message_room_name_changed">%2$s ने रूम का नाम बदलकर %1$s किया</string> <string name="message_room_name_changed">%2$s ने रूम का नाम बदलकर %1$s किया</string>
...@@ -206,8 +206,7 @@ ...@@ -206,8 +206,7 @@
<string name="permission_starring_not_allowed">तारांकित की अनुमति नहीं है</string> <string name="permission_starring_not_allowed">तारांकित की अनुमति नहीं है</string>
<!-- Search message --> <!-- Search message -->
<!-- TODO Add proper translation--> <string name="title_search_message">संदेश खोजें</string>
<string name="title_search_message">Search message</string>
<!-- Favorite/Unfavorite chat room --> <!-- Favorite/Unfavorite chat room -->
<string name="title_favorite_chat">पसंदीदा चैट</string> <string name="title_favorite_chat">पसंदीदा चैट</string>
...@@ -286,7 +285,7 @@ ...@@ -286,7 +285,7 @@
<string name="dialog_sort_by_activity">गतिविधि</string> <string name="dialog_sort_by_activity">गतिविधि</string>
<string name="dialog_group_by_type">प्रकार के आधार पर समूह</string> <string name="dialog_group_by_type">प्रकार के आधार पर समूह</string>
<string name="dialog_group_favourites">पसंदीदा समूह</string> <string name="dialog_group_favourites">पसंदीदा समूह</string>
<string name="dialog_button_done">Done</string><!-- TODO Add translation --> <string name="dialog_button_done">पूर्ण</string>
<string name="chatroom_header">हैडर</string> <string name="chatroom_header">हैडर</string>
<!--ChatRooms Headers--> <!--ChatRooms Headers-->
......
This diff is collapsed.
...@@ -139,7 +139,7 @@ ...@@ -139,7 +139,7 @@
<string name="msg_delete_message">Delete Message</string> <string name="msg_delete_message">Delete Message</string>
<string name="msg_delete_description">Are you sure you want to delete this message</string> <string name="msg_delete_description">Are you sure you want to delete this message</string>
<string name="msg_welcome_to_rocket_chat">Welcome to Rocket.Chat</string> <!-- TODO Add translation --> <string name="msg_welcome_to_rocket_chat">Welcome to Rocket.Chat</string> <!-- TODO Add translation -->
<string name="msg_open_source_communication">Open Source Communication</string> <!-- TODO Add translation --> <string name="msg_team_communication">Open Source Communication</string> <!-- TODO Add translation -->
<string name="msg_login_with_email">Login with e-mail</string> <!-- TODO Add translation --> <string name="msg_login_with_email">Login with e-mail</string> <!-- TODO Add translation -->
<string name="msg_create_account">Create an account</string> <!-- TODO Add translation --> <string name="msg_create_account">Create an account</string> <!-- TODO Add translation -->
<string name="msg_continue_with_facebook">Continue with Facebook</string> <!-- TODO Add translation --> <string name="msg_continue_with_facebook">Continue with Facebook</string> <!-- TODO Add translation -->
......
...@@ -12,9 +12,9 @@ ...@@ -12,9 +12,9 @@
<string name="title_profile">Профиль</string> <string name="title_profile">Профиль</string>
<string name="title_members">Пользователи (%d)</string> <string name="title_members">Пользователи (%d)</string>
<string name="title_settings">Настройки</string> <string name="title_settings">Настройки</string>
<string name="title_preferences">Preferences</string> <!-- TODO Add translation --> <string name="title_preferences">Персональные</string>
<string name="title_change_password">Изменить пароль</string> <string name="title_change_password">Изменить пароль</string>
<string name="title_admin_panel">Admin panel</string> <!-- TODO Add translation --> <string name="title_admin_panel">Панель админа</string>
<string name="title_password">Изменить пароль</string> <string name="title_password">Изменить пароль</string>
<string name="title_update_profile">Обновить профиль</string> <string name="title_update_profile">Обновить профиль</string>
<string name="title_about">О программе</string> <string name="title_about">О программе</string>
...@@ -53,7 +53,7 @@ ...@@ -53,7 +53,7 @@
<!-- Settings List --> <!-- Settings List -->
<string-array name="settings_actions"> <string-array name="settings_actions">
<item name="item_preferences">Preferences</item> <!-- TODO Add translation --> <item name="item_preferences">Персональные</item>
<item name="item_password">Изменить пароль</item> <item name="item_password">Изменить пароль</item>
<item name="item_password">О программе</item> <item name="item_password">О программе</item>
</string-array> </string-array>
...@@ -136,7 +136,7 @@ ...@@ -136,7 +136,7 @@
<string name="msg_channel_name">Название канала</string> <string name="msg_channel_name">Название канала</string>
<string name="msg_search">Поиск</string> <string name="msg_search">Поиск</string>
<string name="msg_welcome_to_rocket_chat">Welcome to Rocket.Chat</string> <!-- TODO Add translation --> <string name="msg_welcome_to_rocket_chat">Welcome to Rocket.Chat</string> <!-- TODO Add translation -->
<string name="msg_open_source_communication">Open Source Communication</string> <!-- TODO Add translation --> <string name="msg_team_communication">Open Source Communication</string> <!-- TODO Add translation -->
<string name="msg_login_with_email">Login with e-mail</string> <!-- TODO Add translation --> <string name="msg_login_with_email">Login with e-mail</string> <!-- TODO Add translation -->
<string name="msg_create_account">Create an account</string> <!-- TODO Add translation --> <string name="msg_create_account">Create an account</string> <!-- TODO Add translation -->
<string name="msg_continue_with_facebook">Continue with Facebook</string> <!-- TODO Add translation --> <string name="msg_continue_with_facebook">Continue with Facebook</string> <!-- TODO Add translation -->
...@@ -160,10 +160,10 @@ ...@@ -160,10 +160,10 @@
<string name="msg_channel_created_successfully">Канал создан успешно</string> <string name="msg_channel_created_successfully">Канал создан успешно</string>
<!-- Preferences messages --> <!-- Preferences messages -->
<string name="msg_analytics_tracking">Analytics tracking</string> <!-- TODO Add translation --> <string name="msg_analytics_tracking">Отслеживание Analytics</string>
<string name="msg_send_analytics_tracking">Send anonymous statics to help improving this app</string> <!-- TODO Add translation --> <string name="msg_send_analytics_tracking">Отправлять анонимную статистику для улучшения приложения.</string>
<string name="msg_do_not_send_analytics_tracking">Do not send anonymous statics to help improving this app</string> <!-- TODO Add translation --> <string name="msg_do_not_send_analytics_tracking">Не отправлять анонимную статистику для улучшения приложения</string>
<string name="msg_not_applicable_since_it_is_a_foss_version">Not applicable since it is a FOSS version</string> <!-- TODO Add translation --> <string name="msg_not_applicable_since_it_is_a_foss_version">Не применимо, так как это FOSS версия</string>
<!-- System messages --> <!-- System messages -->
<string name="message_room_name_changed">%2$s изменил название канала на %1$s</string> <string name="message_room_name_changed">%2$s изменил название канала на %1$s</string>
......
This diff is collapsed.
<!--
REMARK:
When adding a new string in this file do not forget to add a proper translation for the
corresponding supported language - if applicable.
Please, follow the rules as shown here (by adding a new string in the correct section).
Coding style:
https://github.com/RocketChat/java-code-styles/blob/master/CODING_STYLE.md#strings
-->
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<string name="app_name" translatable="false">Rocket.Chat</string> <string name="app_name" translatable="false">Rocket.Chat</string>
...@@ -85,7 +96,6 @@ ...@@ -85,7 +96,6 @@
<string name="msg_invalid_2fa_code">Invalid 2FA Code</string> <string name="msg_invalid_2fa_code">Invalid 2FA Code</string>
<string name="msg_invalid_file">Invalid file</string> <string name="msg_invalid_file">Invalid file</string>
<string name="msg_invalid_server_url">Invalid server URL</string> <string name="msg_invalid_server_url">Invalid server URL</string>
<string name="msg_content_description_onboarding">Onboarding image</string>
<string name="msg_content_description_log_in_using_facebook">Login using Facebook</string> <string name="msg_content_description_log_in_using_facebook">Login using Facebook</string>
<string name="msg_content_description_log_in_using_github">Login using Github</string> <string name="msg_content_description_log_in_using_github">Login using Github</string>
<string name="msg_content_description_log_in_using_google">Login using Google</string> <string name="msg_content_description_log_in_using_google">Login using Google</string>
...@@ -140,7 +150,7 @@ ...@@ -140,7 +150,7 @@
<string name="msg_send">Send</string> <string name="msg_send">Send</string>
<string name="msg_sent_attachment">Sent an attachment</string> <string name="msg_sent_attachment">Sent an attachment</string>
<string name="msg_welcome_to_rocket_chat">Welcome to Rocket.Chat</string> <string name="msg_welcome_to_rocket_chat">Welcome to Rocket.Chat</string>
<string name="msg_open_source_communication">Open Source Communication</string> <string name="msg_team_communication">Team Communication</string>
<string name="msg_login_with_email">Login with e-mail</string> <string name="msg_login_with_email">Login with e-mail</string>
<string name="msg_create_account">Create an account</string> <string name="msg_create_account">Create an account</string>
<string name="msg_continue_with_facebook">Continue with Facebook</string> <string name="msg_continue_with_facebook">Continue with Facebook</string>
......
...@@ -2,14 +2,6 @@ ...@@ -2,14 +2,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="chat.rocket.android"> package="chat.rocket.android">
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<permission
android:name="${applicationId}.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="${applicationId}.permission.C2D_MESSAGE" />
<application <application
android:name=".app.RocketChatApplication" android:name=".app.RocketChatApplication"
android:allowBackup="true" android:allowBackup="true"
...@@ -20,25 +12,6 @@ ...@@ -20,25 +12,6 @@
android:roundIcon="@mipmap/ic_launcher_round" android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"> android:supportsRtl="true">
<receiver
android:name="com.google.android.gms.gcm.GcmReceiver"
android:exported="true"
android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="${applicationId}" />
</intent-filter>
</receiver>
<service
android:name=".push.FirebaseTokenService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
<service <service
android:name=".push.FirebaseMessagingService" android:name=".push.FirebaseMessagingService"
android:enabled="true" android:enabled="true"
......
package chat.rocket.android.util.helper.analytics package chat.rocket.android.analytics
import chat.rocket.android.util.helper.analytics.event.AuthenticationEvent import chat.rocket.android.analytics.event.AuthenticationEvent
import chat.rocket.android.util.helper.analytics.event.ScreenViewEvent import chat.rocket.android.analytics.event.ScreenViewEvent
import chat.rocket.android.util.helper.analytics.event.SubscriptionTypeEvent import chat.rocket.android.analytics.event.SubscriptionTypeEvent
import com.crashlytics.android.answers.Answers import com.crashlytics.android.answers.Answers
import com.crashlytics.android.answers.CustomEvent import com.crashlytics.android.answers.CustomEvent
import com.crashlytics.android.answers.LoginEvent import com.crashlytics.android.answers.LoginEvent
import com.crashlytics.android.answers.SignUpEvent import com.crashlytics.android.answers.SignUpEvent
// TODO inject the and analyticsTrackingInteractor and GetCurrentServerInteractor class AnswersAnalytics : Analytics {
object AnalyticsManager : Analytics {
override fun logLogin(event: AuthenticationEvent, loginSucceeded: Boolean) = override fun logLogin(event: AuthenticationEvent, loginSucceeded: Boolean) =
Answers.getInstance() Answers.getInstance()
......
package chat.rocket.android.analytics
import android.content.Context
import android.os.Bundle
import chat.rocket.android.analytics.event.AuthenticationEvent
import chat.rocket.android.analytics.event.ScreenViewEvent
import chat.rocket.android.analytics.event.SubscriptionTypeEvent
import com.google.firebase.analytics.FirebaseAnalytics
import javax.inject.Inject
class GoogleAnalyticsForFirebase @Inject constructor(val context: Context) :
Analytics {
private val firebaseAnalytics = FirebaseAnalytics.getInstance(context)
override fun logLogin(event: AuthenticationEvent, loginSucceeded: Boolean) {
firebaseAnalytics.logEvent(FirebaseAnalytics.Event.LOGIN, Bundle(1).apply {
putString(FirebaseAnalytics.Param.METHOD, event.methodName)
putLong(FirebaseAnalytics.Param.SUCCESS, if (loginSucceeded) 1 else 0)
})
}
override fun logSignUp(event: AuthenticationEvent, signUpSucceeded: Boolean) {
firebaseAnalytics.logEvent(FirebaseAnalytics.Event.SIGN_UP, Bundle(1).apply {
putString(FirebaseAnalytics.Param.METHOD, event.methodName)
putLong(FirebaseAnalytics.Param.SUCCESS, if (signUpSucceeded) 1 else 0)
})
}
override fun logScreenView(event: ScreenViewEvent) {
firebaseAnalytics.logEvent("screen_view", Bundle(1).apply {
putString("screen", event.screenName)
})
}
override fun logMessageSent(event: SubscriptionTypeEvent, serverUrl: String) {
firebaseAnalytics.logEvent("message_sent", Bundle(1).apply {
putString("subscription_type", event.subscriptionTypeName)
putString("server", serverUrl)
})
}
override fun logMediaUploaded(event: SubscriptionTypeEvent, mimeType: String) {
firebaseAnalytics.logEvent("media_upload", Bundle(1).apply {
putString("subscription_type", event.subscriptionTypeName)
putString("media_type", mimeType)
})
}
override fun logReaction(event: SubscriptionTypeEvent) {
firebaseAnalytics.logEvent("reaction", Bundle(1).apply {
putString("subscription_type", event.subscriptionTypeName)
})
}
override fun logServerSwitch(serverUrl: String, serverCount: Int) {
firebaseAnalytics.logEvent("server_switch", Bundle(1).apply {
putString("server_url", serverUrl)
putInt("server_count", serverCount)
})
}
}
package chat.rocket.android.dagger.module package chat.rocket.android.dagger.module
import androidx.work.Worker
import chat.rocket.android.chatroom.di.MessageServiceProvider import chat.rocket.android.chatroom.di.MessageServiceProvider
import chat.rocket.android.chatroom.service.MessageService import chat.rocket.android.chatroom.service.MessageService
import chat.rocket.android.dagger.qualifier.WorkerKey
import chat.rocket.android.push.FirebaseMessagingService import chat.rocket.android.push.FirebaseMessagingService
import chat.rocket.android.push.FirebaseTokenService
import chat.rocket.android.push.di.FirebaseMessagingServiceProvider import chat.rocket.android.push.di.FirebaseMessagingServiceProvider
import chat.rocket.android.push.di.FirebaseTokenServiceProvider import chat.rocket.android.push.di.TokenRegistrationSubComponent
import chat.rocket.android.push.worker.TokenRegistrationWorker
import dagger.Binds
import dagger.Module import dagger.Module
import dagger.android.AndroidInjector
import dagger.android.ContributesAndroidInjector import dagger.android.ContributesAndroidInjector
import dagger.multibindings.IntoMap
@Module abstract class ServiceBuilder { @Module(subcomponents = [TokenRegistrationSubComponent::class])
abstract class ServiceBuilder {
@ContributesAndroidInjector(modules = [FirebaseTokenServiceProvider::class])
abstract fun bindFirebaseTokenService(): FirebaseTokenService
@ContributesAndroidInjector(modules = [FirebaseMessagingServiceProvider::class]) @ContributesAndroidInjector(modules = [FirebaseMessagingServiceProvider::class])
abstract fun bindGcmListenerService(): FirebaseMessagingService abstract fun bindGcmListenerService(): FirebaseMessagingService
@ContributesAndroidInjector(modules = [MessageServiceProvider::class]) @ContributesAndroidInjector(modules = [MessageServiceProvider::class])
abstract fun bindMessageService(): MessageService abstract fun bindMessageService(): MessageService
@Binds
@IntoMap
@WorkerKey(TokenRegistrationWorker::class)
abstract fun bindTokenRegistrationWorkerFactory(
builder: TokenRegistrationSubComponent.Builder
): AndroidInjector.Factory<out Worker>
} }
\ No newline at end of file
package chat.rocket.android.extensions
import com.google.android.gms.tasks.Task
import kotlin.coroutines.experimental.suspendCoroutine
@JvmName("awaitVoid")
suspend fun Task<Void>.await() = suspendCoroutine<Unit> { continuation ->
addOnSuccessListener { continuation.resume(Unit) }
addOnFailureListener { continuation.resumeWithException(it) }
}
suspend fun <TResult> Task<TResult>.await() = suspendCoroutine<TResult> { continuation ->
addOnSuccessListener { continuation.resume(it) }
addOnFailureListener { continuation.resumeWithException(it) }
}
\ No newline at end of file
package chat.rocket.android.push package chat.rocket.android.push
import androidx.core.os.bundleOf import androidx.core.os.bundleOf
import androidx.work.Constraints
import androidx.work.NetworkType
import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.WorkManager
import androidx.work.workDataOf
import chat.rocket.android.push.worker.TokenRegistrationWorker
import com.google.firebase.messaging.FirebaseMessagingService import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage import com.google.firebase.messaging.RemoteMessage
import dagger.android.AndroidInjection import dagger.android.AndroidInjection
...@@ -17,8 +23,22 @@ class FirebaseMessagingService : FirebaseMessagingService() { ...@@ -17,8 +23,22 @@ class FirebaseMessagingService : FirebaseMessagingService() {
} }
override fun onMessageReceived(message: RemoteMessage) { override fun onMessageReceived(message: RemoteMessage) {
// XXX - for now this is ok, if we start to do network calls, use a Worker instead
message.data?.let { message.data?.let {
pushManager.handle(bundleOf(*(it.map { Pair(it.key, it.value) }).toTypedArray())) pushManager.handle(bundleOf(*(it.map { Pair(it.key, it.value) }).toTypedArray()))
} }
} }
override fun onNewToken(token: String) {
val data = workDataOf("token" to token)
val constraint =
Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build()
val work = OneTimeWorkRequestBuilder<TokenRegistrationWorker>()
.setInputData(data)
.setConstraints(constraint)
.build()
// Schedule a job since we are using network...
WorkManager.getInstance().enqueue(work)
}
} }
\ No newline at end of file
package chat.rocket.android.push
import chat.rocket.android.infrastructure.LocalRepository
import chat.rocket.android.server.domain.GetCurrentServerInteractor
import chat.rocket.android.server.infraestructure.RocketChatClientFactory
import chat.rocket.android.util.retryIO
import chat.rocket.common.RocketChatException
import chat.rocket.core.internal.rest.registerPushToken
import com.google.firebase.iid.FirebaseInstanceId
import com.google.firebase.iid.FirebaseInstanceIdService
import dagger.android.AndroidInjection
import kotlinx.coroutines.experimental.launch
import timber.log.Timber
import javax.inject.Inject
class FirebaseTokenService : FirebaseInstanceIdService() {
@Inject
lateinit var factory: RocketChatClientFactory
@Inject
lateinit var getCurrentServerInteractor: GetCurrentServerInteractor
@Inject
lateinit var localRepository: LocalRepository
override fun onCreate() {
super.onCreate()
AndroidInjection.inject(this)
}
override fun onTokenRefresh() {
try {
val fcmToken = FirebaseInstanceId.getInstance().token
val currentServer = getCurrentServerInteractor.get()
val client = currentServer?.let { factory.create(currentServer) }
fcmToken?.let {
localRepository.save(LocalRepository.KEY_PUSH_TOKEN, fcmToken)
client?.let {
launch {
try {
Timber.d("Registering push token: $fcmToken for ${client.url}")
retryIO("register push token") { client.registerPushToken(fcmToken) }
} catch (ex: RocketChatException) {
Timber.e(ex, "Error registering push token")
}
}
}
}
} catch (ex: Exception) {
Timber.e(ex, "Error refreshing Firebase TOKEN")
}
}
}
\ No newline at end of file
package chat.rocket.android.push
import androidx.work.Constraints
import androidx.work.NetworkType
import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.WorkManager
import chat.rocket.android.push.worker.TokenRegistrationWorker
fun refreshPushToken() {
val constraint =
Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build()
val work = OneTimeWorkRequestBuilder<TokenRegistrationWorker>()
.setConstraints(constraint)
.build()
// Schedule a job since we are using network...
WorkManager.getInstance().enqueue(work)
}
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment