Skip to content

Commit

Permalink
Merge pull request #35 from KevinSchildhorn/AddingSlideshow
Browse files Browse the repository at this point in the history
Adding slideshow Screen
  • Loading branch information
KevinSchildhorn authored Dec 10, 2023
2 parents 2435fe6 + cdadc40 commit 88c2e77
Show file tree
Hide file tree
Showing 78 changed files with 1,050 additions and 334 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,24 @@ import android.os.Bundle
import androidx.activity.compose.setContent
import androidx.appcompat.app.AppCompatActivity
import com.kevinschildhorn.fotopresenter.startKoin
import com.kevinschildhorn.fotopresenter.ui.viewmodel.DirectoryViewModel
import com.kevinschildhorn.fotopresenter.ui.viewmodel.LoginViewModel
import com.kevinschildhorn.fotopresenter.ui.screens.directory.DirectoryViewModel
import com.kevinschildhorn.fotopresenter.ui.screens.login.LoginViewModel
import com.kevinschildhorn.fotopresenter.ui.screens.slideshow.SlideshowViewModel
import org.koin.androidx.viewmodel.ext.android.viewModel
import org.koin.core.component.KoinComponent

class MainActivity : AppCompatActivity(), KoinComponent {

private val loginViewModel by viewModel<LoginViewModel>()
private val directoryViewModel by viewModel<DirectoryViewModel>()
private val slideshowViewModel by viewModel<SlideshowViewModel>()

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
startKoin(this)

setContent {
MainView(loginViewModel, directoryViewModel)
MainView(loginViewModel, directoryViewModel, slideshowViewModel)
}
}
}
1 change: 1 addition & 0 deletions shared/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ kotlin {
implementation("com.russhwolf:multiplatform-settings-test:1.0.0")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.3")
implementation("io.insert-koin:koin-test:3.4.0")
implementation("app.cash.turbine:turbine:1.0.0")
}
}

Expand Down
8 changes: 5 additions & 3 deletions shared/src/androidMain/kotlin/Main.android.kt
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import androidx.compose.runtime.Composable
import com.kevinschildhorn.fotopresenter.ui.viewmodel.DirectoryViewModel
import com.kevinschildhorn.fotopresenter.ui.viewmodel.LoginViewModel
import com.kevinschildhorn.fotopresenter.ui.screens.directory.DirectoryViewModel
import com.kevinschildhorn.fotopresenter.ui.screens.login.LoginViewModel
import com.kevinschildhorn.fotopresenter.ui.screens.slideshow.SlideshowViewModel

actual fun getPlatformName(): String = "Android"

@Composable
fun MainView(
loginViewModel: LoginViewModel,
directoryViewModel: DirectoryViewModel,
) = App(loginViewModel, directoryViewModel)
slideshowViewModel: SlideshowViewModel,
) = App(loginViewModel, directoryViewModel, slideshowViewModel)
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ package com.kevinschildhorn.fotopresenter.ui.compose
import androidx.compose.foundation.layout.Column
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import com.kevinschildhorn.fotopresenter.ui.compose.common.ActionSheet
import com.kevinschildhorn.fotopresenter.ui.compose.common.ButtonState
import com.kevinschildhorn.fotopresenter.ui.compose.common.PrimaryButton
import com.kevinschildhorn.fotopresenter.ui.screens.common.ActionSheetAction
import com.kevinschildhorn.fotopresenter.ui.screens.common.ActionSheetContext
import com.kevinschildhorn.fotopresenter.ui.screens.common.composables.ActionSheet
import com.kevinschildhorn.fotopresenter.ui.screens.common.composables.ButtonState
import com.kevinschildhorn.fotopresenter.ui.screens.common.composables.PrimaryButton

