Skip to content

Commit

Permalink
Apply architecture iteration
Browse files Browse the repository at this point in the history
Added new base classes on `:common:ui` module for Screen, ViewModel, Actions and NavigationActions. For now, it has been applied on About, Settings and AddTaskList features.
  • Loading branch information
serbelga committed Jan 28, 2025
1 parent c28fb90 commit 1ecd2c4
Show file tree
Hide file tree
Showing 38 changed files with 1,046 additions and 174 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright 2024 Sergio Belda
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package dev.sergiobelda.todometer.app.feature.about.di

import dev.sergiobelda.todometer.app.feature.about.ui.AboutViewModel
import dev.sergiobelda.todometer.common.ui.di.baseViewModelOf
import org.koin.core.module.dsl.named
import org.koin.dsl.module

val aboutViewModelModule = module {
baseViewModelOf(::AboutViewModel) {
named<AboutViewModel>()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright 2025 Sergio Belda
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package dev.sergiobelda.todometer.app.feature.about.navigation

import dev.sergiobelda.todometer.common.ui.base.BaseEvent

sealed class AboutNavigationEvents : BaseEvent {
data object NavigateBack : AboutNavigationEvents()
data object NavigateToGitHub : AboutNavigationEvents()
data object NavigateToOpenSourceLicenses : AboutNavigationEvents()
data object NavigateToPrivacyPolicy : AboutNavigationEvents()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright 2025 Sergio Belda
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package dev.sergiobelda.todometer.app.feature.about.navigation

import dev.sergiobelda.todometer.common.ui.base.navigation.NavigationEventsHandler

data class AboutNavigationEventsHandler(
val navigateBack: () -> Unit,
val navigateToGitHub: () -> Unit,
val navigateToOpenSourceLicenses: () -> Unit,
val navigateToPrivacyPolicy: () -> Unit,
) : NavigationEventsHandler<AboutNavigationEvents> {

override fun handleNavigationEvent(event: AboutNavigationEvents) {
when (event) {
AboutNavigationEvents.NavigateBack -> navigateBack()
AboutNavigationEvents.NavigateToGitHub -> navigateToGitHub()
AboutNavigationEvents.NavigateToOpenSourceLicenses -> navigateToOpenSourceLicenses()
AboutNavigationEvents.NavigateToPrivacyPolicy -> navigateToPrivacyPolicy()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,58 +43,89 @@ import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import dev.sergiobelda.navigation.compose.extended.annotation.NavDestination
import dev.sergiobelda.todometer.app.common.ui.components.TodometerTitle
import dev.sergiobelda.todometer.app.feature.about.navigation.AboutNavigationEvents
import dev.sergiobelda.todometer.common.designsystem.resources.images.Images
import dev.sergiobelda.todometer.common.designsystem.resources.images.icons.Code
import dev.sergiobelda.todometer.common.designsystem.resources.images.icons.Description
import dev.sergiobelda.todometer.common.designsystem.resources.images.icons.Github
import dev.sergiobelda.todometer.common.designsystem.resources.images.icons.NavigateBefore
import dev.sergiobelda.todometer.common.resources.TodometerResources
import dev.sergiobelda.todometer.common.ui.base.BaseScreen

@NavDestination(
name = "About",
destinationId = "about",
)
@Composable
fun AboutScreen(
navigateToGitHub: () -> Unit,
navigateToPrivacyPolicy: () -> Unit,
navigateToOpenSourceLicenses: () -> Unit,
navigateBack: () -> Unit,
) {
Scaffold(
topBar = { AboutTopBar(navigateBack = navigateBack) },
) { paddingValues ->
data object AboutScreen : BaseScreen<AboutState, AboutUIState>() {

@Composable
override fun rememberUIState(): AboutUIState = rememberAboutUIState()

@NavDestination(
name = "About",
destinationId = "about",
)
@Composable
override fun Content(
state: AboutState,
uiState: AboutUIState,
) {
Scaffold(
topBar = {
AboutTopBar()
},
content = { paddingValues ->
AboutContent(
modifier = Modifier.padding(paddingValues),
)
},
)
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun AboutTopBar() {
TopAppBar(
navigationIcon = {
IconButton(
onClick = {
onEvent(AboutNavigationEvents.NavigateBack)
},
) {
Icon(
Images.Icons.NavigateBefore,
contentDescription = TodometerResources.strings.back,
)
}
},
title = {},
)
}

@Composable
private fun AboutContent(
modifier: Modifier,
) {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier.fillMaxWidth().padding(paddingValues),
modifier = modifier.fillMaxWidth(),
) {
TodometerTitle()
Spacer(modifier = Modifier.height(72.dp))
AboutItemCard(onCardClick = navigateToGitHub, AboutItem.GitHub)
AboutItemCard(onCardClick = navigateToPrivacyPolicy, AboutItem.PrivacyPolicy)
AboutItemCard(onCardClick = navigateToOpenSourceLicenses, AboutItem.OpenSourceLicenses)
AboutItemCard(
onCardClick = { onEvent(AboutNavigationEvents.NavigateToGitHub) },
AboutItem.GitHub,
)
AboutItemCard(
onCardClick = { onEvent(AboutNavigationEvents.NavigateToPrivacyPolicy) },
AboutItem.PrivacyPolicy,
)
AboutItemCard(
onCardClick = { onEvent(AboutNavigationEvents.NavigateToOpenSourceLicenses) },
AboutItem.OpenSourceLicenses,
)
}
AboutAppVersion()
}
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
internal fun AboutTopBar(navigateBack: () -> Unit) {
TopAppBar(
navigationIcon = {
IconButton(onClick = navigateBack) {
Icon(
Images.Icons.NavigateBefore,
contentDescription = TodometerResources.strings.back,
)
}
},
title = {},
)
}

internal enum class AboutItem {
private enum class AboutItem {
GitHub,
PrivacyPolicy,
OpenSourceLicenses,
Expand All @@ -117,7 +148,7 @@ private fun AboutItem.text(): String =
}

@Composable
internal fun AboutItemCard(
private fun AboutItemCard(
onCardClick: () -> Unit,
aboutItem: AboutItem,
modifier: Modifier = Modifier,
Expand Down Expand Up @@ -145,7 +176,7 @@ internal fun AboutItemCard(
}

@Composable
internal fun AboutAppVersion() {
private fun AboutAppVersion() {
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.BottomCenter) {
Text(
text = appVersionName() ?: "",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Copyright 2025 Sergio Belda
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package dev.sergiobelda.todometer.app.feature.about.ui

import dev.sergiobelda.todometer.common.ui.base.BaseState

data object AboutState : BaseState
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright 2025 Sergio Belda
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package dev.sergiobelda.todometer.app.feature.about.ui

import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import dev.sergiobelda.todometer.common.ui.base.BaseEvent
import dev.sergiobelda.todometer.common.ui.base.BaseUIState

class AboutUIState internal constructor() : BaseUIState {
override fun handleEvent(event: BaseEvent) = Unit
}

@Composable
internal fun rememberAboutUIState(): AboutUIState = remember { AboutUIState() }
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright 2025 Sergio Belda
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package dev.sergiobelda.todometer.app.feature.about.ui

import dev.sergiobelda.todometer.common.ui.base.BaseEvent
import dev.sergiobelda.todometer.common.ui.base.BaseViewModel

class AboutViewModel : BaseViewModel<AboutState>(
AboutState,
) {
override fun handleEvent(event: BaseEvent) = Unit
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,12 @@
package dev.sergiobelda.todometer.app.feature.addtasklist.di

import dev.sergiobelda.todometer.app.feature.addtasklist.ui.AddTaskListViewModel
import org.koin.core.module.dsl.viewModelOf
import dev.sergiobelda.todometer.common.ui.di.baseViewModelOf
import org.koin.core.module.dsl.named
import org.koin.dsl.module

val addTaskListViewModelModule = module {
viewModelOf(::AddTaskListViewModel)
baseViewModelOf(::AddTaskListViewModel) {
named<AddTaskListViewModel>()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright 2025 Sergio Belda
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package dev.sergiobelda.todometer.app.feature.addtasklist.navigation

import dev.sergiobelda.todometer.common.ui.base.BaseEvent

sealed class AddTaskListNavigationEvents : BaseEvent {
data object NavigateBack : AddTaskListNavigationEvents()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright 2025 Sergio Belda
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package dev.sergiobelda.todometer.app.feature.addtasklist.navigation

import dev.sergiobelda.todometer.common.ui.base.navigation.NavigationEventsHandler

fun addTaskListNavigationEventsHandler(
navigateBack: () -> Unit,
): NavigationEventsHandler<AddTaskListNavigationEvents> = NavigationEventsHandler {
when (it) {
AddTaskListNavigationEvents.NavigateBack -> navigateBack()
}
}
Loading

0 comments on commit 1ecd2c4

Please sign in to comment.