Skip to content

Commit

Permalink
fix : finally got room working
Browse files Browse the repository at this point in the history
  • Loading branch information
jerryOkafor committed Jun 13, 2024
1 parent 7946ff2 commit 1e383e9
Show file tree
Hide file tree
Showing 17 changed files with 221 additions and 118 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
*.iml
.kotlin
.kotlintest
.gradle
**/build/
xcuserdata
Expand Down
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# SM Share

![kotlin-version](https://img.shields.io/badge/kotlin-2.0.0-blue?logo=kotlin)

This is a Kotlin Multiplatform project targeting Android, iOS, Web, Desktop.

* `/composeApp` is for code that will be shared across your Compose Multiplatform applications.
Expand Down Expand Up @@ -33,4 +35,5 @@ on [GitHub](https://github.com/JetBrains/compose-multiplatform/issues).
[FantasyPremierLeague](https://github.com/joreilly/FantasyPremierLeague/tree/main)
[Tivi](https://github.com/chrisbanes/tivi)
[Compose Custom Window frame](https://github.com/amir1376/compose-custom-window-frame)
[Targeting Android in KMP](https://medium.com/kodein-koders/targeting-android-in-a-kotlin-multiplatform-mobile-library-b6ab75469287)
[Targeting Android in KMP](https://medium.com/kodein-koders/targeting-android-in-a-kotlin-multiplatform-mobile-library-b6ab75469287)
[Understanding and Configuring your Kotlin Multiplatform Mobile Test Suite](https://touchlab.co/understanding-and-configuring-your-kmm-test-suite)
2 changes: 1 addition & 1 deletion composeApp/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@ kotlin {
}

commonMain.dependencies {
implementation(projects.core.database)
implementation(projects.core.domain)
implementation(projects.core.datastore)
implementation(projects.core.database)
implementation(projects.core.config)

implementation(compose.runtime)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,6 @@ import androidx.compose.runtime.DisposableEffect
import androidx.compose.ui.tooling.preview.Preview
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import androidx.core.util.Consumer
import androidx.lifecycle.lifecycleScope
import com.jerryokafor.smshare.channel.ChannelAuthManager
import kotlinx.coroutines.launch
import org.koin.android.ext.android.inject

class MainActivity : ComponentActivity() {
Expand Down Expand Up @@ -85,7 +82,7 @@ class MainActivity : ComponentActivity() {
// create session id here
val code = data.getQueryParameter("code")!!
val state = data.getQueryParameter("state")
appViewModel.authenticateChannel(code,state)
appViewModel.authenticateChannel(code, state)
}
}
}
Expand Down
107 changes: 69 additions & 38 deletions composeApp/src/commonMain/kotlin/com.jerryokafor.smshare/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,14 @@ import com.jerryokafor.smshare.screens.settings.settingsScreen
import com.jerryokafor.smshare.tags.navigateToTags
import com.jerryokafor.smshare.tags.tagsScreen
import org.jetbrains.compose.resources.painterResource
import org.jetbrains.compose.resources.stringResource
import smshare.composeapp.generated.resources.Res
import smshare.composeapp.generated.resources.avatar6
import smshare.composeapp.generated.resources.ic_twitter
import smshare.composeapp.generated.resources.main_nav_title_analytics
import smshare.composeapp.generated.resources.main_nav_title_drafts
import smshare.composeapp.generated.resources.main_nav_title_posts
import smshare.composeapp.generated.resources.main_nav_title_settings

expect val DEV_SERVER_HOST: String

Expand Down Expand Up @@ -240,6 +245,7 @@ fun Home(
val appUiState by viewModel.userData.collectAsState()
val isOnline by viewModel.isOnLine.collectAsState()
val accounts by viewModel.accounts.collectAsState()
val currentAccount by viewModel.currentAccounts.collectAsState()

val currentOnNetChange by rememberUpdatedState(onNetChange)
LaunchedEffect(viewModel, isOnline) {
Expand Down Expand Up @@ -275,6 +281,16 @@ fun Home(
}
}

val navBackStackEntry by navController.currentBackStackEntryAsState()
val title = when (navBackStackEntry?.destination?.route) {
NavItem.Posts().route() -> stringResource(Res.string.main_nav_title_posts)
NavItem.Drafts().route() -> stringResource(Res.string.main_nav_title_drafts)
NavItem.Analytics().route() -> stringResource(Res.string.main_nav_title_analytics)
NavItem.Settings().route() -> stringResource(Res.string.main_nav_title_settings)
else -> "currentRoute"
}


val mainTopAppBar: @Composable (() -> Unit) = {
CenterAlignedTopAppBar(
title = {
Expand All @@ -283,46 +299,50 @@ fun Home(
Box(
modifier = Modifier.wrapContentSize(Alignment.TopStart)
) {
TextButton(onClick = { expanded = true }) {
ChannelWithName(
modifier = Modifier.wrapContentSize(),
name = "Jerry Okafor",
avatarSize = 38.dp,
avatar = painterResource(Res.drawable.avatar6),
indicator = painterResource(Res.drawable.ic_twitter),
)
}
if (currentAccount != null) {
TextButton(onClick = { expanded = true }) {
ChannelWithName(
modifier = Modifier.wrapContentSize(),
name = currentAccount!!.name,
avatarSize = 38.dp,
avatar = painterResource(Res.drawable.avatar6),
indicator = painterResource(Res.drawable.ic_twitter),
)
}

DropdownMenu(
modifier = Modifier.background(MaterialTheme.colorScheme.surface),
expanded = expanded,
onDismissRequest = { expanded = false },
scrollState = scrollState
) {
accounts.fastForEach { account ->
DropdownMenuItem(
modifier = Modifier.background(MaterialTheme.colorScheme.surface),
colors = MenuDefaults.itemColors(),
text = {
ChannelWithName(
modifier = Modifier.padding(
horizontal = 8.dp,
vertical = 4.dp
),
name = account.name,
avatarSize = 38.dp,
avatar = painterResource(Res.drawable.avatar6),
indicator = iconIndicatorForAccountType(account.type),
)
},
onClick = { expanded = false })
DropdownMenu(
modifier = Modifier.background(MaterialTheme.colorScheme.surface),
expanded = expanded,
onDismissRequest = { expanded = false },
scrollState = scrollState
) {
accounts.fastForEach { account ->
DropdownMenuItem(
modifier = Modifier.background(MaterialTheme.colorScheme.surface),
colors = MenuDefaults.itemColors(),
text = {
ChannelWithName(
modifier = Modifier.padding(
horizontal = 8.dp,
vertical = 4.dp
),
name = account.name,
avatarSize = 38.dp,
avatar = painterResource(Res.drawable.avatar6),
indicator = iconIndicatorForAccountType(account.type),
)
},
onClick = { expanded = false })
}
}
}
LaunchedEffect(expanded) {
if (expanded) {
// Scroll to show the bottom menu items.
scrollState.scrollTo(scrollState.maxValue)
LaunchedEffect(expanded) {
if (expanded) {
// Scroll to show the bottom menu items.
scrollState.scrollTo(scrollState.maxValue)
}
}
} else {
Text(text = title)
}
}

Expand Down Expand Up @@ -619,7 +639,18 @@ fun Home(
},
floatingActionButton = {
AnimatedVisibility(appState.currentTopLevelDestination != null) {
ExtendedFloatingActionButton(onClick = { navController.navigateToCompose() }) {
ExtendedFloatingActionButton(onClick = {
if (accounts.isEmpty() && currentAccount == null) {
scope.launch {
onShowSnackbar(
"No account added, please add account to continue",
""
)
}
} else {
navController.navigateToCompose()
}
}) {
Row(
modifier = Modifier,
verticalAlignment = Alignment.CenterVertically,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.jerryokafor.smshare
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import co.touchlab.kermit.Logger
import com.jerryokafor.core.database.AppDatabase
import com.jerryokafor.core.datastore.UserData
import com.jerryokafor.core.datastore.UserDataStore
import com.jerryokafor.smshare.channel.ChannelAuthManager
Expand All @@ -26,6 +27,7 @@ import org.koin.core.component.KoinComponent
import org.koin.core.component.inject

open class AppViewModel : ViewModel(), KoinComponent {
private val database: AppDatabase by inject()
private val userDataStore: UserDataStore by inject()
private val supportedChannels: List<ChannelConfig> by inject()
private val networkMonitor: NetworkMonitor by inject()
Expand Down Expand Up @@ -54,18 +56,27 @@ open class AppViewModel : ViewModel(), KoinComponent {
initialValue = false,
)

private val _accounts = MutableStateFlow<List<Account>>(emptyList())
val accounts = _accounts.asStateFlow()

init {
_accounts.update {
listOf(
Account(name = "Jerry Okafor", type = AccountType.FACEBOOK),
Account(name = "Jerry Okafor", type = AccountType.LINKEDIN),
Account(name = "Jerry Okafor", type = AccountType.TWITTER_X),
)
val accounts = database.getAccountDao().getAllAsFlow()
.map {
it.mapIndexed { index, entity ->
Account(
type = AccountType.TWITTER_X,
name = entity.name,
description = entity.description,
isSelected = index == 0,
avatarUrl = entity.avatarUrl,
postsCount = 0
)
}
}
}
.stateIn(
scope = viewModelScope,
started = SharingStarted.Eagerly,
initialValue = emptyList(),
)

private val _currentAccounts = MutableStateFlow<Account?>(null)
val currentAccounts = _currentAccounts.asStateFlow()

fun logout() {
viewModelScope.launch {
Expand All @@ -77,13 +88,26 @@ open class AppViewModel : ViewModel(), KoinComponent {
Logger.d("Fetching Token: $code | $state")
viewModelScope.launch {
try {
val tokenResponse =
channelConfigAuthManager.currentChannelConfig?.requestAccessToken(
val currentChannelConfig = channelConfigAuthManager.currentChannelConfig
val tokenResponse = currentChannelConfig?.requestAccessToken(
code = code,
redirectUrl = SMShareConfig.redirectUrl
)

Logger.d("access Token: $tokenResponse")
// val accountDao = database.getAccountDao()
// val accountEntity = AccountEntity(
// name = currentChannelConfig?.name ?: "",
// description = currentChannelConfig?.description ?: "",
// avatarUrl = tokenResponse?.accessToken ?: "",
// accessToken = tokenResponse?.accessToken ?: "",
// expiresInt = tokenResponse?.expiresIn ?: 0,
// scope = tokenResponse?.scope ?: "",
// created = ""
// )
//
// accountDao.insert(accountEntity)

// Logger.d("access Token: $tokenResponse -> $accountEntity")
} catch (e: Exception) {
Logger.w(e.message ?: "Error creating access token")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,12 @@ import screens.login.LoginViewModel
fun initKoin(appDeclaration: KoinAppDeclaration = {}): KoinApplication {
return startKoin {
appDeclaration()
modules(commonModule(), domainModule(), commonNetworkModule(), commonDatabaseModules())
modules(
commonModule(),
domainModule(),
commonNetworkModule(),
commonDatabaseModules()
)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,13 +180,20 @@ fun SideNav(
HorizontalDivider(
modifier = Modifier
.height(0.5.dp)
.padding(
start = 80.dp,
end = 8.dp
),
.padding(start = 80.dp, end = 8.dp)
)
}
}

if (accounts.isEmpty()) {
Row(
modifier = Modifier.padding(
vertical = 8.dp,
horizontal = 16.dp
).fillParentMaxWidth(),
horizontalArrangement = Arrangement.Center
) { Text("No Account", color = MaterialTheme.colorScheme.error) }
}
}
}

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* MIT License
*
* Copyright (c) 2024 SM Share Project
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

package com.jerryokafor.smshare.injection

import com.jerryokafor.core.database.jvmDBModule
import com.jerryokafor.core.datastore.jvmDataStoreModule
import com.jerryokafor.smshare.DesktopChannelAuthManager
import com.jerryokafor.smshare.channel.ChannelAuthManager
import com.jerryokafor.smshare.core.network.injection.jvmNetworkModule
import com.jerryokafor.smshare.platform.Platform
import org.koin.dsl.module

fun desktopModule() = module {
includes(
jvmDataStoreModule(),
jvmDBModule(),
jvmNetworkModule()
)
single<ChannelAuthManager> { DesktopChannelAuthManager() }

single { Platform() }
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ package com.jerryokafor.smshare
import androidx.compose.ui.window.Window
import androidx.compose.ui.window.application
import androidx.compose.ui.window.rememberWindowState
import com.jerryokafor.smshare.injection.desktopModule
import com.jerryokafor.smshare.injection.initKoin


Expand Down

0 comments on commit 1e383e9

Please sign in to comment.