-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMainActivity.kt
More file actions
182 lines (171 loc) · 8.26 KB
/
MainActivity.kt
File metadata and controls
182 lines (171 loc) · 8.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
package net.frozendevelopment.openletters
import android.content.ActivityNotFoundException
import android.content.Intent
import android.os.Bundle
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.WindowInsetsSides
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.only
import androidx.compose.foundation.layout.safeDrawing
import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.material3.DrawerValue
import androidx.compose.material3.Scaffold
import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi
import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo
import androidx.compose.material3.adaptive.layout.calculatePaneScaffoldDirective
import androidx.compose.material3.adaptive.navigation.BackNavigationBehavior
import androidx.compose.material3.adaptive.navigation3.rememberListDetailSceneStrategy
import androidx.compose.material3.rememberDrawerState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.core.net.toUri
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.navigation3.runtime.NavKey
import androidx.navigation3.ui.NavDisplay
import kotlinx.coroutines.launch
import net.frozendevelopment.openletters.extensions.EntryProvider
import net.frozendevelopment.openletters.extensions.koinEntryProvider
import net.frozendevelopment.openletters.feature.category.form.CategoryFormDestination
import net.frozendevelopment.openletters.feature.category.manage.ManageCategoryDestination
import net.frozendevelopment.openletters.feature.letter.list.LetterListDestination
import net.frozendevelopment.openletters.feature.reminder.form.ReminderFormDestination
import net.frozendevelopment.openletters.feature.reminder.list.ReminderListDestination
import net.frozendevelopment.openletters.feature.settings.SettingsDestination
import net.frozendevelopment.openletters.ui.animation.popTransitionSpec
import net.frozendevelopment.openletters.ui.animation.pushTransitionSpec
import net.frozendevelopment.openletters.ui.navigation.LettersNavDrawer
import net.frozendevelopment.openletters.ui.navigation.LocalDrawerState
import net.frozendevelopment.openletters.ui.navigation.LocalNavigationState
import net.frozendevelopment.openletters.ui.navigation.LocalNavigator
import net.frozendevelopment.openletters.ui.navigation.Navigator
import net.frozendevelopment.openletters.ui.navigation.rememberNavigationState
import net.frozendevelopment.openletters.ui.navigation.toEntries
import net.frozendevelopment.openletters.ui.theme.OpenLettersTheme
import net.frozendevelopment.openletters.util.ThemeManagerType
import org.koin.android.ext.android.inject
import org.koin.core.annotation.KoinExperimentalAPI
class MainActivity : ComponentActivity() {
private val themeManager: ThemeManagerType by inject()
@OptIn(KoinExperimentalAPI::class, ExperimentalMaterial3AdaptiveApi::class, ExperimentalMaterial3AdaptiveApi::class)
override fun onCreate(savedInstanceState: Bundle?) {
installSplashScreen()
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
App()
}
}
@OptIn(ExperimentalMaterial3AdaptiveApi::class)
@Composable
private fun App() {
val currentTheme by themeManager.current.collectAsStateWithLifecycle()
val coroutineScope = rememberCoroutineScope()
val drawerState = rememberDrawerState(DrawerValue.Closed)
val navigationState = rememberNavigationState(
LetterListDestination,
setOf(
LetterListDestination,
ManageCategoryDestination,
ReminderListDestination,
),
)
val navigator = remember {
Navigator(
state = navigationState,
backPressedDispatcher = onBackPressedDispatcher,
openInBrowser = {
try {
startActivity(Intent(Intent.ACTION_VIEW, it.toUri()))
} catch (_: ActivityNotFoundException) {
Toast.makeText(this, "No browser found", Toast.LENGTH_SHORT).show()
}
},
)
}
val entryProvider: EntryProvider = koinEntryProvider()
val windowAdaptiveInfo = currentWindowAdaptiveInfo()
val directive = remember(windowAdaptiveInfo) {
calculatePaneScaffoldDirective(windowAdaptiveInfo)
.copy(horizontalPartitionSpacerSize = 0.dp, verticalPartitionSpacerSize = 0.dp)
}
val supportingPaneStrategy = rememberListDetailSceneStrategy<NavKey>(
backNavigationBehavior = BackNavigationBehavior.PopUntilCurrentDestinationChange,
directive = directive,
)
OpenLettersTheme(
appTheme = currentTheme.first,
colorPalette = currentTheme.second,
) {
LettersNavDrawer(
drawerState = drawerState,
goToMail = {
coroutineScope.launch { drawerState.close() }
navigator.navigate(LetterListDestination)
},
goToManageCategories = {
coroutineScope.launch { drawerState.close() }
navigator.navigate(ManageCategoryDestination)
},
goToCreateCategory = {
coroutineScope.launch { drawerState.close() }
navigator.navigate(CategoryFormDestination())
},
goToReminders = {
coroutineScope.launch { drawerState.close() }
navigator.navigate(ReminderListDestination)
},
goToCreateReminder = {
coroutineScope.launch { drawerState.close() }
navigator.navigate(ReminderFormDestination())
},
goToSettings = {
coroutineScope.launch { drawerState.close() }
navigator.navigate(SettingsDestination)
},
) {
Scaffold(modifier = Modifier.fillMaxSize()) { _ ->
Box(
modifier =
Modifier
.fillMaxSize()
.statusBarsPadding()
.windowInsetsPadding(
WindowInsets.safeDrawing.only(
WindowInsetsSides.Horizontal,
),
),
) {
CompositionLocalProvider(LocalDrawerState provides drawerState) {
CompositionLocalProvider(LocalNavigationState provides navigationState) {
CompositionLocalProvider(
LocalNavigator provides navigator,
) {
NavDisplay(
entries = navigationState.toEntries(entryProvider),
sceneStrategy = supportingPaneStrategy,
onBack = { navigator.pop() },
transitionSpec = { pushTransitionSpec() },
popTransitionSpec = { popTransitionSpec() },
predictivePopTransitionSpec = { popTransitionSpec() },
)
}
}
}
}
}
}
}
}
}