Compare commits
4 Commits
1.1.0-beta
...
develop
Author | SHA1 | Date |
---|---|---|
|
7d661712f7 | |
|
8fcf047e99 | |
|
17dbe945e5 | |
|
5f609d4c33 |
|
@ -4,9 +4,16 @@ plugins {
|
|||
id 'org.jetbrains.kotlin.plugin.serialization' version "$kotlin_version"
|
||||
}
|
||||
|
||||
kotlin {
|
||||
jvmToolchain 11
|
||||
sourceSets.configureEach {
|
||||
languageSettings.optIn("kotlin.RequiresOptIn")
|
||||
}
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdk 33
|
||||
buildToolsVersion '30.0.3'
|
||||
compileSdk 34
|
||||
buildToolsVersion = '34.0.0'
|
||||
|
||||
defaultConfig {
|
||||
applicationId "org.mosad.teapod"
|
||||
|
@ -32,16 +39,6 @@ android {
|
|||
}
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
kotlinOptions {
|
||||
jvmTarget = '1.8'
|
||||
kotlin.sourceSets.configureEach {
|
||||
languageSettings.optIn("kotlin.RequiresOptIn")
|
||||
}
|
||||
}
|
||||
namespace 'org.mosad.teapod'
|
||||
}
|
||||
|
||||
|
@ -49,20 +46,20 @@ dependencies {
|
|||
implementation fileTree(dir: "libs", include: ["*.jar"])
|
||||
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
|
||||
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3'
|
||||
implementation 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.1'
|
||||
implementation 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.0'
|
||||
|
||||
implementation 'androidx.core:core-ktx:1.10.1'
|
||||
implementation 'androidx.core:core-ktx:1.12.0'
|
||||
implementation 'androidx.core:core-splashscreen:1.0.1'
|
||||
implementation 'androidx.appcompat:appcompat:1.6.1'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
|
||||
implementation 'androidx.navigation:navigation-fragment-ktx:2.6.0'
|
||||
implementation 'androidx.navigation:navigation-ui-ktx:2.6.0'
|
||||
implementation 'androidx.navigation:navigation-fragment-ktx:2.7.5'
|
||||
implementation 'androidx.navigation:navigation-ui-ktx:2.7.5'
|
||||
implementation 'androidx.security:security-crypto:1.1.0-alpha06'
|
||||
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
||||
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.1'
|
||||
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1'
|
||||
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2'
|
||||
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2'
|
||||
|
||||
implementation 'com.google.android.material:material:1.9.0'
|
||||
implementation 'com.google.android.material:material:1.10.0'
|
||||
implementation "com.google.android.exoplayer:exoplayer-core:$exo_version"
|
||||
implementation "com.google.android.exoplayer:exoplayer-hls:$exo_version"
|
||||
implementation "com.google.android.exoplayer:exoplayer-dash:$exo_version"
|
||||
|
|
|
@ -1,17 +1,21 @@
|
|||
package org.mosad.teapod.ui.activity.main.fragments
|
||||
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.lifecycle.repeatOnLifecycle
|
||||
import androidx.viewpager2.adapter.FragmentStateAdapter
|
||||
import com.google.android.material.tabs.TabLayoutMediator
|
||||
import kotlinx.coroutines.launch
|
||||
import org.mosad.teapod.R
|
||||
import org.mosad.teapod.databinding.FragmentMyListsBinding
|
||||
import org.mosad.teapod.parser.crunchyroll.Crunchyroll
|
||||
import org.mosad.teapod.ui.activity.main.viewmodel.MyListsFragmentViewModel
|
||||
import org.mosad.teapod.util.toItemMediaList
|
||||
|
||||
class MyListsFragment : Fragment() {
|
||||
|
@ -19,6 +23,8 @@ class MyListsFragment : Fragment() {
|
|||
private lateinit var binding: FragmentMyListsBinding
|
||||
private lateinit var pagerAdapter: FragmentStateAdapter
|
||||
|
||||
private val model: MyListsFragmentViewModel by viewModels()
|
||||
|
||||
private val fragments = arrayListOf<Fragment>()
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
||||
|
@ -33,7 +39,6 @@ class MyListsFragment : Fragment() {
|
|||
pagerAdapter = ScreenSlidePagerAdapter(this)
|
||||
binding.pagerMyLists.adapter = pagerAdapter
|
||||
|
||||
// TODO is position 0 always episodes? (and 1 always similar titles)
|
||||
TabLayoutMediator(binding.tabMyLists, binding.pagerMyLists) { tab, position ->
|
||||
tab.text = when(position) {
|
||||
0 -> getString(R.string.my_list)
|
||||
|
@ -43,15 +48,33 @@ class MyListsFragment : Fragment() {
|
|||
}
|
||||
}.attach()
|
||||
|
||||
lifecycleScope.launch {
|
||||
val items = Crunchyroll.watchlist(50)
|
||||
|
||||
MediaFragmentSimilar(items.toItemMediaList()).also {
|
||||
fragments.add(it)
|
||||
pagerAdapter.notifyItemInserted(fragments.indexOf(it))
|
||||
viewLifecycleOwner.lifecycleScope.launch {
|
||||
viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
|
||||
model.onUiState(viewLifecycleOwner.lifecycleScope) { uiState ->
|
||||
when (uiState) {
|
||||
is MyListsFragmentViewModel.UiState.Normal -> bindUiStateNormal(uiState)
|
||||
is MyListsFragmentViewModel.UiState.Loading -> bindUiStateLoading()
|
||||
is MyListsFragmentViewModel.UiState.Error -> bindUiStateError(uiState)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun bindUiStateNormal(uiState: MyListsFragmentViewModel.UiState.Normal) {
|
||||
MediaFragmentSimilar(uiState.watchlistItems.toItemMediaList()).also {
|
||||
fragments.add(it)
|
||||
pagerAdapter.notifyItemInserted(fragments.indexOf(it))
|
||||
}
|
||||
}
|
||||
|
||||
private fun bindUiStateLoading() {
|
||||
// currently not used
|
||||
}
|
||||
|
||||
private fun bindUiStateError(uiState: MyListsFragmentViewModel.UiState.Error) {
|
||||
// currently not used
|
||||
Log.e(javaClass.name, "A error occurred while loading a UiState: ${uiState.message}")
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -32,7 +32,7 @@ import kotlinx.coroutines.launch
|
|||
import org.mosad.teapod.parser.crunchyroll.*
|
||||
import kotlin.random.Random
|
||||
|
||||
class HomeViewModel : ViewModel() {
|
||||
class HomeViewModel : ViewModel() {
|
||||
|
||||
private val WATCHLIST_LENGTH = 50
|
||||
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
package org.mosad.teapod.ui.activity.main.viewmodel
|
||||
|
||||
import androidx.lifecycle.LifecycleCoroutineScope
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.launch
|
||||
import org.mosad.teapod.parser.crunchyroll.Crunchyroll
|
||||
import org.mosad.teapod.parser.crunchyroll.Item
|
||||
|
||||
class MyListsFragmentViewModel : ViewModel() {
|
||||
|
||||
private val WATCHLIST_LENGTH = 50
|
||||
|
||||
private val uiState = MutableStateFlow<UiState>(UiState.Loading)
|
||||
|
||||
sealed class UiState {
|
||||
object Loading : UiState()
|
||||
data class Normal(
|
||||
val watchlistItems: List<Item>
|
||||
) : UiState()
|
||||
data class Error(val message: String?) : UiState()
|
||||
}
|
||||
|
||||
init {
|
||||
load()
|
||||
}
|
||||
|
||||
fun onUiState(scope: LifecycleCoroutineScope, collector: (UiState) -> Unit) {
|
||||
scope.launch { uiState.collect { collector(it) } }
|
||||
}
|
||||
|
||||
fun load() {
|
||||
viewModelScope.launch {
|
||||
uiState.emit(UiState.Loading)
|
||||
try {
|
||||
// run the loading in parallel to speed up the process
|
||||
val watchlistJob = viewModelScope.async { Crunchyroll.watchlist(WATCHLIST_LENGTH).data }
|
||||
uiState.emit(
|
||||
UiState.Normal(watchlistJob.await())
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
uiState.emit(UiState.Error(e.message))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
10
build.gradle
10
build.gradle
|
@ -1,14 +1,14 @@
|
|||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
buildscript {
|
||||
ext.kotlin_version = "1.8.22"
|
||||
ext.ktor_version = "2.3.2"
|
||||
ext.kotlin_version = "1.9.0"
|
||||
ext.ktor_version = "2.3.6"
|
||||
ext.exo_version = "2.18.7"
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:8.1.0'
|
||||
classpath 'com.android.tools.build:gradle:8.1.3'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
|
@ -23,6 +23,6 @@ allprojects {
|
|||
}
|
||||
}
|
||||
|
||||
task clean(type: Delete) {
|
||||
tasks.register('clean', Delete) {
|
||||
delete rootProject.buildDir
|
||||
}
|
||||
}
|
||||
|
|
Binary file not shown.
|
@ -1,6 +1,7 @@
|
|||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2.1-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
|
|
@ -130,10 +130,13 @@ location of your Java installation."
|
|||
fi
|
||||
else
|
||||
JAVACMD=java
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
if ! command -v java >/dev/null 2>&1
|
||||
then
|
||||
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
|
|
Loading…
Reference in New Issue