Skip to content

Commit

Permalink
Refactor curated photos
Browse files Browse the repository at this point in the history
  • Loading branch information
SIKV committed Jun 23, 2024
1 parent 1e88255 commit 5471a1d
Show file tree
Hide file tree
Showing 11 changed files with 163 additions and 144 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ package com.github.sikv.photos.common

import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
import java.util.UUID

class ActivityPermissionManager(
private val activity: AppCompatActivity
private val activity: FragmentActivity
) : DefaultLifecycleObserver {

private val key = UUID.randomUUID().toString()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.github.sikv.photos.compose.ui

import androidx.compose.runtime.Composable
import com.github.sikv.photos.domain.ListLayout
import com.github.sikv.photos.domain.Photo

@Composable
fun DynamicPhotoItem(
photo: Photo,
isFavorite: Boolean,
listLayout: ListLayout,
onPhotoClick: (Photo) -> Unit,
onPhotoAttributionClick: (Photo) -> Unit,
onPhotoActionsClick: (Photo) -> Unit,
onToggleFavoriteClick: (Photo) -> Unit,
onSharePhotoClick: (Photo) -> Unit,
onDownloadPhotoClick: (Photo) -> Unit
) {
when (listLayout) {
ListLayout.LIST -> {
PhotoItem(
photo = photo,
isFavorite = isFavorite,
onClick = {
onPhotoClick(photo)
},
onAttributionClick = {
onPhotoAttributionClick(photo)
},
onMoreClick = {
onPhotoActionsClick(photo)
},
onToggleFavorite = {
onToggleFavoriteClick(photo)
},
onShareClick = {
onSharePhotoClick(photo)
},
onDownloadClick = {
onDownloadPhotoClick(photo)
}
)
}
ListLayout.GRID -> {
PhotoItemCompact(
photo = photo,
onClick = {
onPhotoClick(photo)
}
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.github.sikv.photos.compose.ui

import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import com.github.sikv.photos.domain.ListLayout

@Composable
fun SwitchLayoutAction(
listLayout: ListLayout,
onSwitchLayoutClick: () -> Unit
) {
val icon = when (listLayout) {
ListLayout.LIST -> R.drawable.ic_view_grid_24dp
ListLayout.GRID -> R.drawable.ic_view_list_24dp
}

IconButton(
onClick = onSwitchLayoutClick
) {
Icon(
painter = painterResource(id = icon),
contentDescription = stringResource(id = R.string.switch_layout)
)
}
}
1 change: 1 addition & 0 deletions compose-ui/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@
<string name="share">Share</string>
<string name="download">Download</string>
<string name="more">More</string>
<string name="switch_layout">Switch layout</string>
</resources>
1 change: 1 addition & 0 deletions feature/curated-photos/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ dependencies {
implementation libs.inject
kapt libs.hilt.compiler
implementation libs.hilt.android
implementation libs.androidx.hilt.navigation.compose

implementation libs.androidx.paging.runtime
implementation libs.androidx.paging.compose
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import android.view.View
import android.view.ViewGroup
import androidx.compose.ui.platform.ComposeView
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.navigation.fragment.findNavController
import com.github.sikv.photo.usecase.PhotoActionsUseCase
import com.github.sikv.photos.navigation.args.PhotoDetailsFragmentArguments
import com.github.sikv.photos.navigation.route.PhotoDetailsRoute
import com.google.accompanist.themeadapter.material3.Mdc3Theme
Expand All @@ -20,7 +20,8 @@ class CuratedPhotosFragment : Fragment() {
@Inject
lateinit var photoDetailsRoute: PhotoDetailsRoute

private val viewModel: CuratedPhotosViewModel by viewModels()
@Inject
lateinit var photoActionsUseCase: PhotoActionsUseCase

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
return ComposeView(requireContext()).apply {
Expand All @@ -31,10 +32,19 @@ class CuratedPhotosFragment : Fragment() {
setContent {
Mdc3Theme {
CuratedPhotosScreen(
onGoToPhotoDetails = { photo ->
onPhotoClick = { photo ->
photoDetailsRoute.present(findNavController(), PhotoDetailsFragmentArguments(photo))
},
viewModel = viewModel
onPhotoAttributionClick = photoActionsUseCase::photoAttributionClick,
onPhotoActionsClick = { photo ->
photoActionsUseCase.openMoreActions(requireNotNull(activity), photo)
},
onSharePhotoClick = { photo ->
photoActionsUseCase.sharePhoto(requireNotNull(activity), photo)
},
onDownloadPhotoClick = { photo ->
photoActionsUseCase.downloadPhoto(requireNotNull(activity), photo)
}
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,119 +2,61 @@ package com.github.sikv.photos.curated

import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.paging.compose.collectAsLazyPagingItems
import com.github.sikv.photos.common.ui.findActivity
import com.github.sikv.photos.compose.ui.PhotoItem
import com.github.sikv.photos.compose.ui.PhotoItemCompact
import com.github.sikv.photos.compose.ui.DynamicPhotoItem
import com.github.sikv.photos.compose.ui.Scaffold
import com.github.sikv.photos.domain.ListLayout
import com.github.sikv.photos.compose.ui.SwitchLayoutAction
import com.github.sikv.photos.domain.Photo

// TODO: Add loading indicator.

@Composable
internal fun CuratedPhotosScreen(
onGoToPhotoDetails: (Photo) -> Unit,
viewModel: CuratedPhotosViewModel,
onPhotoClick: (Photo) -> Unit,
onPhotoAttributionClick: (Photo) -> Unit,
onPhotoActionsClick: (Photo) -> Unit,
onSharePhotoClick: (Photo) -> Unit,
onDownloadPhotoClick: (Photo) -> Unit,
viewModel: CuratedPhotosViewModel = hiltViewModel(),
) {
val photos = viewModel.getCuratedPhotos().collectAsLazyPagingItems()
val listLayout by viewModel.listLayoutState.collectAsStateWithLifecycle()

Scaffold(
title = { Text(stringResource(id = R.string.photos)) },
actions = {
SwitchLayoutAction(viewModel = viewModel)
SwitchLayoutAction(
listLayout = listLayout,
onSwitchLayoutClick = viewModel::switchListLayout
)
}
) {
LazyVerticalGrid(
columns = GridCells.Fixed(listLayout.spanCount)
) {
items(photos.itemCount) { index ->
photos[index]?.let { photo ->
Photo(
val isFavorite by viewModel.isFavorite(photo).collectAsStateWithLifecycle(initialValue = false)

DynamicPhotoItem(
photo = photo,
isFavorite = isFavorite,
listLayout = listLayout,
viewModel = viewModel,
onGoToPhotoDetails = onGoToPhotoDetails
onPhotoClick = onPhotoClick,
onPhotoAttributionClick = onPhotoAttributionClick,
onPhotoActionsClick = onPhotoActionsClick,
onToggleFavoriteClick = viewModel::toggleFavorite,
onSharePhotoClick = onSharePhotoClick,
onDownloadPhotoClick = onDownloadPhotoClick
)
}
}
}
}
}

@Composable
private fun Photo(
photo: Photo,
listLayout: ListLayout,
viewModel: CuratedPhotosViewModel,
onGoToPhotoDetails: (Photo) -> Unit
) {
val context = LocalContext.current
val isFavorite by viewModel.isFavorite(photo).collectAsStateWithLifecycle(initialValue = false)

when (listLayout) {
ListLayout.LIST -> {
PhotoItem(
photo = photo,
isFavorite = isFavorite,
onClick = {
onGoToPhotoDetails(photo)
},
onAttributionClick = {
viewModel.onPhotoAttributionClick(context.findActivity(), photo)
},
onMoreClick = {
viewModel.openActions(context.findActivity(), photo)
},
onToggleFavorite = {
viewModel.toggleFavorite(photo)
},
onShareClick = {
viewModel.sharePhoto(context.findActivity(), photo)
},
onDownloadClick = {
viewModel.downloadPhoto(context.findActivity(), photo)
}
)
}
ListLayout.GRID -> {
PhotoItemCompact(
photo = photo,
onClick = {
onGoToPhotoDetails(photo)
}
)
}
}
}

@Composable
private fun SwitchLayoutAction(
viewModel: CuratedPhotosViewModel
) {
val listLayout by viewModel.listLayoutState.collectAsStateWithLifecycle()

val icon = when (listLayout) {
ListLayout.LIST -> R.drawable.ic_view_grid_24dp
ListLayout.GRID -> R.drawable.ic_view_list_24dp
}

IconButton(
onClick = viewModel::switchListLayout
) {
Icon(
painter = painterResource(id = icon),
contentDescription = stringResource(id = R.string.switch_layout)
)
}
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,12 @@
package com.github.sikv.photos.curated

import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingData
import com.github.sikv.photo.usecase.DownloadPhotoUseCase
import com.github.sikv.photo.usecase.PhotoActionsUseCase
import com.github.sikv.photos.common.PreferencesService
import com.github.sikv.photos.common.ui.openUrl
import com.github.sikv.photos.config.ConfigProvider
import com.github.sikv.photos.data.createShareIntent
import com.github.sikv.photos.data.repository.FavoritesRepository2
import com.github.sikv.photos.data.repository.PhotosRepository
import com.github.sikv.photos.domain.ListLayout
Expand All @@ -30,9 +24,7 @@ internal class CuratedPhotosViewModel @Inject constructor(
private val photosRepository: PhotosRepository,
private val favoritesRepository: FavoritesRepository2,
private val preferencesService: PreferencesService,
private val configProvider: ConfigProvider,
private val photoActionsUseCase: PhotoActionsUseCase,
private val downloadPhotoUseCase: DownloadPhotoUseCase
private val configProvider: ConfigProvider
) : ViewModel() {

private val mutableListLayoutState = MutableStateFlow(preferencesService.getCuratedListLayout())
Expand All @@ -51,40 +43,6 @@ internal class CuratedPhotosViewModel @Inject constructor(
}
}

// TODO: This is temporary solution!
// Will be refactored after migration to Compose Navigation is finished.
fun onPhotoAttributionClick(activity: AppCompatActivity, photo: Photo) {
photo.getPhotoPhotographerUrl()?.let { photographerUrl ->
activity.openUrl(photographerUrl)
} ?: run {
activity.openUrl(photo.getPhotoShareUrl())
}
}

// TODO: This is temporary solution!
// Will be refactored after migration to Compose Navigation is finished.
fun openActions(activity: AppCompatActivity, photo: Photo) {
photoActionsUseCase.openActions(activity.supportFragmentManager, photo) { message ->
Toast.makeText(activity, message, Toast.LENGTH_SHORT)
.show()
}
}

// TODO: This is temporary solution!
// Will be refactored after migration to Compose Navigation is finished.
fun downloadPhoto(activity: AppCompatActivity, photo: Photo) {
downloadPhotoUseCase.download(activity, photo) { message ->
Toast.makeText(activity, message, Toast.LENGTH_SHORT)
.show()
}
}

// TODO: This is temporary solution!
// Will be refactored after migration to Compose Navigation is finished.
fun sharePhoto(activity: AppCompatActivity, photo: Photo) {
activity.startActivity(photo.createShareIntent())
}

fun switchListLayout() {
when (listLayoutState.value) {
ListLayout.LIST -> {
Expand Down
1 change: 0 additions & 1 deletion feature/curated-photos/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="photos">Photos</string>
<string name="switch_layout">Switch layout</string>
</resources>
Loading

0 comments on commit 5471a1d

Please sign in to comment.