Skip to content

Commit 22d1854

Browse files
committed
Address remaining review comments: intent builders, braces, welcome flow callback, Hub write access
1 parent 0751f3c commit 22d1854

12 files changed

Lines changed: 133 additions & 45 deletions

File tree

presentation/src/main/java/org/cryptomator/presentation/CryptomatorApp.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,9 @@ class CryptomatorApp : MultiDexApplication(), HasComponent<ApplicationComponent>
166166

167167
private fun drainPendingProductDetailsCallbacks() {
168168
synchronized(pendingProductDetailsCallbacks) {
169-
if (pendingProductDetailsCallbacks.isEmpty()) return
169+
if (pendingProductDetailsCallbacks.isEmpty()) {
170+
return
171+
}
170172
val callbacks = ArrayList(pendingProductDetailsCallbacks)
171173
pendingProductDetailsCallbacks.clear()
172174
iapBillingServiceBinder?.queryProductDetails { products ->

presentation/src/main/java/org/cryptomator/presentation/licensing/LicenseEnforcer.kt

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,18 @@ package org.cryptomator.presentation.licensing
33
import android.app.Activity
44
import android.content.Context
55
import android.content.Intent
6-
import android.net.Uri
76
import android.widget.Toast
87
import androidx.annotation.StringRes
98
import org.cryptomator.domain.di.PerView
109
import org.cryptomator.presentation.R
10+
import org.cryptomator.presentation.intent.Intents
1111
import org.cryptomator.presentation.model.VaultModel
12-
import org.cryptomator.presentation.ui.activity.LicenseCheckActivity
12+
import org.cryptomator.presentation.presenter.ContextHolder
1313
import org.cryptomator.util.FlavorConfig
1414
import org.cryptomator.util.SharedPreferencesHandler
1515
import java.text.DateFormat
1616
import java.util.Date
17+
import java.util.concurrent.TimeUnit
1718
import javax.inject.Inject
1819

1920
@PerView
@@ -140,31 +141,33 @@ class LicenseEnforcer @Inject constructor(private val sharedPreferencesHandler:
140141
return false
141142
}
142143

143-
val intent = Intent(activity, LicenseCheckActivity::class.java).apply {
144-
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
145-
data = Uri.parse("app://cryptomator/")
146-
putExtra(LicenseCheckActivity.EXTRA_LOCKED_ACTION, action.name)
147-
}
144+
val intent = Intents.licenseCheckIntent()
145+
.withLockedAction(action.name)
146+
.build(activity as ContextHolder)
147+
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
148148
activity.startActivity(intent)
149149
return false
150150
}
151151

152152
fun hasWriteAccessForVault(vault: VaultModel?): Boolean {
153-
if (vault?.isHubVault == true) return vault.hasHubPaidLicense
153+
if (vault?.isHubVault == true) {
154+
return vault.hasHubPaidLicense || hasWriteAccess()
155+
}
154156
return hasWriteAccess()
155157
}
156158

157159
fun ensureWriteAccessForVault(activity: Activity, vault: VaultModel?, action: LockedAction): Boolean {
158160
if (vault?.isHubVault == true) {
159-
if (hasWriteAccessForVault(vault)) return true
161+
if (hasWriteAccessForVault(vault)) {
162+
return true
163+
}
160164
Toast.makeText(activity, R.string.read_only_reason_hub_inactive, Toast.LENGTH_LONG).show()
161165
return false
162166
}
163167
return ensureWriteAccess(activity, action)
164168
}
165169

166170
companion object {
167-
private const val TRIAL_DURATION_DAYS = 30L
168-
private const val TRIAL_DURATION_MS = TRIAL_DURATION_DAYS * 24 * 60 * 60 * 1000
171+
private val TRIAL_DURATION_MS = TimeUnit.DAYS.toMillis(30)
169172
}
170173
}

presentation/src/main/java/org/cryptomator/presentation/presenter/VaultListPresenter.kt

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ import org.cryptomator.presentation.model.CloudTypeModel
4646
import org.cryptomator.presentation.model.ProgressModel
4747
import org.cryptomator.presentation.model.VaultModel
4848
import org.cryptomator.presentation.model.mappers.CloudFolderModelMapper
49+
import org.cryptomator.presentation.ui.activity.WelcomeActivity
4950
import org.cryptomator.presentation.ui.activity.view.VaultListView
5051
import org.cryptomator.presentation.ui.dialog.AppIsObscuredInfoDialog
5152
import org.cryptomator.presentation.ui.dialog.AskForLockScreenDialog
@@ -103,6 +104,10 @@ class VaultListPresenter @Inject constructor( //
103104
}
104105

105106
override fun resumed() {
107+
if (launchWelcomeFlowIfNeeded()) {
108+
return
109+
}
110+
106111
if (!hasShownTrialExpiredDialog && FlavorConfig.isFreemiumFlavor) {
107112
val trialState = licenseEnforcer.evaluateTrialState()
108113
if (trialState.isExpired && !licenseEnforcer.hasPaidLicense()) {
@@ -112,13 +117,28 @@ class VaultListPresenter @Inject constructor( //
112117
}
113118
}
114119

120+
private fun launchWelcomeFlowIfNeeded(): Boolean {
121+
if (!sharedPreferencesHandler.hasCompletedWelcomeFlow()) {
122+
requestActivityResult(
123+
ActivityResultCallbacks.welcomeFlowCompleted(),
124+
Intent(context(), WelcomeActivity::class.java)
125+
)
126+
return true
127+
}
128+
return false
129+
}
130+
115131
fun onWindowFocusChanged(hasFocus: Boolean) {
116132
if (hasFocus) {
117133
loadVaultList()
118134
}
119135
}
120136

121137
fun prepareView() {
138+
if (launchWelcomeFlowIfNeeded()) {
139+
return
140+
}
141+
122142
if (!sharedPreferencesHandler.isScreenLockDialogAlreadyShown) {
123143
val keyguardManager = context().getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
124144
if (!keyguardManager.isKeyguardSecure) {
@@ -490,6 +510,11 @@ class VaultListPresenter @Inject constructor( //
490510
}
491511
}
492512

513+
@Callback
514+
fun welcomeFlowCompleted(result: ActivityResult) {
515+
prepareView()
516+
}
517+
493518
@Callback
494519
fun vaultUnlockedVaultList(result: ActivityResult) {
495520
val cloud = result.intent().getSerializableExtra(SINGLE_RESULT) as Cloud

presentation/src/main/java/org/cryptomator/presentation/ui/activity/LicenseCheckActivity.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,13 @@ class LicenseCheckActivity : BaseActivity<ActivityLicenseCheckBinding>(ActivityL
8585
supportActionBar?.setHomeAsUpIndicator(R.drawable.ic_clear)
8686
binding.mtToolbar.toolbar.setNavigationOnClickListener { finish() }
8787

88-
lockedAction?.let { action ->
88+
val action = lockedAction
89+
if (action != null) {
8990
binding.licenseContent.tvInfoText.visibility = View.VISIBLE
9091
binding.licenseContent.tvInfoText.text = getString(action.headerMessageRes)
92+
} else {
93+
binding.licenseContent.tvInfoText.visibility = View.GONE
94+
binding.licenseContent.tvInfoText.text = null
9195
}
9296

9397
if (FlavorConfig.isFreemiumFlavor) {
@@ -124,7 +128,7 @@ class LicenseCheckActivity : BaseActivity<ActivityLicenseCheckBinding>(ActivityL
124128

125129
override fun onNewIntent(intent: Intent) {
126130
super.onNewIntent(intent)
127-
lockedAction = LicenseEnforcer.LockedAction.fromName(intent.getStringExtra(EXTRA_LOCKED_ACTION)) ?: lockedAction
131+
lockedAction = LicenseEnforcer.LockedAction.fromName(intent.getStringExtra(EXTRA_LOCKED_ACTION))
128132
setupUpsellView()
129133
validate(intent)
130134
}

presentation/src/main/java/org/cryptomator/presentation/ui/activity/VaultListActivity.kt

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import org.cryptomator.generator.InjectIntent
1212
import org.cryptomator.presentation.CryptomatorApp
1313
import org.cryptomator.presentation.R
1414
import org.cryptomator.presentation.databinding.ActivityLayoutObscureAwareBinding
15+
import org.cryptomator.presentation.intent.Intents
1516
import org.cryptomator.presentation.intent.Intents.browseFilesIntent
1617
import org.cryptomator.presentation.intent.Intents.settingsIntent
1718
import org.cryptomator.presentation.intent.VaultListIntent
@@ -70,12 +71,6 @@ class VaultListActivity : BaseActivity<ActivityLayoutObscureAwareBinding>(Activi
7071
}
7172

7273
override fun setupView() {
73-
if (!sharedPreferencesHandler.hasCompletedWelcomeFlow()) {
74-
startActivity(Intent(this, WelcomeActivity::class.java))
75-
finish()
76-
return
77-
}
78-
7974
setupToolbar()
8075
vaultListPresenter.prepareView()
8176
binding.activityRootView.setOnFilteredTouchEventForSecurityListener(object : Listener {
@@ -222,7 +217,7 @@ class VaultListActivity : BaseActivity<ActivityLayoutObscureAwareBinding>(Activi
222217
}
223218

224219
override fun onUnlockFullVersionClicked() {
225-
startActivity(Intent(this, LicenseCheckActivity::class.java))
220+
Intents.licenseCheckIntent().startActivity(this)
226221
}
227222

228223
private fun vaultListFragment(): VaultListFragment = //

presentation/src/main/java/org/cryptomator/presentation/ui/activity/WelcomeActivity.kt

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -46,24 +46,22 @@ class WelcomeActivity : BaseActivity<ActivityWelcomeBinding>(ActivityWelcomeBind
4646
@Inject
4747
lateinit var licenseEnforcer: LicenseEnforcer
4848

49-
private val shouldShowLicenseSection: Boolean
50-
get() = !FlavorConfig.isPremiumFlavor
51-
52-
private val isFreemiumFlavor: Boolean
53-
get() = FlavorConfig.isFreemiumFlavor
54-
5549
private val keyguardManager by lazy { getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager }
5650

5751
private val orchestrator by lazy {
5852
LicenseStateOrchestrator(
5953
sharedPreferencesHandler, licenseEnforcer, { this },
6054
target = object : LicenseStateOrchestrator.Target {
6155
override fun onPurchaseStateChanged(hasWriteAccess: Boolean, hasPaidLicense: Boolean) {
62-
if (!this@WelcomeActivity::pagerAdapter.isInitialized) return
56+
if (!this@WelcomeActivity::pagerAdapter.isInitialized) {
57+
return
58+
}
6359
pagerAdapter.licenseFragment?.updateUnlocked(hasWriteAccess, hasPaidLicense)
6460
}
6561
override fun onTrialStateChanged(active: Boolean, expired: Boolean, expirationText: String?) {
66-
if (!this@WelcomeActivity::pagerAdapter.isInitialized) return
62+
if (!this@WelcomeActivity::pagerAdapter.isInitialized) {
63+
return
64+
}
6765
pagerAdapter.licenseFragment?.updateTrialState(active, expired, expirationText)
6866
}
6967
},
@@ -136,7 +134,7 @@ class WelcomeActivity : BaseActivity<ActivityWelcomeBinding>(ActivityWelcomeBind
136134
private fun setupPages() {
137135
pages.clear()
138136
pages.add(FragmentPage.Intro)
139-
if (shouldShowLicenseSection) {
137+
if (!FlavorConfig.isPremiumFlavor) {
140138
pages.add(FragmentPage.License)
141139
}
142140
pages.add(FragmentPage.Notifications)
@@ -151,7 +149,7 @@ class WelcomeActivity : BaseActivity<ActivityWelcomeBinding>(ActivityWelcomeBind
151149
binding.welcomePager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
152150
override fun onPageSelected(position: Int) {
153151
updateNavigationButtons(position)
154-
if (isFreemiumFlavor && pages[position] is FragmentPage.License) {
152+
if (FlavorConfig.isFreemiumFlavor && pages[position] is FragmentPage.License) {
155153
orchestrator.updateState()
156154
}
157155
}
@@ -211,13 +209,13 @@ class WelcomeActivity : BaseActivity<ActivityWelcomeBinding>(ActivityWelcomeBind
211209
}
212210

213211
private fun openVaultList() {
214-
startActivity(Intent(this, VaultListActivity::class.java))
212+
setResult(RESULT_OK)
215213
finish()
216214
}
217215

218216
private fun validate(intent: Intent?) {
219217
val data = intent?.data
220-
if (data != null && shouldShowLicenseSection) {
218+
if (data != null && !FlavorConfig.isPremiumFlavor) {
221219
welcomePresenter.validate(data)
222220
}
223221
}

presentation/src/main/java/org/cryptomator/presentation/ui/fragment/SettingsFragment.kt

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,16 @@ import androidx.preference.SwitchPreference
1616
import org.cryptomator.presentation.BuildConfig
1717
import org.cryptomator.presentation.CryptomatorApp
1818
import org.cryptomator.presentation.R
19+
import org.cryptomator.presentation.intent.Intents
1920
import org.cryptomator.presentation.licensing.LicenseEnforcer
21+
import org.cryptomator.presentation.presenter.ContextHolder
2022
import org.cryptomator.presentation.service.PhotoContentJob
2123
import org.cryptomator.presentation.service.ProductInfo
2224
import org.cryptomator.presentation.service.resolveProductPrices
2325
import org.cryptomator.presentation.ui.activity.AutoUploadChooseVaultActivity
2426
import org.cryptomator.presentation.ui.activity.BiometricAuthSettingsActivity
2527
import org.cryptomator.presentation.ui.activity.CloudSettingsActivity
2628
import org.cryptomator.presentation.ui.activity.CryptomatorVariantsActivity
27-
import org.cryptomator.presentation.ui.activity.LicenseCheckActivity
2829
import org.cryptomator.presentation.ui.activity.LicensesActivity
2930
import org.cryptomator.presentation.ui.activity.SettingsActivity
3031
import org.cryptomator.presentation.ui.dialog.DebugModeDisclaimerDialog
@@ -213,7 +214,7 @@ class SettingsFragment : PreferenceFragmentCompatLayout() {
213214
getString(R.string.screen_settings_license_summary_tap_to_unlock)
214215
}
215216
pref.setOnPreferenceClickListener {
216-
startActivity(Intent(activity(), LicenseCheckActivity::class.java))
217+
Intents.licenseCheckIntent().startActivity(activity() as ContextHolder)
217218
true
218219
}
219220
}
@@ -254,7 +255,9 @@ class SettingsFragment : PreferenceFragmentCompatLayout() {
254255
app.queryProductDetails { products ->
255256
val prices = products.resolveProductPrices()
256257
activity?.runOnUiThread {
257-
if (!isAdded) return@runOnUiThread
258+
if (!isAdded) {
259+
return@runOnUiThread
260+
}
258261
category.findPreference<Preference>(UPGRADE_LIFETIME_KEY)?.let { pref ->
259262
if (!prices.lifetimePrice.isNullOrEmpty()) {
260263
pref.summary = prices.lifetimePrice
@@ -278,7 +281,7 @@ class SettingsFragment : PreferenceFragmentCompatLayout() {
278281
pref.title = getString(R.string.screen_settings_license_title_unlock)
279282
pref.summary = getString(R.string.screen_settings_license_summary_tap_to_unlock)
280283
pref.setOnPreferenceClickListener {
281-
startActivity(Intent(activity(), LicenseCheckActivity::class.java))
284+
Intents.licenseCheckIntent().startActivity(activity() as ContextHolder)
282285
true
283286
}
284287
} else {

presentation/src/main/java/org/cryptomator/presentation/ui/fragment/WelcomeLicenseFragment.kt

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,22 +82,30 @@ class WelcomeLicenseFragment : BaseFragment<FragmentWelcomeLicenseBinding>(Fragm
8282
}
8383

8484
fun updateUnlocked(unlocked: Boolean, hasPaidLicense: Boolean) {
85-
if (!isAdded) return
85+
if (!isAdded) {
86+
return
87+
}
8688
licenseContentViewBinder.bindPurchaseState(unlocked, hasPaidLicense)
8789
}
8890

8991
fun updateTrialState(active: Boolean, expired: Boolean, expirationText: String?) {
90-
if (!isAdded) return
92+
if (!isAdded) {
93+
return
94+
}
9195
licenseContentViewBinder.bindTrialState(active, expired, expirationText)
9296
}
9397

9498
fun loadAndBindPrices(app: CryptomatorApp) {
95-
if (!isAdded) return
99+
if (!isAdded) {
100+
return
101+
}
96102
licenseContentViewBinder.loadAndBindPrices(app)
97103
}
98104

99105
fun prefillLicense(license: String) {
100-
if (!isAdded) return
106+
if (!isAdded) {
107+
return
108+
}
101109
binding.licenseContent.etLicense.setText(license)
102110
binding.licenseContent.licenseEntryGroup.visibility = if (isFreemiumFlavor) View.GONE else View.VISIBLE
103111
}

presentation/src/main/java/org/cryptomator/presentation/ui/fragment/WelcomeNotificationsFragment.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@ class WelcomeNotificationsFragment : BaseFragment<FragmentWelcomeNotificationsBi
3030
}
3131

3232
fun updatePermissionState(granted: Boolean) {
33-
if (!isAdded) return
33+
if (!isAdded) {
34+
return
35+
}
3436
binding.btnNotificationPermission.isEnabled = !granted
3537
binding.btnNotificationPermission.visibility = View.VISIBLE
3638
binding.tvNotificationStatus.visibility = if (granted) View.VISIBLE else View.GONE

presentation/src/main/java/org/cryptomator/presentation/ui/fragment/WelcomeScreenLockFragment.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@ class WelcomeScreenLockFragment : BaseFragment<FragmentWelcomeScreenLockBinding>
3030
}
3131

3232
fun updateScreenLockState(isSecure: Boolean) {
33-
if (!isAdded) return
33+
if (!isAdded) {
34+
return
35+
}
3436
binding.btnSetScreenLock.isEnabled = !isSecure
3537
binding.cbSetScreenLock.isEnabled = !isSecure
3638
if (isSecure) {

0 commit comments

Comments
 (0)