@Preview
@Composable
Expand All @@ -21,9 +23,13 @@ fun PrimaryButtonPreview() {
@Composable
fun ActionSheetPreview() {
ActionSheet(
true,
visible = true,
offset = 200,
values = listOf("Option A", "Option B"),
) {
}
values = listOf(
ActionSheetContext(ActionSheetAction.START_SLIDESHOW, 1),
ActionSheetContext(ActionSheetAction.NONE, 2),
),
onClick = {},
onDismiss = {},
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,13 @@ package com.kevinschildhorn.fotopresenter.ui.compose
import androidx.compose.foundation.layout.Column
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import com.kevinschildhorn.fotopresenter.data.DirectoryContents
import com.kevinschildhorn.fotopresenter.data.FolderDirectory
import com.kevinschildhorn.fotopresenter.data.State
import com.kevinschildhorn.fotopresenter.data.network.MockNetworkDirectoryDetails
import com.kevinschildhorn.fotopresenter.ui.compose.directory.DirectoryGridCell
import com.kevinschildhorn.fotopresenter.ui.compose.directory.DirectoryGrid
import com.kevinschildhorn.fotopresenter.ui.compose.directory.FolderDirectoryGridCell
import com.kevinschildhorn.fotopresenter.ui.state.DirectoryGridState
import com.kevinschildhorn.fotopresenter.ui.state.FolderDirectoryGridCellState
import com.kevinschildhorn.fotopresenter.ui.state.ImageDirectoryGridCellState
import com.kevinschildhorn.fotopresenter.ui.screens.directory.composables.DirectoryGridCell
import com.kevinschildhorn.fotopresenter.ui.screens.directory.composables.DirectoryGrid
import com.kevinschildhorn.fotopresenter.ui.screens.directory.composables.FolderDirectoryGridCell
import com.kevinschildhorn.fotopresenter.ui.screens.directory.DirectoryGridState
import com.kevinschildhorn.fotopresenter.ui.screens.directory.FolderDirectoryGridCellState
import com.kevinschildhorn.fotopresenter.ui.screens.directory.ImageDirectoryGridCellState

@Preview
@Composable
Expand Down Expand Up @@ -44,5 +41,6 @@ fun DirectoryGridPreview() {
),
onFolderPressed = {},
onImageDirectoryPressed = {},
onStartSlideshow = {},
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ package com.kevinschildhorn.fotopresenter.ui.compose
import androidx.compose.foundation.layout.Column
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import com.kevinschildhorn.fotopresenter.ui.compose.common.ErrorView
import com.kevinschildhorn.fotopresenter.ui.compose.common.TitleView
import com.kevinschildhorn.fotopresenter.ui.compose.login.LoginPasswordTextField
import com.kevinschildhorn.fotopresenter.ui.compose.login.LoginTextField
import com.kevinschildhorn.fotopresenter.ui.compose.login.LoginScreenForm
import com.kevinschildhorn.fotopresenter.ui.state.LoginScreenState
import com.kevinschildhorn.fotopresenter.ui.state.UiState
import com.kevinschildhorn.fotopresenter.ui.screens.common.composables.ErrorView
import com.kevinschildhorn.fotopresenter.ui.screens.common.composables.TitleView
import com.kevinschildhorn.fotopresenter.ui.screens.login.composables.LoginPasswordTextField
import com.kevinschildhorn.fotopresenter.ui.screens.login.composables.LoginTextField
import com.kevinschildhorn.fotopresenter.ui.screens.login.composables.LoginScreenForm
import com.kevinschildhorn.fotopresenter.ui.screens.login.LoginScreenState
import com.kevinschildhorn.fotopresenter.ui.UiState

@Preview
@Composable
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.kevinschildhorn.fotopresenter.ui.viewmodel
package com.kevinschildhorn.fotopresenter.ui.shared

import androidx.lifecycle.ViewModel
import kotlinx.coroutines.CoroutineScope
Expand All @@ -9,4 +9,4 @@ actual abstract class ViewModel actual constructor() : ViewModel() {
actual override fun onCleared() {
super.onCleared()
}
}
}
31 changes: 23 additions & 8 deletions shared/src/commonMain/kotlin/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,19 @@ import androidx.compose.material.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import com.kevinschildhorn.fotopresenter.ui.compose.DirectoryScreen
import com.kevinschildhorn.fotopresenter.ui.compose.LoginScreen
import com.kevinschildhorn.fotopresenter.ui.compose.Screen
import com.kevinschildhorn.fotopresenter.ui.viewmodel.DirectoryViewModel
import com.kevinschildhorn.fotopresenter.ui.viewmodel.LoginViewModel
import com.kevinschildhorn.fotopresenter.ui.screens.common.Screen
import com.kevinschildhorn.fotopresenter.ui.screens.directory.DirectoryScreen
import com.kevinschildhorn.fotopresenter.ui.screens.directory.DirectoryViewModel
import com.kevinschildhorn.fotopresenter.ui.screens.login.LoginScreen
import com.kevinschildhorn.fotopresenter.ui.screens.login.LoginViewModel
import com.kevinschildhorn.fotopresenter.ui.screens.slideshow.SlideshowScreen
import com.kevinschildhorn.fotopresenter.ui.screens.slideshow.SlideshowViewModel

@Composable
fun App(
loginViewModel: LoginViewModel,
directoryViewModel: DirectoryViewModel,
slideshowViewModel: SlideshowViewModel,
) {
val currentScreen = remember { mutableStateOf(Screen.LOGIN) }

Expand All @@ -24,9 +27,21 @@ fun App(
}

Screen.DIRECTORY ->
DirectoryScreen(directoryViewModel) {
loginViewModel.setLoggedOut()
currentScreen.value = Screen.LOGIN
DirectoryScreen(
directoryViewModel,
onLogout = {
loginViewModel.setLoggedOut()
currentScreen.value = Screen.LOGIN
},
onStartSlideshow = {
slideshowViewModel.setSlideshow(it)
currentScreen.value = Screen.SLIDESHOW
},
)

Screen.SLIDESHOW ->
SlideshowScreen(slideshowViewModel) {
currentScreen.value = Screen.DIRECTORY
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,24 @@ import co.touchlab.kermit.Logger
import co.touchlab.kermit.LoggerConfig
import com.kevinschildhorn.fotopresenter.data.datasources.CredentialsDataSource
import com.kevinschildhorn.fotopresenter.data.datasources.DirectoryDataSource
import com.kevinschildhorn.fotopresenter.data.datasources.ImageCacheDataSource
import com.kevinschildhorn.fotopresenter.data.datasources.ImageRemoteDataSource
import com.kevinschildhorn.fotopresenter.data.repositories.CredentialsRepository
import com.kevinschildhorn.fotopresenter.data.repositories.DirectoryRepository
import com.kevinschildhorn.fotopresenter.data.repositories.ImageRepository
import com.kevinschildhorn.fotopresenter.domain.AutoConnectUseCase
import com.kevinschildhorn.fotopresenter.domain.ChangeDirectoryUseCase
import com.kevinschildhorn.fotopresenter.domain.ConnectToServerUseCase
import com.kevinschildhorn.fotopresenter.domain.LogoutUseCase
import com.kevinschildhorn.fotopresenter.domain.RetrieveDirectoryContentsUseCase
import com.kevinschildhorn.fotopresenter.domain.RetrieveImagesUseCase
import com.kevinschildhorn.fotopresenter.domain.SaveCredentialsUseCase
import com.kevinschildhorn.fotopresenter.ui.viewmodel.DirectoryViewModel
import com.kevinschildhorn.fotopresenter.ui.viewmodel.LoginViewModel
import com.kevinschildhorn.fotopresenter.domain.connection.AutoConnectUseCase
import com.kevinschildhorn.fotopresenter.domain.connection.ConnectToServerUseCase
import com.kevinschildhorn.fotopresenter.domain.connection.DisconnectFromServerUseCase
import com.kevinschildhorn.fotopresenter.domain.connection.SaveCredentialsUseCase
import com.kevinschildhorn.fotopresenter.domain.directory.ChangeDirectoryUseCase
import com.kevinschildhorn.fotopresenter.domain.image.RetrieveImageDirectoriesUseCase
import com.kevinschildhorn.fotopresenter.domain.image.RetrieveImageUseCase
import com.kevinschildhorn.fotopresenter.ui.screens.directory.DirectoryViewModel
import com.kevinschildhorn.fotopresenter.ui.screens.login.LoginViewModel
import com.kevinschildhorn.fotopresenter.ui.screens.slideshow.SlideshowViewModel
import com.kevinschildhorn.fotopresenter.ui.shared.CacheInterface
import com.kevinschildhorn.fotopresenter.ui.shared.SharedCache
import org.koin.core.module.Module
import org.koin.dsl.module

Expand All @@ -25,31 +30,35 @@ val commonModule =
val baseLogger = Logger(LoggerConfig.default)

// Data
single<CacheInterface> { SharedCache }
single { CredentialsDataSource(get()) }
single { CredentialsRepository(get()) }
single { DirectoryDataSource(get()) }
single { DirectoryRepository(get()) }
single { ImageRemoteDataSource(get()) }
single { ImageRepository(get()) }
single { ImageCacheDataSource(get()) }

// Domain
factory { ConnectToServerUseCase(get(), baseLogger.withTag("ConnectToServerUseCase")) }
factory { ChangeDirectoryUseCase(get(), baseLogger.withTag("ChangeDirectoryUseCase")) }
factory { AutoConnectUseCase(get(), get(), baseLogger.withTag("AutoConnectUseCase")) }
factory { SaveCredentialsUseCase(get(), baseLogger.withTag("SaveCredentialsUseCase")) }
factory { LogoutUseCase(get(), get(), baseLogger.withTag("LogoutUseCase")) }
factory { DisconnectFromServerUseCase(get(), get(), baseLogger.withTag("LogoutUseCase")) }
factory { RetrieveImageDirectoriesUseCase(baseLogger.withTag("LogoutUseCase")) }
factory {
RetrieveDirectoryContentsUseCase(
get(),
get(),
baseLogger.withTag("RetrieveDirectoryContentsUseCase"),
)
}
factory { RetrieveImagesUseCase(baseLogger.withTag("RetrieveImagesUseCase")) }
factory { RetrieveImageUseCase(get(), baseLogger.withTag("RetrieveImagesUseCase")) }

// UI
single { LoginViewModel(baseLogger.withTag("LoginViewModel"), get()) }
single { DirectoryViewModel(baseLogger.withTag("DirectoryViewModel")) }
single { SlideshowViewModel(baseLogger.withTag("SlideshowViewModel")) }
}

internal expect val platformModule: Module
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,31 @@ interface Directory {

data class FolderDirectory(
override val details: NetworkDirectoryDetails,
) : Directory
) : Directory {
override fun toString(): String = "(F:${details.fullPath}:${details.id})"
}

data class ImageDirectory(
override val details: NetworkDirectoryDetails,
val image: SharedImage? = null,
) : Directory
) : Directory {
override fun toString(): String = "(I:${details.fullPath}:${details.id})"
}

data class DirectoryContents(
val folders: List<FolderDirectory> = emptyList(),
val images: List<ImageDirectory> = emptyList(),
) {
val allDirectories: List<Directory>
get() = folders + images

override fun toString(): String {
return """
DirectoryContents:
Folders: ${folders.count()}
${folders.map { it.toString() }.joinToString(", ")}
Images: ${images.count()}
${images.map { it.toString() }.joinToString(", ")}
"""
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.kevinschildhorn.fotopresenter.data

data class ImageSlideshowDetails(
val directories: List<ImageDirectory> = emptyList(),
)
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ package com.kevinschildhorn.fotopresenter.data

import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import com.kevinschildhorn.fotopresenter.ui.compose.common.ErrorView
import com.kevinschildhorn.fotopresenter.ui.compose.common.LoadingOverlay
import com.kevinschildhorn.fotopresenter.ui.screens.common.composables.ErrorView
import com.kevinschildhorn.fotopresenter.ui.screens.common.composables.LoadingOverlay

sealed class State<out DATA> {
data object IDLE : State<Nothing>()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@ package com.kevinschildhorn.fotopresenter.data.datasources

import androidx.compose.ui.graphics.ImageBitmap
import com.kevinschildhorn.fotopresenter.data.network.NetworkDirectoryDetails
import com.kevinschildhorn.fotopresenter.ui.shared.SharedCache
import com.kevinschildhorn.fotopresenter.ui.shared.CacheInterface

class ImageCacheDataSource {
fun getImage(directory: NetworkDirectoryDetails): ImageBitmap? = SharedCache.getImage(directory.cacheId)
class ImageCacheDataSource(private val cache: CacheInterface) {
fun getImage(directory: NetworkDirectoryDetails): ImageBitmap? = cache.getImage(directory.cacheId)

fun saveImage(
directory: NetworkDirectoryDetails,
bitmap: ImageBitmap,
) {
SharedCache.cacheImage(directory.cacheId, bitmap)
cache.cacheImage(directory.cacheId, bitmap)
}

private val NetworkDirectoryDetails.cacheId: String
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,18 @@ import com.kevinschildhorn.fotopresenter.data.repositories.ImageRepository
import com.kevinschildhorn.fotopresenter.ui.shared.SharedImage

/**
Retrieving Directories from Location
Retrieving Directory Contents from Path
**/
class RetrieveDirectoryContentsUseCase(
private val directoryRepository: DirectoryRepository,
private val imageRepository: ImageRepository,
private val logger: Logger,
) {
suspend operator fun invoke(path: String): DirectoryContents {
logger.i { "Getting directory Contents at path $path" }
val directoryContents = directoryRepository.getDirectoryContents(path)
return directoryContents.updateImages {
logger.i { "Updating Image File ${it.name}" }
imageRepository.getImage(it)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.kevinschildhorn.fotopresenter.domain
package com.kevinschildhorn.fotopresenter.domain.connection

import co.touchlab.kermit.Logger
import com.kevinschildhorn.fotopresenter.data.network.NetworkHandler
Expand All @@ -14,9 +14,12 @@ class AutoConnectUseCase(
) {
suspend operator fun invoke(): Boolean =
try {
logger.i { "Fetching Credentials" }
val credentials = repository.fetchCredentials()
logger.i { "Connecting to the client with auto-connect:${credentials.shouldAutoConnect}" }
client.connect(credentials)
} catch (e: Exception) {
logger.e(e) { "Could not connect" }
false
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package com.kevinschildhorn.fotopresenter.domain
package com.kevinschildhorn.fotopresenter.domain.connection

import co.touchlab.kermit.Logger
import com.kevinschildhorn.fotopresenter.data.LoginCredentials
import com.kevinschildhorn.fotopresenter.data.network.NetworkHandler

/**
Connect to Server using FTPS
Connect to Server using The [NetworkHandler]
**/
class ConnectToServerUseCase(
private val client: NetworkHandler,
Expand Down
Loading

0 comments on commit 88c2e77

Please sign in to comment.