Skip to content

Commit 59e7e99

Browse files
authored
Merge branch 'main' into merge/release-7.85-into-main
2 parents c37e157 + 6c336ce commit 59e7e99

File tree

20 files changed

+268
-126
lines changed

20 files changed

+268
-126
lines changed

.configure

+2-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"project_name": "pocketcasts-android",
33
"branch": "trunk",
4-
"pinned_hash": "21f42df268ccea3b3d0f258e6e8e8d0b09a32545",
4+
"pinned_hash": "765c7553f0b9fcd4db077f71f4fdc18d321fce71",
55
"files_to_copy": [
66
{
77
"file": "android/pocket-casts/secret.properties",
@@ -44,7 +44,5 @@
4444
"encrypt": true
4545
}
4646
],
47-
"file_dependencies": [
48-
49-
]
47+
"file_dependencies": []
5048
}
64 Bytes
Binary file not shown.

CHANGELOG.md

+7-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
7.86
22
-----
3-
4-
3+
* Bug Fixes
4+
* Fix share transcript text when API less than 33.
5+
([#3789](https://github.com/Automattic/pocket-casts-android/pull/3789))
6+
* Updates
7+
* Show a confirmation dialog when deleting more than three episode downloads.
8+
([#3800](https://github.com/Automattic/pocket-casts-android/pull/3800))
9+
510
7.85
611
-----
712
* New Features

Gemfile.lock

+12-12
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ GEM
55
base64
66
nkf
77
rexml
8-
activesupport (8.0.1)
8+
activesupport (8.0.2)
99
base64
1010
benchmark (>= 0.3)
1111
bigdecimal
@@ -23,9 +23,9 @@ GEM
2323
artifactory (3.0.17)
2424
ast (2.4.2)
2525
atomos (0.1.3)
26-
aws-eventstream (1.3.1)
27-
aws-partitions (1.1060.0)
28-
aws-sdk-core (3.220.0)
26+
aws-eventstream (1.3.2)
27+
aws-partitions (1.1067.0)
28+
aws-sdk-core (3.220.1)
2929
aws-eventstream (~> 1, >= 1.3.0)
3030
aws-partitions (~> 1, >= 1.992.0)
3131
aws-sigv4 (~> 1.9)
@@ -124,7 +124,7 @@ GEM
124124
faraday_middleware (1.2.1)
125125
faraday (~> 1.0)
126126
fastimage (2.4.0)
127-
fastlane (2.226.0)
127+
fastlane (2.227.0)
128128
CFPropertyList (>= 2.3, < 4.0.0)
129129
addressable (>= 2.8, < 3.0.0)
130130
artifactory (~> 3.0)
@@ -205,7 +205,7 @@ GEM
205205
google-apis-core (>= 0.11.0, < 2.a)
206206
google-apis-storage_v1 (0.31.0)
207207
google-apis-core (>= 0.11.0, < 2.a)
208-
google-cloud-core (1.7.1)
208+
google-cloud-core (1.8.0)
209209
google-cloud-env (>= 1.0, < 3.a)
210210
google-cloud-errors (~> 1.0)
211211
google-cloud-env (1.6.0)
@@ -234,7 +234,7 @@ GEM
234234
concurrent-ruby (~> 1.0)
235235
java-properties (0.3.0)
236236
jmespath (1.6.2)
237-
json (2.10.1)
237+
json (2.10.2)
238238
jwt (2.10.1)
239239
base64
240240
kramdown (2.5.1)
@@ -247,15 +247,15 @@ GEM
247247
mini_magick (4.13.2)
248248
mini_mime (1.1.5)
249249
mini_portile2 (2.8.8)
250-
minitest (5.25.4)
250+
minitest (5.25.5)
251251
multi_json (1.15.0)
252252
multipart-post (2.4.1)
253253
mutex_m (0.3.0)
254254
nanaimo (0.4.0)
255255
nap (1.1.0)
256256
naturally (2.2.1)
257257
nkf (0.2.0)
258-
nokogiri (1.18.3)
258+
nokogiri (1.18.4)
259259
mini_portile2 (~> 2.8.2)
260260
racc (~> 1.4)
261261
octokit (6.1.1)
@@ -273,7 +273,7 @@ GEM
273273
progress_bar (1.3.4)
274274
highline (>= 1.6)
275275
options (~> 2.3.0)
276-
pstore (0.1.4)
276+
pstore (0.2.0)
277277
public_suffix (6.0.1)
278278
racc (1.8.1)
279279
rainbow (3.1.1)
@@ -289,7 +289,7 @@ GEM
289289
retriable (3.1.2)
290290
rexml (3.4.1)
291291
rouge (3.28.0)
292-
rubocop (1.73.2)
292+
rubocop (1.74.0)
293293
json (~> 2.3)
294294
language_server-protocol (~> 3.17.0.2)
295295
lint_roller (~> 1.1.0)
@@ -300,7 +300,7 @@ GEM
300300
rubocop-ast (>= 1.38.0, < 2.0)
301301
ruby-progressbar (~> 1.7)
302302
unicode-display_width (>= 2.4.0, < 4.0)
303-
rubocop-ast (1.38.1)
303+
rubocop-ast (1.39.0)
304304
parser (>= 3.3.1.0)
305305
ruby-progressbar (1.13.0)
306306
ruby2_keywords (0.0.5)

gradle/libs.versions.toml

+4-4
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ android-gradle-plugin = "8.9.0"
2121
billing = "7.0.0"
2222
coil = "2.7.0"
2323
compose = "2024.10.00" # https://developer.android.com/jetpack/compose/bom/bom-mapping
24-
dependency-analysis = "2.10.1"
24+
dependency-analysis = "2.12.0"
2525
espresso = "3.6.1"
2626
firebase = "33.10.0"
2727
fragment = "1.8.6"
@@ -38,12 +38,12 @@ ktlint = "0.50.0"
3838
lifecycle = "2.8.7"
3939
lottie = "6.6.3"
4040
media3 = "1.5.1"
41-
mockito = "5.16.0"
41+
mockito = "5.16.1"
4242
mockito-kotlin = "5.4.0"
4343
moshi = "1.15.2"
4444
navigation = "2.7.7"
4545
okhttp = "4.12.0"
46-
protobuf = "4.30.0"
46+
protobuf = "4.30.1"
4747
protobuf-plugin = "0.9.4"
4848
retrofit = "2.11.0"
4949
room = "2.6.1"
@@ -54,7 +54,7 @@ tasker-plugin = "0.4.10"
5454
test = "1.6.1"
5555
tracks = "6.0.3"
5656
wear-compose = "1.4.1"
57-
webkit = "1.12.1"
57+
webkit = "1.13.0"
5858
work = "2.10.0"
5959

6060
[libraries]

modules/features/player/src/main/java/au/com/shiftyjelly/pocketcasts/player/view/transcripts/TranscriptPage.kt

+1
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,7 @@ private fun ScrollableTranscriptView(
245245
LocalTextToolbar provides CustomTextToolbar(
246246
view = LocalView.current,
247247
customMenuItems = buildList {
248+
// Only show the share option on older versions of Android, as the new versions have a share feature built into the copy
248249
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
249250
add(CustomMenuItemOption.Share)
250251
}

modules/features/podcasts/src/main/java/au/com/shiftyjelly/pocketcasts/podcasts/view/ProfileEpisodeListFragment.kt

+36-4
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,13 @@ import androidx.appcompat.app.AppCompatActivity
1010
import androidx.appcompat.widget.Toolbar
1111
import androidx.compose.foundation.background
1212
import androidx.compose.foundation.layout.Box
13+
import androidx.compose.foundation.layout.fillMaxSize
1314
import androidx.compose.foundation.layout.padding
15+
import androidx.compose.foundation.rememberScrollState
16+
import androidx.compose.foundation.verticalScroll
1417
import androidx.compose.material.MaterialTheme
1518
import androidx.compose.ui.Modifier
19+
import androidx.compose.ui.res.stringResource
1620
import androidx.compose.ui.unit.dp
1721
import androidx.core.view.isVisible
1822
import androidx.core.view.updatePadding
@@ -29,6 +33,8 @@ import au.com.shiftyjelly.pocketcasts.analytics.AnalyticsTracker
2933
import au.com.shiftyjelly.pocketcasts.analytics.SourceView
3034
import au.com.shiftyjelly.pocketcasts.compose.AppTheme
3135
import au.com.shiftyjelly.pocketcasts.compose.CallOnce
36+
import au.com.shiftyjelly.pocketcasts.compose.components.EmptyState
37+
import au.com.shiftyjelly.pocketcasts.compose.extensions.setContentWithViewCompositionStrategy
3238
import au.com.shiftyjelly.pocketcasts.compose.theme
3339
import au.com.shiftyjelly.pocketcasts.models.entity.BaseEpisode
3440
import au.com.shiftyjelly.pocketcasts.models.entity.PodcastEpisode
@@ -276,13 +282,12 @@ class ProfileEpisodeListFragment : BaseFragment(), Toolbar.OnMenuItemClickListen
276282
viewLifecycleOwner.lifecycleScope.launch {
277283
viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
278284
viewModel.state.collect { state ->
285+
updateEmptyStateView(state)
286+
279287
when (state) {
280288
is State.Empty -> {
281289
binding?.recyclerView?.isVisible = false
282290
binding?.manageDownloadsCard?.isVisible = false
283-
binding?.emptyLayout?.isVisible = true
284-
binding?.lblEmptyTitle?.setText(state.titleRes)
285-
binding?.lblEmptySummary?.setText(state.summaryRes)
286291
}
287292

288293
State.Loading -> Unit
@@ -292,7 +297,6 @@ class ProfileEpisodeListFragment : BaseFragment(), Toolbar.OnMenuItemClickListen
292297
top = if (state.showSearchBar) 0 else 16.dpToPx(requireContext()),
293298
)
294299
binding?.recyclerView?.isVisible = true
295-
binding?.emptyLayout?.isVisible = false
296300
adapter.submitList(state.results)
297301
}
298302
}
@@ -413,6 +417,34 @@ class ProfileEpisodeListFragment : BaseFragment(), Toolbar.OnMenuItemClickListen
413417
}
414418
}
415419

420+
private fun updateEmptyStateView(state: State) {
421+
binding?.emptyLayout?.isVisible = state is State.Empty
422+
423+
if (state is State.Empty) {
424+
binding?.emptyLayout?.setContentWithViewCompositionStrategy {
425+
AppTheme(theme.activeTheme) {
426+
val buttonText = if (mode is Mode.History) stringResource(LR.string.go_to_discover) else null
427+
428+
EmptyState(
429+
title = stringResource(state.titleRes),
430+
subtitle = stringResource(state.summaryRes),
431+
iconResourcerId = state.iconRes,
432+
buttonText = buttonText,
433+
onButtonClick = {
434+
analyticsTracker.track(AnalyticsEvent.LISTENING_HISTORY_DISCOVER_BUTTON_TAPPED)
435+
(activity as FragmentHostListener).openTab(VR.id.navigation_discover)
436+
},
437+
modifier = Modifier
438+
.fillMaxSize()
439+
.padding(horizontal = 32.dp)
440+
.padding(vertical = 8.dp)
441+
.verticalScroll(rememberScrollState()),
442+
)
443+
}
444+
}
445+
}
446+
}
447+
416448
private fun updateToolbar() {
417449
val toolbar = binding?.toolbar ?: return
418450
val title = when (mode) {

modules/features/podcasts/src/main/java/au/com/shiftyjelly/pocketcasts/podcasts/view/ProfileEpisodeListViewModel.kt

+11
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package au.com.shiftyjelly.pocketcasts.podcasts.view
22

3+
import androidx.annotation.DrawableRes
34
import androidx.annotation.StringRes
45
import androidx.lifecycle.ViewModel
56
import androidx.lifecycle.viewModelScope
@@ -24,6 +25,7 @@ import kotlinx.coroutines.flow.flowOf
2425
import kotlinx.coroutines.flow.stateIn
2526
import kotlinx.coroutines.launch
2627
import kotlinx.coroutines.reactive.asFlow
28+
import au.com.shiftyjelly.pocketcasts.images.R as IR
2729
import au.com.shiftyjelly.pocketcasts.localization.R as LR
2830

2931
@HiltViewModel
@@ -70,6 +72,7 @@ class ProfileEpisodeListViewModel @Inject constructor(
7072
(results.isNotEmpty() || searchQuery.isNotEmpty())
7173
_state.value = if (results.isEmpty()) {
7274
State.Empty(
75+
iconRes = State.Empty.iconRes(mode),
7376
titleRes = State.Empty.titleRes(mode, searchQuery.isNotEmpty()),
7477
summaryRes = State.Empty.summaryRes(mode, searchQuery.isNotEmpty()),
7578
showSearchBar = showSearchBar,
@@ -112,6 +115,7 @@ class ProfileEpisodeListViewModel @Inject constructor(
112115
) : State()
113116

114117
data class Empty(
118+
@DrawableRes val iconRes: Int,
115119
@StringRes val titleRes: Int,
116120
@StringRes val summaryRes: Int,
117121
override val showSearchBar: Boolean = false,
@@ -136,6 +140,13 @@ class ProfileEpisodeListViewModel @Inject constructor(
136140
is Mode.History -> LR.string.profile_empty_history_summary
137141
}
138142
}
143+
144+
fun iconRes(mode: Mode): Int =
145+
when (mode) {
146+
is Mode.Downloaded -> IR.drawable.ic_download
147+
is Mode.Starred -> IR.drawable.ic_starred
148+
is Mode.History -> IR.drawable.ic_listen_history
149+
}
139150
}
140151
}
141152

modules/features/podcasts/src/main/res/layout/fragment_profile_episode_list.xml

+4-24
Original file line numberDiff line numberDiff line change
@@ -55,32 +55,12 @@
5555
app:layout_constraintBottom_toBottomOf="parent"
5656
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
5757

58-
<LinearLayout
58+
<androidx.compose.ui.platform.ComposeView
5959
android:id="@+id/emptyLayout"
6060
android:layout_width="match_parent"
61-
android:layout_height="wrap_content"
62-
android:orientation="vertical"
63-
app:layout_constraintTop_toTopOf="parent"
61+
android:layout_height="0dp"
6462
app:layout_constraintBottom_toBottomOf="parent"
65-
android:layout_marginStart="24dp"
66-
android:layout_marginEnd="24dp"
67-
android:visibility="gone">
68-
<TextView
69-
android:id="@+id/lblEmptyTitle"
70-
android:layout_width="match_parent"
71-
android:layout_height="wrap_content"
72-
style="?attr/textH2"
73-
android:textColor="?attr/primary_text_01"
74-
android:gravity="center"
75-
android:layout_marginBottom="16dp" />
76-
<TextView
77-
android:id="@+id/lblEmptySummary"
78-
android:layout_width="match_parent"
79-
android:layout_height="wrap_content"
80-
android:lineSpacingMultiplier="1.3"
81-
style="?attr/textSubtitle2"
82-
android:textColor="?attr/primary_text_02"
83-
android:gravity="center" />
84-
</LinearLayout>
63+
app:layout_constraintTop_toBottomOf="@+id/toolbarBarrier"
64+
/>
8565

8666
</androidx.constraintlayout.widget.ConstraintLayout>

modules/features/podcasts/src/test/java/au/com/shiftyjelly/pocketcasts/podcasts/view/ProfileEpisodeListViewModelTest.kt

+3
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import org.mockito.kotlin.mock
2323
import org.mockito.kotlin.never
2424
import org.mockito.kotlin.verify
2525
import org.mockito.kotlin.whenever
26+
import au.com.shiftyjelly.pocketcasts.images.R as IR
2627

2728
@OptIn(ExperimentalCoroutinesApi::class)
2829
class ProfileEpisodeListViewModelTest {
@@ -84,6 +85,7 @@ class ProfileEpisodeListViewModelTest {
8485
State.Empty(
8586
titleRes = R.string.profile_empty_history,
8687
summaryRes = R.string.profile_empty_history_summary,
88+
iconRes = IR.drawable.ic_listen_history,
8789
),
8890
)
8991
}
@@ -173,6 +175,7 @@ class ProfileEpisodeListViewModelTest {
173175
titleRes = R.string.search_episodes_not_found_title,
174176
summaryRes = R.string.search_episodes_not_found_summary,
175177
showSearchBar = true,
178+
iconRes = IR.drawable.ic_listen_history,
176179
),
177180
)
178181
}

0 commit comments

Comments
 (0)