Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .idea/compiler.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .idea/gradle.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions .idea/inspectionProfiles/Project_Default.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/kotlinc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

44 changes: 33 additions & 11 deletions app/src/main/java/com/stslex/cnotes/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,40 +3,62 @@ package com.stslex.cnotes
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material3.windowsizeclass.ExperimentalMaterial3WindowSizeClassApi
import androidx.compose.material3.windowsizeclass.calculateWindowSizeClass
import androidx.compose.runtime.Composable
import androidx.compose.runtime.SideEffect
import androidx.compose.ui.graphics.Color
import androidx.core.view.WindowCompat
import androidx.navigation.NavHostController
import com.google.accompanist.navigation.animation.rememberAnimatedNavController
import com.google.accompanist.systemuicontroller.SystemUiController
import com.google.accompanist.systemuicontroller.rememberSystemUiController
import com.stslex.cnotes.di.ActivityComponent
import com.stslex.cnotes.ui.AppCreator
import com.stslex.cnotes.utils.ShortcutBuilder
import com.stslex.core_firebase.utils.abstraction.FirebaseAppInitialisationUtil
import org.koin.android.ext.android.inject
import org.koin.core.context.loadKoinModules

class MainActivity : ComponentActivity() {

private val firebaseAppInitialisationUtil: FirebaseAppInitialisationUtil by inject()
private val shortcutBuilder: ShortcutBuilder by inject()

@OptIn(ExperimentalMaterial3WindowSizeClassApi::class)
@OptIn(ExperimentalMaterial3WindowSizeClassApi::class, ExperimentalAnimationApi::class)
override fun onCreate(savedInstanceState: Bundle?) {
firebaseAppInitialisationUtil.invoke()
firebaseAppInitialisationUtil()
super.onCreate(savedInstanceState)
WindowCompat.setDecorFitsSystemWindows(window, false)
setContent {
val systemUiController: SystemUiController = rememberSystemUiController()
val iconsDark = !isSystemInDarkTheme()
SideEffect {
systemUiController.setSystemBarsColor(
color = Color.Transparent,
darkIcons = iconsDark
)
}
AppCreator(calculateWindowSizeClass(this))
SetUpUIEffects()
val navController = rememberAnimatedNavController()
setUpDependencies(navController)
AppCreator(
windowSizeClass = calculateWindowSizeClass(this),
navController = navController
)
}
shortcutBuilder.invoke()
}

private fun setUpDependencies(navController: NavHostController) {
val component = ActivityComponent()
val moduleNavigation = component.module(navController)
loadKoinModules(moduleNavigation)
}

@Composable
private fun SetUpUIEffects() {
val systemUiController: SystemUiController = rememberSystemUiController()
val iconsDark = !isSystemInDarkTheme()
SideEffect {
systemUiController.setSystemBarsColor(
color = Color.Transparent,
darkIcons = iconsDark
)
}
}
}
18 changes: 18 additions & 0 deletions app/src/main/java/com/stslex/cnotes/di/ActivityComponent.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.stslex.cnotes.di

import androidx.navigation.NavController
import androidx.navigation.NavHostController
import org.koin.core.annotation.Single
import org.koin.core.module.Module
import org.koin.dsl.module

