Browse Source

Merge remote-tracking branch 'remotes/origin/develop'

master v2.4.2
Sergey Petrov 4 months ago
parent
commit
a7fb60e6f3
30 changed files with 291 additions and 132 deletions
  1. +8
    -4
      app/build.gradle
  2. +5
    -0
      app/src/main/AndroidManifest.xml
  3. +2
    -4
      app/src/main/java/com/telex/App.kt
  4. +6
    -6
      app/src/main/java/com/telex/analytics/FirebaseAnalyticsReporter.kt
  5. +0
    -12
      app/src/main/java/com/telex/di/AnalyticsModule.kt
  6. +25
    -0
      app/src/main/java/com/telex/di/AppToolsModule.kt
  7. +0
    -11
      app/src/main/java/com/telex/di/RemoteConfigModule.kt
  8. +11
    -9
      app/src/main/java/com/telex/model/interactors/FirebaseRemoteConfigInteractor.kt
  9. +62
    -0
      app/src/main/java/com/telex/review/InAppReviewManager.kt
  10. +6
    -4
      base/src/free/java/com/telex/base/presentation/home/TopBannerDelegate.kt
  11. +2
    -4
      base/src/main/java/com/telex/base/BaseApp.kt
  12. +28
    -23
      base/src/main/java/com/telex/base/analytics/AnalyticsHelper.kt
  13. +0
    -11
      base/src/main/java/com/telex/base/di/AnalyticsModule.kt
  14. +22
    -0
      base/src/main/java/com/telex/base/di/AppToolsModule.kt
  15. +0
    -11
      base/src/main/java/com/telex/base/di/RemoteConfigModule.kt
  16. +22
    -0
      base/src/main/java/com/telex/base/extention/RxExtensions.kt
  17. +2
    -1
      base/src/main/java/com/telex/base/model/interactors/RemoteConfigInteractor.kt
  18. +8
    -0
      base/src/main/java/com/telex/base/model/source/local/AppData.kt
  19. +29
    -10
      base/src/main/java/com/telex/base/presentation/AppActivity.kt
  20. +10
    -9
      base/src/main/java/com/telex/base/presentation/pages/BaseTopBannerDelegate.kt
  21. +0
    -1
      base/src/main/java/com/telex/base/presentation/pages/PagesAdapter.kt
  22. +1
    -2
      base/src/main/java/com/telex/base/presentation/pages/PagesFragment.kt
  23. +9
    -0
      base/src/main/java/com/telex/base/review/AppReviewManager.kt
  24. +14
    -0
      base/src/main/java/com/telex/base/review/DefaultAppReviewManager.kt
  25. +9
    -0
      base/src/main/res/layout/dialog_iframe.xml
  26. +3
    -3
      base/src/main/res/layout/dialog_image_url_caption.xml
  27. +1
    -2
      base/src/main/res/layout/fragment_pages.xml
  28. +1
    -0
      base/src/main/res/layout/layout_top_banner.xml
  29. +3
    -3
      base/src/pro/java/com/telex/base/presentation/home/TopBannerDelegate.kt
  30. +2
    -2
      build.gradle

+ 8
- 4
app/build.gradle View File

