diff --git a/app/build.gradle b/app/build.gradle index 324de7286..d07c51dc9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -138,7 +138,6 @@ dependencies { implementation libs.compose.foundation implementation libs.compose.material implementation libs.compose.ui - implementation libs.accompanist.drawablepainter implementation libs.androidx.profileinstaller diff --git a/app/dependencies/releaseRuntimeClasspath.txt b/app/dependencies/releaseRuntimeClasspath.txt index 4d0fdb7af..93ff60c23 100644 --- a/app/dependencies/releaseRuntimeClasspath.txt +++ b/app/dependencies/releaseRuntimeClasspath.txt @@ -4,8 +4,8 @@ androidx.activity:activity:1.9.0 androidx.annotation:annotation-experimental:1.4.0 androidx.annotation:annotation-jvm:1.8.0 androidx.annotation:annotation:1.8.0 -androidx.appcompat:appcompat-resources:1.6.1 -androidx.appcompat:appcompat:1.6.1 +androidx.appcompat:appcompat-resources:1.7.0 +androidx.appcompat:appcompat:1.7.0 androidx.arch.core:core-common:2.2.0 androidx.arch.core:core-runtime:2.2.0 androidx.autofill:autofill:1.0.0 @@ -13,41 +13,41 @@ androidx.browser:browser:1.8.0 androidx.collection:collection-jvm:1.4.0 androidx.collection:collection-ktx:1.4.0 androidx.collection:collection:1.4.0 -androidx.compose.animation:animation-android:1.6.7 -androidx.compose.animation:animation-core-android:1.6.7 -androidx.compose.animation:animation-core:1.6.7 -androidx.compose.animation:animation-graphics-android:1.6.7 -androidx.compose.animation:animation-graphics:1.6.7 -androidx.compose.animation:animation:1.6.7 -androidx.compose.foundation:foundation-android:1.6.7 -androidx.compose.foundation:foundation-layout-android:1.6.7 -androidx.compose.foundation:foundation-layout:1.6.7 -androidx.compose.foundation:foundation:1.6.7 -androidx.compose.material:material-android:1.6.7 -androidx.compose.material:material-icons-core-android:1.6.7 -androidx.compose.material:material-icons-core:1.6.7 -androidx.compose.material:material-icons-extended-android:1.6.7 -androidx.compose.material:material-icons-extended:1.6.7 -androidx.compose.material:material-ripple-android:1.6.7 -androidx.compose.material:material-ripple:1.6.7 -androidx.compose.material:material:1.6.7 -androidx.compose.runtime:runtime-android:1.6.7 -androidx.compose.runtime:runtime-saveable-android:1.6.7 -androidx.compose.runtime:runtime-saveable:1.6.7 -androidx.compose.runtime:runtime:1.6.7 -androidx.compose.ui:ui-android:1.6.7 -androidx.compose.ui:ui-geometry-android:1.6.7 -androidx.compose.ui:ui-geometry:1.6.7 -androidx.compose.ui:ui-graphics-android:1.6.7 -androidx.compose.ui:ui-graphics:1.6.7 -androidx.compose.ui:ui-text-android:1.6.7 -androidx.compose.ui:ui-text:1.6.7 -androidx.compose.ui:ui-unit-android:1.6.7 -androidx.compose.ui:ui-unit:1.6.7 -androidx.compose.ui:ui-util-android:1.6.7 -androidx.compose.ui:ui-util:1.6.7 -androidx.compose.ui:ui:1.6.7 -androidx.compose:compose-bom:2024.05.00 +androidx.compose.animation:animation-android:1.7.0-beta02 +androidx.compose.animation:animation-core-android:1.7.0-beta02 +androidx.compose.animation:animation-core:1.7.0-beta02 +androidx.compose.animation:animation-graphics-android:1.7.0-beta02 +androidx.compose.animation:animation-graphics:1.7.0-beta02 +androidx.compose.animation:animation:1.7.0-beta02 +androidx.compose.foundation:foundation-android:1.7.0-beta02 +androidx.compose.foundation:foundation-layout-android:1.7.0-beta02 +androidx.compose.foundation:foundation-layout:1.7.0-beta02 +androidx.compose.foundation:foundation:1.7.0-beta02 +androidx.compose.material:material-android:1.7.0-beta02 +androidx.compose.material:material-icons-core-android:1.7.0-beta02 +androidx.compose.material:material-icons-core:1.7.0-beta02 +androidx.compose.material:material-icons-extended-android:1.7.0-beta02 +androidx.compose.material:material-icons-extended:1.7.0-beta02 +androidx.compose.material:material-ripple-android:1.7.0-beta02 +androidx.compose.material:material-ripple:1.7.0-beta02 +androidx.compose.material:material:1.7.0-beta02 +androidx.compose.runtime:runtime-android:1.7.0-beta02 +androidx.compose.runtime:runtime-saveable-android:1.7.0-beta02 +androidx.compose.runtime:runtime-saveable:1.7.0-beta02 +androidx.compose.runtime:runtime:1.7.0-beta02 +androidx.compose.ui:ui-android:1.7.0-beta02 +androidx.compose.ui:ui-geometry-android:1.7.0-beta02 +androidx.compose.ui:ui-geometry:1.7.0-beta02 +androidx.compose.ui:ui-graphics-android:1.7.0-beta02 +androidx.compose.ui:ui-graphics:1.7.0-beta02 +androidx.compose.ui:ui-text-android:1.7.0-beta02 +androidx.compose.ui:ui-text:1.7.0-beta02 +androidx.compose.ui:ui-unit-android:1.7.0-beta02 +androidx.compose.ui:ui-unit:1.7.0-beta02 +androidx.compose.ui:ui-util-android:1.7.0-beta02 +androidx.compose.ui:ui-util:1.7.0-beta02 +androidx.compose.ui:ui:1.7.0-beta02 +androidx.compose:compose-bom:2023.01.00 androidx.concurrent:concurrent-futures:1.1.0 androidx.constraintlayout:constraintlayout-core:1.0.4 androidx.constraintlayout:constraintlayout:2.1.4 @@ -73,37 +73,40 @@ androidx.emoji2:emoji2:1.3.0 androidx.exifinterface:exifinterface:1.3.7 androidx.fragment:fragment-ktx:1.7.1 androidx.fragment:fragment:1.7.1 +androidx.graphics:graphics-path:1.0.1 androidx.hilt:hilt-common:1.2.0 androidx.hilt:hilt-navigation-compose:1.2.0 androidx.hilt:hilt-navigation:1.2.0 androidx.hilt:hilt-work:1.2.0 androidx.interpolator:interpolator:1.0.0 androidx.legacy:legacy-support-core-utils:1.0.0 -androidx.lifecycle:lifecycle-common-java8:2.8.0 -androidx.lifecycle:lifecycle-common-jvm:2.8.0 -androidx.lifecycle:lifecycle-common:2.8.0 -androidx.lifecycle:lifecycle-livedata-core-ktx:2.8.0 -androidx.lifecycle:lifecycle-livedata-core:2.8.0 -androidx.lifecycle:lifecycle-livedata:2.8.0 -androidx.lifecycle:lifecycle-process:2.8.0 -androidx.lifecycle:lifecycle-runtime-android:2.8.0 -androidx.lifecycle:lifecycle-runtime-ktx-android:2.8.0 -androidx.lifecycle:lifecycle-runtime-ktx:2.8.0 -androidx.lifecycle:lifecycle-runtime:2.8.0 -androidx.lifecycle:lifecycle-service:2.8.0 -androidx.lifecycle:lifecycle-viewmodel-android:2.8.0 -androidx.lifecycle:lifecycle-viewmodel-compose-android:2.8.0 -androidx.lifecycle:lifecycle-viewmodel-compose:2.8.0 -androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.0 -androidx.lifecycle:lifecycle-viewmodel-savedstate:2.8.0 -androidx.lifecycle:lifecycle-viewmodel:2.8.0 +androidx.lifecycle:lifecycle-common-java8:2.8.1 +androidx.lifecycle:lifecycle-common-jvm:2.8.1 +androidx.lifecycle:lifecycle-common:2.8.1 +androidx.lifecycle:lifecycle-livedata-core-ktx:2.8.1 +androidx.lifecycle:lifecycle-livedata-core:2.8.1 +androidx.lifecycle:lifecycle-livedata:2.8.1 +androidx.lifecycle:lifecycle-process:2.8.1 +androidx.lifecycle:lifecycle-runtime-android:2.8.1 +androidx.lifecycle:lifecycle-runtime-compose-android:2.8.1 +androidx.lifecycle:lifecycle-runtime-compose:2.8.1 +androidx.lifecycle:lifecycle-runtime-ktx-android:2.8.1 +androidx.lifecycle:lifecycle-runtime-ktx:2.8.1 +androidx.lifecycle:lifecycle-runtime:2.8.1 +androidx.lifecycle:lifecycle-service:2.8.1 +androidx.lifecycle:lifecycle-viewmodel-android:2.8.1 +androidx.lifecycle:lifecycle-viewmodel-compose-android:2.8.1 +androidx.lifecycle:lifecycle-viewmodel-compose:2.8.1 +androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.1 +androidx.lifecycle:lifecycle-viewmodel-savedstate:2.8.1 +androidx.lifecycle:lifecycle-viewmodel:2.8.1 androidx.loader:loader:1.0.0 androidx.localbroadcastmanager:localbroadcastmanager:1.0.0 -androidx.navigation:navigation-common-ktx:2.7.7 -androidx.navigation:navigation-common:2.7.7 -androidx.navigation:navigation-compose:2.7.7 -androidx.navigation:navigation-runtime-ktx:2.7.7 -androidx.navigation:navigation-runtime:2.7.7 +androidx.navigation:navigation-common-ktx:2.8.0-beta02 +androidx.navigation:navigation-common:2.8.0-beta02 +androidx.navigation:navigation-compose:2.8.0-beta02 +androidx.navigation:navigation-runtime-ktx:2.8.0-beta02 +androidx.navigation:navigation-runtime:2.8.0-beta02 androidx.print:print:1.0.0 androidx.privacysandbox.ads:ads-adservices-java:1.0.0-beta05 androidx.privacysandbox.ads:ads-adservices:1.0.0-beta05 @@ -125,13 +128,11 @@ androidx.vectordrawable:vectordrawable:1.1.0 androidx.versionedparcelable:versionedparcelable:1.1.1 androidx.viewpager:viewpager:1.0.0 androidx.window.extensions.core:core:1.0.0 -androidx.window:window:1.2.0 +androidx.window:window:1.3.0 androidx.work:work-runtime-ktx:2.9.0 androidx.work:work-runtime:2.9.0 com.getkeepsafe.relinker:relinker:1.4.4 -com.google.accompanist:accompanist-drawablepainter:0.34.0 -com.google.accompanist:accompanist-pager-indicators:0.34.0 -com.google.accompanist:accompanist-pager:0.34.0 +com.google.accompanist:accompanist-drawablepainter:0.35.1-alpha com.google.accompanist:accompanist-permissions:0.34.0 com.google.android.datatransport:transport-api:3.1.0 com.google.android.datatransport:transport-backend-cct:3.1.9 @@ -210,7 +211,7 @@ com.squareup.retrofit2:converter-kotlinx-serialization:2.11.0 com.squareup.retrofit2:retrofit:2.11.0 com.webtoonscorp.android:readmore-foundation:1.5.6 com.webtoonscorp.android:readmore-material:1.5.6 -dev.chrisbanes.snapper:snapper:0.2.2 +dev.chrisbanes.compose:compose-bom:2024.05.00-alpha03 io.coil-kt:coil-base:2.6.0 io.coil-kt:coil-compose-base:2.6.0 io.coil-kt:coil-compose:2.6.0 diff --git a/feature/detail/src/main/java/soup/movie/feature/detail/DetailScreen.kt b/feature/detail/src/main/java/soup/movie/feature/detail/DetailScreen.kt index f0a2cba57..523ad1aac 100644 --- a/feature/detail/src/main/java/soup/movie/feature/detail/DetailScreen.kt +++ b/feature/detail/src/main/java/soup/movie/feature/detail/DetailScreen.kt @@ -17,7 +17,6 @@ package soup.movie.feature.detail import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.text.ClickableText import androidx.compose.material.AlertDialog import androidx.compose.material.ButtonDefaults import androidx.compose.material.Text @@ -30,10 +29,12 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.LinkAnnotation import androidx.compose.ui.text.SpanStyle +import androidx.compose.ui.text.TextLinkStyles import androidx.compose.ui.text.buildAnnotatedString import androidx.compose.ui.text.style.TextDecoration -import androidx.compose.ui.text.withStyle +import androidx.compose.ui.text.withLink import soup.movie.core.designsystem.theme.MovieTheme import soup.movie.core.external.YouTube import soup.movie.core.external.executeWeb @@ -98,20 +99,25 @@ internal fun DetailScreen( Text(text = stringResource(R.string.trailer_dialog_message)) val url = "https://policies.google.com/privacy" - ClickableText( + Text( text = buildAnnotatedString { - withStyle( - SpanStyle( - color = MovieTheme.colors.secondary, - textDecoration = TextDecoration.Underline, - ), + withLink( + LinkAnnotation.Url( + url = url, + styles = TextLinkStyles( + style = SpanStyle( + color = MovieTheme.colors.secondary, + textDecoration = TextDecoration.Underline, + ), + ), + ) { + context.executeWeb(url) + }, ) { append(url) } }, - ) { - context.executeWeb(url) - } + ) } }, confirmButton = { diff --git a/feature/home/build.gradle b/feature/home/build.gradle index b234280fa..b45a3417b 100644 --- a/feature/home/build.gradle +++ b/feature/home/build.gradle @@ -30,7 +30,6 @@ dependencies { implementation libs.compose.foundation implementation libs.compose.material implementation libs.compose.ui - implementation libs.accompanist.pagerIndicators testImplementation projects.testing androidTestImplementation projects.testing diff --git a/feature/theater/build.gradle b/feature/theater/build.gradle index 6a3b25f9c..0d085ac20 100644 --- a/feature/theater/build.gradle +++ b/feature/theater/build.gradle @@ -23,7 +23,6 @@ dependencies { implementation libs.compose.foundation implementation libs.compose.material implementation libs.compose.ui - implementation libs.accompanist.pagerIndicators testImplementation projects.testing androidTestImplementation projects.testing diff --git a/feature/theater/src/main/java/soup/movie/feature/theater/edit/PagerTab.kt b/feature/theater/src/main/java/soup/movie/feature/theater/edit/PagerTab.kt new file mode 100644 index 000000000..e362af6d2 --- /dev/null +++ b/feature/theater/src/main/java/soup/movie/feature/theater/edit/PagerTab.kt @@ -0,0 +1,98 @@ +/* + * Copyright 2024 SOUP + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package soup.movie.feature.theater.edit + +import androidx.compose.foundation.pager.HorizontalPager +import androidx.compose.foundation.pager.PagerState +import androidx.compose.foundation.pager.VerticalPager +import androidx.compose.material.ScrollableTabRow +import androidx.compose.material.TabPosition +import androidx.compose.material.TabRow +import androidx.compose.ui.Modifier +import androidx.compose.ui.layout.layout +import androidx.compose.ui.unit.Constraints +import androidx.compose.ui.unit.lerp + +/** + * From https://github.com/google/accompanist/tree/main/pager-indicators + * + * This indicator syncs up a [TabRow] or [ScrollableTabRow] tab indicator with a + * [HorizontalPager] or [VerticalPager]. + */ +fun Modifier.pagerTabIndicatorOffset( + pagerState: PagerState, + tabPositions: List, + pageIndexMapping: (Int) -> Int = { it }, +): Modifier { + val stateBridge = object : PagerStateBridge { + override val currentPage: Int + get() = pagerState.currentPage + override val currentPageOffset: Float + get() = pagerState.currentPageOffsetFraction + } + + return pagerTabIndicatorOffset(stateBridge, tabPositions, pageIndexMapping) +} + +private fun Modifier.pagerTabIndicatorOffset( + pagerState: PagerStateBridge, + tabPositions: List, + pageIndexMapping: (Int) -> Int = { it }, +): Modifier = layout { measurable, constraints -> + if (tabPositions.isEmpty()) { + // If there are no pages, nothing to show + layout(constraints.maxWidth, 0) {} + } else { + val currentPage = minOf(tabPositions.lastIndex, pageIndexMapping(pagerState.currentPage)) + val currentTab = tabPositions[currentPage] + val previousTab = tabPositions.getOrNull(currentPage - 1) + val nextTab = tabPositions.getOrNull(currentPage + 1) + val fraction = pagerState.currentPageOffset + val indicatorWidth = if (fraction > 0 && nextTab != null) { + lerp(currentTab.width, nextTab.width, fraction).roundToPx() + } else if (fraction < 0 && previousTab != null) { + lerp(currentTab.width, previousTab.width, -fraction).roundToPx() + } else { + currentTab.width.roundToPx() + } + val indicatorOffset = if (fraction > 0 && nextTab != null) { + lerp(currentTab.left, nextTab.left, fraction).roundToPx() + } else if (fraction < 0 && previousTab != null) { + lerp(currentTab.left, previousTab.left, -fraction).roundToPx() + } else { + currentTab.left.roundToPx() + } + val placeable = measurable.measure( + Constraints( + minWidth = indicatorWidth, + maxWidth = indicatorWidth, + minHeight = 0, + maxHeight = constraints.maxHeight, + ), + ) + layout(constraints.maxWidth, maxOf(placeable.height, constraints.minHeight)) { + placeable.placeRelative( + indicatorOffset, + maxOf(constraints.minHeight - placeable.height, 0), + ) + } + } +} + +internal interface PagerStateBridge { + val currentPage: Int + val currentPageOffset: Float +} diff --git a/feature/theater/src/main/java/soup/movie/feature/theater/edit/TheaterEditScreen.kt b/feature/theater/src/main/java/soup/movie/feature/theater/edit/TheaterEditScreen.kt index e3ee0257e..e8e15a969 100644 --- a/feature/theater/src/main/java/soup/movie/feature/theater/edit/TheaterEditScreen.kt +++ b/feature/theater/src/main/java/soup/movie/feature/theater/edit/TheaterEditScreen.kt @@ -63,7 +63,6 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import com.google.accompanist.pager.pagerTabIndicatorOffset import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.delay import kotlinx.coroutines.launch diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index daef7c8bd..da83db14e 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,19 +15,19 @@ androidxhilt = "1.2.0" # AndroidX androidx-activity = "1.9.0" -androidx-appcompat = "1.6.1" +androidx-appcompat = "1.7.0" androidx-benchmark = "1.2.4" androidx-browser = "1.8.0" androidx-constraintlayout = "2.1.4" androidx-core = "1.13.1" androidx-datastore = "1.1.1" androidx-fragment = "1.7.1" -androidx-lifecycle = "2.8.0" -androidx-navigation = "2.7.7" +androidx-lifecycle = "2.8.1" +androidx-navigation = "2.8.0-beta02" androidx-profileinstaller = "1.3.1" androidx-room = "2.6.1" androidx-startup = "1.1.1" -androidx-window = "1.2.0" +androidx-window = "1.3.0" androidx-work = "2.9.0" # Google @@ -39,8 +39,8 @@ firebase-crashlytics = "2.9.9" firebase-perf = "1.4.2" # Compose -compose-bom = "2024.05.00" -accompanist = "0.34.0" +compose-bom = "2024.05.00-alpha03" +accompanist = "0.35.1-alpha" navermap-compose = "1.5.7" readmore = "1.5.6" materialmotion = "1.1.3" @@ -111,7 +111,7 @@ androidx-work-testing = { module = "androidx.work:work-testing", version.ref = " # Compose -compose-bom = { module = "androidx.compose:compose-bom", version.ref = "compose-bom" } +compose-bom = { module = "dev.chrisbanes.compose:compose-bom", version.ref = "compose-bom" } compose-foundation = { module = "androidx.compose.foundation:foundation" } compose-material = { module = "androidx.compose.material:material" } compose-materialIconsExtended = { module = "androidx.compose.material:material-icons-extended" } @@ -119,7 +119,6 @@ compose-ui = { module = "androidx.compose.ui:ui" } compose-animation-graphics = { module = "androidx.compose.animation:animation-graphics" } accompanist-drawablepainter = { module = "com.google.accompanist:accompanist-drawablepainter", version.ref = "accompanist" } -accompanist-pagerIndicators = { module = "com.google.accompanist:accompanist-pager-indicators", version.ref = "accompanist" } readmore-material = { module = "com.webtoonscorp.android:readmore-material", version.ref = "readmore" }