Skip to content

Commit 10aeafe

Browse files
author
Josh
committed
modularized the project
1 parent 122734b commit 10aeafe

244 files changed

Lines changed: 4354 additions & 3332 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

app/build.gradle.kts

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ plugins {
55
alias(libs.plugins.ksp)
66
alias(libs.plugins.sqldelight)
77
alias(libs.plugins.serialization)
8-
alias(libs.plugins.parcelize)
98
alias(libs.plugins.ktlint)
109
}
1110

@@ -76,8 +75,8 @@ android {
7675
}
7776

7877
compileOptions {
79-
sourceCompatibility = JavaVersion.VERSION_1_8
80-
targetCompatibility = JavaVersion.VERSION_1_8
78+
sourceCompatibility = JavaVersion.VERSION_17
79+
targetCompatibility = JavaVersion.VERSION_17
8180
}
8281
buildFeatures {
8382
compose = true
@@ -91,7 +90,7 @@ android {
9190

9291
kotlin {
9392
compilerOptions {
94-
jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_1_8)
93+
jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17)
9594
}
9695
}
9796

@@ -101,18 +100,23 @@ tasks.register("printVersionName") {
101100
}
102101
}
103102

104-
sqldelight {
105-
databases {
106-
create("OpenLettersDB") {
107-
packageName.set("net.frozendevelopment.openletters.data.sqldelight")
108-
srcDirs("src/main/java")
109-
deriveSchemaFromMigrations = true
110-
dialect("app.cash.sqldelight:sqlite-3-38-dialect:2.0.2")
111-
}
112-
}
113-
}
114-
115103
dependencies {
104+
implementation(project(":core:migration"))
105+
implementation(project(":core:design"))
106+
implementation(project(":core:database"))
107+
implementation(project(":core:database-connection"))
108+
implementation(project(":core:architecture"))
109+
implementation(project(":feature:letters:api"))
110+
implementation(project(":feature:letters:impl"))
111+
implementation(project(":feature:reminders:api"))
112+
implementation(project(":feature:reminders:impl"))
113+
implementation(project(":feature:categories:api"))
114+
implementation(project(":feature:categories:impl"))
115+
implementation(project(":feature:drawer:api"))
116+
implementation(project(":feature:drawer:impl"))
117+
implementation(project(":feature:settings:api"))
118+
implementation(project(":feature:settings:impl"))
119+
116120
implementation(libs.androidx.core.ktx)
117121
implementation(libs.androidx.lifecycle.runtime.ktx)
118122
implementation(libs.androidx.activity.compose)

app/src/main/AndroidManifest.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@
2525
android:theme="@style/Theme.OpenLetters.Starting"
2626
tools:targetApi="31">
2727
<receiver
28-
android:name=".feature.reminder.notification.ReminderReceiver"
28+
android:name="net.frozendevelopment.feature.reminders.impl.notification.ReminderReceiver"
2929
android:enabled="true" />
3030
<receiver
31-
android:name=".feature.reminder.notification.AlarmHydrationReceiver"
31+
android:name="net.frozendevelopment.feature.reminders.impl.notification.AlarmHydrationReceiver"
3232
android:enabled="true"
3333
android:exported="true">
3434
<intent-filter>
Lines changed: 4 additions & 168 deletions
Original file line numberDiff line numberDiff line change
@@ -1,187 +1,23 @@
11
package net.frozendevelopment.openletters
22

3-
import android.content.ActivityNotFoundException
4-
import android.content.Intent
53
import android.os.Bundle
6-
import android.widget.Toast
74
import androidx.activity.ComponentActivity
8-
import androidx.activity.compose.BackHandler
95
import androidx.activity.compose.setContent
106
import androidx.activity.enableEdgeToEdge
11-
import androidx.compose.foundation.layout.Box
12-
import androidx.compose.foundation.layout.WindowInsets
13-
import androidx.compose.foundation.layout.WindowInsetsSides
14-
import androidx.compose.foundation.layout.fillMaxSize
15-
import androidx.compose.foundation.layout.only
16-
import androidx.compose.foundation.layout.safeDrawing
17-
import androidx.compose.foundation.layout.statusBarsPadding
18-
import androidx.compose.foundation.layout.windowInsetsPadding
19-
import androidx.compose.material3.DrawerValue
20-
import androidx.compose.material3.Scaffold
21-
import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi
22-
import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo
23-
import androidx.compose.material3.adaptive.layout.calculatePaneScaffoldDirective
24-
import androidx.compose.material3.adaptive.navigation.BackNavigationBehavior
25-
import androidx.compose.material3.adaptive.navigation3.rememberListDetailSceneStrategy
26-
import androidx.compose.material3.rememberDrawerState
27-
import androidx.compose.runtime.Composable
28-
import androidx.compose.runtime.CompositionLocalProvider
29-
import androidx.compose.runtime.getValue
30-
import androidx.compose.runtime.remember
31-
import androidx.compose.runtime.rememberCoroutineScope
32-
import androidx.compose.ui.Modifier
33-
import androidx.compose.ui.unit.dp
34-
import androidx.core.net.toUri
357
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
36-
import androidx.lifecycle.compose.collectAsStateWithLifecycle
37-
import androidx.navigation3.runtime.NavKey
38-
import androidx.navigation3.ui.NavDisplay
39-
import kotlinx.coroutines.launch
40-
import net.frozendevelopment.openletters.extensions.EntryProvider
41-
import net.frozendevelopment.openletters.extensions.koinEntryProvider
42-
import net.frozendevelopment.openletters.feature.category.form.CategoryFormDestination
43-
import net.frozendevelopment.openletters.feature.category.manage.ManageCategoryDestination
44-
import net.frozendevelopment.openletters.feature.letter.list.LetterListDestination
45-
import net.frozendevelopment.openletters.feature.reminder.form.ReminderFormDestination
46-
import net.frozendevelopment.openletters.feature.reminder.list.ReminderListDestination
47-
import net.frozendevelopment.openletters.feature.settings.SettingsDestination
48-
import net.frozendevelopment.openletters.ui.animation.popTransitionSpec
49-
import net.frozendevelopment.openletters.ui.animation.pushTransitionSpec
50-
import net.frozendevelopment.openletters.ui.navigation.LettersNavDrawer
51-
import net.frozendevelopment.openletters.ui.navigation.LocalDrawerState
52-
import net.frozendevelopment.openletters.ui.navigation.LocalNavigationState
53-
import net.frozendevelopment.openletters.ui.navigation.LocalNavigator
54-
import net.frozendevelopment.openletters.ui.navigation.Navigator
55-
import net.frozendevelopment.openletters.ui.navigation.rememberNavigationState
56-
import net.frozendevelopment.openletters.ui.navigation.toEntries
57-
import net.frozendevelopment.openletters.ui.theme.OpenLettersTheme
58-
import net.frozendevelopment.openletters.util.ThemeManagerType
59-
import org.koin.android.ext.android.inject
60-
import org.koin.core.annotation.KoinExperimentalAPI
8+
import net.frozendevelopment.openletters.ui.OpenLettersApp
619

6210
class MainActivity : ComponentActivity() {
63-
private val themeManager: ThemeManagerType by inject()
64-
65-
@OptIn(KoinExperimentalAPI::class, ExperimentalMaterial3AdaptiveApi::class, ExperimentalMaterial3AdaptiveApi::class)
6611
override fun onCreate(savedInstanceState: Bundle?) {
6712
installSplashScreen()
68-
6913
super.onCreate(savedInstanceState)
70-
7114
enableEdgeToEdge()
7215

7316
setContent {
74-
App()
75-
}
76-
}
77-
78-
@OptIn(ExperimentalMaterial3AdaptiveApi::class)
79-
@Composable
80-
private fun App() {
81-
val currentTheme by themeManager.current.collectAsStateWithLifecycle()
82-
83-
val coroutineScope = rememberCoroutineScope()
84-
val drawerState = rememberDrawerState(DrawerValue.Closed)
85-
val navigationState = rememberNavigationState(
86-
LetterListDestination,
87-
setOf(
88-
LetterListDestination,
89-
ManageCategoryDestination,
90-
ReminderListDestination,
91-
),
92-
)
93-
val navigator = remember {
94-
Navigator(
95-
state = navigationState,
96-
backPressedDispatcher = onBackPressedDispatcher,
97-
openInBrowser = {
98-
try {
99-
startActivity(Intent(Intent.ACTION_VIEW, it.toUri()))
100-
} catch (_: ActivityNotFoundException) {
101-
Toast.makeText(this, "No browser found", Toast.LENGTH_SHORT).show()
102-
}
103-
},
17+
OpenLettersApp(
18+
activity = this,
19+
onBackPressedDispatcher = onBackPressedDispatcher,
10420
)
10521
}
106-
val entryProvider: EntryProvider = koinEntryProvider()
107-
108-
val windowAdaptiveInfo = currentWindowAdaptiveInfo()
109-
val directive = remember(windowAdaptiveInfo) {
110-
calculatePaneScaffoldDirective(windowAdaptiveInfo)
111-
.copy(horizontalPartitionSpacerSize = 0.dp, verticalPartitionSpacerSize = 0.dp)
112-
}
113-
114-
val supportingPaneStrategy = rememberListDetailSceneStrategy<NavKey>(
115-
backNavigationBehavior = BackNavigationBehavior.PopUntilCurrentDestinationChange,
116-
directive = directive,
117-
)
118-
119-
BackHandler(drawerState.isOpen) {
120-
coroutineScope.launch { drawerState.close() }
121-
}
122-
123-
OpenLettersTheme(
124-
appTheme = currentTheme.first,
125-
colorPalette = currentTheme.second,
126-
) {
127-
LettersNavDrawer(
128-
drawerState = drawerState,
129-
goToMail = {
130-
coroutineScope.launch { drawerState.close() }
131-
navigator.navigate(LetterListDestination)
132-
},
133-
goToManageCategories = {
134-
coroutineScope.launch { drawerState.close() }
135-
navigator.navigate(ManageCategoryDestination)
136-
},
137-
goToCreateCategory = {
138-
coroutineScope.launch { drawerState.close() }
139-
navigator.navigate(CategoryFormDestination())
140-
},
141-
goToReminders = {
142-
coroutineScope.launch { drawerState.close() }
143-
navigator.navigate(ReminderListDestination)
144-
},
145-
goToCreateReminder = {
146-
coroutineScope.launch { drawerState.close() }
147-
navigator.navigate(ReminderFormDestination())
148-
},
149-
goToSettings = {
150-
coroutineScope.launch { drawerState.close() }
151-
navigator.navigate(SettingsDestination)
152-
},
153-
) {
154-
Scaffold(modifier = Modifier.fillMaxSize()) { _ ->
155-
Box(
156-
modifier =
157-
Modifier
158-
.fillMaxSize()
159-
.statusBarsPadding()
160-
.windowInsetsPadding(
161-
WindowInsets.safeDrawing.only(
162-
WindowInsetsSides.Horizontal,
163-
),
164-
),
165-
) {
166-
CompositionLocalProvider(LocalDrawerState provides drawerState) {
167-
CompositionLocalProvider(LocalNavigationState provides navigationState) {
168-
CompositionLocalProvider(
169-
LocalNavigator provides navigator,
170-
) {
171-
NavDisplay(
172-
entries = navigationState.toEntries(entryProvider),
173-
sceneStrategy = supportingPaneStrategy,
174-
onBack = { navigator.pop() },
175-
transitionSpec = { pushTransitionSpec() },
176-
popTransitionSpec = { popTransitionSpec() },
177-
predictivePopTransitionSpec = { popTransitionSpec() },
178-
)
179-
}
180-
}
181-
}
182-
}
183-
}
184-
}
185-
}
18622
}
18723
}

app/src/main/java/net/frozendevelopment/openletters/OpenLettersApplication.kt

Lines changed: 31 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,21 @@ import android.app.NotificationChannel
55
import android.app.NotificationManager
66
import androidx.work.OneTimeWorkRequestBuilder
77
import androidx.work.WorkManager
8-
import net.frozendevelopment.openletters.data.sqldelight.sqlDelightKoinModule
9-
import net.frozendevelopment.openletters.feature.category.categoryKoinModule
10-
import net.frozendevelopment.openletters.feature.letter.letterKoinModule
11-
import net.frozendevelopment.openletters.feature.reminder.reminderKoinModule
12-
import net.frozendevelopment.openletters.feature.settings.settingsKoinModule
13-
import net.frozendevelopment.openletters.migration.appMigrationKoinModule
14-
import net.frozendevelopment.openletters.usecase.useCaseKoinModule
15-
import net.frozendevelopment.openletters.util.utilKoinModule
16-
import net.frozendevelopment.openletters.work.AppMigrationWorker
17-
import net.frozendevelopment.openletters.work.workKoinModule
8+
import net.frozendevelopment.categories.impl.categoriesModule
9+
import net.frozendevelopment.core.database.OPEN_LETTERS_DB_QUALIFIER
10+
import net.frozendevelopment.core.database.databaseModule
11+
import net.frozendevelopment.feature.letters.impl.lettersKoinModule
12+
import net.frozendevelopment.feature.reminders.impl.remindersKoinModule
13+
import net.frozendevelopment.migration.AppMigrationWorker
14+
import net.frozendevelopment.migration.migrationModule
15+
import net.frozendevelopment.openletters.migration.InitialCategoriesMigration
16+
import net.frozendevelopment.settings.settingsModule
1817
import org.koin.android.ext.koin.androidContext
1918
import org.koin.androidx.workmanager.koin.workManagerFactory
2019
import org.koin.core.component.KoinComponent
20+
import org.koin.core.component.get
2121
import org.koin.core.context.startKoin
22+
import org.koin.core.qualifier.named
2223

2324
class OpenLettersApplication :
2425
Application(),
@@ -30,21 +31,19 @@ class OpenLettersApplication :
3031
androidContext(this@OpenLettersApplication)
3132
workManagerFactory()
3233
modules(
33-
// SqlDelightKoin().module,
34-
sqlDelightKoinModule,
35-
// FeatureKoin().module,
36-
letterKoinModule,
37-
categoryKoinModule,
38-
reminderKoinModule,
39-
settingsKoinModule,
40-
// UseCaseKoin().module,
41-
useCaseKoinModule,
42-
// AppMigrationKoin().module,
43-
appMigrationKoinModule,
44-
// WorkKoin().module,
45-
workKoinModule,
46-
// UtilKoin().module,
47-
utilKoinModule,
34+
migrationModule {
35+
listOf(
36+
InitialCategoriesMigration(
37+
dbConnection = get(named(OPEN_LETTERS_DB_QUALIFIER)),
38+
stringResource = ::getString,
39+
),
40+
)
41+
},
42+
databaseModule,
43+
lettersKoinModule,
44+
categoriesModule,
45+
remindersKoinModule,
46+
settingsModule,
4847
)
4948
}
5049

@@ -55,20 +54,18 @@ class OpenLettersApplication :
5554
private fun initializeWorkManager() {
5655
val workManager = WorkManager.getInstance(this)
5756

58-
val appMigrationRequest =
59-
OneTimeWorkRequestBuilder<AppMigrationWorker>()
60-
.build()
57+
val appMigrationRequest = OneTimeWorkRequestBuilder<AppMigrationWorker>()
58+
.build()
6159

6260
workManager.enqueue(appMigrationRequest)
6361
}
6462

6563
private fun initializeNotificationChannel() {
66-
val notificationChannel =
67-
NotificationChannel(
68-
REMINDERS_CHANNEL_ID,
69-
REMINDERS_CHANNEL_NAME,
70-
NotificationManager.IMPORTANCE_HIGH,
71-
)
64+
val notificationChannel = NotificationChannel(
65+
REMINDERS_CHANNEL_ID,
66+
REMINDERS_CHANNEL_NAME,
67+
NotificationManager.IMPORTANCE_HIGH,
68+
)
7269

7370
val notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
7471
notificationManager.createNotificationChannel(notificationChannel)

0 commit comments

Comments
 (0)