Skip to content

Commit edbfd9f

Browse files
authored
Merge branch 'master' into intro-skipper
2 parents 526d10d + 9aa4159 commit edbfd9f

33 files changed

+537
-353
lines changed

Diff for: app/src/main/java/org/jellyfin/androidtv/SessionInitializer.kt

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import androidx.lifecycle.ProcessLifecycleOwner
55
import androidx.lifecycle.lifecycleScope
66
import androidx.startup.AppInitializer
77
import androidx.startup.Initializer
8+
import kotlinx.coroutines.Dispatchers
89
import kotlinx.coroutines.launch
910
import org.jellyfin.androidtv.auth.repository.SessionRepository
1011
import org.jellyfin.androidtv.di.KoinInitializer
@@ -17,7 +18,7 @@ class SessionInitializer : Initializer<Unit> {
1718
.koin
1819

1920
// Restore system session
20-
ProcessLifecycleOwner.get().lifecycleScope.launch {
21+
ProcessLifecycleOwner.get().lifecycleScope.launch(Dispatchers.IO) {
2122
koin.get<SessionRepository>().restoreSession(destroyOnly = false)
2223
}
2324
}

Diff for: app/src/main/java/org/jellyfin/androidtv/data/repository/ItemMutationRepository.kt

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package org.jellyfin.androidtv.data.repository
22

3+
import kotlinx.coroutines.Dispatchers
4+
import kotlinx.coroutines.withContext
35
import org.jellyfin.androidtv.data.model.DataRefreshService
46
import org.jellyfin.sdk.api.client.ApiClient
57
import org.jellyfin.sdk.api.client.extensions.playStateApi
@@ -19,8 +21,8 @@ class ItemMutationRepositoryImpl(
1921
) : ItemMutationRepository {
2022
override suspend fun setFavorite(item: UUID, favorite: Boolean): UserItemDataDto {
2123
val response by when {
22-
favorite -> api.userLibraryApi.markFavoriteItem(itemId = item)
23-
else -> api.userLibraryApi.unmarkFavoriteItem(itemId = item)
24+
favorite -> withContext(Dispatchers.IO) { api.userLibraryApi.markFavoriteItem(itemId = item) }
25+
else -> withContext(Dispatchers.IO) { api.userLibraryApi.unmarkFavoriteItem(itemId = item) }
2426
}
2527

2628
dataRefreshService.lastFavoriteUpdate = Instant.now()
@@ -29,8 +31,8 @@ class ItemMutationRepositoryImpl(
2931

3032
override suspend fun setPlayed(item: UUID, played: Boolean): UserItemDataDto {
3133
val response by when {
32-
played -> api.playStateApi.markPlayedItem(itemId = item)
33-
else -> api.playStateApi.markUnplayedItem(itemId = item)
34+
played -> withContext(Dispatchers.IO) { api.playStateApi.markPlayedItem(itemId = item) }
35+
else -> withContext(Dispatchers.IO) { api.playStateApi.markUnplayedItem(itemId = item) }
3436
}
3537

3638
return response

Diff for: app/src/main/java/org/jellyfin/androidtv/ui/AsyncImageView.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ class AsyncImageView @JvmOverloads constructor(
6464
aspectRatio: Double = 1.0,
6565
blurHashResolution: Int = 32,
6666
) = doOnAttach {
67-
lifeCycleOwner?.lifecycleScope?.launch {
67+
lifeCycleOwner?.lifecycleScope?.launch(Dispatchers.IO) {
6868
var placeholderOrBlurHash = placeholder
6969

7070
// Only show blurhash if an image is going to be loaded from the network

Diff for: app/src/main/java/org/jellyfin/androidtv/ui/ItemListViewHelper.kt

+8-4
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ package org.jellyfin.androidtv.ui
22

33
import androidx.lifecycle.findViewTreeLifecycleOwner
44
import androidx.lifecycle.lifecycleScope
5+
import kotlinx.coroutines.Dispatchers
56
import kotlinx.coroutines.launch
7+
import kotlinx.coroutines.withContext
68
import org.jellyfin.androidtv.data.repository.ItemRepository
79
import org.jellyfin.sdk.api.client.ApiClient
810
import org.jellyfin.sdk.api.client.extensions.itemsApi
@@ -12,10 +14,12 @@ fun ItemListView.refresh() {
1214
val api by KoinJavaComponent.inject<ApiClient>(ApiClient::class.java)
1315

1416
findViewTreeLifecycleOwner()?.lifecycleScope?.launch {
15-
val response by api.itemsApi.getItems(
16-
ids = mItemIds,
17-
fields = ItemRepository.itemFields
18-
)
17+
val response = withContext(Dispatchers.IO) {
18+
api.itemsApi.getItems(
19+
ids = mItemIds,
20+
fields = ItemRepository.itemFields
21+
).content
22+
}
1923

2024
response.items?.forEachIndexed { index, item ->
2125
val view = mList.getChildAt(index)

Diff for: app/src/main/java/org/jellyfin/androidtv/ui/LiveProgramDetailPopupHelper.kt

+22-10
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package org.jellyfin.androidtv.ui
22

33
import androidx.lifecycle.coroutineScope
4+
import kotlinx.coroutines.Dispatchers
45
import kotlinx.coroutines.launch
6+
import kotlinx.coroutines.withContext
57
import org.jellyfin.androidtv.data.repository.ItemMutationRepository
68
import org.jellyfin.androidtv.util.getActivity
79
import org.jellyfin.sdk.api.client.ApiClient
@@ -32,7 +34,9 @@ fun LiveProgramDetailPopup.cancelTimer(
3234

3335
lifecycle.coroutineScope.launch {
3436
runCatching {
35-
api.liveTvApi.cancelTimer(timerId)
37+
withContext(Dispatchers.IO) {
38+
api.liveTvApi.cancelTimer(timerId)
39+
}
3640
}.onSuccess {
3741
callback()
3842
}
@@ -47,7 +51,9 @@ fun LiveProgramDetailPopup.cancelSeriesTimer(
4751

4852
lifecycle.coroutineScope.launch {
4953
runCatching {
50-
api.liveTvApi.cancelSeriesTimer(seriesTimerId)
54+
withContext(Dispatchers.IO) {
55+
api.liveTvApi.cancelSeriesTimer(seriesTimerId)
56+
}
5157
}.onSuccess {
5258
callback()
5359
}
@@ -88,10 +94,12 @@ fun LiveProgramDetailPopup.recordProgram(
8894

8995
lifecycle.coroutineScope.launch {
9096
runCatching {
91-
val seriesTimer by api.liveTvApi.getDefaultTimer(programId.toString())
92-
val timer = seriesTimer.asTimerInfoDto()
93-
api.liveTvApi.createTimer(timer)
94-
api.liveTvApi.getProgram(programId.toString()).content
97+
withContext(Dispatchers.IO) {
98+
val seriesTimer by api.liveTvApi.getDefaultTimer(programId.toString())
99+
val timer = seriesTimer.asTimerInfoDto()
100+
api.liveTvApi.createTimer(timer)
101+
api.liveTvApi.getProgram(programId.toString()).content
102+
}
95103
}.onSuccess { program ->
96104
callback(program)
97105
}
@@ -106,9 +114,11 @@ fun LiveProgramDetailPopup.recordSeries(
106114

107115
lifecycle.coroutineScope.launch {
108116
runCatching {
109-
val timer by api.liveTvApi.getDefaultTimer(programId.toString())
110-
api.liveTvApi.createSeriesTimer(timer)
111-
api.liveTvApi.getProgram(programId.toString()).content
117+
withContext(Dispatchers.IO) {
118+
val timer by api.liveTvApi.getDefaultTimer(programId.toString())
119+
api.liveTvApi.createSeriesTimer(timer)
120+
api.liveTvApi.getProgram(programId.toString()).content
121+
}
112122
}.onSuccess { program ->
113123
callback(program)
114124
}
@@ -123,7 +133,9 @@ fun LiveProgramDetailPopup.getSeriesTimer(
123133

124134
lifecycle.coroutineScope.launch {
125135
runCatching {
126-
api.liveTvApi.getSeriesTimer(seriesTimerId).content
136+
withContext(Dispatchers.IO) {
137+
api.liveTvApi.getSeriesTimer(seriesTimerId).content
138+
}
127139
}.onSuccess { seriesTimer ->
128140
callback(seriesTimer)
129141
}

Diff for: app/src/main/java/org/jellyfin/androidtv/ui/RecordPopupHelper.kt

+15-7
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package org.jellyfin.androidtv.ui
22

33
import androidx.lifecycle.coroutineScope
4+
import kotlinx.coroutines.Dispatchers
45
import kotlinx.coroutines.launch
6+
import kotlinx.coroutines.withContext
57
import org.jellyfin.androidtv.util.getActivity
68
import org.jellyfin.sdk.api.client.ApiClient
79
import org.jellyfin.sdk.api.client.extensions.liveTvApi
@@ -41,9 +43,11 @@ fun RecordPopup.updateSeriesTimer(
4143

4244
lifecycle.coroutineScope.launch {
4345
runCatching {
44-
val id = seriesTimer.id
45-
if (id == null) api.liveTvApi.createSeriesTimer(seriesTimer)
46-
else api.liveTvApi.updateSeriesTimer(id, seriesTimer)
46+
withContext(Dispatchers.IO) {
47+
val id = seriesTimer.id
48+
if (id == null) api.liveTvApi.createSeriesTimer(seriesTimer)
49+
else api.liveTvApi.updateSeriesTimer(id, seriesTimer)
50+
}
4751
}.onSuccess {
4852
callback()
4953
}
@@ -58,9 +62,11 @@ fun RecordPopup.updateTimer(
5862

5963
lifecycle.coroutineScope.launch {
6064
runCatching {
61-
val id = timer.id
62-
if (id == null) api.liveTvApi.createTimer(timer)
63-
else api.liveTvApi.updateTimer(id, timer)
65+
withContext(Dispatchers.IO) {
66+
val id = timer.id
67+
if (id == null) api.liveTvApi.createTimer(timer)
68+
else api.liveTvApi.updateTimer(id, timer)
69+
}
6470
}.onSuccess {
6571
callback()
6672
}
@@ -86,7 +92,9 @@ fun RecordPopup.getLiveTvProgram(
8692

8793
lifecycle.coroutineScope.launch {
8894
runCatching {
89-
api.liveTvApi.getProgram(id.toString()).content
95+
withContext(Dispatchers.IO) {
96+
api.liveTvApi.getProgram(id.toString()).content
97+
}
9098
}.onSuccess { program ->
9199
callback(program)
92100
}

Diff for: app/src/main/java/org/jellyfin/androidtv/ui/browsing/BrowseViewFragmentHelper.kt

+12-6
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package org.jellyfin.androidtv.ui.browsing
22

33
import androidx.lifecycle.lifecycleScope
4+
import kotlinx.coroutines.Dispatchers
45
import kotlinx.coroutines.launch
6+
import kotlinx.coroutines.withContext
57
import org.jellyfin.androidtv.data.repository.ItemRepository
68
import org.jellyfin.sdk.api.client.ApiClient
79
import org.jellyfin.sdk.api.client.extensions.liveTvApi
@@ -23,11 +25,13 @@ fun EnhancedBrowseFragment.getLiveTvRecordingsAndTimers(
2325

2426
lifecycleScope.launch {
2527
runCatching {
26-
val recordings by api.liveTvApi.getRecordings(
27-
fields = ItemRepository.itemFields,
28-
enableImages = true,
29-
limit = 40,
30-
)
28+
val recordings = withContext(Dispatchers.IO) {
29+
api.liveTvApi.getRecordings(
30+
fields = ItemRepository.itemFields,
31+
enableImages = true,
32+
limit = 40,
33+
).content
34+
}
3135

3236
val timers by api.liveTvApi.getTimers()
3337

@@ -47,7 +51,9 @@ fun EnhancedBrowseFragment.getLiveTvTimers(
4751

4852
lifecycleScope.launch {
4953
runCatching {
50-
api.liveTvApi.getTimers().content
54+
withContext(Dispatchers.IO) {
55+
api.liveTvApi.getTimers().content
56+
}
5157
}.fold(
5258
onSuccess = { timers -> callback(timers) },
5359
onFailure = { exception -> errorCallback(exception) }

Diff for: app/src/main/java/org/jellyfin/androidtv/ui/browsing/BrowsingUtils.kt

+10-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ package org.jellyfin.androidtv.ui.browsing
22

33
import androidx.lifecycle.LifecycleOwner
44
import androidx.lifecycle.lifecycleScope
5+
import kotlinx.coroutines.Dispatchers
56
import kotlinx.coroutines.launch
7+
import kotlinx.coroutines.withContext
68
import org.jellyfin.androidtv.data.repository.ItemRepository
79
import org.jellyfin.sdk.api.client.ApiClient
810
import org.jellyfin.sdk.api.client.exception.ApiClientException
@@ -36,7 +38,7 @@ object BrowsingUtils {
3638
type: BaseItemKind,
3739
callback: (item: BaseItemDto?) -> Unit
3840
) {
39-
lifecycle.lifecycleScope.launch {
41+
lifecycle.lifecycleScope.launch(Dispatchers.IO) {
4042
try {
4143
val result by api.itemsApi.getItems(
4244
parentId = library.id,
@@ -46,10 +48,15 @@ object BrowsingUtils {
4648
limit = 1,
4749
)
4850

49-
callback(result.items?.firstOrNull())
51+
withContext(Dispatchers.Main) {
52+
callback(result.items.firstOrNull())
53+
}
5054
} catch (error: ApiClientException) {
5155
Timber.w(error, "Failed to retrieve random item")
52-
callback(null)
56+
57+
withContext(Dispatchers.Main) {
58+
callback(null)
59+
}
5360
}
5461
}
5562
}

Diff for: app/src/main/java/org/jellyfin/androidtv/ui/browsing/MainActivity.kt

+2-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import androidx.lifecycle.flowWithLifecycle
1414
import androidx.lifecycle.lifecycleScope
1515
import androidx.work.OneTimeWorkRequestBuilder
1616
import androidx.work.WorkManager
17+
import kotlinx.coroutines.Dispatchers
1718
import kotlinx.coroutines.flow.launchIn
1819
import kotlinx.coroutines.flow.onEach
1920
import kotlinx.coroutines.launch
@@ -110,7 +111,7 @@ class MainActivity : FragmentActivity() {
110111

111112
workManager.enqueue(OneTimeWorkRequestBuilder<LeanbackChannelWorker>().build())
112113

113-
lifecycleScope.launch {
114+
lifecycleScope.launch(Dispatchers.IO) {
114115
Timber.d("MainActivity stopped")
115116
sessionRepository.restoreSession(destroyOnly = true)
116117
}

Diff for: app/src/main/java/org/jellyfin/androidtv/ui/browsing/SuggestedMoviesFragment.kt

+12-8
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package org.jellyfin.androidtv.ui.browsing
22

33
import androidx.lifecycle.lifecycleScope
4+
import kotlinx.coroutines.Dispatchers
45
import kotlinx.coroutines.launch
6+
import kotlinx.coroutines.withContext
57
import org.jellyfin.androidtv.R
68
import org.jellyfin.androidtv.constant.QueryType
79
import org.jellyfin.androidtv.data.repository.ItemRepository
@@ -22,14 +24,16 @@ class SuggestedMoviesFragment : EnhancedBrowseFragment() {
2224

2325
override fun setupQueries(rowLoader: RowLoader) {
2426
lifecycleScope.launch {
25-
val response by api.itemsApi.getItems(
26-
parentId = mFolder.id,
27-
includeItemTypes = setOf(BaseItemKind.MOVIE),
28-
sortOrder = setOf(SortOrder.DESCENDING),
29-
sortBy = setOf(ItemSortBy.DATE_PLAYED),
30-
limit = 8,
31-
recursive = true,
32-
)
27+
val response = withContext(Dispatchers.IO) {
28+
api.itemsApi.getItems(
29+
parentId = mFolder.id,
30+
includeItemTypes = setOf(BaseItemKind.MOVIE),
31+
sortOrder = setOf(SortOrder.DESCENDING),
32+
sortBy = setOf(ItemSortBy.DATE_PLAYED),
33+
limit = 8,
34+
recursive = true,
35+
).content
36+
}
3337

3438
for (item in response.items) {
3539
val similar = GetSimilarItemsRequest(

0 commit comments

Comments
 (0)