Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce SealedX KSP library #1

Merged
merged 2 commits into from
Aug 12, 2022
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
4 changes: 4 additions & 0 deletions buildSrc/src/main/kotlin/Dependencies.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ object Versions {
internal const val APP_STARTUP = "1.1.1"
internal const val LIFECYCLE = "2.6.0-alpha01"
internal const val ROOM = "2.4.2"
internal const val SEALEDX = "1.0.0"

internal const val LANDSCAPIST_GLIDE = "1.6.0"
internal const val ACCOMPANIST = "0.25.0"
Expand Down Expand Up @@ -77,6 +78,7 @@ object Dependencies {
const val accompanistIndicator =
"com.google.accompanist:accompanist-pager-indicators:${Versions.ACCOMPANIST}"
const val streamCompose = "io.getstream:stream-chat-android-compose:${Versions.STREAM_CHAT}"
const val streamClient = "io.getstream:stream-chat-android-client:${Versions.STREAM_CHAT}"

const val appStartUp = "androidx.startup:startup-runtime:${Versions.APP_STARTUP}"
const val hiltAndroid = "com.google.dagger:hilt-android:${Versions.HILT}"
Expand All @@ -85,6 +87,8 @@ object Dependencies {
const val roomRuntime = "androidx.room:room-runtime:${Versions.ROOM}"
const val roomKtx = "androidx.room:room-ktx:${Versions.ROOM}"
const val roomCompiler = "androidx.room:room-compiler:${Versions.ROOM}"
const val sealedXCore = "com.github.skydoves:sealedx-core:${Versions.SEALEDX}"
const val sealedXProcessor = "com.github.skydoves:sealedx-processor:${Versions.SEALEDX}"

const val okHttp = "com.squareup.okhttp3:okhttp:${Versions.OKHTTP}"
const val retrofit = "com.squareup.retrofit2:retrofit:${Versions.RETROFIT}"
Expand Down
12 changes: 12 additions & 0 deletions core-data/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ plugins {
id("org.jetbrains.kotlin.android")
id("org.jetbrains.kotlin.plugin.serialization")
id("kotlin-kapt")
id("com.google.devtools.ksp")
id("dagger.hilt.android.plugin")
}

Expand All @@ -24,13 +25,24 @@ android {
}
}

kotlin {
sourceSets.configureEach {
kotlin.srcDir("$buildDir/generated/ksp/$name/kotlin/")
}
}

dependencies {
api(project(":core-model"))
api(project(":core-network"))
api(project(":core-database"))

api(Dependencies.streamClient)

api(Dependencies.coroutines)

api(Dependencies.hiltAndroid)
kapt(Dependencies.hiltCompiler)

implementation(Dependencies.sealedXCore)
ksp(Dependencies.sealedXProcessor)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright 2022 Stream.IO, Inc. All Rights Reserved.
*
* 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 io.getstream.whatsappclone.data.model

import com.skydoves.sealedx.core.Extensive
import com.skydoves.sealedx.core.annotations.ExtensiveModel
import com.skydoves.sealedx.core.annotations.ExtensiveSealed
import io.getstream.chat.android.client.models.Channel
import io.getstream.whatsappclone.model.WhatsAppUserExtensive

@ExtensiveSealed(
models = [
ExtensiveModel(type = Channel::class, name = "WhatsAppMessage"),
ExtensiveModel(type = WhatsAppUserExtensive::class, name = "WhatsAppUser")
]
)
sealed interface UiState {
data class Success(val data: Extensive) : UiState
object Loading : UiState
object Error : UiState
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Copyright 2022 Stream.IO, Inc. All Rights Reserved.
*
* 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 io.getstream.whatsappclone.model

data class WhatsAppUserExtensive(
val whatsappUserList: List<WhatsAppUser>
)
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import androidx.compose.foundation.lazy.items
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import io.getstream.whatsappclone.data.model.WhatsAppUserUiState
import io.getstream.whatsappclone.designsystem.component.WhatsAppError
import io.getstream.whatsappclone.designsystem.component.WhatsAppLoadingColumn
import io.getstream.whatsappclone.navigation.AppComposeNavigator
Expand All @@ -42,15 +43,15 @@ fun WhatsAppCalls(
@Composable
private fun WhatsAppCallsScreen(
composeNavigator: AppComposeNavigator,
whatsAppUsersUiState: WhatsAppUiState
whatsAppUsersUiState: WhatsAppUserUiState
) {
when (whatsAppUsersUiState) {
WhatsAppUiState.Loading -> WhatsAppLoadingColumn()
WhatsAppUiState.Error -> WhatsAppError()
is WhatsAppUiState.Success -> {
WhatsAppUserUiState.Loading -> WhatsAppLoadingColumn()
WhatsAppUserUiState.Error -> WhatsAppError()
is WhatsAppUserUiState.Success -> {
LazyColumn {
items(
items = whatsAppUsersUiState.whatsAppUsers,
items = whatsAppUsersUiState.data.whatsappUserList,
key = { it.name }
) {
WhatsAppCallHistory(whatsAppUser = it) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ package io.getstream.whatsappclone.calls
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import io.getstream.whatsappclone.data.model.WhatsAppUserUiState
import io.getstream.whatsappclone.data.repository.CallHistoryRepository
import io.getstream.whatsappclone.model.WhatsAppUser
import io.getstream.whatsappclone.model.WhatsAppUserExtensive
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.flatMapLatest
Expand All @@ -33,24 +34,22 @@ class WhatsAppCallsViewModel @Inject constructor(
callHistoryRepository: CallHistoryRepository
) : ViewModel() {

val whatsAppUserState: StateFlow<WhatsAppUiState> =
val whatsAppUserState: StateFlow<WhatsAppUserUiState> =
callHistoryRepository.getCallHistoryUsersStream()
.flatMapLatest {
if (it.isSuccess) {
flowOf(WhatsAppUiState.Success(it.getOrThrow()))
flowOf(
WhatsAppUserUiState.Success(
WhatsAppUserExtensive(it.getOrThrow())
)
)
} else {
flowOf(WhatsAppUiState.Error)
flowOf(WhatsAppUserUiState.Error)
}
}
.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5_000),
initialValue = WhatsAppUiState.Loading
initialValue = WhatsAppUserUiState.Loading
)
}

sealed interface WhatsAppUiState {
data class Success(val whatsAppUsers: List<WhatsAppUser>) : WhatsAppUiState
object Error : WhatsAppUiState
object Loading : WhatsAppUiState
}
1 change: 1 addition & 0 deletions feature-chats/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ dependencies {
implementation(project(":core-designsystem"))
implementation(project(":core-navigation"))
implementation(project(":core-network"))
implementation(project(":core-data"))

// Stream chat Compose
api(Dependencies.streamCompose)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.skydoves.landscapist.glide.GlideImage
import io.getstream.chat.android.client.ChatClient
import io.getstream.whatsappclone.data.model.WhatsAppMessageUiState
import io.getstream.whatsappclone.designsystem.component.WhatsAppLoadingIndicator
import io.getstream.whatsappclone.designsystem.icon.WhatsAppIcons
import io.getstream.whatsappclone.designsystem.theme.WhatsAppCloneComposeTheme
Expand Down Expand Up @@ -122,14 +123,14 @@ private fun WhatsAppMessageUserInfo(
modifier = Modifier
.size(32.dp)
.clip(CircleShape),
imageModel = messageUiState.channel.image.takeIf { it.isNotEmpty() }
imageModel = messageUiState.data.image.takeIf { it.isNotEmpty() }
?: io.getstream.whatsappclone.designsystem.R.drawable.stream_logo,
previewPlaceholder = io.getstream.whatsappclone.designsystem.R.drawable.placeholder
)

Text(
modifier = Modifier.padding(start = 12.dp),
text = messageUiState.channel.name,
text = messageUiState.data.name,
color = MaterialTheme.colorScheme.tertiary,
style = MaterialTheme.typography.bodyLarge
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import io.getstream.chat.android.client.ChatClient
import io.getstream.chat.android.client.models.Channel
import io.getstream.chat.android.client.utils.onError
import io.getstream.chat.android.client.utils.onSuccess
import io.getstream.whatsappclone.data.model.WhatsAppMessageUiState
import io.getstream.whatsappclone.network.Dispatcher
import io.getstream.whatsappclone.network.WhatsAppDispatchers
import kotlinx.coroutines.CoroutineDispatcher
Expand Down Expand Up @@ -61,9 +61,3 @@ class WhatsAppMessagesViewModel @Inject constructor(
sealed interface WhatsAppMessageEvent {
class FetchChannel(val channelId: String) : WhatsAppMessageEvent
}

sealed interface WhatsAppMessageUiState {
data class Success(val channel: Channel) : WhatsAppMessageUiState
object Loading : WhatsAppMessageUiState
object Error : WhatsAppMessageUiState
}
Binary file added previews/preview.mp4
Binary file not shown.