diff --git a/README.md b/README.md
index 1c17005..da7967b 100644
--- a/README.md
+++ b/README.md
@@ -43,5 +43,6 @@
alt="Get it on GitHub"
height="80">](https://github.com/SuhasDissa/MemerizeApp/releases/latest)
-## Translations
-[Crowdin Translate](https://crowdin.com/project/memerize)
+## Useful Links
+
+
diff --git a/app/src/main/java/app/suhasdissa/memerize/Destination.kt b/app/src/main/java/app/suhasdissa/memerize/Destination.kt
index 68c4237..235af4b 100644
--- a/app/src/main/java/app/suhasdissa/memerize/Destination.kt
+++ b/app/src/main/java/app/suhasdissa/memerize/Destination.kt
@@ -18,13 +18,13 @@ sealed class Destination(val route: String) {
object Subreddits : Destination("subreddits")
object Communities : Destination("communities")
object About : Destination("about")
- object PhotoView : Destination("memescreen") {
- val routeWithArgs = "$route/{url}"
- val arguments = listOf(navArgument("url") { type = NavType.StringType })
+ object RedditFeed : Destination("reddit_feed") {
+ val routeWithArgs = "$route/{id}"
+ val arguments = listOf(navArgument("id") { type = NavType.IntType })
}
- object VideoPlayer : Destination("videoplayer") {
- val routeWithArgs = "$route/{url}"
- val arguments = listOf(navArgument("url") { type = NavType.StringType })
+ object LemmyFeed : Destination("lemmy_feed") {
+ val routeWithArgs = "$route/{id}"
+ val arguments = listOf(navArgument("id") { type = NavType.IntType })
}
}
diff --git a/app/src/main/java/app/suhasdissa/memerize/MemerizeApplication.kt b/app/src/main/java/app/suhasdissa/memerize/MemerizeApplication.kt
index ef5e325..9ee700c 100644
--- a/app/src/main/java/app/suhasdissa/memerize/MemerizeApplication.kt
+++ b/app/src/main/java/app/suhasdissa/memerize/MemerizeApplication.kt
@@ -33,7 +33,7 @@ class MemerizeApplication : Application(), ImageLoaderFactory {
.respectCacheHeaders(false)
.diskCache(
DiskCache.Builder()
- .directory(cacheDir.resolve("coil"))
+ .directory(cacheDir.resolve("image_cache"))
.maxSizeBytes(
preferences.getInt(imageCacheKey, defaultImageCacheSize) * 1024 * 1024L
)
diff --git a/app/src/main/java/app/suhasdissa/memerize/NavHost.kt b/app/src/main/java/app/suhasdissa/memerize/NavHost.kt
index 457223c..23a544d 100644
--- a/app/src/main/java/app/suhasdissa/memerize/NavHost.kt
+++ b/app/src/main/java/app/suhasdissa/memerize/NavHost.kt
@@ -9,20 +9,16 @@ package app.suhasdissa.memerize
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
-import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
-import app.suhasdissa.memerize.backend.viewmodels.LemmyViewModel
-import app.suhasdissa.memerize.backend.viewmodels.PlayerViewModel
-import app.suhasdissa.memerize.backend.viewmodels.RedditViewModel
import app.suhasdissa.memerize.ui.screens.home.CommunityScreen
import app.suhasdissa.memerize.ui.screens.home.HomeScreen
import app.suhasdissa.memerize.ui.screens.home.SubredditScreen
import app.suhasdissa.memerize.ui.screens.primary.LemmyMemeScreen
import app.suhasdissa.memerize.ui.screens.primary.RedditMemeScreen
-import app.suhasdissa.memerize.ui.screens.secondary.PhotoView
-import app.suhasdissa.memerize.ui.screens.secondary.VideoView
+import app.suhasdissa.memerize.ui.screens.secondary.LemmyMemeFeed
+import app.suhasdissa.memerize.ui.screens.secondary.RedditMemeFeed
import app.suhasdissa.memerize.ui.screens.settings.AboutScreen
import app.suhasdissa.memerize.ui.screens.settings.SettingsScreen
@@ -32,9 +28,6 @@ fun AppNavHost(
onDrawerOpen: () -> Unit,
modifier: Modifier = Modifier
) {
- val redditViewModel: RedditViewModel = viewModel(factory = RedditViewModel.Factory)
- val lemmyViewModel: LemmyViewModel = viewModel(factory = LemmyViewModel.Factory)
- val playerViewModel: PlayerViewModel = viewModel(factory = PlayerViewModel.Factory)
NavHost(
navController = navController,
startDestination = Destination.Home.route,
@@ -45,9 +38,7 @@ fun AppNavHost(
onNavigate = { destination ->
navController.navigateTo(destination.route)
},
- onDrawerOpen,
- redditViewModel = redditViewModel,
- lemmyViewModel = lemmyViewModel
+ onDrawerOpen
)
}
composable(route = Destination.Settings.route) {
@@ -71,12 +62,8 @@ fun AppNavHost(
route = Destination.RedditMemeView.route
) {
RedditMemeScreen(
- redditViewModel = redditViewModel,
- onClickMeme = { url ->
- navController.navigateTo("${Destination.PhotoView.route}/$url")
- },
- onClickVideo = { url ->
- navController.navigateTo("${Destination.VideoPlayer.route}/$url")
+ onClickCard = { id ->
+ navController.navigateTo("${Destination.RedditFeed.route}/$id")
}
)
}
@@ -84,32 +71,28 @@ fun AppNavHost(
route = Destination.LemmyMemeView.route
) {
LemmyMemeScreen(
- lemmyViewModel = lemmyViewModel,
- onClickMeme = { url ->
- navController.navigateTo("${Destination.PhotoView.route}/$url")
- },
- onClickVideo = { url ->
- navController.navigateTo("${Destination.VideoPlayer.route}/$url")
+ onClickCard = { id ->
+ navController.navigateTo("${Destination.LemmyFeed.route}/$id")
}
)
}
composable(
- route = Destination.PhotoView.routeWithArgs,
- arguments = Destination.PhotoView.arguments
+ route = Destination.RedditFeed.routeWithArgs,
+ arguments = Destination.RedditFeed.arguments
) {
- val imgurl = it.arguments?.getString("url")
- if (imgurl != null) {
- PhotoView(imgurl)
+ val id = it.arguments?.getInt("id")
+ if (id != null) {
+ RedditMemeFeed(initialPage = id)
}
}
composable(
- route = Destination.VideoPlayer.routeWithArgs,
- arguments = Destination.VideoPlayer.arguments
+ route = Destination.LemmyFeed.routeWithArgs,
+ arguments = Destination.LemmyFeed.arguments
) {
- val url = it.arguments?.getString("url")
- if (url != null) {
- VideoView(url = url, playerViewModel = playerViewModel)
+ val id = it.arguments?.getInt("id")
+ if (id != null) {
+ LemmyMemeFeed(initialPage = id)
}
}
}
diff --git a/app/src/main/java/app/suhasdissa/memerize/backend/apis/LemmyApi.kt b/app/src/main/java/app/suhasdissa/memerize/backend/apis/LemmyApi.kt
index 510cb2b..4090c1c 100644
--- a/app/src/main/java/app/suhasdissa/memerize/backend/apis/LemmyApi.kt
+++ b/app/src/main/java/app/suhasdissa/memerize/backend/apis/LemmyApi.kt
@@ -20,7 +20,9 @@ private const val header =
interface LemmyApi {
/**
* @param community The name of the community.
- * @param sort "TopAll", "TopDay", "TopMonth", "TopWeek".
+ * @param sort "Active", "Hot", "MostComments", "New", "NewComments",
+ * "Old", "TopAll", "TopDay", "TopMonth", "TopWeek",
+ * "TopYear".
*/
@Headers(header)
@GET("https://{instance}/api/v3/post/list")
diff --git a/app/src/main/java/app/suhasdissa/memerize/backend/apis/RedditApi.kt b/app/src/main/java/app/suhasdissa/memerize/backend/apis/RedditApi.kt
index 84e3ad9..0f73222 100644
--- a/app/src/main/java/app/suhasdissa/memerize/backend/apis/RedditApi.kt
+++ b/app/src/main/java/app/suhasdissa/memerize/backend/apis/RedditApi.kt
@@ -19,10 +19,11 @@ private const val header =
interface RedditApi {
@Headers(header)
- @GET("r/{subreddit}/top.json?sort=top&limit=100")
+ @GET("r/{subreddit}/{sort}.json")
suspend fun getRedditData(
@Path("subreddit") subreddit: String,
- @Query("t") time: String
+ @Path("sort") sort: String,
+ @Query("t") time: String? = null
): Reddit
@Headers(header)
diff --git a/app/src/main/java/app/suhasdissa/memerize/backend/model/Sort.kt b/app/src/main/java/app/suhasdissa/memerize/backend/model/Sort.kt
new file mode 100644
index 0000000..cd57337
--- /dev/null
+++ b/app/src/main/java/app/suhasdissa/memerize/backend/model/Sort.kt
@@ -0,0 +1,32 @@
+/*******************************************************************************
+Created By Suhas Dissanayake on 7/30/23, 6:12 PM
+Copyright (c) 2023
+https://github.com/SuhasDissa/
+All Rights Reserved
+ ******************************************************************************/
+
+package app.suhasdissa.memerize.backend.model
+
+import app.suhasdissa.memerize.R
+
+sealed class Sort(open val name: Int, val redditSort: String, open val lemmySort: String) {
+ object Hot : Sort(R.string.hot, "hot", "Hot")
+ object New : Sort(R.string.sort_new, "new", "New")
+ object Rising : Sort(R.string.rising, "rising", "Active")
+ sealed class Top(val redditT: String) : Sort(R.string.top, "top", "") {
+ object Today : Top("today") {
+ override val name = R.string.reddit_today_btn
+ override val lemmySort = "TopDay"
+ }
+
+ object Week : Top("week") {
+ override val name = R.string.reddit_week_btn
+ override val lemmySort = "TopWeek"
+ }
+
+ object Month : Top("month") {
+ override val name = R.string.reddit_month_btn
+ override val lemmySort = "TopMonth"
+ }
+ }
+}
diff --git a/app/src/main/java/app/suhasdissa/memerize/backend/model/SortTime.kt b/app/src/main/java/app/suhasdissa/memerize/backend/model/SortTime.kt
deleted file mode 100644
index 4f5117e..0000000
--- a/app/src/main/java/app/suhasdissa/memerize/backend/model/SortTime.kt
+++ /dev/null
@@ -1,28 +0,0 @@
-/*******************************************************************************
-Created By Suhas Dissanayake on 7/30/23, 6:12 PM
-Copyright (c) 2023
-https://github.com/SuhasDissa/
-All Rights Reserved
- ******************************************************************************/
-
-package app.suhasdissa.memerize.backend.model
-
-enum class SortTime {
- TODAY,
- WEEK,
- MONTH
-}
-
-val SortTime.reddit: String
- get() = when (this) {
- SortTime.TODAY -> "today"
- SortTime.WEEK -> "week"
- SortTime.MONTH -> "month"
- }
-
-val SortTime.lemmy: String
- get() = when (this) {
- SortTime.TODAY -> "TopDay"
- SortTime.WEEK -> "TopWeek"
- SortTime.MONTH -> "TopMonth"
- }
diff --git a/app/src/main/java/app/suhasdissa/memerize/backend/repositories/LemmyMemeRepository.kt b/app/src/main/java/app/suhasdissa/memerize/backend/repositories/LemmyMemeRepository.kt
index e9fc70d..9013243 100644
--- a/app/src/main/java/app/suhasdissa/memerize/backend/repositories/LemmyMemeRepository.kt
+++ b/app/src/main/java/app/suhasdissa/memerize/backend/repositories/LemmyMemeRepository.kt
@@ -13,6 +13,7 @@ import app.suhasdissa.memerize.backend.apis.LemmyApi
import app.suhasdissa.memerize.backend.database.dao.LemmyMemeDAO
import app.suhasdissa.memerize.backend.database.entity.LemmyCommunity
import app.suhasdissa.memerize.backend.database.entity.LemmyMeme
+import app.suhasdissa.memerize.backend.model.Sort
interface LemmyMemeRepository : MemeRepository
class LemmyMemeRepositoryImpl(
@@ -22,10 +23,10 @@ class LemmyMemeRepositoryImpl(
override suspend fun getOnlineData(
community: LemmyCommunity,
- time: String
+ sort: Sort
): List? {
return try {
- val memesList = getNetworkData(community, time)
+ val memesList = getNetworkData(community, sort.lemmySort)
Thread {
insertMemes(memesList)
}.start()
diff --git a/app/src/main/java/app/suhasdissa/memerize/backend/repositories/MemeRepository.kt b/app/src/main/java/app/suhasdissa/memerize/backend/repositories/MemeRepository.kt
index 445a088..6f215db 100644
--- a/app/src/main/java/app/suhasdissa/memerize/backend/repositories/MemeRepository.kt
+++ b/app/src/main/java/app/suhasdissa/memerize/backend/repositories/MemeRepository.kt
@@ -9,8 +9,9 @@ package app.suhasdissa.memerize.backend.repositories
import app.suhasdissa.memerize.backend.database.entity.AboutCommunity
import app.suhasdissa.memerize.backend.database.entity.Meme
+import app.suhasdissa.memerize.backend.model.Sort
interface MemeRepository {
- suspend fun getOnlineData(community: C, time: String): List?
+ suspend fun getOnlineData(community: C, sort: Sort): List?
suspend fun getLocalData(community: C): List
}
diff --git a/app/src/main/java/app/suhasdissa/memerize/backend/repositories/RedditMemeRepository.kt b/app/src/main/java/app/suhasdissa/memerize/backend/repositories/RedditMemeRepository.kt
index 4c4dbf9..b888e78 100644
--- a/app/src/main/java/app/suhasdissa/memerize/backend/repositories/RedditMemeRepository.kt
+++ b/app/src/main/java/app/suhasdissa/memerize/backend/repositories/RedditMemeRepository.kt
@@ -7,11 +7,13 @@ All Rights Reserved
package app.suhasdissa.memerize.backend.repositories
+import android.util.Log
import androidx.annotation.WorkerThread
import app.suhasdissa.memerize.backend.apis.RedditApi
import app.suhasdissa.memerize.backend.database.dao.RedditMemeDao
import app.suhasdissa.memerize.backend.database.entity.RedditCommunity
import app.suhasdissa.memerize.backend.database.entity.RedditMeme
+import app.suhasdissa.memerize.backend.model.Sort
interface RedditMemeRepository : MemeRepository
@@ -23,15 +25,20 @@ class RedditMemeRepositoryImpl(
private val imageRegex = Regex("^.+\\.(jpg|jpeg|png|webp)\$")
override suspend fun getOnlineData(
community: RedditCommunity,
- time: String
+ sort: Sort
): List? {
+ val srt = when (sort) {
+ is Sort.Top -> sort.redditSort to sort.redditT
+ else -> sort.redditSort to null
+ }
return try {
- val memesList = getNetworkData(community.id, time)
+ val memesList = getNetworkData(community.id, srt.first, srt.second)
Thread {
insertMemes(memesList)
}.start()
memesList
} catch (e: Exception) {
+ Log.e("Reddit Repository", e.message, e)
null
}
}
@@ -39,9 +46,13 @@ class RedditMemeRepositoryImpl(
override suspend fun getLocalData(community: RedditCommunity): List =
redditMemeDao.getAll(community.id)
- private suspend fun getNetworkData(subreddit: String, time: String): List {
+ private suspend fun getNetworkData(
+ subreddit: String,
+ sort: String,
+ time: String?
+ ): List {
val memeList: ArrayList = arrayListOf()
- val redditData = redditApi.getRedditData(subreddit, time).data.children
+ val redditData = redditApi.getRedditData(subreddit, sort, time).data.children
redditData.forEach { child ->
val url = child.Childdata.url
if (url.matches(imageRegex)) {
diff --git a/app/src/main/java/app/suhasdissa/memerize/backend/viewmodels/LemmyViewModel.kt b/app/src/main/java/app/suhasdissa/memerize/backend/viewmodels/LemmyViewModel.kt
index c7c421d..c7f63ef 100644
--- a/app/src/main/java/app/suhasdissa/memerize/backend/viewmodels/LemmyViewModel.kt
+++ b/app/src/main/java/app/suhasdissa/memerize/backend/viewmodels/LemmyViewModel.kt
@@ -18,8 +18,7 @@ import androidx.lifecycle.viewmodel.initializer
import androidx.lifecycle.viewmodel.viewModelFactory
import app.suhasdissa.memerize.MemerizeApplication
import app.suhasdissa.memerize.backend.database.entity.LemmyCommunity
-import app.suhasdissa.memerize.backend.model.SortTime
-import app.suhasdissa.memerize.backend.model.lemmy
+import app.suhasdissa.memerize.backend.model.Sort
import app.suhasdissa.memerize.backend.repositories.LemmyMemeRepository
import app.suhasdissa.memerize.backend.viewmodels.state.MemeUiState
import kotlinx.coroutines.launch
@@ -31,19 +30,19 @@ class LemmyViewModel(private val lemmyRepository: LemmyMemeRepository) :
var currentCommunity: LemmyCommunity? = null
private set
- var currentSortTime: SortTime = SortTime.TODAY
+ var currentSortTime: Sort = Sort.Top.Today
private set
fun getMemePhotos(
community: LemmyCommunity? = currentCommunity,
- time: SortTime = SortTime.TODAY
+ sort: Sort = Sort.Top.Today
) {
currentCommunity = community!!
- currentSortTime = time
+ currentSortTime = sort
viewModelScope.launch {
memeUiState = MemeUiState.Loading
- memeUiState = when (val data = lemmyRepository.getOnlineData(community, time.lemmy)) {
+ memeUiState = when (val data = lemmyRepository.getOnlineData(community, sort)) {
null -> {
MemeUiState.Error("")
}
diff --git a/app/src/main/java/app/suhasdissa/memerize/backend/viewmodels/PlayerViewModel.kt b/app/src/main/java/app/suhasdissa/memerize/backend/viewmodels/PlayerViewModel.kt
index f85c187..45e1e57 100644
--- a/app/src/main/java/app/suhasdissa/memerize/backend/viewmodels/PlayerViewModel.kt
+++ b/app/src/main/java/app/suhasdissa/memerize/backend/viewmodels/PlayerViewModel.kt
@@ -15,30 +15,16 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel
-import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
-import androidx.lifecycle.viewmodel.initializer
-import androidx.lifecycle.viewmodel.viewModelFactory
+import androidx.media3.common.Player
import androidx.media3.common.util.UnstableApi
-import androidx.media3.exoplayer.ExoPlayer
-import app.suhasdissa.memerize.MemerizeApplication
import app.suhasdissa.memerize.utils.RedditVideoDownloader
import kotlinx.coroutines.launch
@UnstableApi
-class PlayerViewModel(appContext: Context) : ViewModel() {
- val player: ExoPlayer = ExoPlayer.Builder(appContext).build()
-
+class PlayerViewModel() : ViewModel() {
var downloadState: DownloadState by mutableStateOf(DownloadState.NotStarted)
- fun playPause() {
- if (player.isPlaying) player.pause() else player.play()
- }
-
- fun seekTo(to: Long) {
- player.seekTo(to)
- }
-
@RequiresApi(Build.VERSION_CODES.O)
fun downloadVideo(context: Context, url: String) {
viewModelScope.launch {
@@ -54,14 +40,8 @@ class PlayerViewModel(appContext: Context) : ViewModel() {
}
}
}
+}
- companion object {
- val Factory: ViewModelProvider.Factory = viewModelFactory {
- initializer {
- val application =
- (this[ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY] as MemerizeApplication) // ktlint-disable max-line-length
- PlayerViewModel(application)
- }
- }
- }
+fun Player.playPause() {
+ if (isPlaying) pause() else play()
}
diff --git a/app/src/main/java/app/suhasdissa/memerize/backend/viewmodels/RedditViewModel.kt b/app/src/main/java/app/suhasdissa/memerize/backend/viewmodels/RedditViewModel.kt
index e0934ee..956caae 100644
--- a/app/src/main/java/app/suhasdissa/memerize/backend/viewmodels/RedditViewModel.kt
+++ b/app/src/main/java/app/suhasdissa/memerize/backend/viewmodels/RedditViewModel.kt
@@ -19,8 +19,7 @@ import androidx.lifecycle.viewmodel.viewModelFactory
import app.suhasdissa.memerize.MemerizeApplication
import app.suhasdissa.memerize.backend.database.entity.RedditCommunity
import app.suhasdissa.memerize.backend.database.entity.RedditMeme
-import app.suhasdissa.memerize.backend.model.SortTime
-import app.suhasdissa.memerize.backend.model.reddit
+import app.suhasdissa.memerize.backend.model.Sort
import app.suhasdissa.memerize.backend.repositories.RedditMemeRepository
import app.suhasdissa.memerize.backend.viewmodels.state.MemeUiState
import kotlinx.coroutines.async
@@ -35,21 +34,21 @@ class RedditViewModel(private val redditRepository: RedditMemeRepository) :
var currentSubreddit: RedditCommunity? = null
private set
- var currentSortTime: SortTime = SortTime.TODAY
+ var currentSortTime: Sort = Sort.Top.Today
private set
fun getMemePhotos(
subreddit: RedditCommunity? = currentSubreddit,
- time: SortTime = SortTime.TODAY
+ sort: Sort = Sort.Top.Today
) {
currentSubreddit = subreddit!!
- currentSortTime = time
+ currentSortTime = sort
viewModelScope.launch {
memeUiState = MemeUiState.Loading
memeUiState = when (
val data =
- redditRepository.getOnlineData(subreddit, time.reddit)
+ redditRepository.getOnlineData(subreddit, sort)
) {
null -> {
MemeUiState.Error("")
@@ -76,7 +75,7 @@ class RedditViewModel(private val redditRepository: RedditMemeRepository) :
currentSubreddit = null
memeUiState = MemeUiState.Loading
val results = communities.map {
- async { redditRepository.getOnlineData(it, SortTime.TODAY.reddit) }
+ async { redditRepository.getOnlineData(it, Sort.Top.Today) }
}.awaitAll()
val memeList: List = results.filterNotNull().flatten().shuffled()
memeUiState = if (memeList.isEmpty()) {
diff --git a/app/src/main/java/app/suhasdissa/memerize/ui/components/MemeCard.kt b/app/src/main/java/app/suhasdissa/memerize/ui/components/MemeCard.kt
index fbea54a..96cbe05 100644
--- a/app/src/main/java/app/suhasdissa/memerize/ui/components/MemeCard.kt
+++ b/app/src/main/java/app/suhasdissa/memerize/ui/components/MemeCard.kt
@@ -8,16 +8,12 @@ All Rights Reserved
package app.suhasdissa.memerize.ui.components
import androidx.compose.runtime.Composable
-import java.net.URLEncoder
-import java.nio.charset.StandardCharsets
@Composable
fun MemeCard(
- onClickMeme: (url: String) -> Unit,
+ onClickMeme: () -> Unit,
photo: String,
title: String
) {
- val encodedImg = URLEncoder.encode(photo, StandardCharsets.UTF_8.toString())
-
- ImageCard({ onClickMeme(encodedImg) }, photo, title)
+ ImageCard({ onClickMeme.invoke() }, photo, title)
}
diff --git a/app/src/main/java/app/suhasdissa/memerize/ui/components/MemeGrid.kt b/app/src/main/java/app/suhasdissa/memerize/ui/components/MemeGrid.kt
index 742edd8..4aa96a3 100644
--- a/app/src/main/java/app/suhasdissa/memerize/ui/components/MemeGrid.kt
+++ b/app/src/main/java/app/suhasdissa/memerize/ui/components/MemeGrid.kt
@@ -15,7 +15,7 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
-import androidx.compose.foundation.lazy.grid.items
+import androidx.compose.foundation.lazy.grid.itemsIndexed
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
@@ -29,8 +29,7 @@ import app.suhasdissa.memerize.backend.database.entity.Meme
@Composable
fun MemeGrid(
memes: List,
- onClickMeme: (url: String) -> Unit,
- onClickVideo: (url: String) -> Unit
+ onClickCard: (id: Int) -> Unit
) {
Column(
modifier = Modifier
@@ -44,11 +43,15 @@ fun MemeGrid(
modifier = Modifier.fillMaxWidth(),
contentPadding = PaddingValues(8.dp)
) {
- items(items = memes) { meme ->
+ itemsIndexed(items = memes) { index, meme ->
if (meme.isVideo) {
- VideoCard(onClickVideo, meme.url, meme.title, meme.preview, Modifier)
+ VideoCard(onClickVideo = {
+ onClickCard.invoke(index)
+ }, meme.title, meme.preview, Modifier)
} else {
- MemeCard(onClickMeme, meme.url, meme.title)
+ MemeCard(onClickMeme = {
+ onClickCard.invoke(index)
+ }, meme.url, meme.title)
}
}
}
diff --git a/app/src/main/java/app/suhasdissa/memerize/ui/components/SortBottomSheet.kt b/app/src/main/java/app/suhasdissa/memerize/ui/components/SortBottomSheet.kt
new file mode 100644
index 0000000..44467d0
--- /dev/null
+++ b/app/src/main/java/app/suhasdissa/memerize/ui/components/SortBottomSheet.kt
@@ -0,0 +1,70 @@
+/*******************************************************************************
+Created By Suhas Dissanayake on 8/14/23, 1:10 PM
+Copyright (c) 2023
+https://github.com/SuhasDissa/
+All Rights Reserved
+ ******************************************************************************/
+
+package app.suhasdissa.memerize.ui.components
+
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.FilterChip
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.ModalBottomSheet
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.remember
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.unit.dp
+import app.suhasdissa.memerize.R
+import app.suhasdissa.memerize.backend.model.Sort
+
+@OptIn(ExperimentalMaterial3Api::class)
+@Composable
+fun SortBottomSheet(currentSort: Sort, onSelect: (Sort) -> Unit, onDismissRequest: () -> Unit) {
+ val options = remember { listOf(Sort.Hot, Sort.New, Sort.Rising) }
+ val topOptions = remember { listOf(Sort.Top.Today, Sort.Top.Week, Sort.Top.Month) }
+
+ ModalBottomSheet(onDismissRequest) {
+ Column(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(16.dp)
+ ) {
+ Text(
+ text = stringResource(R.string.sort_by),
+ style = MaterialTheme.typography.titleLarge
+ )
+ Row(Modifier.fillMaxWidth(), Arrangement.SpaceEvenly) {
+ options.forEach {
+ SortFilterChip(selected = currentSort == it, sort = it, onSelect)
+ }
+ }
+ Text(
+ text = stringResource(id = R.string.top),
+ style = MaterialTheme.typography.titleMedium
+ )
+ Row(Modifier.fillMaxWidth(), Arrangement.SpaceEvenly) {
+ topOptions.forEach {
+ SortFilterChip(selected = currentSort == it, sort = it, onSelect)
+ }
+ }
+ }
+ }
+}
+
+@OptIn(ExperimentalMaterial3Api::class)
+@Composable
+fun SortFilterChip(selected: Boolean, sort: Sort, onSelect: (Sort) -> Unit) {
+ FilterChip(
+ selected,
+ onClick = { onSelect(sort) },
+ label = { Text(stringResource(id = sort.name)) }
+ )
+}
diff --git a/app/src/main/java/app/suhasdissa/memerize/ui/components/VideoCard.kt b/app/src/main/java/app/suhasdissa/memerize/ui/components/VideoCard.kt
index 8cd67f7..3a9b79c 100644
--- a/app/src/main/java/app/suhasdissa/memerize/ui/components/VideoCard.kt
+++ b/app/src/main/java/app/suhasdissa/memerize/ui/components/VideoCard.kt
@@ -22,25 +22,21 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
-import java.net.URLEncoder
-import java.nio.charset.StandardCharsets
@Composable
fun VideoCard(
- onClickVideo: (url: String) -> Unit,
- vidlink: String,
+ onClickVideo: () -> Unit,
title: String,
preview: String,
modifier: Modifier = Modifier
) {
- val encodedLink = URLEncoder.encode(vidlink, StandardCharsets.UTF_8.toString())
Box(
contentAlignment = Alignment.Center,
modifier = modifier
.fillMaxSize()
) {
- ImageCard({ onClickVideo(encodedLink) }, preview, title)
- Card(modifier.clickable(onClick = { onClickVideo(encodedLink) }), shape = CircleShape) {
+ ImageCard({ onClickVideo.invoke() }, preview, title)
+ Card(modifier.clickable(onClick = { onClickVideo.invoke() }), shape = CircleShape) {
Icon(
modifier = modifier.size(64.dp),
imageVector = Icons.Default.PlayCircle,
@@ -55,5 +51,5 @@ fun VideoCard(
@Preview
@Composable
fun VideoCardPreview() {
- VideoCard(onClickVideo = {}, vidlink = "", title = "Preview", preview = "")
+ VideoCard(onClickVideo = {}, title = "Preview", preview = "")
}
diff --git a/app/src/main/java/app/suhasdissa/memerize/ui/screens/home/HomeScreen.kt b/app/src/main/java/app/suhasdissa/memerize/ui/screens/home/HomeScreen.kt
index 7f947fc..9032c20 100644
--- a/app/src/main/java/app/suhasdissa/memerize/ui/screens/home/HomeScreen.kt
+++ b/app/src/main/java/app/suhasdissa/memerize/ui/screens/home/HomeScreen.kt
@@ -7,6 +7,7 @@ All Rights Reserved
package app.suhasdissa.memerize.ui.screens.home
+import androidx.activity.ComponentActivity
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
@@ -27,13 +28,13 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import app.suhasdissa.memerize.Destination
import app.suhasdissa.memerize.R
import app.suhasdissa.memerize.backend.database.entity.RedditCommunity
-import app.suhasdissa.memerize.backend.model.SortTime
import app.suhasdissa.memerize.backend.viewmodels.LemmyCommunityViewModel
import app.suhasdissa.memerize.backend.viewmodels.LemmyViewModel
import app.suhasdissa.memerize.backend.viewmodels.RedditCommunityViewModel
@@ -51,8 +52,14 @@ fun HomeScreen(
lemmyCommunityViewModel: LemmyCommunityViewModel = viewModel(
factory = LemmyCommunityViewModel.Factory
),
- redditViewModel: RedditViewModel,
- lemmyViewModel: LemmyViewModel
+ redditViewModel: RedditViewModel = viewModel(
+ LocalContext.current as ComponentActivity,
+ factory = RedditViewModel.Factory
+ ),
+ lemmyViewModel: LemmyViewModel = viewModel(
+ LocalContext.current as ComponentActivity,
+ factory = LemmyViewModel.Factory
+ )
) {
val subreddits by redditCommunityViewModel.communities.collectAsState()
val communities by lemmyCommunityViewModel.communities.collectAsState()
@@ -105,7 +112,7 @@ fun HomeScreen(
selectedSubreddits.add(it)
}
} else {
- redditViewModel.getMemePhotos(it, SortTime.TODAY)
+ redditViewModel.getMemePhotos(it)
onNavigate(Destination.RedditMemeView)
}
},
diff --git a/app/src/main/java/app/suhasdissa/memerize/ui/screens/primary/LemmyMemeScreen.kt b/app/src/main/java/app/suhasdissa/memerize/ui/screens/primary/LemmyMemeScreen.kt
index 0847a8c..f911e3f 100644
--- a/app/src/main/java/app/suhasdissa/memerize/ui/screens/primary/LemmyMemeScreen.kt
+++ b/app/src/main/java/app/suhasdissa/memerize/ui/screens/primary/LemmyMemeScreen.kt
@@ -7,24 +7,19 @@ All Rights Reserved
package app.suhasdissa.memerize.ui.screens.primary
-import androidx.compose.animation.AnimatedVisibility
-import androidx.compose.foundation.layout.Arrangement
+import androidx.activity.ComponentActivity
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
-import androidx.compose.foundation.lazy.grid.LazyGridState
-import androidx.compose.foundation.lazy.grid.rememberLazyGridState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.FilterList
import androidx.compose.material3.ExperimentalMaterial3Api
-import androidx.compose.material3.FilterChip
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
@@ -43,13 +38,14 @@ import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
+import androidx.lifecycle.viewmodel.compose.viewModel
import app.suhasdissa.memerize.R
-import app.suhasdissa.memerize.backend.model.SortTime
import app.suhasdissa.memerize.backend.viewmodels.LemmyViewModel
import app.suhasdissa.memerize.backend.viewmodels.state.MemeUiState
import app.suhasdissa.memerize.ui.components.LoadingScreen
import app.suhasdissa.memerize.ui.components.MemeGrid
import app.suhasdissa.memerize.ui.components.RetryScreen
+import app.suhasdissa.memerize.ui.components.SortBottomSheet
import coil.compose.AsyncImage
import coil.request.ImageRequest
@@ -57,9 +53,11 @@ import coil.request.ImageRequest
@Composable
fun LemmyMemeScreen(
modifier: Modifier = Modifier,
- lemmyViewModel: LemmyViewModel,
- onClickMeme: (url: String) -> Unit,
- onClickVideo: (url: String) -> Unit
+ lemmyViewModel: LemmyViewModel = viewModel(
+ LocalContext.current as ComponentActivity,
+ factory = LemmyViewModel.Factory
+ ),
+ onClickCard: (Int) -> Unit
) {
var showFilterButtons by remember { mutableStateOf(false) }
Scaffold(
@@ -102,45 +100,6 @@ fun LemmyMemeScreen(
}
) { paddingValues ->
Column(Modifier.padding(paddingValues)) {
- val listState: LazyGridState = rememberLazyGridState()
- lemmyViewModel.currentCommunity?.let {
- AnimatedVisibility(visible = !listState.canScrollBackward) {
- AnimatedVisibility(visible = showFilterButtons) {
- Row(modifier.fillMaxWidth(), Arrangement.SpaceEvenly) {
- FilterChip(
- selected = lemmyViewModel.currentSortTime == SortTime.TODAY,
- onClick = {
- showFilterButtons = false
- lemmyViewModel.getMemePhotos(time = SortTime.TODAY)
- },
- label = {
- Text(stringResource(R.string.reddit_today_btn))
- }
- )
- FilterChip(
- selected = lemmyViewModel.currentSortTime == SortTime.WEEK,
- onClick = {
- showFilterButtons = false
- lemmyViewModel.getMemePhotos(time = SortTime.WEEK)
- },
- label = {
- Text(stringResource(R.string.reddit_week_btn))
- }
- )
- FilterChip(
- selected = lemmyViewModel.currentSortTime == SortTime.MONTH,
- onClick = {
- showFilterButtons = false
- lemmyViewModel.getMemePhotos(time = SortTime.MONTH)
- },
- label = {
- Text(stringResource(R.string.reddit_month_btn))
- }
- )
- }
- }
- }
- }
when (val memeDataState = lemmyViewModel.memeUiState) {
is MemeUiState.Loading -> LoadingScreen(modifier)
is MemeUiState.Error -> RetryScreen(
@@ -152,10 +111,15 @@ fun LemmyMemeScreen(
is MemeUiState.Success -> MemeGrid(
memeDataState.memes,
- onClickMeme,
- onClickVideo
+ onClickCard
)
}
}
}
+ if (showFilterButtons) {
+ SortBottomSheet(currentSort = lemmyViewModel.currentSortTime, onSelect = {
+ showFilterButtons = false
+ lemmyViewModel.getMemePhotos(sort = it)
+ }, onDismissRequest = { showFilterButtons = false })
+ }
}
diff --git a/app/src/main/java/app/suhasdissa/memerize/ui/screens/primary/RedditMemeScreen.kt b/app/src/main/java/app/suhasdissa/memerize/ui/screens/primary/RedditMemeScreen.kt
index c541e94..7c6af2e 100644
--- a/app/src/main/java/app/suhasdissa/memerize/ui/screens/primary/RedditMemeScreen.kt
+++ b/app/src/main/java/app/suhasdissa/memerize/ui/screens/primary/RedditMemeScreen.kt
@@ -7,14 +7,12 @@ All Rights Reserved
package app.suhasdissa.memerize.ui.screens.primary
-import androidx.compose.animation.AnimatedVisibility
-import androidx.compose.foundation.layout.Arrangement
+import androidx.activity.ComponentActivity
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
@@ -22,7 +20,6 @@ import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.FilterList
import androidx.compose.material3.ExperimentalMaterial3Api
-import androidx.compose.material3.FilterChip
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
@@ -41,13 +38,14 @@ import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
+import androidx.lifecycle.viewmodel.compose.viewModel
import app.suhasdissa.memerize.R
-import app.suhasdissa.memerize.backend.model.SortTime
import app.suhasdissa.memerize.backend.viewmodels.RedditViewModel
import app.suhasdissa.memerize.backend.viewmodels.state.MemeUiState
import app.suhasdissa.memerize.ui.components.LoadingScreen
import app.suhasdissa.memerize.ui.components.MemeGrid
import app.suhasdissa.memerize.ui.components.RetryScreen
+import app.suhasdissa.memerize.ui.components.SortBottomSheet
import coil.compose.AsyncImage
import coil.request.ImageRequest
@@ -55,9 +53,11 @@ import coil.request.ImageRequest
@Composable
fun RedditMemeScreen(
modifier: Modifier = Modifier,
- redditViewModel: RedditViewModel,
- onClickMeme: (url: String) -> Unit,
- onClickVideo: (url: String) -> Unit
+ redditViewModel: RedditViewModel = viewModel(
+ LocalContext.current as ComponentActivity,
+ factory = RedditViewModel.Factory
+ ),
+ onClickCard: (Int) -> Unit
) {
var showFilterButtons by remember { mutableStateOf(false) }
Scaffold(
@@ -100,42 +100,6 @@ fun RedditMemeScreen(
}
) { paddingValues ->
Column(Modifier.padding(paddingValues)) {
- redditViewModel.currentSubreddit?.let {
- AnimatedVisibility(visible = showFilterButtons) {
- Row(modifier.fillMaxWidth(), Arrangement.SpaceEvenly) {
- FilterChip(
- selected = redditViewModel.currentSortTime == SortTime.TODAY,
- onClick = {
- showFilterButtons = false
- redditViewModel.getMemePhotos(time = SortTime.TODAY)
- },
- label = {
- Text(stringResource(R.string.reddit_today_btn))
- }
- )
- FilterChip(
- selected = redditViewModel.currentSortTime == SortTime.WEEK,
- onClick = {
- showFilterButtons = false
- redditViewModel.getMemePhotos(time = SortTime.WEEK)
- },
- label = {
- Text(stringResource(R.string.reddit_week_btn))
- }
- )
- FilterChip(
- selected = redditViewModel.currentSortTime == SortTime.MONTH,
- onClick = {
- showFilterButtons = false
- redditViewModel.getMemePhotos(time = SortTime.MONTH)
- },
- label = {
- Text(stringResource(R.string.reddit_month_btn))
- }
- )
- }
- }
- }
when (val memeDataState = redditViewModel.memeUiState) {
is MemeUiState.Loading -> LoadingScreen(modifier)
is MemeUiState.Error -> RetryScreen(
@@ -147,10 +111,15 @@ fun RedditMemeScreen(
is MemeUiState.Success -> MemeGrid(
memeDataState.memes,
- onClickMeme,
- onClickVideo
+ onClickCard
)
}
}
}
+ if (showFilterButtons) {
+ SortBottomSheet(currentSort = redditViewModel.currentSortTime, onSelect = {
+ showFilterButtons = false
+ redditViewModel.getMemePhotos(sort = it)
+ }, onDismissRequest = { showFilterButtons = false })
+ }
}
diff --git a/app/src/main/java/app/suhasdissa/memerize/ui/screens/secondary/MemeFeedView.kt b/app/src/main/java/app/suhasdissa/memerize/ui/screens/secondary/MemeFeedView.kt
new file mode 100644
index 0000000..1f294f9
--- /dev/null
+++ b/app/src/main/java/app/suhasdissa/memerize/ui/screens/secondary/MemeFeedView.kt
@@ -0,0 +1,70 @@
+/*******************************************************************************
+Created By Suhas Dissanayake on 8/15/23, 12:48 PM
+Copyright (c) 2023
+https://github.com/SuhasDissa/
+All Rights Reserved
+ ******************************************************************************/
+
+package app.suhasdissa.memerize.ui.screens.secondary
+
+import androidx.activity.ComponentActivity
+import androidx.compose.foundation.ExperimentalFoundationApi
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.pager.VerticalPager
+import androidx.compose.foundation.pager.rememberPagerState
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.LocalContext
+import androidx.lifecycle.viewmodel.compose.viewModel
+import app.suhasdissa.memerize.backend.database.entity.Meme
+import app.suhasdissa.memerize.backend.viewmodels.LemmyViewModel
+import app.suhasdissa.memerize.backend.viewmodels.RedditViewModel
+import app.suhasdissa.memerize.backend.viewmodels.state.MemeUiState
+
+@Composable
+fun RedditMemeFeed(
+ initialPage: Int,
+ redditViewModel: RedditViewModel = viewModel(
+ LocalContext.current as ComponentActivity,
+ factory = RedditViewModel.Factory
+ )
+) {
+ when (val state = redditViewModel.memeUiState) {
+ is MemeUiState.Success -> MemeFeedView(initialPage, memes = state.memes)
+ else -> {}
+ }
+}
+
+@Composable
+fun LemmyMemeFeed(
+ initialPage: Int,
+ lemmyViewModel: LemmyViewModel = viewModel(
+ LocalContext.current as ComponentActivity,
+ factory = LemmyViewModel.Factory
+ )
+) {
+ when (val state = lemmyViewModel.memeUiState) {
+ is MemeUiState.Success -> MemeFeedView(initialPage, memes = state.memes)
+ else -> {}
+ }
+}
+
+@OptIn(ExperimentalFoundationApi::class)
+@Composable
+private fun MemeFeedView(initialPage: Int, memes: List) {
+ val pagerState = rememberPagerState(
+ initialPage = initialPage,
+ initialPageOffsetFraction = 0f
+ ) {
+ memes.size
+ }
+ VerticalPager(modifier = Modifier.fillMaxSize(), state = pagerState) {
+ with(memes[it]) {
+ if (isVideo) {
+ VideoView(this, playWhenReady = (it == pagerState.currentPage))
+ } else {
+ PhotoView(this)
+ }
+ }
+ }
+}
diff --git a/app/src/main/java/app/suhasdissa/memerize/ui/screens/secondary/PhotoView.kt b/app/src/main/java/app/suhasdissa/memerize/ui/screens/secondary/PhotoView.kt
index 96da1f8..f304094 100644
--- a/app/src/main/java/app/suhasdissa/memerize/ui/screens/secondary/PhotoView.kt
+++ b/app/src/main/java/app/suhasdissa/memerize/ui/screens/secondary/PhotoView.kt
@@ -49,21 +49,18 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import app.suhasdissa.memerize.R
+import app.suhasdissa.memerize.backend.database.entity.Meme
import app.suhasdissa.memerize.backend.viewmodels.DownloadState
import app.suhasdissa.memerize.backend.viewmodels.PhotoViewModel
import coil.compose.AsyncImage
-import coil.request.ImageRequest
import java.lang.Float.max
-import java.net.URLDecoder
-import java.nio.charset.StandardCharsets
@Composable
fun PhotoView(
- photo: String,
+ meme: Meme,
photoViewModel: PhotoViewModel = viewModel()
) {
val context = LocalContext.current
- val photoUrl = remember { URLDecoder.decode(photo, StandardCharsets.UTF_8.toString()) }
Column(Modifier.fillMaxSize(), verticalArrangement = Arrangement.SpaceEvenly) {
var scale by remember { mutableFloatStateOf(1f) }
var offsetX by remember { mutableFloatStateOf(1f) }
@@ -93,8 +90,7 @@ fun PhotoView(
contentAlignment = Alignment.Center
) {
AsyncImage(
- model = ImageRequest.Builder(context = LocalContext.current).data(photoUrl)
- .crossfade(true).build(),
+ model = meme.url,
contentDescription = stringResource(R.string.meme_photo),
contentScale = ContentScale.Fit,
modifier = Modifier
@@ -124,7 +120,7 @@ fun PhotoView(
) {
IconButton(onClick = {
view.playSoundEffect(SoundEffectConstants.CLICK)
- photoViewModel.savePhotoToDisk(photoUrl, context)
+ photoViewModel.savePhotoToDisk(meme.url, context)
}) {
Icon(
imageVector = when (photoViewModel.downloadState) {
@@ -139,7 +135,7 @@ fun PhotoView(
}
IconButton(onClick = {
view.playSoundEffect(SoundEffectConstants.CLICK)
- photoViewModel.shareImage(photoUrl, context)
+ photoViewModel.shareImage(meme.url, context)
}) {
Icon(
imageVector = Icons.Default.Share,
diff --git a/app/src/main/java/app/suhasdissa/memerize/ui/screens/secondary/VideoView.kt b/app/src/main/java/app/suhasdissa/memerize/ui/screens/secondary/VideoView.kt
index 5959b5a..2b950dc 100644
--- a/app/src/main/java/app/suhasdissa/memerize/ui/screens/secondary/VideoView.kt
+++ b/app/src/main/java/app/suhasdissa/memerize/ui/screens/secondary/VideoView.kt
@@ -51,69 +51,70 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.res.stringResource
-import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.media3.common.MediaItem
import androidx.media3.common.Player
+import androidx.media3.exoplayer.ExoPlayer
import androidx.media3.ui.PlayerView
import app.suhasdissa.memerize.R
+import app.suhasdissa.memerize.backend.database.entity.Meme
import app.suhasdissa.memerize.backend.viewmodels.DownloadState
import app.suhasdissa.memerize.backend.viewmodels.PlayerViewModel
+import app.suhasdissa.memerize.backend.viewmodels.playPause
import app.suhasdissa.memerize.utils.PlayerState
import app.suhasdissa.memerize.utils.isPlayingState
import app.suhasdissa.memerize.utils.positionAndDurationState
import app.suhasdissa.memerize.utils.shareUrl
-import java.net.URLDecoder
-import java.nio.charset.StandardCharsets
@Composable
fun VideoView(
- url: String,
- modifier: Modifier = Modifier,
- playerViewModel: PlayerViewModel = viewModel(factory = PlayerViewModel.Factory)
+ meme: Meme,
+ playWhenReady: Boolean = false,
+ playerViewModel: PlayerViewModel = viewModel()
) {
- val decodedUrl = remember { URLDecoder.decode(url, StandardCharsets.UTF_8.toString()) }
-
+ val context = LocalContext.current
+ val player = remember(context) { ExoPlayer.Builder(context).build() }
+ player.playWhenReady = playWhenReady
DisposableEffect(Unit) {
- with(playerViewModel.player) {
- val mediaItem = MediaItem.Builder().setUri(decodedUrl).build()
+ with(player) {
+ val mediaItem = MediaItem.Builder().setUri(meme.url).build()
setMediaItem(mediaItem)
- playWhenReady = true
prepare()
onDispose {
- stop()
+ player.release()
}
}
}
- Column(modifier.fillMaxSize(), verticalArrangement = Arrangement.SpaceEvenly) {
+ Column(Modifier.fillMaxSize(), verticalArrangement = Arrangement.SpaceEvenly) {
Box(
- modifier = modifier
+ modifier = Modifier
.weight(1f)
.fillMaxWidth(),
contentAlignment = Alignment.Center
) {
AndroidView(factory = { context ->
PlayerView(context).apply {
- player = playerViewModel.player
+ this.player = player
useController = false
}
}, modifier = Modifier.fillMaxSize())
}
- PlayerController(playerViewModel, decodedUrl)
+ PlayerController(player, playerViewModel, meme.url)
}
}
@SuppressLint("UnsafeOptInUsageError")
@Composable
fun PlayerController(
- playerViewModel: PlayerViewModel = viewModel(factory = PlayerViewModel.Factory),
+ player: Player,
+ playerViewModel: PlayerViewModel = viewModel(),
decodedUrl: String
) {
val view = LocalView.current
- with(playerViewModel.player) {
+ with(player) {
Column(Modifier.padding(16.dp)) {
val positionAndDuration by positionAndDurationState()
Row(Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) {
@@ -128,7 +129,7 @@ fun PlayerController(
),
onValueChangeFinished = {
tempSliderPosition?.let {
- playerViewModel.seekTo(it.toLong())
+ player.seekTo(it.toLong())
}
tempSliderPosition = null
}
@@ -180,7 +181,7 @@ fun PlayerController(
IconButton(
onClick = {
view.playSoundEffect(SoundEffectConstants.CLICK)
- playerViewModel.playPause()
+ player.playPause()
},
modifier = Modifier.padding(8.dp)
) {
@@ -250,9 +251,3 @@ fun PlayerController(
}
}
}
-
-@Preview(showBackground = true)
-@Composable
-private fun DefaultPreview() {
- PlayerController(decodedUrl = "")
-}