@Single
class ActivityComponent {

val module: (navController: NavHostController) -> Module
get() = { navController ->
module {
single<NavController> { navController }
}
}
}
13 changes: 6 additions & 7 deletions app/src/main/java/com/stslex/cnotes/navigation/NavigationHost.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.navigation.NavGraph.Companion.findStartDestination
import androidx.navigation.NavHostController
import com.google.accompanist.navigation.animation.AnimatedNavHost
import com.stslex.core_navigation.destinations.AuthCodeDestination
import com.stslex.core_navigation.destinations.NoteListDestination
import com.stslex.core_navigation.destinations.PhoneNumberDestination
import com.stslex.core_navigation.destinations.ProfileDestination
import com.stslex.feature_auth_code.navigation.authCodeGraph
import com.stslex.feature_auth_phonenumber.navigation.authPhoneNumberGraph
import com.stslex.feature_note_list.navigation.noteListGraph
import com.google.accompanist.navigation.animation.AnimatedNavHost
import com.stslex.core_navigation.destinations.*
import com.stslex.feature_profile.navigation.profileGraph
import com.stslex.feature_single_note.navigation.singleNoteGraph
import com.stslex.feature_todo.navigation.todoGraph
Expand All @@ -26,11 +29,7 @@ fun NavigationHost(
navController = navController,
startDestination = startDestination
) {
noteListGraph(
openSingleNote = { navController.navigate("${SingleNoteDestination.route}/$it") },
openProfile = { navController.navigate(ProfileDestination.route) },
openAuthPhoneNumber = { navController.navigate(PhoneNumberDestination.route) }
) {
noteListGraph {
singleNoteGraph(popBackStack = { navController.popBackStack() })
}
todoGraph()
Expand Down
8 changes: 6 additions & 2 deletions app/src/main/java/com/stslex/cnotes/ui/AppCreator.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.navigation.NavController
import androidx.navigation.NavHostController
import androidx.navigation.compose.currentBackStackEntryAsState
import com.stslex.feature_note_list.navigation.noteListTopLevelDestination
import com.google.accompanist.navigation.animation.rememberAnimatedNavController
Expand All @@ -34,9 +36,11 @@ private val listOfDestinations = listOf(
ExperimentalAnimationApi::class
)
@Composable
fun AppCreator(windowSizeClass: WindowSizeClass) {
fun AppCreator(
windowSizeClass: WindowSizeClass,
navController: NavHostController
) {
AppTheme(dynamicColor = Build.VERSION.SDK_INT > 30) {
val navController = rememberAnimatedNavController()
val niaTopLevelNavigation = remember(navController) {
AppTopLevelNavigation(navController)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,34 @@
package com.stslex.feature_note_list.di

import androidx.paging.PagingConfig
import com.stslex.feature_note_list.ui.NotesViewModel
import com.stslex.core_model.common.MapperName
import com.stslex.feature_note_list.data.abstraction.NoteListRepository
import com.stslex.feature_note_list.data.realisation.NoteListRepositoryImpl
import com.stslex.feature_note_list.navigation.NoteListRouter
import com.stslex.feature_note_list.navigation.NoteListRouterImpl
import com.stslex.feature_note_list.ui.NotesViewModel
import org.koin.androidx.viewmodel.dsl.viewModel
import org.koin.core.module.dsl.bind
import org.koin.core.module.dsl.factoryOf
import org.koin.core.qualifier.named
import org.koin.dsl.module

class NoteListModule {

val module = module {

single { PagingConfig(10) }

factoryOf(::NoteListRepositoryImpl) { bind<NoteListRepository>() }

factoryOf(::NoteListRouterImpl) { bind<NoteListRouter>() }

viewModel {
NotesViewModel(
noteRepository = get(),
noteMapper = get(named(MapperName.PAGING_ENTITY_DYNAMIC)),
dispatchers = get()
dispatchers = get(),
router = get()
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@ import com.stslex.core_navigation.TopLevelDestination

@OptIn(ExperimentalAnimationApi::class)
fun NavGraphBuilder.noteListGraph(
openSingleNote: (Int) -> Unit,
openProfile: () -> Unit,
openAuthPhoneNumber: () -> Unit,
nestedGraphs: NavGraphBuilder.() -> Unit
) {
navigation(
Expand All @@ -30,11 +27,7 @@ fun NavGraphBuilder.noteListGraph(
popEnterTransition = NoteListTransitions.popEnterTransition,
popExitTransition = NoteListTransitions.popExitTransition
) {
NoteListRoute(
openSingleNote = openSingleNote,
openProfile = openProfile,
openAuthPhoneNumber = openAuthPhoneNumber
)
NoteListRoute()
}
nestedGraphs()
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.stslex.feature_note_list.navigation

interface NoteListRouter {
val openSingleNote: (noteId: Int) -> Unit
val openProfile: () -> Unit
val openAuthPhoneNumber: () -> Unit
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.stslex.feature_note_list.navigation

import androidx.navigation.NavController
import com.stslex.core_navigation.destinations.PhoneNumberDestination
import com.stslex.core_navigation.destinations.ProfileDestination
import com.stslex.core_navigation.destinations.SingleNoteDestination

class NoteListRouterImpl(
private val navController: NavController
) : NoteListRouter {

override val openSingleNote: (Int) -> Unit
get() = { noteId ->
navController.navigate("${SingleNoteDestination.route}/$noteId")
}

override val openProfile: () -> Unit
get() = { navController.navigate(ProfileDestination.route) }

override val openAuthPhoneNumber: () -> Unit
get() = { navController.navigate(PhoneNumberDestination.route) }
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,8 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier

@Composable
fun NoteListRoute(
openSingleNote: (Int) -> Unit,
openProfile: () -> Unit,
openAuthPhoneNumber: () -> Unit
) {
fun NoteListRoute() {
NotesScreen(
openSingleNote = openSingleNote,
openProfile = openProfile,
openAuthPhoneNumber = openAuthPhoneNumber,
modifier = Modifier.windowInsetsPadding(WindowInsets.safeDrawing)
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material3.*
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.FabPosition
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface
import androidx.compose.material3.TopAppBarDefaults.enterAlwaysScrollBehavior
import androidx.compose.material3.TopAppBarScrollState
import androidx.compose.material3.rememberTopAppBarScrollState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.tooling.preview.Preview
Expand All @@ -19,44 +21,33 @@ import androidx.paging.compose.items
import com.stslex.feature_note_list.ui.fab.NotesFab
import com.stslex.feature_note_list.ui.note.NotePagingItem
import com.stslex.feature_note_list.ui.top_bar.NoteMediumTopAppBar
import com.stslex.core_model.model.NoteDynamicUI
import org.koin.androidx.compose.getViewModel


@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun NotesScreen(
openSingleNote: (Int) -> Unit,
openProfile: () -> Unit,
openAuthPhoneNumber: () -> Unit,
modifier: Modifier = Modifier,
viewModel: NotesViewModel = getViewModel(),
lazyListState: LazyListState = rememberLazyListState(),
scrollState: TopAppBarScrollState = rememberTopAppBarScrollState()
) {
val pagingItems = viewModel.allNotes.collectAsLazyPagingItems()
val selectedNotes = remember { mutableStateListOf<NoteDynamicUI>() }
val deleteNotesFunction = viewModel::deleteNotesById
val scrollBehavior = enterAlwaysScrollBehavior(scrollState) { pagingItems.itemCount >= 6 }
val isButtonVisible = remember { mutableStateOf(true) }
Scaffold(
modifier = modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
floatingActionButton = {
AnimatedVisibility(visible = isButtonVisible.value) {
AnimatedVisibility(visible = viewModel.isCreateButtonVisible.value) {
NotesFab(
lazyListState = lazyListState,
selectedNotes = selectedNotes,
deleteNotesFunction = deleteNotesFunction,
openSingleNote = openSingleNote,
isButtonVisible = isButtonVisible
viewModel = viewModel
)
}
},
topBar = {
NoteMediumTopAppBar(
scrollBehavior = scrollBehavior,
openAccount = if (viewModel.isUserAuth) openProfile else openAuthPhoneNumber,
selectedNotes = selectedNotes
viewModel = viewModel
)
},
floatingActionButtonPosition = FabPosition.End
Expand All @@ -71,9 +62,7 @@ fun NotesScreen(
item?.let {
NotePagingItem(
note = item,
selectedNotes = selectedNotes,
openSingleNote = openSingleNote,
isButtonVisible = isButtonVisible
viewModel = viewModel
)
}
}
Expand All @@ -86,5 +75,5 @@ fun NotesScreen(
@Preview
@Composable
fun NotesPreview() {
NotesScreen({}, {}, {})
NotesScreen()
}
Loading