Skip to content

Commit d92f3b0

Browse files
committed
wip
1 parent bf870ff commit d92f3b0

File tree

8 files changed

+445
-128
lines changed

8 files changed

+445
-128
lines changed

FlowCrypt/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,7 @@ dependencies {
389389
implementation "androidx.navigation:navigation-fragment-ktx:${rootProject.ext.navVersion}"
390390
implementation "androidx.navigation:navigation-ui-ktx:${rootProject.ext.navVersion}"
391391
implementation "androidx.navigation:navigation-runtime-ktx:${rootProject.ext.navVersion}"
392+
implementation("androidx.navigation:navigation-dynamic-features-fragment:${rootProject.ext.navVersion}")
392393

393394
//https://developers.google.com/android/guides/setup
394395
implementation 'com.google.android.gms:play-services-base:18.0.1'

FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/MainActivity.kt

Lines changed: 178 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,60 +9,90 @@ import android.accounts.AccountManager
99
import android.content.Intent
1010
import android.os.Bundle
1111
import android.view.MenuItem
12-
import android.view.View
12+
import android.widget.TextView
1313
import androidx.activity.viewModels
14+
import androidx.appcompat.app.AppCompatActivity
1415
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
16+
import androidx.core.view.GravityCompat
17+
import androidx.lifecycle.lifecycleScope
18+
import androidx.navigation.NavController
19+
import androidx.navigation.NavDestination
20+
import androidx.navigation.NavGraph
21+
import androidx.navigation.fragment.NavHostFragment
22+
import androidx.navigation.ui.AppBarConfiguration
23+
import androidx.navigation.ui.NavigationUI
24+
import androidx.navigation.ui.navigateUp
25+
import androidx.work.WorkManager
1526
import com.flowcrypt.email.BuildConfig
1627
import com.flowcrypt.email.R
28+
import com.flowcrypt.email.api.email.FoldersManager
29+
import com.flowcrypt.email.api.email.JavaEmailConstants
30+
import com.flowcrypt.email.database.FlowCryptRoomDatabase
31+
import com.flowcrypt.email.database.entity.AccountEntity
32+
import com.flowcrypt.email.databinding.ActivityMainBinding
33+
import com.flowcrypt.email.jetpack.viewmodel.AccountViewModel
34+
import com.flowcrypt.email.jetpack.viewmodel.ActionsViewModel
35+
import com.flowcrypt.email.jetpack.viewmodel.LabelsViewModel
1736
import com.flowcrypt.email.jetpack.viewmodel.LauncherViewModel
18-
import com.flowcrypt.email.ui.activity.base.BaseActivity
37+
import com.flowcrypt.email.jetpack.workmanager.sync.BaseSyncWorker
1938
import com.flowcrypt.email.ui.activity.fragment.AddOtherAccountFragment
2039
import com.flowcrypt.email.ui.activity.fragment.UserRecoverableAuthExceptionFragment
2140
import com.flowcrypt.email.ui.activity.fragment.base.BaseOAuthFragment
41+
import com.flowcrypt.email.ui.model.NavigationViewManager
2242
import com.flowcrypt.email.util.GeneralUtil
43+
import kotlinx.coroutines.launch
2344

2445
/**
2546
* @author Denis Bondarenko
2647
* Date: 3/8/22
2748
* Time: 11:13 AM
2849
* E-mail: DenBond7@gmail.com
2950
*/
30-
class MainActivity : BaseActivity() {
31-
private val launcherViewModel: LauncherViewModel by viewModels()
32-
private var accountAuthenticatorResponse: AccountAuthenticatorResponse? = null
33-
private val resultBundle: Bundle? = null
51+
class MainActivity : AppCompatActivity(), NavController.OnDestinationChangedListener {
52+
private lateinit var navController: NavController
53+
private lateinit var binding: ActivityMainBinding
54+
private lateinit var appBarConfiguration: AppBarConfiguration
3455

35-
override val rootView: View
36-
get() = findViewById(R.id.fragmentContainerView)
56+
private var isNavigationArrowDisplayed: Boolean = false
57+
private var navigationViewManager: NavigationViewManager? = null
3758

38-
override val isDisplayHomeAsUpEnabled: Boolean
39-
get() = false
59+
private val launcherViewModel: LauncherViewModel by viewModels()
60+
private val accountViewModel: AccountViewModel by viewModels()
61+
private val actionsViewModel: ActionsViewModel by viewModels()
62+
private val labelsViewModel: LabelsViewModel by viewModels()
4063

41-
override val contentViewResourceId: Int
42-
get() = R.layout.activity_main
64+
private var accountAuthenticatorResponse: AccountAuthenticatorResponse? = null
65+
private val resultBundle: Bundle? = null
4366

4467
override fun onCreate(savedInstanceState: Bundle?) {
4568
installSplashScreen().apply {
4669
setKeepOnScreenCondition {
4770
launcherViewModel.isLoadingStateFlow.value
4871
}
4972
}
50-
5173
super.onCreate(savedInstanceState)
5274

53-
accountAuthenticatorResponse =
54-
intent.getParcelableExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE)
55-
accountAuthenticatorResponse?.onRequestContinued()
75+
initViews()
76+
handleAccountAuthenticatorResponse()
77+
initAccountViewModel()
78+
setupLabelsViewModel()
5679
}
5780

5881
override fun onOptionsItemSelected(item: MenuItem): Boolean {
59-
when (item.itemId) {
60-
android.R.id.home -> {
82+
return when (item.itemId) {
83+
android.R.id.home -> if (isNavigationArrowDisplayed) {
6184
onBackPressed()
62-
return true
85+
true
86+
} else {
87+
super.onOptionsItemSelected(item)
6388
}
89+
90+
else -> super.onOptionsItemSelected(item)
6491
}
65-
return super.onOptionsItemSelected(item)
92+
}
93+
94+
override fun onSupportNavigateUp(): Boolean {
95+
return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
6696
}
6797

6898
override fun finish() {
@@ -91,6 +121,134 @@ class MainActivity : BaseActivity() {
91121
oAuthFragment?.handleOAuth2Intent(intent)
92122
}
93123

124+
override fun onDestinationChanged(
125+
controller: NavController,
126+
destination: NavDestination,
127+
arguments: Bundle?
128+
) {
129+
130+
}
131+
132+
private fun initViews() {
133+
binding = ActivityMainBinding.inflate(layoutInflater)
134+
val view = binding.root
135+
setContentView(view)
136+
setSupportActionBar(binding.toolbar)
137+
138+
navController = (supportFragmentManager.findFragmentById(R.id.fragmentContainerView)
139+
as NavHostFragment).navController
140+
navController.addOnDestinationChangedListener(this)
141+
142+
setupAppBarConfiguration()
143+
setupNavigationView()
144+
setupDrawerLayout()
145+
}
146+
147+
private fun setupAppBarConfiguration() {
148+
val topLevelDestinationIds = mutableSetOf(R.id.emailListFragment)
149+
findStartDest(navController.graph)?.id?.let { topLevelDestinationIds.add(it) }
150+
appBarConfiguration = AppBarConfiguration(topLevelDestinationIds, binding.drawerLayout)
151+
NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration)
152+
153+
navController.addOnDestinationChangedListener { _, destination, _ ->
154+
isNavigationArrowDisplayed = destination.id !in topLevelDestinationIds
155+
}
156+
}
157+
158+
private fun setupNavigationView() {
159+
navigationViewManager = NavigationViewManager(
160+
activity = this,
161+
navHeaderActionsListener = object : NavigationViewManager.NavHeaderActionsListener {
162+
override fun onAccountsMenuExpanded(isExpanded: Boolean) {
163+
binding.navigationView.menu.setGroupVisible(0, isExpanded)
164+
}
165+
166+
override fun onAddAccountClick() {
167+
binding.drawerLayout.closeDrawer(GravityCompat.START)
168+
//open main sign in
169+
}
170+
171+
override fun onSwitchAccountClick(accountEntity: AccountEntity) {
172+
lifecycleScope.launch {
173+
val roomDatabase = FlowCryptRoomDatabase.getDatabase(this@MainActivity)
174+
WorkManager.getInstance(applicationContext).cancelAllWorkByTag(BaseSyncWorker.TAG_SYNC)
175+
roomDatabase.accountDao().switchAccountSuspend(accountEntity)
176+
binding.drawerLayout.closeDrawer(GravityCompat.START)
177+
}
178+
}
179+
})
180+
navigationViewManager?.accountManagementLayout?.let { binding.navigationView.addHeaderView(it) }
181+
}
182+
183+
private fun setupDrawerLayout() {
184+
//
185+
}
186+
187+
private fun findStartDest(graph: NavGraph): NavDestination? {
188+
var startDestination: NavDestination? = graph
189+
while (startDestination is NavGraph) {
190+
val parent = startDestination
191+
startDestination = parent.findNode(parent.startDestination)
192+
}
193+
return startDestination
194+
}
195+
196+
private fun handleAccountAuthenticatorResponse() {
197+
accountAuthenticatorResponse =
198+
intent.getParcelableExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE)
199+
accountAuthenticatorResponse?.onRequestContinued()
200+
}
201+
202+
private fun initAccountViewModel() {
203+
accountViewModel.activeAccountLiveData.observe(this) { accountEntity ->
204+
accountEntity?.let {
205+
actionsViewModel.checkAndAddActionsToQueue(accountEntity)
206+
invalidateOptionsMenu()
207+
binding.navigationView.getHeaderView(0)?.let { headerView ->
208+
navigationViewManager?.initUserProfileView(this@MainActivity, headerView, accountEntity)
209+
}
210+
}
211+
}
212+
213+
accountViewModel.nonActiveAccountsLiveData.observe(this) {
214+
navigationViewManager?.genAccountsLayout(this@MainActivity, it)
215+
}
216+
}
217+
218+
private fun setupLabelsViewModel() {
219+
labelsViewModel.foldersManagerLiveData.observe(this) {
220+
val mailLabels = binding.navigationView.menu.findItem(R.id.mailLabels)
221+
mailLabels?.subMenu?.clear()
222+
223+
it?.getSortedNames()?.forEach { name ->
224+
mailLabels?.subMenu?.add(name)
225+
if (JavaEmailConstants.FOLDER_OUTBOX == name) {
226+
addOutboxLabel(it, mailLabels, name)
227+
}
228+
}
229+
230+
for (localFolder in it?.customLabels ?: emptyList()) {
231+
mailLabels?.subMenu?.add(localFolder.folderAlias)
232+
}
233+
}
234+
}
235+
236+
private fun addOutboxLabel(foldersManager: FoldersManager, mailLabels: MenuItem?, label: String) {
237+
val menuItem = mailLabels?.subMenu?.getItem(mailLabels.subMenu.size() - 1) ?: return
238+
239+
if (foldersManager.getFolderByAlias(label)?.msgCount ?: 0 > 0) {
240+
val folder = foldersManager.getFolderByAlias(label) ?: return
241+
val view = layoutInflater.inflate(
242+
R.layout.navigation_view_item_with_amount, binding.navigationView, false
243+
)
244+
val textViewMsgsCount = view.findViewById<TextView>(R.id.textViewMessageCount)
245+
textViewMsgsCount.text = folder.msgCount.toString()
246+
menuItem.actionView = view
247+
} else {
248+
menuItem.actionView = null
249+
}
250+
}
251+
94252
companion object {
95253
const val ACTION_ADD_ONE_MORE_ACCOUNT =
96254
BuildConfig.APPLICATION_ID + ".ACTION_ADD_ONE_MORE_ACCOUNT"

0 commit comments

Comments
 (0)