@@ -9,60 +9,90 @@ import android.accounts.AccountManager
99import android.content.Intent
1010import android.os.Bundle
1111import android.view.MenuItem
12- import android.view.View
12+ import android.widget.TextView
1313import androidx.activity.viewModels
14+ import androidx.appcompat.app.AppCompatActivity
1415import 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
1526import com.flowcrypt.email.BuildConfig
1627import 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
1736import com.flowcrypt.email.jetpack.viewmodel.LauncherViewModel
18- import com.flowcrypt.email.ui.activity.base.BaseActivity
37+ import com.flowcrypt.email.jetpack.workmanager.sync.BaseSyncWorker
1938import com.flowcrypt.email.ui.activity.fragment.AddOtherAccountFragment
2039import com.flowcrypt.email.ui.activity.fragment.UserRecoverableAuthExceptionFragment
2140import com.flowcrypt.email.ui.activity.fragment.base.BaseOAuthFragment
41+ import com.flowcrypt.email.ui.model.NavigationViewManager
2242import 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