@ -80,10 +80,14 @@ android {
dependencies {
implementation project(':base')
implementation 'com.google.firebase:firebase-crashlytics:17.3.0'
implementation 'com.google.firebase:firebase-analytics:18.0.0'
implementation 'com.google.firebase:firebase-core:18.0.0'
implementation 'com.google.firebase:firebase-config:19.2.0'
implementation "com.google.android.play:core:1.8.3"
implementation platform('com.google.firebase:firebase-bom:26.1.0')
// Declare the dependencies for the Remote Config and Analytics libraries
// When using the BoM, you don't specify versions in Firebase library dependencies
implementation 'com.google.firebase:firebase-config-ktx'
implementation 'com.google.firebase:firebase-analytics-ktx'
implementation 'com.google.firebase:firebase-crashlytics-ktx'
kapt "com.github.moxy-community:moxy-compiler:$moxyVersion"
kapt 'com.github.stephanenicolas.toothpick:toothpick-compiler:3.0.2'

+ 5
- 0
app/src/main/AndroidManifest.xml View File

@ -2,6 +2,11 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.telex">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<application android:name=".App">
<activity
android:name=".base.presentation.splash.SplashActivity"

+ 2
- 4
app/src/main/java/com/telex/App.kt View File

@ -4,8 +4,7 @@ import com.telex.base.BaseApp
import com.telex.base.di.AppModule
import com.telex.base.di.Scopes
import com.telex.base.utils.Constants
import com.telex.di.AnalyticsModule
import com.telex.di.RemoteConfigModule
import com.telex.di.AppToolsModule
import com.telex.utils.DebugTree
import com.telex.utils.ReleaseTree
import timber.log.Timber
@ -21,8 +20,7 @@ class App : BaseApp() {
val scope = Toothpick.openScope(Scopes.App)
scope.installModules(
AppModule(this),
AnalyticsModule(this),
RemoteConfigModule()
AppToolsModule(this)
)
return scope
}

+ 6
- 6
app/src/main/java/com/telex/analytics/FirebaseAnalyticsReporter.kt View File

@ -1,18 +1,18 @@
package com.telex.analytics
import android.content.Context
import android.os.Bundle
import com.google.firebase.analytics.FirebaseAnalytics
import com.google.firebase.analytics.ktx.analytics
import com.google.firebase.ktx.Firebase
import com.telex.base.analytics.AnalyticsReporter
/**
* @author Sergey Petrov
*/
class FirebaseAnalyticsReporter(
private val context: Context
) : AnalyticsReporter {
class FirebaseAnalyticsReporter : AnalyticsReporter {
private val firebaseAnalytics = Firebase.analytics
override fun logEvent(eventKey: String) {
FirebaseAnalytics.getInstance(context).logEvent(eventKey, Bundle())
firebaseAnalytics.logEvent(eventKey, Bundle())
}
}

+ 0
- 12
app/src/main/java/com/telex/di/AnalyticsModule.kt View File

@ -1,12 +0,0 @@
package com.telex.di
import android.content.Context
import com.telex.analytics.FirebaseAnalyticsReporter
import com.telex.base.analytics.AnalyticsReporter
import toothpick.config.Module
class AnalyticsModule(context: Context) : Module() {
init {
bind(AnalyticsReporter::class.java).toInstance(FirebaseAnalyticsReporter(context))
}
}

+ 25
- 0
app/src/main/java/com/telex/di/AppToolsModule.kt View File

@ -0,0 +1,25 @@
package com.telex.di
import android.content.Context
import com.telex.analytics.FirebaseAnalyticsReporter
import com.telex.base.analytics.AnalyticsReporter
import com.telex.base.model.interactors.RemoteConfigInteractor
import com.telex.base.model.source.local.AppData
import com.telex.base.review.AppReviewManager
import com.telex.model.interactors.FirebaseRemoteConfigInteractor
import com.telex.review.InAppReviewManager
import toothpick.config.Module
class AppToolsModule(context: Context) : Module() {
init {
val appData = AppData(context)
bind(AppData::class.java).toInstance(appData)
val analyticsReporter = FirebaseAnalyticsReporter()
bind(AnalyticsReporter::class.java).toInstance(analyticsReporter)
bind(RemoteConfigInteractor::class.java).toInstance(FirebaseRemoteConfigInteractor())
val appReviewManager = InAppReviewManager(context, appData)
bind(AppReviewManager::class.java).toInstance(appReviewManager)
}
}

+ 0
- 11
app/src/main/java/com/telex/di/RemoteConfigModule.kt View File

@ -1,11 +0,0 @@
package com.telex.di
import com.telex.base.model.interactors.RemoteConfigInteractor
import com.telex.model.interactors.FirebaseRemoteConfigInteractor
import toothpick.config.Module
class RemoteConfigModule : Module() {
init {
bind(RemoteConfigInteractor::class.java).toInstance(FirebaseRemoteConfigInteractor())
}
}

+ 11
- 9
app/src/main/java/com/telex/model/interactors/FirebaseRemoteConfigInteractor.kt View File

@ -5,12 +5,12 @@ import com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings
import com.google.gson.Gson
import com.google.gson.JsonSyntaxException
import com.telex.R
import com.telex.base.BuildConfig
import com.telex.base.model.interactors.RemoteConfigInteractor
import com.telex.base.model.interactors.RemoteConfigInteractor.Companion.CACHE_EXPIRATION
import com.telex.base.model.interactors.RemoteConfigInteractor.Companion.CREATED_WITH_CAPTION_DISABLED
import com.telex.base.model.interactors.RemoteConfigInteractor.Companion.MINIMUM_FETCH_INTERVAL_IN_SECONDS
import com.telex.base.model.interactors.RemoteConfigInteractor.Companion.TOP_BANNER
import com.telex.base.model.source.remote.data.TopBannerData
import com.telex.base.utils.Constants.isDebug
import timber.log.Timber
/**
@ -19,21 +19,23 @@ import timber.log.Timber
class FirebaseRemoteConfigInteractor : RemoteConfigInteractor {
private var remoteConfig = FirebaseRemoteConfig.getInstance()
private val minimumFetchIntervalInSeconds = when {
isDebug() -> 0
else -> MINIMUM_FETCH_INTERVAL_IN_SECONDS
}
init {
val configSettings = FirebaseRemoteConfigSettings.Builder()
.setDeveloperModeEnabled(BuildConfig.DEBUG)
.setMinimumFetchIntervalInSeconds(minimumFetchIntervalInSeconds)
.build()
remoteConfig.setConfigSettings(configSettings)
remoteConfig.setDefaults(R.xml.remote_config_defaults)
remoteConfig.setConfigSettingsAsync(configSettings)
remoteConfig.setDefaultsAsync(R.xml.remote_config_defaults)
}
override fun fetch(onCompleted: () -> Unit) {
val cacheExpiration = if (BuildConfig.DEBUG) 0 else CACHE_EXPIRATION
remoteConfig.fetch(cacheExpiration)
remoteConfig.fetchAndActivate()
.addOnCompleteListener { task ->
if (task.isSuccessful) {
remoteConfig.activateFetched()
onCompleted.invoke()
}
}

+ 62
- 0
app/src/main/java/com/telex/review/InAppReviewManager.kt View File

@ -0,0 +1,62 @@
package com.telex.review
import android.app.Activity
import android.content.Context
import com.google.android.play.core.review.ReviewManagerFactory
import com.telex.base.analytics.AnalyticsHelper
import com.telex.base.model.source.local.AppData
import com.telex.base.review.AppReviewManager
import io.reactivex.Completable
import java.lang.ref.WeakReference
import java.util.concurrent.TimeUnit
import javax.inject.Singleton
/**
* @author Sergey Petrov
*/
private val APP_REVIEW_REQUEST_INTERVAL = TimeUnit.DAYS.toMillis(60) // 2 months
@Singleton
class InAppReviewManager constructor(
private val context: Context,
private val appData: AppData
) : AppReviewManager {
override fun tryRequestAppReview(activity: Activity): Completable {
val activityReference = WeakReference(activity)
return Completable.create { emitter ->
if (needRequestAppReview()) {
val reviewManager = ReviewManagerFactory.create(context)
val requestReviewFlow = reviewManager.requestReviewFlow()
AnalyticsHelper.logAppReviewRequested()
appData.putLastAppReviewRequestTime(System.currentTimeMillis())
requestReviewFlow.addOnCompleteListener { request ->
when {
request.isSuccessful -> {
activityReference.get()?.apply {
reviewManager.launchReviewFlow(this, request.result)
.addOnCompleteListener {
emitter.onComplete()
}.addOnFailureListener { emitter.tryOnError(it) }
} ?: emitter.onComplete()
}
else -> {
emitter.onComplete()
}
}
}.addOnFailureListener { emitter.tryOnError(it) }
} else emitter.onComplete()
}
}
override fun trackAuthorizedAppLaunch() {
appData.putAuthorizedAppLaunch(appData.getAuthorizedAppLaunch() + 1)
}
private fun needRequestAppReview(): Boolean {
return appData.getAuthorizedAppLaunch() % 10 == 0 &&
System.currentTimeMillis() - appData.getLastAppReviewRequestTime() > APP_REVIEW_REQUEST_INTERVAL
}
}

+ 6
- 4
base/src/free/java/com/telex/base/presentation/home/TopBannerDelegate.kt View File

@ -2,21 +2,23 @@ package com.telex.base.presentation.home
import android.content.Intent
import com.telex.base.model.source.remote.data.TopBannerData
import com.telex.base.presentation.base.BaseActivity
import com.telex.base.presentation.pages.BaseTopBannerDelegate
import com.telex.base.presentation.pages.PagesFragment
/**
* @author Sergey Petrov
*/
class TopBannerDelegate(
activity: BaseActivity,
fragment: PagesFragment?,
banner: TopBannerData
) : BaseTopBannerDelegate(activity, banner) {
) : BaseTopBannerDelegate(fragment, banner) {
override val enabled: Boolean
get() = !banner.disabled
override fun showDefaultOnSecondActionClicked() {
activity.startActivity(Intent(activity, UpgradeToProActivity::class.java))
fragment?.activity?.apply {
startActivity(Intent(this, UpgradeToProActivity::class.java))
}
}
}

+ 2
- 4
base/src/main/java/com/telex/base/BaseApp.kt View File

@ -2,9 +2,8 @@ package com.telex.base
import androidx.appcompat.app.AppCompatDelegate
import androidx.multidex.MultiDexApplication
import com.telex.base.di.AnalyticsModule
import com.telex.base.di.AppModule
import com.telex.base.di.RemoteConfigModule
import com.telex.base.di.AppToolsModule
import com.telex.base.di.Scopes
import com.telex.base.model.interactors.RemoteConfigInteractor
import com.telex.base.model.source.local.AppData
@ -53,8 +52,7 @@ abstract class BaseApp : MultiDexApplication() {
val scope = Toothpick.openScope(Scopes.App)
scope.installModules(
AppModule(this),
AnalyticsModule(),
RemoteConfigModule()
AppToolsModule(this)
)
return scope
}

+ 28
- 23
base/src/main/java/com/telex/base/analytics/AnalyticsHelper.kt View File

@ -8,34 +8,35 @@ import toothpick.Toothpick
* @author Sergey Petrov
*/
object AnalyticsHelper {
private const val LAUNCH_TELEGRAM = "Launch Telegram"
private const val LAUNCH_TELEGRAM = "Launch_Telegram"
private const val LOGOUT = "Logout"
private const val CREATE_PAGE = "Create Page"
private const val EDIT_PAGE = "Edit Page"
private const val EDIT_ACCOUNT_INFO = "Edit Account Info"
private const val OPEN_ACCOUNT_SETTINGS = "Open Account Settings"
private const val OPEN_PROXY = "Open Proxy"
private const val SAVE_PROXY = "Save Proxy"
private const val PROXY_ON = "Proxy On"
private const val PROXY_OFF = "Proxy Off"
private const val OPEN_PAGE_IN_BROWSER = "Open Page In Browser"
private const val COPY_PAGE_LINK = "Copy Page Link"
private const val SHARE_PAGE = "Share Page"
private const val OPEN_ABOUT_DEVELOPER = "About Developer"
private const val MOVE_BLOCK_UP = "Move Block Up"
private const val MOVE_BLOCK_DOWN = "Move Block Down"
private const val DELETE_BLOCK = "Delete Block"
private const val DUPLICATE_BLOCK = "Duplicate Block"
private const val OPEN_PAGE_STATISTICS = "Open Page Statistics"
private const val CLICK_DELETE_POST = "Click Delete Post"
private const val CLICK_TOP_BANNER = "Click Top Banner"
private const val CLICK_ADD_ACCOUNT = "Click Add Account"
private const val CLICK_DRAWER_UPGRADE_TO_PRO_BUTTON = "Click Drawer Upgrade To Pro Button"
private const val CREATE_PAGE = "Create_Page"
private const val EDIT_PAGE = "Edit_Page"
private const val EDIT_ACCOUNT_INFO = "Edit_Account_Info"
private const val OPEN_ACCOUNT_SETTINGS = "Open_Account_Settings"
private const val OPEN_PROXY = "Open_Proxy"
private const val SAVE_PROXY = "Save_Proxy"
private const val PROXY_ON = "Proxy_On"
private const val PROXY_OFF = "Proxy_Off"
private const val OPEN_PAGE_IN_BROWSER = "Open_Page_In_Browser"
private const val COPY_PAGE_LINK = "Copy_Page_Link"
private const val SHARE_PAGE = "Share_Page"
private const val OPEN_ABOUT_DEVELOPER = "About_Developer"
private const val MOVE_BLOCK_UP = "Move_Block_Up"
private const val MOVE_BLOCK_DOWN = "Move_Block_Down"
private const val DELETE_BLOCK = "Delete_Block"
private const val DUPLICATE_BLOCK = "Duplicate_Block"
private const val OPEN_PAGE_STATISTICS = "Open_Page_Statistics"
private const val CLICK_DELETE_POST = "Click_Delete_Post"
private const val CLICK_TOP_BANNER = "Click_Top_Banner"
private const val CLICK_ADD_ACCOUNT = "Click_Add_Account"
private const val CLICK_DRAWER_UPGRADE_TO_PRO_BUTTON = "Click_Drawer_Upgrade_To_Pro_Button"
private const val APP_REVIEW_REQUESTED = "App_Review_Requested"
private var analyticsReporter: AnalyticsReporter = Toothpick.openScope(Scopes.App).getInstance(AnalyticsReporter::class.java)
private fun logEvent(eventKey: String) {
if (!BuildConfig.DEBUG) {
if (BuildConfig.DEBUG) {
analyticsReporter.logEvent(eventKey)
}
}
@ -131,4 +132,8 @@ object AnalyticsHelper {
fun logClickDrawerUpgradeToProButton() {
logEvent(CLICK_DRAWER_UPGRADE_TO_PRO_BUTTON)
}
fun logAppReviewRequested() {
logEvent(APP_REVIEW_REQUESTED)
}
}

+ 0
- 11
base/src/main/java/com/telex/base/di/AnalyticsModule.kt View File

@ -1,11 +0,0 @@
package com.telex.base.di
import com.telex.base.analytics.AnalyticsReporter
import com.telex.base.analytics.DefaultAnalyticsReporter
import toothpick.config.Module
class AnalyticsModule : Module() {
init {
bind(AnalyticsReporter::class.java).toInstance(DefaultAnalyticsReporter())
}
}

+ 22
- 0
base/src/main/java/com/telex/base/di/AppToolsModule.kt View File

@ -0,0 +1,22 @@
package com.telex.base.di
import android.content.Context
import com.telex.base.analytics.AnalyticsReporter
import com.telex.base.analytics.DefaultAnalyticsReporter
import com.telex.base.model.interactors.DefaultRemoteConfigInteractor
import com.telex.base.model.interactors.RemoteConfigInteractor
import com.telex.base.model.source.local.AppData
import com.telex.base.review.AppReviewManager
import com.telex.base.review.DefaultAppReviewManager
import toothpick.config.Module
class AppToolsModule(context: Context) : Module() {
init {
val appData = AppData(context)
bind(AppData::class.java).toInstance(appData)
bind(AnalyticsReporter::class.java).toInstance(DefaultAnalyticsReporter())
bind(RemoteConfigInteractor::class.java).toInstance(DefaultRemoteConfigInteractor())
bind(AppReviewManager::class.java).toInstance(DefaultAppReviewManager())
}
}

+ 0
- 11
base/src/main/java/com/telex/base/di/RemoteConfigModule.kt View File

@ -1,11 +0,0 @@
package com.telex.base.di
import com.telex.base.model.interactors.DefaultRemoteConfigInteractor
import com.telex.base.model.interactors.RemoteConfigInteractor
import toothpick.config.Module
class RemoteConfigModule : Module() {
init {
bind(RemoteConfigInteractor::class.java).toInstance(DefaultRemoteConfigInteractor())
}
}

+ 22
- 0
base/src/main/java/com/telex/base/extention/RxExtensions.kt View File

@ -6,6 +6,7 @@ import io.reactivex.Maybe
import io.reactivex.Observable
import io.reactivex.Single
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import timber.log.Timber
@ -51,3 +52,24 @@ fun Completable.withDefaults(): Completable {
.doOnError { error -> Timber.e(error) }
}
}
fun Completable.justSubscribe(
onComplete: () -> Unit = {},
onError: (Throwable) -> Unit = { error -> Timber.e(error) }
): Disposable = subscribe({ onComplete.invoke() }, { error -> onError.invoke(error) })
fun <T> Observable<T>.justSubscribe(
onNext: (T) -> Unit = {},
onError: (Throwable) -> Unit = { error -> Timber.e(error) }
): Disposable = subscribe({ result -> onNext.invoke(result) }, { error -> onError.invoke(error) })
fun <T> Single<T>.justSubscribe(
onSuccess: (T) -> Unit = {},
onError: (Throwable) -> Unit = { error -> Timber.e(error) }
): Disposable = subscribe({ result -> onSuccess.invoke(result) }, { error -> onError.invoke(error) })
fun <T> Maybe<T>.justSubscribe(
onSuccess: (T) -> Unit = {},
onError: (Throwable) -> Unit = { error -> Timber.e(error) }
): Disposable = subscribe({ result -> onSuccess.invoke(result) }, { error -> onError.invoke(error) })

+ 2
- 1
base/src/main/java/com/telex/base/model/interactors/RemoteConfigInteractor.kt View File

@ -1,6 +1,7 @@
package com.telex.base.model.interactors
import com.telex.base.model.source.remote.data.TopBannerData
import java.util.concurrent.TimeUnit
/**
* @author Sergey Petrov
@ -11,7 +12,7 @@ interface RemoteConfigInteractor {
fun createdWithCaptionDisabled(): Boolean
companion object {
const val CACHE_EXPIRATION = 3600L // 1 hour in milliseconds
val MINIMUM_FETCH_INTERVAL_IN_SECONDS = TimeUnit.HOURS.toSeconds(12)
const val TOP_BANNER = "top_banner"
const val CREATED_WITH_CAPTION_DISABLED = "created_with_caption_disabled"
}

+ 8
- 0
base/src/main/java/com/telex/base/model/source/local/AppData.kt View File

@ -26,6 +26,12 @@ class AppData @Inject constructor(context: Context) {
fun needShowMultipleImagesUploadingDialog(): Boolean = preferences.getBoolean(MULTIPLE_IMAGES_UPLOADING_DIALOG, true)
fun putNeedShowMultipleImagesUploadingDialog(need: Boolean) = preferences.edit().putBoolean(MULTIPLE_IMAGES_UPLOADING_DIALOG, need).apply()
fun getLastAppReviewRequestTime(): Long = preferences.getLong(LAST_APP_REVIEW_REQUEST_TIME, -1)
fun putLastAppReviewRequestTime(time: Long) = preferences.edit().putLong(LAST_APP_REVIEW_REQUEST_TIME, time).apply()
fun getAuthorizedAppLaunch(): Int = preferences.getInt(AUTHORIZED_APP_LAUNCH, 0)
fun putAuthorizedAppLaunch(count: Int) = preferences.edit().putInt(AUTHORIZED_APP_LAUNCH, count).apply()
fun clearAuthData() {
putCurrentAccessToken(null)
}
@ -53,5 +59,7 @@ class AppData @Inject constructor(context: Context) {
private const val NIGHT_MODE_ENABLED = "NIGHT_MODE_ENABLED"
private const val NEED_SHOW_ADD_ACCOUNT_DIALOG = "NEED_SHOW_ADD_ACCOUNT_DIALOG"
private const val MULTIPLE_IMAGES_UPLOADING_DIALOG = "MULTIPLE_IMAGES_UPLOADING_DIALOG"
private const val LAST_APP_REVIEW_REQUEST_TIME = "LAST_APP_REVIEW_REQUEST_TIME"
private const val AUTHORIZED_APP_LAUNCH = "AUTHORIZED_APP_LAUNCH"
}
}

+ 29
- 10
base/src/main/java/com/telex/base/presentation/AppActivity.kt View File

@ -13,15 +13,21 @@ import androidx.navigation.NavGraph
import androidx.navigation.fragment.findNavController
import com.google.android.material.transition.Hold
import com.telex.base.R
import com.telex.base.extention.justSubscribe
import com.telex.base.extention.withDefaults
import com.telex.base.model.interactors.UserInteractor
import com.telex.base.presentation.base.BaseActivity
import com.telex.base.presentation.drawer.BottomNavigationDrawerFragment
import com.telex.base.presentation.page.PageEditorFragmentDirections
import com.telex.base.presentation.pages.DraftsFragment
import com.telex.base.presentation.pages.PagesFragment
import com.telex.base.review.AppReviewManager
import io.reactivex.Completable
import kotlinx.android.synthetic.main.activity_app.*
import moxy.presenter.InjectPresenter
import moxy.presenter.ProvidePresenter
import toothpick.Toothpick
import javax.inject.Inject
/**
* @author Sergey Petrov
@ -30,6 +36,8 @@ class AppActivity : BaseActivity(), AppActivityView {
override val layoutRes: Int = R.layout.activity_app
@Inject
lateinit var appReviewManager: AppReviewManager
private var navController: NavController? = null
private lateinit var navGraph: NavGraph
@ -44,6 +52,8 @@ class AppActivity : BaseActivity(), AppActivityView {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Toothpick.inject(this, scope)
setupStatusBar()
overridePendingTransition(0, 0)
@ -53,6 +63,7 @@ class AppActivity : BaseActivity(), AppActivityView {
if (savedInstanceState == null) {
if (scope.getInstance(UserInteractor::class.java).isTokenValid()) {
navGraph.startDestination = R.id.pagesFragment
trackAndTryRequestAppReview()
} else {
navGraph.startDestination = R.id.loginFragment
}
@ -113,16 +124,6 @@ class AppActivity : BaseActivity(), AppActivityView {
}
}
private fun circularRevealActivity() {
val cx = coordinatorLayout.width / 2
val cy = coordinatorLayout.height / 2
val finalRadius = coordinatorLayout.width.coerceAtLeast(coordinatorLayout.height)
val circularReveal = ViewAnimationUtils.createCircularReveal(coordinatorLayout, cx, cy, 0f, finalRadius.toFloat())
circularReveal.duration = 700
coordinatorLayout.visibility = View.VISIBLE
circularReveal.start()
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
getCurrentFragment()?.onActivityResult(requestCode, resultCode, data)
@ -133,6 +134,16 @@ class AppActivity : BaseActivity(), AppActivityView {
getCurrentFragment()?.onRequestPermissionsResult(requestCode, permissions, grantResults)
}
private fun circularRevealActivity() {
val cx = coordinatorLayout.width / 2
val cy = coordinatorLayout.height / 2
val finalRadius = coordinatorLayout.width.coerceAtLeast(coordinatorLayout.height)
val circularReveal = ViewAnimationUtils.createCircularReveal(coordinatorLayout, cx, cy, 0f, finalRadius.toFloat())
circularReveal.duration = 700
coordinatorLayout.visibility = View.VISIBLE
circularReveal.start()
}
private fun showBottomAppBar() {
fab.setImageState(intArrayOf(-android.R.attr.state_activated), true)
bottomAppBar.visibility = View.VISIBLE
@ -160,4 +171,12 @@ class AppActivity : BaseActivity(), AppActivityView {
private fun getCurrentFragment(): Fragment? {
return supportFragmentManager.findFragmentById(R.id.fragmentContainerView)?.childFragmentManager?.primaryNavigationFragment
}
private fun trackAndTryRequestAppReview() {
Completable
.fromAction { appReviewManager.trackAuthorizedAppLaunch() }
.andThen(appReviewManager.tryRequestAppReview(this))
.withDefaults()
.justSubscribe()
}
}

+ 10
- 9
base/src/main/java/com/telex/base/presentation/pages/BaseTopBannerDelegate.kt View File

@ -10,7 +10,6 @@ import com.telex.base.analytics.AnalyticsHelper
import com.telex.base.extention.isVisible
import com.telex.base.extention.setGone
import com.telex.base.model.source.remote.data.TopBannerData
import com.telex.base.presentation.base.BaseActivity
import com.telex.base.utils.ViewUtils
import kotlinx.android.synthetic.main.layout_top_banner.view.*
@ -18,8 +17,8 @@ import kotlinx.android.synthetic.main.layout_top_banner.view.*
* @author Sergey Petrov
*/
abstract class BaseTopBannerDelegate(
protected val activity: BaseActivity,
protected val banner: TopBannerData
protected val fragment: PagesFragment?,
protected val banner: TopBannerData
) {
abstract val enabled: Boolean
@ -36,7 +35,7 @@ abstract class BaseTopBannerDelegate(
firstActionButton.text = action.title
firstActionButton.setOnClickListener {
AnalyticsHelper.logTopBannerActionClick(action.title)
ViewUtils.openUrl(activity, action.url, onError = { message -> activity.showError(message) })
ViewUtils.openUrl(context, action.url, onError = { message -> fragment?.showError(message) })
}
}
banner.secondAction?.let { action ->
@ -44,15 +43,17 @@ abstract class BaseTopBannerDelegate(
secondActionButton.text = action.title
secondActionButton.setOnClickListener {
AnalyticsHelper.logTopBannerActionClick(action.title)
ViewUtils.openUrl(activity, action.url, onError = { message -> activity.showError(message) })
if (fragment != null) {
ViewUtils.openUrl(fragment.context, action.url, onError = { message -> fragment.showError(message) })
}
if (action.url.isNullOrEmpty()) {
showDefaultOnSecondActionClicked()
}
}
}
}
val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerView)
if (recyclerView.scrollState == RecyclerView.SCROLL_STATE_IDLE) {
val recyclerView = fragment?.view?.findViewById<RecyclerView>(R.id.pagesRecyclerView)
if (recyclerView?.scrollState == RecyclerView.SCROLL_STATE_IDLE) {
TransitionManager.beginDelayedTransition(coordinatorLayout, ChangeBounds())
}
}
@ -61,8 +62,8 @@ abstract class BaseTopBannerDelegate(
fun hideBanner(coordinatorLayout: CoordinatorLayout, bannerView: View) {
if (bannerView.isVisible) {
bannerView.setGone(true)
val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerView)
if (recyclerView.scrollState == RecyclerView.SCROLL_STATE_IDLE) {
val recyclerView = fragment?.view?.findViewById<RecyclerView>(R.id.pagesRecyclerView)
if (recyclerView?.scrollState == RecyclerView.SCROLL_STATE_IDLE) {
TransitionManager.beginDelayedTransition(coordinatorLayout, ChangeBounds())
}
}

+ 0
- 1
base/src/main/java/com/telex/base/presentation/pages/PagesAdapter.kt View File

@ -24,7 +24,6 @@ class PagesAdapter(
val onItemClickListener: (View, Page, EditorMode) -> Unit,
private var items: ArrayList<Page> = ArrayList(),
private val onNextPageListener: (() -> Unit)?
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private var footer: Footer? = null

+ 1
- 2
base/src/main/java/com/telex/base/presentation/pages/PagesFragment.kt View File

@ -11,7 +11,6 @@ import com.telex.base.extention.applySystemWindowInsetsPadding
import com.telex.base.extention.getColorFromAttr
import com.telex.base.model.source.local.entity.Page
import com.telex.base.model.source.remote.data.TopBannerData
import com.telex.base.presentation.base.BaseActivity
import com.telex.base.presentation.base.BaseFragment
import com.telex.base.presentation.home.TopBannerDelegate
import com.telex.base.presentation.page.EditorMode
@ -87,7 +86,7 @@ open class PagesFragment : BaseFragment(), PagesView {
}
override fun showTopBanner(banner: TopBannerData) {
topBannerDelegate = TopBannerDelegate(activity as BaseActivity, banner)
topBannerDelegate = TopBannerDelegate(this, banner)
topBannerDelegate?.showBanner(coordinatorLayout, topBannerLayout)
}

+ 9
- 0
base/src/main/java/com/telex/base/review/AppReviewManager.kt View File

@ -0,0 +1,9 @@
package com.telex.base.review
import android.app.Activity
import io.reactivex.Completable
interface AppReviewManager {
fun tryRequestAppReview(activity: Activity): Completable
fun trackAuthorizedAppLaunch()
}

+ 14
- 0
base/src/main/java/com/telex/base/review/DefaultAppReviewManager.kt View File

@ -0,0 +1,14 @@
package com.telex.base.review
import android.app.Activity
import io.reactivex.Completable
class DefaultAppReviewManager : AppReviewManager {
override fun tryRequestAppReview(activity: Activity): Completable {
return Completable.complete()
}
override fun trackAuthorizedAppLaunch() {
}
}

+ 9
- 0
base/src/main/res/layout/dialog_iframe.xml View File

@ -40,6 +40,15 @@
</com.telex.base.presentation.base.UrlTextInputLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="@dimen/text_size_tiny"
android:textColor="@color/secondary_text_color"
android:layout_marginHorizontal="@dimen/margin_16"
android:layout_marginVertical="@dimen/margin_8"
android:text="@string/iframe_hint" />
<com.google.android.material.button.MaterialButton
android:id="@+id/submitButton"
style="@style/TextButtonStyle"

+ 3
- 3
base/src/main/res/layout/dialog_image_url_caption.xml View File

@ -24,7 +24,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="@dimen/margin_16"
android:layout_marginTop="@dimen/margin_8"
android:layout_marginVertical="@dimen/margin_8"
app:hintEnabled="false">
<EditText
@ -45,13 +45,13 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="@dimen/margin_16"
android:layout_marginTop="@dimen/margin_16"
android:paddingVertical="@dimen/margin_8"
android:background="@android:color/transparent"
android:hint="@string/caption_optional"
android:paddingStart="0dp"
android:paddingEnd="0dp"
android:singleLine="true"
android:textSize="@dimen/text_size_small" />
android:textSize="@dimen/text_size_tiny" />
<com.google.android.material.button.MaterialButton
android:id="@+id/submitButton"

+ 1
- 2
base/src/main/res/layout/fragment_pages.xml View File

@ -31,8 +31,7 @@
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorAccentDark"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
android:background="?attr/colorAccentDark">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/pagesRecyclerView"

+ 1
- 0
base/src/main/res/layout/layout_top_banner.xml View File

@ -4,6 +4,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/height_status_bar"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll">

+ 3
- 3
base/src/pro/java/com/telex/base/presentation/home/TopBannerDelegate.kt View File

@ -1,16 +1,16 @@
package com.telex.base.presentation.home
import com.telex.base.model.source.remote.data.TopBannerData
import com.telex.base.presentation.base.BaseActivity
import com.telex.base.presentation.pages.BaseTopBannerDelegate
import com.telex.base.presentation.pages.PagesFragment
/**
* @author Sergey Petrov
*/
class TopBannerDelegate(
activity: BaseActivity,
fragment: PagesFragment?,
banner: TopBannerData
) : BaseTopBannerDelegate(activity, banner) {
) : BaseTopBannerDelegate(fragment, banner) {
override val enabled: Boolean
get() = !banner.disabled && banner.showForPro

+ 2
- 2
build.gradle View File

@ -29,8 +29,8 @@ task clean(type: Delete) {
}
ext {
versionCode = 50
versionName = "2.4.1"
versionCode = 54
versionName = "2.4.2"
compileSdk = 29
targetSdk = 29

Loading…
Cancel
Save