diff --git a/.gitignore b/.gitignore
index 3a47c2982..6114060d2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,6 +8,9 @@
# Java class files
*.class
+# Kotlin
+.kotlin/
+
# Generated files
bin/
gen/
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
index b67486ec8..fb93d254a 100644
--- a/.idea/inspectionProfiles/Project_Default.xml
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -3,15 +3,19 @@
+
+
+
+
diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml
index fe63bb677..6d0ee1c2a 100644
--- a/.idea/kotlinc.xml
+++ b/.idea/kotlinc.xml
@@ -1,6 +1,6 @@
-
+
\ No newline at end of file
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 7198a6de4..9efe360e1 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -8,6 +8,7 @@ plugins {
alias(libs.plugins.gms.googleServices)
alias(libs.plugins.hilt)
alias(libs.plugins.kotlin.android)
+ alias(libs.plugins.kotlin.compose.compiler)
alias(libs.plugins.kotlin.kapt)
alias(libs.plugins.kotlin.serialization)
}
@@ -17,8 +18,8 @@ android {
defaultConfig {
applicationId = "com.kafka.user"
- versionCode = 61
- versionName = "0.21.0"
+ versionCode = 66
+ versionName = "0.26.0"
val properties = Properties()
properties.load(project.rootProject.file("local.properties").inputStream())
@@ -40,15 +41,16 @@ android {
targetCompatibility = JavaVersion.VERSION_11
}
- buildFeatures {
- compose = true
+ composeCompiler {
+ enableStrongSkippingMode = true
+ includeSourceInformation = true
}
- composeOptions {
- kotlinCompilerExtensionVersion = libs.versions.composecompiler.get()
+ buildFeatures {
+ compose = true
}
- packagingOptions {
+ packaging {
packagingOptions.resources.excludes += setOf(
// Exclude AndroidX version files
"META-INF/*.version",
@@ -165,7 +167,6 @@ dependencies {
implementation(libs.google.analytics)
implementation(libs.google.auth)
implementation(libs.google.crashlytics)
- implementation(libs.google.dynamic.links)
implementation(libs.google.firestore)
implementation(libs.google.messaging)
implementation(libs.google.performance)
diff --git a/app/release/baselineProfiles/0/app-release.dm b/app/release/baselineProfiles/0/app-release.dm
index 41dff19ff..df918ac46 100644
Binary files a/app/release/baselineProfiles/0/app-release.dm and b/app/release/baselineProfiles/0/app-release.dm differ
diff --git a/app/release/baselineProfiles/1/app-release.dm b/app/release/baselineProfiles/1/app-release.dm
index 680ebaae5..b6e7c76ea 100644
Binary files a/app/release/baselineProfiles/1/app-release.dm and b/app/release/baselineProfiles/1/app-release.dm differ
diff --git a/app/release/output-metadata.json b/app/release/output-metadata.json
index e7093428e..0e9d2f3d4 100644
--- a/app/release/output-metadata.json
+++ b/app/release/output-metadata.json
@@ -11,8 +11,8 @@
"type": "SINGLE",
"filters": [],
"attributes": [],
- "versionCode": 61,
- "versionName": "0.21.0",
+ "versionCode": 66,
+ "versionName": "0.26.0",
"outputFile": "app-release.apk"
}
],
diff --git a/app/src/debug/res/mipmap-hdpi/ic_launcher_background.png b/app/src/debug/res/mipmap-hdpi/ic_launcher_background.png
deleted file mode 100644
index 5b22184e7..000000000
Binary files a/app/src/debug/res/mipmap-hdpi/ic_launcher_background.png and /dev/null differ
diff --git a/app/src/debug/res/mipmap-mdpi/ic_launcher_background.png b/app/src/debug/res/mipmap-mdpi/ic_launcher_background.png
deleted file mode 100644
index d71285066..000000000
Binary files a/app/src/debug/res/mipmap-mdpi/ic_launcher_background.png and /dev/null differ
diff --git a/app/src/main/java/com/kafka/user/deeplink/FirebaseDynamicDeepLinkHandler.kt b/app/src/main/java/com/kafka/user/deeplink/FirebaseDynamicDeepLinkHandler.kt
deleted file mode 100644
index 68f88820c..000000000
--- a/app/src/main/java/com/kafka/user/deeplink/FirebaseDynamicDeepLinkHandler.kt
+++ /dev/null
@@ -1,46 +0,0 @@
-package com.kafka.user.deeplink
-
-import android.app.Activity
-import android.content.Intent
-import android.net.Uri
-import com.google.firebase.dynamiclinks.FirebaseDynamicLinks
-import com.google.firebase.dynamiclinks.PendingDynamicLinkData
-import com.google.firebase.dynamiclinks.ktx.androidParameters
-import com.google.firebase.dynamiclinks.ktx.dynamicLink
-import com.google.firebase.dynamiclinks.ktx.dynamicLinks
-import com.google.firebase.ktx.Firebase
-import dagger.Reusable
-import org.kafka.base.debug
-import org.kafka.base.errorLog
-import org.kafka.navigation.deeplink.DynamicDeepLinkHandler
-import org.kafka.navigation.Navigator
-import javax.inject.Inject
-
-@Reusable
-class FirebaseDynamicDeepLinkHandler @Inject constructor() : DynamicDeepLinkHandler {
-
- override fun handleDeepLink(activity: Activity, intent: Intent) {
- FirebaseDynamicLinks.getInstance()
- .getDynamicLink(intent)
- .addOnSuccessListener(activity) { pendingDynamicLinkData: PendingDynamicLinkData? ->
- var deepLink: Uri? = null
- if (pendingDynamicLinkData != null) {
- deepLink = pendingDynamicLinkData.link
- }
- debug { "deepLink: $deepLink" }
- }
- .addOnFailureListener(activity) { e -> errorLog(e) }
- }
-
- override fun createDeepLinkUri(link: String): Uri {
- val dynamicLink = Firebase.dynamicLinks.dynamicLink {
- this.link = Uri.parse(link)
- domainUriPrefix = "https://kafka.page.link"
- // Open links with this app on Android
- androidParameters {
- fallbackUrl = Uri.parse("https://www.archive.org")
- }
- }
- return dynamicLink.uri
- }
-}
diff --git a/app/src/main/java/com/kafka/user/fcm/FirebaseMessageService.kt b/app/src/main/java/com/kafka/user/fcm/FirebaseMessageService.kt
index c3d9fff26..69a0e62b1 100644
--- a/app/src/main/java/com/kafka/user/fcm/FirebaseMessageService.kt
+++ b/app/src/main/java/com/kafka/user/fcm/FirebaseMessageService.kt
@@ -1,14 +1,10 @@
package com.kafka.user.fcm
-import android.app.PendingIntent
-import android.app.TaskStackBuilder
-import android.content.Context
import android.content.Intent
import androidx.datastore.preferences.core.stringPreferencesKey
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage
import com.kafka.data.prefs.PreferencesStore
-import com.kafka.user.MainActivity
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
@@ -31,9 +27,6 @@ class FirebaseMessageService : FirebaseMessagingService() {
@Inject
lateinit var dispatchers: CoroutineDispatchers
- @Inject
- lateinit var pushMapper: PushMapper
-
@Inject
lateinit var notificationManager: NotificationManager
@@ -60,15 +53,6 @@ class FirebaseMessageService : FirebaseMessagingService() {
preferencesStore.save(fcmTokenPreferenceKey, token)
}
}
-
- private fun Context.mainActivityIntent(): PendingIntent {
- val intent = Intent(this, MainActivity::class.java)
-
- return TaskStackBuilder.create(this).run {
- addNextIntentWithParentStack(intent)
- getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)
- }
- }
}
const val EXTRA_DEEPLINK_URL = "deeplink_url"
diff --git a/app/src/main/java/com/kafka/user/fcm/Push.kt b/app/src/main/java/com/kafka/user/fcm/Push.kt
deleted file mode 100644
index 0da20bd6e..000000000
--- a/app/src/main/java/com/kafka/user/fcm/Push.kt
+++ /dev/null
@@ -1,3 +0,0 @@
-package com.kafka.user.fcm
-
-data class Push(val id: String, val title: String, val message: String, val action: String)
diff --git a/app/src/main/java/com/kafka/user/fcm/PushMapper.kt b/app/src/main/java/com/kafka/user/fcm/PushMapper.kt
deleted file mode 100644
index 1d6ea01bc..000000000
--- a/app/src/main/java/com/kafka/user/fcm/PushMapper.kt
+++ /dev/null
@@ -1,20 +0,0 @@
-package com.kafka.user.fcm
-
-import com.google.firebase.messaging.RemoteMessage
-import org.kafka.notifications.Push
-import javax.inject.Inject
-
-class PushMapper @Inject constructor() {
- fun map(remoteMessage: RemoteMessage) = Push(
- notification = Push.Notification(
- id = remoteMessage.messageId.hashCode(),
- title = remoteMessage.notification?.title.orEmpty(),
- message = remoteMessage.notification?.body.orEmpty(),
- ),
- channel = Push.Channel(
- id = remoteMessage.messageId.orEmpty(),
- name = remoteMessage.notification?.title.orEmpty(),
- ),
- actions = emptyList()
- )
-}
diff --git a/app/src/main/java/com/kafka/user/home/AppNavigation.kt b/app/src/main/java/com/kafka/user/home/AppNavigation.kt
index a4b2551e6..10cfc2bfe 100644
--- a/app/src/main/java/com/kafka/user/home/AppNavigation.kt
+++ b/app/src/main/java/com/kafka/user/home/AppNavigation.kt
@@ -35,7 +35,7 @@ import com.kafka.search.SearchScreen
import com.kafka.user.playback.PlaybackViewModel
import com.sarahang.playback.ui.sheet.PlaybackSheet
import org.kafka.base.debug
-import org.kafka.common.extensions.collectEvent
+import org.kafka.common.extensions.CollectEvent
import org.kafka.homepage.Homepage
import org.kafka.homepage.recent.RecentItemsScreen
import org.kafka.item.detail.ItemDetail
@@ -60,7 +60,7 @@ internal fun AppNavigation(
modifier: Modifier = Modifier,
navigator: Navigator = LocalNavigator.current
) {
- collectEvent(navigator.queue) { event ->
+ CollectEvent(navigator.queue) { event ->
when (event) {
is NavigationEvent.Destination -> {
navController.navigate(event.route)
diff --git a/app/src/main/java/com/kafka/user/home/bottombar/rail/HomeNavigationRailItemRow.kt b/app/src/main/java/com/kafka/user/home/bottombar/rail/HomeNavigationRailItemRow.kt
index 84601e045..2070189f5 100644
--- a/app/src/main/java/com/kafka/user/home/bottombar/rail/HomeNavigationRailItemRow.kt
+++ b/app/src/main/java/com/kafka/user/home/bottombar/rail/HomeNavigationRailItemRow.kt
@@ -14,10 +14,10 @@ import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.selection.selectable
-import androidx.compose.material.ripple.rememberRipple
import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
+import androidx.compose.material3.ripple
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.getValue
@@ -54,10 +54,7 @@ internal fun HomeNavigationRailItemRow(
enabled = enabled,
role = Role.Tab,
interactionSource = interactionSource,
- indication = rememberRipple(
- bounded = true,
- color = activeColor
- )
+ indication = ripple(bounded = true, color = activeColor)
)
.padding(horizontal = Dimens.Spacing40, vertical = Dimens.Spacing20)
) {
diff --git a/app/src/main/java/com/kafka/user/injection/AppModule.kt b/app/src/main/java/com/kafka/user/injection/AppModule.kt
index a59e6fa72..9843091f6 100644
--- a/app/src/main/java/com/kafka/user/injection/AppModule.kt
+++ b/app/src/main/java/com/kafka/user/injection/AppModule.kt
@@ -16,7 +16,6 @@ import com.kafka.recommendations.topic.FirebaseTopics
import com.kafka.recommendations.topic.FirebaseTopicsImpl
import com.kafka.recommendations.topic.FirebaseTopicsInitializer
import com.kafka.user.BuildConfig
-import com.kafka.user.deeplink.FirebaseDynamicDeepLinkHandler
import com.kafka.user.initializer.AudioProgressInitializer
import com.kafka.user.initializer.FirebaseInitializer
import com.kafka.user.initializer.LoggerInitializer
@@ -41,7 +40,6 @@ import org.kafka.base.CoroutineDispatchers
import org.kafka.base.ProcessLifetime
import org.kafka.base.SecretsProvider
import org.kafka.common.image.CoilAppInitializer
-import org.kafka.navigation.deeplink.DynamicDeepLinkHandler
import org.kafka.notifications.NotificationManager
import org.kafka.notifications.NotificationManagerImpl
import tm.alashow.datmusic.downloader.DownloadInitializer
@@ -164,11 +162,6 @@ abstract class AppModuleBinds {
@Binds
abstract fun provideNotificationManager(bind: NotificationManagerImpl): NotificationManager
- @Binds
- abstract fun deepLinkHandler(
- firebaseDynamicDeepLinkHandler: FirebaseDynamicDeepLinkHandler
- ): DynamicDeepLinkHandler
-
@Binds
abstract fun provideAppReviewManager(appReviewManagerImpl: AppReviewManagerImpl): AppReviewManager
diff --git a/app/src/main/java/com/kafka/user/injection/PlayerModule.kt b/app/src/main/java/com/kafka/user/injection/PlayerModule.kt
index c30bb513c..9272dc60e 100644
--- a/app/src/main/java/com/kafka/user/injection/PlayerModule.kt
+++ b/app/src/main/java/com/kafka/user/injection/PlayerModule.kt
@@ -1,17 +1,13 @@
package com.kafka.user.injection
-import com.kafka.remote.config.RemoteConfig
-import com.kafka.remote.config.isExactAlarmEnabled
import com.kafka.user.playback.KafkaPlayerEventLogger
import com.kafka.user.playback.PlayerAudioDataSource
-import com.sarahang.playback.core.PlayerRemoteConfig
import com.sarahang.playback.core.apis.AudioDataSource
import com.sarahang.playback.core.apis.PlayerEventLogger
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
-import javax.inject.Inject
@InstallIn(SingletonComponent::class)
@Module
@@ -22,15 +18,4 @@ abstract class PlayerModule {
@Binds
abstract fun playerEventLogger(kafkaPlayerEventLogger: KafkaPlayerEventLogger): PlayerEventLogger
-
- @Binds
- abstract fun PlayerRemoteConfig(playerRemoteConfig: PlayerRemoteConfigImpl): PlayerRemoteConfig
-}
-
-class PlayerRemoteConfigImpl @Inject constructor(
- private val remoteConfig: RemoteConfig
-) : PlayerRemoteConfig {
- override fun isExactAlarmEnabled(): Boolean {
- return remoteConfig.isExactAlarmEnabled()
- }
}
diff --git a/app/src/main/res/drawable-nodpi/exo_notification_next.xml b/app/src/main/res/drawable-nodpi/exo_notification_next.xml
deleted file mode 100644
index f3e4be04f..000000000
--- a/app/src/main/res/drawable-nodpi/exo_notification_next.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
diff --git a/app/src/main/res/drawable-nodpi/exo_notification_pause.xml b/app/src/main/res/drawable-nodpi/exo_notification_pause.xml
deleted file mode 100644
index 538a4bc66..000000000
--- a/app/src/main/res/drawable-nodpi/exo_notification_pause.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
diff --git a/app/src/main/res/drawable-nodpi/exo_notification_play.xml b/app/src/main/res/drawable-nodpi/exo_notification_play.xml
deleted file mode 100644
index 5dfb4728f..000000000
--- a/app/src/main/res/drawable-nodpi/exo_notification_play.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
diff --git a/app/src/main/res/drawable-nodpi/exo_notification_previous.xml b/app/src/main/res/drawable-nodpi/exo_notification_previous.xml
deleted file mode 100644
index 59a2ee602..000000000
--- a/app/src/main/res/drawable-nodpi/exo_notification_previous.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
diff --git a/app/src/main/res/drawable/exo_notification_fastforward.xml b/app/src/main/res/drawable/exo_notification_fastforward.xml
deleted file mode 100644
index 7c2885f25..000000000
--- a/app/src/main/res/drawable/exo_notification_fastforward.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
-
diff --git a/app/src/main/res/drawable/exo_notification_fastforward_2.xml b/app/src/main/res/drawable/exo_notification_fastforward_2.xml
deleted file mode 100644
index d73bb7177..000000000
--- a/app/src/main/res/drawable/exo_notification_fastforward_2.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-
diff --git a/app/src/main/res/drawable/exo_notification_rewind.xml b/app/src/main/res/drawable/exo_notification_rewind.xml
deleted file mode 100644
index 881ff45e0..000000000
--- a/app/src/main/res/drawable/exo_notification_rewind.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
-
diff --git a/app/src/main/res/drawable/exo_notification_rewind_2.xml b/app/src/main/res/drawable/exo_notification_rewind_2.xml
deleted file mode 100644
index 10b7d6314..000000000
--- a/app/src/main/res/drawable/exo_notification_rewind_2.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-
diff --git a/app/src/main/res/drawable/exo_notification_small_icon.xml b/app/src/main/res/drawable/exo_notification_small_icon.xml
deleted file mode 100644
index 5833b3376..000000000
--- a/app/src/main/res/drawable/exo_notification_small_icon.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
-
-
-
diff --git a/app/src/main/res/drawable/ic_feather.xml b/app/src/main/res/drawable/ic_feather.xml
deleted file mode 100644
index 5833b3376..000000000
--- a/app/src/main/res/drawable/ic_feather.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
-
-
-
diff --git a/app/src/main/res/drawable/ic_linked_camera_black_24dp.xml b/app/src/main/res/drawable/ic_linked_camera_black_24dp.xml
deleted file mode 100644
index 37cfcfc41..000000000
--- a/app/src/main/res/drawable/ic_linked_camera_black_24dp.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
-
-
diff --git a/app/src/main/res/drawable/ic_player_logo.xml b/app/src/main/res/drawable/ic_player_logo.xml
deleted file mode 100644
index 8c28f200f..000000000
--- a/app/src/main/res/drawable/ic_player_logo.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
diff --git a/app/src/main/res/drawable/ic_search_black_24dp.xml b/app/src/main/res/drawable/ic_search_black_24dp.xml
deleted file mode 100644
index dd465a2f5..000000000
--- a/app/src/main/res/drawable/ic_search_black_24dp.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
diff --git a/app/src/main/res/drawable/ic_share_black_24dp.xml b/app/src/main/res/drawable/ic_share_black_24dp.xml
deleted file mode 100644
index e3fe874d6..000000000
--- a/app/src/main/res/drawable/ic_share_black_24dp.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
diff --git a/app/src/main/res/drawable/ic_skip_previous_black_24dp.xml b/app/src/main/res/drawable/ic_skip_previous_black_24dp.xml
deleted file mode 100644
index cd05efeb6..000000000
--- a/app/src/main/res/drawable/ic_skip_previous_black_24dp.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png b/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png
deleted file mode 100644
index 3a21c8009..000000000
Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png and /dev/null differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png b/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png
deleted file mode 100644
index c2f311b65..000000000
Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png and /dev/null differ
diff --git a/app/src/main/res/transition/tranform.xml b/app/src/main/res/transition/tranform.xml
deleted file mode 100644
index 0f36a28ab..000000000
--- a/app/src/main/res/transition/tranform.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
diff --git a/app/src/main/res/values-night/sys_ui.xml b/app/src/main/res/values-night/sys_ui.xml
deleted file mode 100644
index 1b8c23706..000000000
--- a/app/src/main/res/values-night/sys_ui.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-
- false
-
diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml
index ff6070bde..742510b7b 100644
--- a/app/src/main/res/values-night/themes.xml
+++ b/app/src/main/res/values-night/themes.xml
@@ -16,7 +16,6 @@
-->
-
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 05df286b2..ef7ab02eb 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -1,22 +1,12 @@
Kafka
- I’ve already been in all the sick rooms, far and wide, and I tell you your wound is not so bad. Made in a tight corner with two blows from an axe. Many people offer their side and hardly hear the axe in the forest, to say nothing of the fact that it’s coming closer to them.”
- I’ve already been in all the sick rooms, far and wide, and I tell you your wound is not so bad.
- ⍟⍟⍟⍟⍟“Young friend,” I say, “your mistake is that you have no perspective. I’ve already been in all the sick rooms, far and wide, and I tell you your wound is not so bad. Made in a tight corner with two blows from an axe. Many people offer their side and hardly hear the axe in the forest, to say nothing of the fact that it’s coming closer to them.”
Cancel
- See Reviews
- Pause
Play
- Next
- Previous
- Dark mode
Library
- Module Title
Search
Home
- Default channel
Update Available
This version is outdated. Please update the app to continue using it.
Update
diff --git a/app/src/main/res/values/sys_ui.xml b/app/src/main/res/values/sys_ui.xml
deleted file mode 100644
index ebbfd4e0a..000000000
--- a/app/src/main/res/values/sys_ui.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
- true
-
-
- false
-
diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml
index ffceb38fa..a35521e5c 100644
--- a/app/src/main/res/values/themes.xml
+++ b/app/src/main/res/values/themes.xml
@@ -1,29 +1,12 @@
-
-
-
-
-
-
-
-
+
diff --git a/app/src/main/res/xml/network_config.xml b/app/src/main/res/xml/network_config.xml
deleted file mode 100644
index b5e7e5376..000000000
--- a/app/src/main/res/xml/network_config.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
-
-
-
-
diff --git a/app/src/main/res/xml/provider_paths.xml b/app/src/main/res/xml/provider_paths.xml
deleted file mode 100644
index 9d0ba93d2..000000000
--- a/app/src/main/res/xml/provider_paths.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
-
-
-
-
diff --git a/base/domain/src/main/java/org/kafka/base/domain/InvokeStatus.kt b/base/domain/src/main/java/org/kafka/base/domain/InvokeStatus.kt
index 2d5b9b7f0..3313486ea 100644
--- a/base/domain/src/main/java/org/kafka/base/domain/InvokeStatus.kt
+++ b/base/domain/src/main/java/org/kafka/base/domain/InvokeStatus.kt
@@ -1,6 +1,6 @@
package org.kafka.base.domain
sealed class InvokeStatus
-object InvokeStarted : InvokeStatus()
-object InvokeSuccess : InvokeStatus()
+data object InvokeStarted : InvokeStatus()
+data object InvokeSuccess : InvokeStatus()
data class InvokeError(val throwable: Throwable) : InvokeStatus()
diff --git a/base/domain/src/main/java/org/kafka/base/extensions/CoroutineExtensions.kt b/base/domain/src/main/java/org/kafka/base/extensions/CoroutineExtensions.kt
index 6936ef8a4..de579244b 100644
--- a/base/domain/src/main/java/org/kafka/base/extensions/CoroutineExtensions.kt
+++ b/base/domain/src/main/java/org/kafka/base/extensions/CoroutineExtensions.kt
@@ -1,12 +1,9 @@
package org.kafka.base.extensions
import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
-import kotlinx.coroutines.flow.channelFlow
import kotlinx.coroutines.flow.stateIn
-import java.util.concurrent.TimeUnit
/**
* Alias to stateIn with defaults
@@ -16,15 +13,3 @@ fun Flow.stateInDefault(
initialValue: T,
started: SharingStarted = SharingStarted.WhileSubscribed(5_000),
) = stateIn(scope, started, initialValue)
-
-fun flowInterval(interval: Long, timeUnit: TimeUnit = TimeUnit.MILLISECONDS): Flow {
- val delayMillis = timeUnit.toMillis(interval)
- return channelFlow {
- var tick = 0
- send(tick)
- while (true) {
- delay(delayMillis)
- send(++tick)
- }
- }
-}
diff --git a/base/domain/src/main/res/values/app_strings.xml b/base/domain/src/main/res/values/app_strings.xml
index 76314b773..feb0b333b 100644
--- a/base/domain/src/main/res/values/app_strings.xml
+++ b/base/domain/src/main/res/values/app_strings.xml
@@ -1,20 +1,6 @@
- Search
- Songs, albums, artists
- Search query
- Songs
- Artists
- Albums
- Minerva
- Flacs
-
- Artist
-
- Album
-
- Audio menu
Play
Play next
Download
@@ -31,65 +17,6 @@
The item is deleted
Download request exists but has unhandled status: %1$s
- Downloads
- No Downloads
-
- Paused
- Queued
- Downloading
- Failed
- Cancelled
-
- Play
- Play next
- Pause
- Resume
- Cancel
- Retry
- Open file
- Remove
- Delete file
-
- Playing from queue
- Playing from downloads
- Playing from artist
- Playing from artist
- Playing from album
- Playing from search
-
- Settings
-
- Theme
- Dark mode
- Color palette
-
- Downloads
- Downloads location
- Select
- Change
- Songs folder grouping
- By Album
- /Artist/Album/Song
- By Artist
- /Artist/Song
- Flat
- /Song
-
- About
- Author
- Alashov Berkeli
- https://alashov.com
- Community
- t.me/datmusictesters
- https://t.me/datmusictesters
- Version
-
- Captcha error
- Type letters above
- Reload
- Captcha cannot be empty
- Send
-
The server is not responding
The server is unavailable
diff --git a/base/domain/src/main/res/values/base.xml b/base/domain/src/main/res/values/base.xml
index f7a4f89f8..7adf25aa9 100644
--- a/base/domain/src/main/res/values/base.xml
+++ b/base/domain/src/main/res/values/base.xml
@@ -1,79 +1,13 @@
- Default channel
- Back
- Close
- Clear
Copied
- Warning
- Confirm
- No
- @string/dialog.ok
- @android:string/ok
- @string/generic.close
-
- Unknown
- Error
- Whoops :(
- Try again
Network could not be reached
Server could not be reached
Authorization error
- You need to login
Resource could not be found
- API error
- Empty
- No results
- Must not be empty
Unknown error
- Log out failed, try resetting app settings
- Already logged in
- Loading failed. Tap to retry
Retry
- Server unavailable
-
- %1$d hour %2$d min.
- %1$d minute
-
-
- - January
- - February
- - March
- - April
- - May
- - June
- - July
- - August
- - September
- - October
- - November
- - December
-
-
-
- - Jan
- - Feb
- - Mar
- - Apr
- - May
- - Jun
- - Jul
- - Aug
- - Sept
- - Oct
- - Nov
- - Dec
-
-
- - Mon
- - Tue
- - Wed
- - Th
- - Fri
- - Sat
- - Sun
-
diff --git a/baselineprofile/src/main/java/com/kafka/baseline/profile/BaselineProfileGenerator.kt b/baselineprofile/src/main/java/com/kafka/baseline/profile/BaselineProfileGenerator.kt
index 3fdd52467..64ad2fe38 100644
--- a/baselineprofile/src/main/java/com/kafka/baseline/profile/BaselineProfileGenerator.kt
+++ b/baselineprofile/src/main/java/com/kafka/baseline/profile/BaselineProfileGenerator.kt
@@ -65,7 +65,7 @@ class BaselineProfileGenerator {
// contentList.wait(Until.hasObject(By.res("snack_collection")), 5_000)
}
- fun MacrobenchmarkScope.scrollHomepageJourney() {
+ private fun MacrobenchmarkScope.scrollHomepageJourney() {
val list = device.findObject(By.res(homepageListKey))
// Set gesture margin to avoid triggering gesture navigation.
list.setGestureMargin(device.displayWidth / 5)
diff --git a/build.gradle.kts b/build.gradle.kts
index 75162aa71..c660994cd 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -45,20 +45,6 @@ allprojects {
}
}
- // Workaround for https://issuetracker.google.com/issues/268961156
- tasks.withType() {
- val kspTestTask = tasks.findByName("kspTestKotlin")
- if (kspTestTask != null) {
- dependsOn(kspTestTask)
- }
- }
- tasks.withType() {
- val kspTestTask = tasks.findByName("kspTestKotlin")
- if (kspTestTask != null) {
- dependsOn(kspTestTask)
- }
- }
-
tasks.withType>().configureEach {
compilerOptions {
// Treat all Kotlin warnings as errors
diff --git a/core/analytics/src/main/java/org/kafka/analytics/EventRepository.kt b/core/analytics/src/main/java/org/kafka/analytics/EventRepository.kt
index 26edf5617..f7b1dea71 100644
--- a/core/analytics/src/main/java/org/kafka/analytics/EventRepository.kt
+++ b/core/analytics/src/main/java/org/kafka/analytics/EventRepository.kt
@@ -4,20 +4,27 @@ import org.kafka.analytics.logger.AnalyticsImpl
import javax.inject.Inject
class EventRepository @Inject constructor() {
- fun searchQuery(keyword: String, filters: List? = null) =
- AnalyticsImpl.SEARCH to mapOf(
- "keyword" to keyword,
- "filters" to filters?.joinToString(),
- )
+ fun searchQuery(
+ keyword: String,
+ filters: List? = null,
+ mediaTypes: List? = null
+ ) = AnalyticsImpl.SEARCH to mapOf(
+ "keyword" to keyword,
+ "filters" to filters?.joinToString(),
+ "media_types" to mediaTypes?.joinToString(),
+ )
fun removeRecentSearch(keyword: String) = "remove_recent_search" to mapOf("keyword" to keyword)
- fun openItemDetail(itemId: String, source: String? = null, name: String? = null) =
- "open_item_detail" to mapOf(
- "item_id" to itemId,
- "source" to source,
- "name" to name,
- )
+ fun openItemDetail(
+ itemId: String,
+ source: String? = null,
+ name: String? = null,
+ ) = "open_item_detail" to mapOf(
+ "item_id" to itemId,
+ "source" to source,
+ "name" to name,
+ )
fun playItem(itemId: String, source: String? = null, index: Int = 0) = "play_item" to mapOf(
"item_id" to itemId,
@@ -25,11 +32,16 @@ class EventRepository @Inject constructor() {
"index" to index.toString(),
)
- fun readItem(itemId: String, type: String = "offline", source: String? = null) =
+ fun readItem(
+ itemId: String, type: String = "offline",
+ source: String? = null,
+ isRestrictedAccess: Boolean? = null
+ ) =
"read_item" to mapOf(
"item_id" to itemId,
"type" to type,
"source" to source,
+ "restricted_access" to isRestrictedAccess.toString(),
)
fun fileNotSupported(itemId: String) = "file_not_supported" to mapOf("item_id" to itemId)
diff --git a/core/downloader/src/main/java/tm/alashow/datmusic/downloader/DownloaderEvent.kt b/core/downloader/src/main/java/tm/alashow/datmusic/downloader/DownloaderEvent.kt
index 6946fcaa6..dffdb90ec 100644
--- a/core/downloader/src/main/java/tm/alashow/datmusic/downloader/DownloaderEvent.kt
+++ b/core/downloader/src/main/java/tm/alashow/datmusic/downloader/DownloaderEvent.kt
@@ -7,14 +7,8 @@ package tm.alashow.datmusic.downloader
import org.kafka.downloader.R
import tm.alashow.datmusic.downloader.DownloaderEvent.ChooseDownloadsLocation.message
-typealias DownloaderEvents = List
-
-data class DownloaderEventsError(val events: DownloaderEvents) : Throwable(), UiMessageConvertable {
- override fun toUiMessage() = events.first().toUiMessage()
-}
-
sealed class DownloaderEvent : UiMessageConvertable {
- object ChooseDownloadsLocation : DownloaderEvent() {
+ data object ChooseDownloadsLocation : DownloaderEvent() {
val message = DownloadMessage.Resource(R.string.downloader_enqueue_downloadsLocationNotSelected)
}
diff --git a/core/downloader/src/main/java/tm/alashow/datmusic/downloader/DownloaderImpl.kt b/core/downloader/src/main/java/tm/alashow/datmusic/downloader/DownloaderImpl.kt
index 347251fdb..bf24e7d7d 100644
--- a/core/downloader/src/main/java/tm/alashow/datmusic/downloader/DownloaderImpl.kt
+++ b/core/downloader/src/main/java/tm/alashow/datmusic/downloader/DownloaderImpl.kt
@@ -356,13 +356,4 @@ internal class DownloaderImpl @Inject constructor(
}
return file
}
-
- private fun fileExistsFromPreviousSession(
- downloadLocationUri: Uri,
- fileName: String,
- ): Boolean {
- val downloadsLocationFolder = downloadLocationUri.toDocumentFile(appContext)
- val file = downloadsLocationFolder.findFile(fileName)
- return file != null && file.exists()
- }
}
diff --git a/core/downloader/src/main/java/tm/alashow/datmusic/downloader/FetchExtensions.kt b/core/downloader/src/main/java/tm/alashow/datmusic/downloader/FetchExtensions.kt
deleted file mode 100644
index 15d370d4f..000000000
--- a/core/downloader/src/main/java/tm/alashow/datmusic/downloader/FetchExtensions.kt
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright (C) 2021, Alashov Berkeli
- * All rights reserved.
- */
-package tm.alashow.datmusic.downloader
-
-import com.tonyodev.fetch2.Download
-import com.tonyodev.fetch2.Status
-
-fun Download.isRetriable() = status in listOf(Status.FAILED, Status.CANCELLED)
-fun Download.isResumable() = status in listOf(Status.PAUSED)
-fun Download.isQueued() = status in listOf(Status.QUEUED)
-fun Download.isPausable() = status in listOf(Status.DOWNLOADING, Status.QUEUED)
-fun Download.isCancelable() = status in listOf(Status.DOWNLOADING, Status.QUEUED, Status.PAUSED)
-fun Download.isComplete() = status in listOf(Status.COMPLETED)
-fun Download.isIncomplete() = status in listOf(Status.CANCELLED, Status.FAILED)
-fun Download.progressVisible() = status in listOf(Status.DOWNLOADING, Status.PAUSED, Status.FAILED, Status.CANCELLED, Status.QUEUED)
diff --git a/core/downloader/src/main/java/tm/alashow/datmusic/downloader/manager/FetchDownloadManager.kt b/core/downloader/src/main/java/tm/alashow/datmusic/downloader/manager/FetchDownloadManager.kt
index a7e50e09f..0084e20a9 100644
--- a/core/downloader/src/main/java/tm/alashow/datmusic/downloader/manager/FetchDownloadManager.kt
+++ b/core/downloader/src/main/java/tm/alashow/datmusic/downloader/manager/FetchDownloadManager.kt
@@ -5,7 +5,6 @@ import com.tonyodev.fetch2.Download
import com.tonyodev.fetch2.Fetch
import com.tonyodev.fetch2.Request
import com.tonyodev.fetch2.Status
-import com.tonyodev.fetch2.database.DownloadInfo
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.callbackFlow
@@ -126,8 +125,6 @@ sealed class Downloadable(
val download: Download,
)
-object DownloadUninitialized : Downloadable(DownloadInfo())
-
class DownloadCompleted(
download: Download,
) : Downloadable(download)
diff --git a/core/remote-config/src/main/java/com/kafka/remote/config/RemoteConfigExtensions.kt b/core/remote-config/src/main/java/com/kafka/remote/config/RemoteConfigExtensions.kt
index 6ee47a5ad..061ea2d1e 100644
--- a/core/remote-config/src/main/java/com/kafka/remote/config/RemoteConfigExtensions.kt
+++ b/core/remote-config/src/main/java/com/kafka/remote/config/RemoteConfigExtensions.kt
@@ -8,10 +8,9 @@ const val RECOMMENDATION_ENABLED = "recommendation_data_enabled"
const val VIEW_RECOMMENDATION_ENABLED = "view_recommendation_data_enabled"
const val USE_RECOMMENDATION_ENABLED = "use_recommendation_data_enabled"
const val RECOMMENDATION_ROW_ENABLED = "recommendation_row_enabled"
-const val RECOMMENDATION_ROW_INDEX = "recommendation_row_index"
+const val RECOMMENDATION_ROW_INDEX = "recommendation_row_index"
const val RELATED_CONTENT_ROW_ENABLED = "related_content_row_enabled"
const val ONLINE_READER_ENABLED = "online_reader_enabled"
-const val EXACT_ALARM_ENABLED = "exact_alarm_enabled"
const val MIN_SUPPORTED_VERSION = "min_supported_version"
const val SHARE_APP_INDEX = "share_app_index"
@@ -37,8 +36,6 @@ fun RemoteConfig.isRelatedContentRowEnabled() = getBoolean(RELATED_CONTENT_ROW_E
fun RemoteConfig.isOnlineReaderEnabled() = getBoolean(ONLINE_READER_ENABLED)
-fun RemoteConfig.isExactAlarmEnabled() = getBoolean(EXACT_ALARM_ENABLED)
-
fun RemoteConfig.minSupportedVersion() = getLong(MIN_SUPPORTED_VERSION)
fun RemoteConfig.shareAppIndex() = getLong(SHARE_APP_INDEX)
diff --git a/data/database/build.gradle b/data/database/build.gradle
index a5dcdca35..625ff8952 100644
--- a/data/database/build.gradle
+++ b/data/database/build.gradle
@@ -3,8 +3,9 @@ plugins {
alias(libs.plugins.kotlin.android)
alias(libs.plugins.ksp)
alias(libs.plugins.cacheFixPlugin)
- id 'kotlin-kapt'
- id 'kotlinx-serialization'
+ alias(libs.plugins.kotlin.compose.compiler)
+ alias(libs.plugins.kotlin.kapt)
+ alias(libs.plugins.kotlin.serialization)
}
ksp {
arg("room.schemaLocation", "$projectDir/schemas")
@@ -20,10 +21,6 @@ android {
compose true
}
- composeOptions {
- kotlinCompilerExtensionVersion = libs.versions.composecompiler.get()
- }
-
namespace 'com.kafka.database'
}
@@ -50,7 +47,6 @@ dependencies {
implementation libs.compose.runtime.runtime
implementation platform(libs.google.bom)
- implementation libs.google.dynamic.links
implementation libs.google.firestore
implementation libs.jsoup
diff --git a/data/database/src/main/java/com/kafka/data/dao/FileDao.kt b/data/database/src/main/java/com/kafka/data/dao/FileDao.kt
index 7a4125619..b37abf650 100644
--- a/data/database/src/main/java/com/kafka/data/dao/FileDao.kt
+++ b/data/database/src/main/java/com/kafka/data/dao/FileDao.kt
@@ -22,11 +22,10 @@ abstract class FileDao : EntityDao {
abstract suspend fun getByItemId(itemId: String): List
suspend fun playerFilesByItemId(itemId: String): List {
- return getByItemId(itemId)
- .groupBy { it.format }
- .filter { it.key.contains("mp3", true) }
- .filterKeys { it.contains("mp3", true) }
- .values.flatten()
+ val items = getByItemId(itemId).groupBy { it.extension }
+ val selectedFormat = File.playableExtensions.firstOrNull { it in items.keys }
+
+ return selectedFormat?.let { items[it] } ?: emptyList()
}
@Query("select * from File where fileId = :fileId")
@@ -39,10 +38,6 @@ abstract class FileDao : EntityDao {
@Query("SELECT * FROM file WHERE fileId IN (:ids) ORDER BY name")
abstract suspend fun getByIds(ids: List): List
- @Transaction
- @Query("SELECT * FROM file WHERE name LIKE :title ORDER BY name")
- abstract suspend fun searchByTitle(title: String): List
-
@Transaction
@Query("SELECT * FROM file WHERE name LIKE :title ORDER BY name")
abstract fun entriesByTitle(title: String): Flow>
diff --git a/data/database/src/main/java/com/kafka/data/db/AppTypeConverters.kt b/data/database/src/main/java/com/kafka/data/db/AppTypeConverters.kt
index e66515d56..5b324ad02 100644
--- a/data/database/src/main/java/com/kafka/data/db/AppTypeConverters.kt
+++ b/data/database/src/main/java/com/kafka/data/db/AppTypeConverters.kt
@@ -2,7 +2,8 @@ package com.kafka.data.db
import androidx.room.TypeConverter
import com.kafka.data.entities.RecentTextItem
-import kotlinx.serialization.decodeFromString
+import com.kafka.data.model.MediaType
+import com.kafka.data.model.SearchFilter
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import org.threeten.bp.LocalDateTime
@@ -41,4 +42,16 @@ class AppTypeConverters {
@TypeConverter
fun fromLocalDateTime(value: LocalDateTime): String = localDateFormat.format(value)
+
+ @TypeConverter
+ fun stringToMediaType(data: String) = json.decodeFromString>(data)
+
+ @TypeConverter
+ fun mediaTypeToString(data: List) = json.encodeToString(data)
+
+ @TypeConverter
+ fun stringToSearchFilter(data: String) = json.decodeFromString>(data)
+
+ @TypeConverter
+ fun searchFilterToString(data: List) = json.encodeToString(data)
}
diff --git a/data/database/src/main/java/com/kafka/data/db/KafkaDatabase.kt b/data/database/src/main/java/com/kafka/data/db/KafkaDatabase.kt
index 3d8ca309a..c8b4c276d 100644
--- a/data/database/src/main/java/com/kafka/data/db/KafkaDatabase.kt
+++ b/data/database/src/main/java/com/kafka/data/db/KafkaDatabase.kt
@@ -44,11 +44,11 @@ interface KafkaDatabase {
RecentAudioItem::class,
DownloadRequest::class,
],
- version = 5,
+ version = 7,
exportSchema = true,
autoMigrations = [
AutoMigration(from = 3, to = 4, spec = KafkaRoomDatabase.UserRemovalMigration::class),
- AutoMigration(from = 4, to = 5, spec = KafkaRoomDatabase.RecentAudioMigration::class),
+ AutoMigration(from = 4, to = 5, spec = KafkaRoomDatabase.RecentAudioMigration::class)
],
)
@TypeConverters(AppTypeConverters::class)
diff --git a/data/database/src/main/java/com/kafka/data/entities/File.kt b/data/database/src/main/java/com/kafka/data/entities/File.kt
index 6c4909c6f..af85adc39 100644
--- a/data/database/src/main/java/com/kafka/data/entities/File.kt
+++ b/data/database/src/main/java/com/kafka/data/entities/File.kt
@@ -3,8 +3,6 @@ package com.kafka.data.entities
import androidx.room.Entity
import androidx.room.PrimaryKey
-const val mediaTypeAudio = "audio"
-
@Entity
data class File(
@PrimaryKey val fileId: String,
@@ -24,11 +22,12 @@ data class File(
val localUri: String? = null,
) : BaseEntity {
companion object {
- val audioExtensions = listOf("mp3", "wav", "aac", "ogg", "flac")
+ val audioExtensions = listOf("mp3", "wav", "m4a", "ogg", "aac", "flac")
val textExtensions = listOf("pdf", "txt")
val supportedExtensions = audioExtensions + textExtensions
- val playableExtensions = listOf("mp3", "wav")
+ // extensions that show up in player, in order of preference
+ val playableExtensions = listOf("mp3", "wav", "m4a", "ogg", "aac", "flac")
}
val duration: Long
diff --git a/data/database/src/main/java/com/kafka/data/entities/Homepage.kt b/data/database/src/main/java/com/kafka/data/entities/Homepage.kt
index 64d2fe537..54d5bb020 100644
--- a/data/database/src/main/java/com/kafka/data/entities/Homepage.kt
+++ b/data/database/src/main/java/com/kafka/data/entities/Homepage.kt
@@ -1,7 +1,6 @@
package com.kafka.data.entities
import androidx.compose.runtime.Immutable
-import com.kafka.data.model.homepage.HomepageBanner
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toPersistentList
@@ -30,19 +29,15 @@ val ImmutableList.recentItems
sealed class HomepageCollection {
abstract val enabled: Boolean
- @Immutable
- data class Banners(
- val items: ImmutableList,
- override val enabled: Boolean = true,
- ) : HomepageCollection()
-
@Immutable
data class FeaturedItem(
val label: String?,
val items: ImmutableList- ,
- val image: String? = null,
+ val image: ImmutableList = persistentListOf(),
override val enabled: Boolean = true,
- ) : HomepageCollection()
+ ) : HomepageCollection() {
+ val heroImage = image.randomOrNull().orEmpty()
+ }
@Immutable
data class RecentItems(
diff --git a/data/database/src/main/java/com/kafka/data/entities/ItemDetail.kt b/data/database/src/main/java/com/kafka/data/entities/ItemDetail.kt
index a147defba..eed58083e 100644
--- a/data/database/src/main/java/com/kafka/data/entities/ItemDetail.kt
+++ b/data/database/src/main/java/com/kafka/data/entities/ItemDetail.kt
@@ -3,6 +3,7 @@ package com.kafka.data.entities
import androidx.room.Entity
import androidx.room.Index
import androidx.room.PrimaryKey
+import com.kafka.data.model._mediaTypeAudio
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toPersistentList
@@ -24,15 +25,14 @@ data class ItemDetail(
val primaryFile: String? = null,
val subject: List? = null,
val rating: Double? = null,
+ val isAccessRestricted: Boolean = false
) : BaseEntity {
val uiRating: Int
get() = (rating ?: 0.0).toInt()
val isAudio
- get() = this.mediaType == mediaTypeAudio
+ get() = this.mediaType == _mediaTypeAudio
val immutableSubjects: ImmutableList
get() = subject.orEmpty().toPersistentList()
}
-
-fun ItemDetail?.webUrl() = "https://archive.org/details/${this?.itemId}/mode/1up?view=theater"
diff --git a/data/database/src/main/java/com/kafka/data/entities/RecentItem.kt b/data/database/src/main/java/com/kafka/data/entities/RecentItem.kt
index b089151a7..876e8a8b2 100644
--- a/data/database/src/main/java/com/kafka/data/entities/RecentItem.kt
+++ b/data/database/src/main/java/com/kafka/data/entities/RecentItem.kt
@@ -1,9 +1,10 @@
package com.kafka.data.entities
+import androidx.annotation.Keep
import androidx.compose.runtime.Immutable
import androidx.room.Entity
import androidx.room.PrimaryKey
-import com.google.errorprone.annotations.Keep
+
import com.google.firebase.firestore.DocumentId
import kotlinx.serialization.Serializable
diff --git a/data/database/src/main/java/com/kafka/data/entities/RecentSearch.kt b/data/database/src/main/java/com/kafka/data/entities/RecentSearch.kt
index 68f436d99..9ee8214b6 100644
--- a/data/database/src/main/java/com/kafka/data/entities/RecentSearch.kt
+++ b/data/database/src/main/java/com/kafka/data/entities/RecentSearch.kt
@@ -4,6 +4,8 @@ import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.Index
import androidx.room.PrimaryKey
+import com.kafka.data.model.MediaType
+import com.kafka.data.model.SearchFilter
import javax.annotation.concurrent.Immutable
@Entity(
@@ -14,6 +16,6 @@ import javax.annotation.concurrent.Immutable
data class RecentSearch(
@PrimaryKey(autoGenerate = true) @ColumnInfo(name = "id") var id: Long = 0,
@ColumnInfo(name = "search_term") var searchTerm: String = "",
+ @ColumnInfo(name = "filters") var filters: List,
+ @ColumnInfo(name = "media_types") var mediaTypes: List
) : BaseEntity
-
-//todo: add search filter to recent search
diff --git a/data/database/src/main/java/com/kafka/data/prefs/InternalPreferencesStore.kt b/data/database/src/main/java/com/kafka/data/prefs/InternalPreferencesStore.kt
index 04da7a858..8f42c81ee 100644
--- a/data/database/src/main/java/com/kafka/data/prefs/InternalPreferencesStore.kt
+++ b/data/database/src/main/java/com/kafka/data/prefs/InternalPreferencesStore.kt
@@ -15,10 +15,4 @@ internal class InternalPreferencesStore @Inject constructor(
settings.remove(key)
}
}
-
- suspend fun save(key: Preferences.Key, value: T) {
- context.dataStore.edit { settings ->
- settings[key] = value
- }
- }
}
diff --git a/data/database/src/main/java/com/kafka/data/prefs/PreferencesStore.kt b/data/database/src/main/java/com/kafka/data/prefs/PreferencesStore.kt
index 45d294c97..7fa61e537 100644
--- a/data/database/src/main/java/com/kafka/data/prefs/PreferencesStore.kt
+++ b/data/database/src/main/java/com/kafka/data/prefs/PreferencesStore.kt
@@ -7,6 +7,8 @@ import androidx.datastore.preferences.core.booleanPreferencesKey
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.stringPreferencesKey
import androidx.datastore.preferences.preferencesDataStore
+import com.kafka.data.model._mediaTypeAudio
+import com.kafka.data.model._mediaTypeText
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
@@ -98,9 +100,9 @@ enum class ContentType {
val mediaTypes
get() = when (this) {
- AUDIO -> listOf("audio")
- TEXT -> listOf("texts")
- BOTH -> listOf("texts", "audio")
+ AUDIO -> listOf(_mediaTypeAudio)
+ TEXT -> listOf(_mediaTypeText)
+ BOTH -> listOf(_mediaTypeText, _mediaTypeAudio)
}
companion object {
diff --git a/data/models/src/main/java/com/kafka/data/model/ArchiveQuery.kt b/data/models/src/main/java/com/kafka/data/model/ArchiveQuery.kt
index c106eb92c..1239adda6 100644
--- a/data/models/src/main/java/com/kafka/data/model/ArchiveQuery.kt
+++ b/data/models/src/main/java/com/kafka/data/model/ArchiveQuery.kt
@@ -9,14 +9,12 @@ const val _mediaType = "mediaType"
const val _mediaTypeText = "texts"
const val _mediaTypeAudio = "audio"
const val _identifier = "identifier"
-const val _collection = "collection"
const val _creator = "creator_name"
const val _subject = "subject"
const val _creator_remote = "creator"
const val _title = "title"
-const val joinerAnd = "AND"
const val joinerOr = "OR"
data class QueryItem(val key: String, val value: String, val joiner: String = "")
@@ -25,10 +23,6 @@ data class ArchiveQuery(
var queries: MutableList = mutableListOf(),
)
-fun ArchiveQuery.booksByIdentifiers(identifiers: String): ArchiveQuery {
- return booksByIdentifiers(identifiers.split(", "))
-}
-
fun ArchiveQuery.booksByIdentifiers(identifiers: List): ArchiveQuery {
identifiers.forEach {
queries.add(QueryItem(_identifier, it, joinerOr))
@@ -40,11 +34,6 @@ fun ArchiveQuery.booksByIdentifiers(identifiers: List): ArchiveQuery {
return this
}
-fun ArchiveQuery.booksByCollection(collection: String, joiner: String = ""): ArchiveQuery {
- queries.add(QueryItem(_collection, collection, joiner))
- return this
-}
-
fun ArchiveQuery.booksByTitleKeyword(keyword: String, joiner: String = ""): ArchiveQuery {
queries.add(QueryItem(_title, keyword, joiner))
return this
@@ -67,9 +56,3 @@ fun ArchiveQuery.booksBySubject(subject: String, joiner: String = ""): ArchiveQu
queries.add(QueryItem(_subject, subject, joiner))
return this
}
-
-fun ArchiveQuery.booksByTitleOrCreator(keyword: String): ArchiveQuery {
- queries.add(QueryItem(_title, keyword, joinerOr))
- queries.add(QueryItem(_creator, keyword))
- return this
-}
diff --git a/data/models/src/main/java/com/kafka/data/model/MediaType.kt b/data/models/src/main/java/com/kafka/data/model/MediaType.kt
index df9e15c99..b25f23f19 100644
--- a/data/models/src/main/java/com/kafka/data/model/MediaType.kt
+++ b/data/models/src/main/java/com/kafka/data/model/MediaType.kt
@@ -1,6 +1,5 @@
package com.kafka.data.model
-sealed class MediaType {
- data object Text : MediaType()
- data object Audio : MediaType()
+enum class MediaType(val value: String) {
+ Text(_mediaTypeText), Audio(_mediaTypeAudio);
}
diff --git a/data/models/src/main/java/com/kafka/data/model/homepage/HomepageResponse.kt b/data/models/src/main/java/com/kafka/data/model/homepage/HomepageResponse.kt
index dcbac500b..154074a17 100644
--- a/data/models/src/main/java/com/kafka/data/model/homepage/HomepageResponse.kt
+++ b/data/models/src/main/java/com/kafka/data/model/homepage/HomepageResponse.kt
@@ -1,6 +1,5 @@
package com.kafka.data.model.homepage
-import androidx.compose.runtime.Immutable
import com.google.firebase.firestore.DocumentId
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@@ -11,15 +10,6 @@ sealed class HomepageCollectionResponse {
abstract val topics: String
abstract val index: Float
- @Serializable
- @SerialName("banners")
- data class Banners(
- val items: List = listOf(),
- override val index: Float,
- override val enabled: Boolean = true,
- override val topics: String = "",
- ) : HomepageCollectionResponse()
-
@Serializable
@SerialName("featuredItem")
data class FeaturedItem(
@@ -91,26 +81,6 @@ sealed class HomepageCollectionResponse {
) : HomepageCollectionResponse()
}
-@Serializable
-@Immutable
-data class HomepageBanner(
- @DocumentId
- val id: String = "",
- val action: Action = Action.Search,
- val imageUrl: String = "",
- val keyword: String? = null,
- val index: Int = 0,
-) {
- @Serializable
- enum class Action {
- @SerialName("search")
- Search,
-
- @SerialName("item_detail")
- ItemDetail,
- }
-}
-
@Serializable
data class FirebaseImage(
@DocumentId
diff --git a/data/models/src/main/java/com/kafka/data/model/item/Doc.kt b/data/models/src/main/java/com/kafka/data/model/item/Doc.kt
index 9b71e3c58..c1770d4b4 100644
--- a/data/models/src/main/java/com/kafka/data/model/item/Doc.kt
+++ b/data/models/src/main/java/com/kafka/data/model/item/Doc.kt
@@ -32,8 +32,6 @@ data class Doc(
val language: List? = null,
@SerialName("mediatype")
val mediatype: String,
- @SerialName("month")
- val month: Int? = 0,
@SerialName("subject")
@Serializable(with = StringListSerializer::class)
val subject: List? = null,
diff --git a/data/models/src/main/java/com/kafka/data/model/item/Metadata.kt b/data/models/src/main/java/com/kafka/data/model/item/Metadata.kt
index 13d73f352..42bfa7584 100644
--- a/data/models/src/main/java/com/kafka/data/model/item/Metadata.kt
+++ b/data/models/src/main/java/com/kafka/data/model/item/Metadata.kt
@@ -34,4 +34,6 @@ data class Metadata(
@SerialName("language")
@Serializable(with = StringListSerializer::class)
val languages: List? = null,
+ @SerialName("access-restricted-item")
+ val accessRestrictedItem: Boolean = false,
)
diff --git a/data/repo/src/main/java/com/kafka/data/MediaTypeManager.kt b/data/repo/src/main/java/com/kafka/data/MediaTypeManager.kt
deleted file mode 100644
index c4950ca8a..000000000
--- a/data/repo/src/main/java/com/kafka/data/MediaTypeManager.kt
+++ /dev/null
@@ -1,36 +0,0 @@
-package com.kafka.data
-
-import androidx.datastore.preferences.core.stringPreferencesKey
-import com.kafka.data.prefs.PreferencesStore
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.flow.map
-import org.kafka.base.ProcessLifetime
-import org.kafka.base.extensions.stateInDefault
-import javax.inject.Inject
-
-/* Unused class: we might add functionality to filter by media type in future. */
-class MediaTypeManager @Inject constructor(
- preferencesStore: PreferencesStore,
- @ProcessLifetime private val coroutineScope: CoroutineScope,
-) {
- private val preferenceKey get() = stringPreferencesKey("media_type")
-
- private val mediaTypeState = preferencesStore.getStateFlow(
- keyName = preferenceKey,
- scope = coroutineScope,
- initialValue = MediaType.Audio.name,
- )
-
- private val mediaTypeFlow = mediaTypeState.map { MediaType.valueOf(it) }
- .stateInDefault(coroutineScope, MediaType.Audio)
-
- val mediaType: MediaType = mediaTypeFlow.value
-
- fun updateMediaType(mediaType: MediaType) {
- mediaTypeState.value = mediaType.name
- }
-}
-
-enum class MediaType {
- Audio, Texts
-}
diff --git a/data/repo/src/main/java/com/kafka/data/feature/homepage/HomepageMapper.kt b/data/repo/src/main/java/com/kafka/data/feature/homepage/HomepageMapper.kt
index 84c11ee2c..bdc4954f2 100644
--- a/data/repo/src/main/java/com/kafka/data/feature/homepage/HomepageMapper.kt
+++ b/data/repo/src/main/java/com/kafka/data/feature/homepage/HomepageMapper.kt
@@ -17,7 +17,6 @@ class HomepageMapper @Inject constructor(private val itemDao: ItemDao) {
when (it) {
is HomepageCollectionResponse.Row -> it.mapRows()
is HomepageCollectionResponse.Column -> it.mapColumn()
- is HomepageCollectionResponse.Banners -> it.mapBanners()
is HomepageCollectionResponse.FeaturedItem -> it.mapFeatured()
is HomepageCollectionResponse.RecentItems -> it.mapRecentItems()
is HomepageCollectionResponse.Grid -> it.mapGrid()
@@ -75,19 +74,21 @@ class HomepageMapper @Inject constructor(private val itemDao: ItemDao) {
}
}
- private fun HomepageCollectionResponse.Banners.mapBanners() =
- flowOf(HomepageCollection.Banners(items = items.toPersistentList(), enabled = enabled))
-
// todo: items are filled later on domain layer, find a way to fill them here
private fun HomepageCollectionResponse.RecentItems.mapRecentItems() =
flowOf(HomepageCollection.RecentItems(persistentListOf(), enabled))
private fun HomepageCollectionResponse.FeaturedItem.mapFeatured() =
itemDao.observe(itemIds.split(", ")).map { items ->
+ val itemIdsIndexMap = itemIds.split(", ")
+ .withIndex()
+ .associate { it.value to it.index }
+ val sortedItems = items.sortedBy { itemIdsIndexMap[it.itemId] ?: Int.MAX_VALUE }
+
HomepageCollection.FeaturedItem(
label = label,
- items = items.toPersistentList(),
- image = image?.randomOrNull()?.downloadURL,
+ items = sortedItems.toPersistentList(),
+ image = image?.map { it.downloadURL }?.toPersistentList() ?: persistentListOf(),
enabled = enabled,
)
}
diff --git a/data/repo/src/main/java/com/kafka/data/feature/item/ItemDetailMapper.kt b/data/repo/src/main/java/com/kafka/data/feature/item/ItemDetailMapper.kt
index 689643afe..4e3c2fed5 100644
--- a/data/repo/src/main/java/com/kafka/data/feature/item/ItemDetailMapper.kt
+++ b/data/repo/src/main/java/com/kafka/data/feature/item/ItemDetailMapper.kt
@@ -5,6 +5,7 @@ import com.kafka.data.dao.FileDao
import com.kafka.data.dao.ItemDao
import com.kafka.data.entities.File.Companion.supportedExtensions
import com.kafka.data.entities.ItemDetail
+import com.kafka.data.model._mediaTypeText
import com.kafka.data.model.item.File
import com.kafka.data.model.item.ItemDetailResponse
import org.kafka.base.debug
@@ -38,13 +39,14 @@ class ItemDetailMapper @Inject constructor(
?.filter { it.isNotEmpty() }
},
rating = itemDao.getOrNull(from.metadata.identifier)?.rating,
+ isAccessRestricted = from.metadata.accessRestrictedItem
).also {
insertFiles(from, it)
}
}
private fun List.primaryFile(mediaType: String?) =
- if (mediaType == "texts") getTextFile() else firstOrNull()
+ if (mediaType == _mediaTypeText) getTextFile() else firstOrNull()
private fun List.getTextFile() = firstOrNull { it.name.extension() == "pdf" }
diff --git a/domain/src/main/java/org/kafka/domain/interactors/AddRecentSearch.kt b/domain/src/main/java/org/kafka/domain/interactors/AddRecentSearch.kt
index 12119eb4f..0ada08142 100644
--- a/domain/src/main/java/org/kafka/domain/interactors/AddRecentSearch.kt
+++ b/domain/src/main/java/org/kafka/domain/interactors/AddRecentSearch.kt
@@ -2,6 +2,8 @@ package org.kafka.domain.interactors
import com.kafka.data.dao.RecentSearchDao
import com.kafka.data.entities.RecentSearch
+import com.kafka.data.model.MediaType
+import com.kafka.data.model.SearchFilter
import kotlinx.coroutines.withContext
import org.kafka.base.CoroutineDispatchers
import org.kafka.base.domain.Interactor
@@ -10,13 +12,24 @@ import javax.inject.Inject
class AddRecentSearch @Inject constructor(
private val dispatchers: CoroutineDispatchers,
private val recentSearchDao: RecentSearchDao,
-) : Interactor() {
+) : Interactor() {
- override suspend fun doWork(params: String) {
+ override suspend fun doWork(params: Params) {
withContext(dispatchers.io) {
- recentSearchDao.insert(RecentSearch(searchTerm = params))
+ val recentSearch = RecentSearch(
+ searchTerm = params.searchTerm,
+ filters = params.filters,
+ mediaTypes = params.mediaTypes
+ )
+ recentSearchDao.insert(recentSearch)
}
}
+
+ data class Params(
+ val searchTerm: String,
+ val filters: List,
+ val mediaTypes: List
+ )
}
class RemoveRecentSearch @Inject constructor(
diff --git a/domain/src/main/java/org/kafka/domain/interactors/SearchQueryItems.kt b/domain/src/main/java/org/kafka/domain/interactors/SearchQueryItems.kt
index 1b5168de4..26aac8aa6 100644
--- a/domain/src/main/java/org/kafka/domain/interactors/SearchQueryItems.kt
+++ b/domain/src/main/java/org/kafka/domain/interactors/SearchQueryItems.kt
@@ -2,13 +2,13 @@ package org.kafka.domain.interactors
import com.kafka.data.feature.item.ItemRepository
import com.kafka.data.model.ArchiveQuery
+import com.kafka.data.model.MediaType
import com.kafka.data.model.SearchFilter
import com.kafka.data.model.booksByAuthor
import com.kafka.data.model.booksBySubject
import com.kafka.data.model.booksByTitleKeyword
import com.kafka.data.model.filterByType
import com.kafka.data.model.joinerOr
-import com.kafka.data.prefs.ContentType
import kotlinx.coroutines.withContext
import org.kafka.base.CoroutineDispatchers
import org.kafka.base.domain.Interactor
@@ -24,19 +24,23 @@ class SearchQueryItems @Inject constructor(
override suspend fun doWork(params: Params): Unit = withContext(dispatchers.io) {
if (params.keyword.isEmpty()) return@withContext
- val archiveQuery = buildQuery(params.keyword, params.searchFilter)
+ val archiveQuery = buildQuery(params.keyword, params.searchFilter, params.mediaTypes)
itemRepository.updateQuery(buildRemoteQuery(archiveQuery)).let {
itemRepository.saveItems(it)
}
}
- data class Params(val keyword: String, val searchFilter: List)
+ data class Params(
+ val keyword: String,
+ val searchFilter: List,
+ val mediaTypes: List
+ )
}
internal fun buildQuery(
keyword: String,
searchFilters: List = SearchFilter.entries,
- contentType: ContentType = ContentType.DEFAULT,
+ mediaTypes: List = MediaType.entries,
): ArchiveQuery {
val query = ArchiveQuery()
searchFilters.forEach {
@@ -48,5 +52,5 @@ internal fun buildQuery(
}
}
- return query.filterByType(contentType.mediaTypes)
+ return query.filterByType(mediaTypes.map { it.value })
}
diff --git a/domain/src/main/java/org/kafka/domain/interactors/query/BuildArchiveQuery.kt b/domain/src/main/java/org/kafka/domain/interactors/query/BuildArchiveQuery.kt
deleted file mode 100644
index 4b4d89244..000000000
--- a/domain/src/main/java/org/kafka/domain/interactors/query/BuildArchiveQuery.kt
+++ /dev/null
@@ -1,31 +0,0 @@
-package org.kafka.domain.interactors.query
-
-import com.kafka.data.model._creator
-import kotlinx.coroutines.withContext
-import org.kafka.base.CoroutineDispatchers
-import org.kafka.domain.interactors.query.BuildArchiveQuery.Query.QueryByCreator
-import javax.inject.Inject
-
-class BuildArchiveQuery @Inject constructor(private val dispatchers: CoroutineDispatchers) {
- suspend operator fun invoke(params: Params): ArchiveQuery {
- return withContext(dispatchers.computation) {
- ArchiveQuery().apply {
- when (params.query) {
- is QueryByCreator -> queries.add(QueryItem(_creator, params.query.creator))
- }
- }
- }
- }
-
- data class QueryItem(val key: String, val value: String, val joiner: String = "")
-
- data class ArchiveQuery(
- var queries: MutableList = mutableListOf(),
- )
-
- data class Params(val query: Query)
-
- sealed class Query {
- data class QueryByCreator(val creator: String) : Query()
- }
-}
diff --git a/domain/src/main/java/org/kafka/domain/interactors/query/BuildLocalQuery.kt b/domain/src/main/java/org/kafka/domain/interactors/query/BuildLocalQuery.kt
index ef7507318..24646f886 100644
--- a/domain/src/main/java/org/kafka/domain/interactors/query/BuildLocalQuery.kt
+++ b/domain/src/main/java/org/kafka/domain/interactors/query/BuildLocalQuery.kt
@@ -2,10 +2,10 @@ package org.kafka.domain.interactors.query
import androidx.sqlite.db.SimpleSQLiteQuery
import com.kafka.data.model.ArchiveQuery
+import com.kafka.data.model.MediaType
import com.kafka.data.model.QueryItem
import com.kafka.data.model._identifier
import com.kafka.data.model._mediaType
-import com.kafka.data.prefs.ContentType
import org.kafka.base.debug
import javax.inject.Inject
@@ -22,7 +22,7 @@ class BuildLocalQuery @Inject constructor() {
val mediaTypeQuery = queries.filter { it.key == _mediaType }
.takeIf { it.isNotEmpty() }
- ?: ContentType.DEFAULT.mediaTypes.map { QueryItem(_mediaType, it) }
+ ?: MediaType.entries.map { QueryItem(_mediaType, it.value) }
queries.removeIf { it.key == _mediaType }
diff --git a/domain/src/main/java/org/kafka/domain/observers/ObserveRecentSearch.kt b/domain/src/main/java/org/kafka/domain/observers/ObserveRecentSearch.kt
index d6dec8be5..7a204f1ce 100644
--- a/domain/src/main/java/org/kafka/domain/observers/ObserveRecentSearch.kt
+++ b/domain/src/main/java/org/kafka/domain/observers/ObserveRecentSearch.kt
@@ -1,6 +1,7 @@
package org.kafka.domain.observers
import com.kafka.data.dao.RecentSearchDao
+import com.kafka.data.entities.RecentSearch
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
@@ -11,15 +12,12 @@ import javax.inject.Inject
class ObserveRecentSearch @Inject constructor(
private val dispatchers: CoroutineDispatchers,
private val recentSearchDao: RecentSearchDao,
-) : SubjectInteractor>() {
+) : SubjectInteractor>() {
- override fun createObservable(params: Unit): Flow
> {
+ override fun createObservable(params: Unit): Flow> {
return recentSearchDao.observeRecentSearch()
- .map {
- it.take(MaxRecentSearches)
- .distinctBy { it.searchTerm }
- .map { it.searchTerm }
- }.flowOn(dispatchers.io)
+ .map { it.take(MaxRecentSearches).distinctBy { it.searchTerm } }
+ .flowOn(dispatchers.io)
}
}
diff --git a/domain/src/main/java/org/kafka/domain/observers/ObserveSearchItems.kt b/domain/src/main/java/org/kafka/domain/observers/ObserveSearchItems.kt
index 0b9164761..b54711ed2 100644
--- a/domain/src/main/java/org/kafka/domain/observers/ObserveSearchItems.kt
+++ b/domain/src/main/java/org/kafka/domain/observers/ObserveSearchItems.kt
@@ -2,6 +2,7 @@ package org.kafka.domain.observers
import com.kafka.data.entities.Item
import com.kafka.data.feature.item.ItemRepository
+import com.kafka.data.model.MediaType
import com.kafka.data.model.SearchFilter
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flowOf
@@ -22,11 +23,15 @@ class ObserveSearchItems @Inject constructor(
return if (params.keyword.isEmpty()) {
flowOf(emptyList())
} else {
- itemRepository.observeQueryItems(
- buildLocalQuery(buildQuery(params.keyword, params.searchFilter)),
- ).flowOn(dispatchers.io)
+ val query = buildQuery(params.keyword, params.searchFilter, params.mediaTypes)
+ itemRepository.observeQueryItems(buildLocalQuery(query))
+ .flowOn(dispatchers.io)
}
}
- data class Params(val keyword: String, val searchFilter: List)
+ data class Params(
+ val keyword: String,
+ val searchFilter: List,
+ val mediaTypes: List
+ )
}
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index fa3fcc724..43b65e0a9 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -1,33 +1,33 @@
[versions]
accompanist = "0.34.0"
-agp = "8.3.2"
+agp = "8.5.0"
androidxhilt = "1.2.0"
-androidxlifecycle = "2.7.0"
+androidxlifecycle = "2.8.2"
navigation = "2.7.7"
coil = "2.6.0"
compose-alpha = "2024.01.00-alpha01"
-compose-bom = "2024.05.00"
-composecompiler = "1.5.12"
-coroutines = "1.8.0"
-dagger = "2.51"
+compose-bom = "2024.06.00"
+coroutines = "1.8.1"
+dagger = "2.51.1"
icons = "1.0.0"
-kotlin = "1.9.23"
+kotlin = "2.0.0"
kotlin-immutable = "0.3.7"
-material3 = "1.2.1"
+material3 = "1.3.0-beta03"
+media3 = "1.3.1"
mixpanel = "7.0.0"
okhttp = "4.12.0"
-paging = "3.2.1"
+paging = "3.3.0"
retrofit = "2.9.0"
room = "2.6.1"
-serialization = "1.6.3"
+serialization = "1.7.0"
exoplayer = "2.19.1"
pdfviewer = "3.2.0-beta.1"
compileSdk = "34"
minSdk = "24"
targetSdk = "33"
core-ktx = "1.13.1"
-androidx-test-ext-junit = "1.1.5"
-espresso-core = "3.5.1"
+androidx-test-ext-junit = "1.2.0"
+espresso-core = "3.6.0"
uiautomator = "2.3.0"
benchmark-macro-junit4 = "1.2.4"
androidx-baselineprofile = "1.2.4"
@@ -40,10 +40,11 @@ android-library = { id = "com.android.library", version.ref = "agp" }
android-lint = { id = "com.android.lint", version.ref = "agp" }
cacheFixPlugin = { id = "org.gradle.android.cache-fix", version = "3.0.1" }
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
+kotlin-compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
kotlin-kapt = { id = "org.jetbrains.kotlin.kapt", version.ref = "kotlin" }
-ksp = "com.google.devtools.ksp:1.9.23-1.0.19"
-gms-googleServices = "com.google.gms.google-services:4.4.1"
-firebase-crashlytics = "com.google.firebase.crashlytics:2.9.9"
+ksp = "com.google.devtools.ksp:2.0.0-1.0.22"
+gms-googleServices = "com.google.gms.google-services:4.4.2"
+firebase-crashlytics = "com.google.firebase.crashlytics:3.0.2"
spotless = "com.diffplug.spotless:6.25.0"
kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
hilt = { id = "com.google.dagger.hilt.android", version.ref = "dagger" }
@@ -91,7 +92,7 @@ lottie-compose = "com.airbnb.android:lottie-compose:6.1.0"
androidx-paging-common = { module = "androidx.paging:paging-common-ktx", version.ref = "paging" }
androidx-paging-runtime = { module = "androidx.paging:paging-runtime-ktx", version.ref = "paging" }
-androidx-paging-compose = "androidx.paging:paging-compose:3.2.1"
+androidx-paging-compose = "androidx.paging:paging-compose:3.3.0"
androidx-palette = "androidx.palette:palette:1.0.0"
@@ -112,6 +113,7 @@ compose-foundation-layout = { module = "androidx.compose.foundation:foundation-l
compose-material-iconsext = { module = "androidx.compose.material:material-icons-extended" }
compose-material-material = { module = "androidx.compose.material:material" }
compose-material-material3 = { module = "androidx.compose.material3:material3", version.ref = "material3" }
+compose-material-navigation = { module = "androidx.compose.material:material-navigation" }
compose-ui-test = { module = "androidx.compose.ui:ui-test-junit4" }
compose-ui-tooling = { module = "androidx.compose.ui:ui-tooling" }
compose-ui-ui = { module = "androidx.compose.ui:ui" }
@@ -123,16 +125,15 @@ fetch-okhttp = "androidx.tonyodev.fetch2okhttp:xfetch2okhttp:3.1.6"
dagger-dagger = { module = "com.google.dagger:dagger", version.ref = "dagger" }
-google-bom = "com.google.firebase:firebase-bom:32.8.1"
+google-bom = "com.google.firebase:firebase-bom:33.1.1"
google-analytics = { module = "com.google.firebase:firebase-analytics" }
google-crashlytics = { module = "com.google.firebase:firebase-crashlytics" }
-google-dynamic_links = { module = "com.google.firebase:firebase-dynamic-links" }
google-auth = { module = "com.google.firebase:firebase-auth" }
-google-coroutines = "org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.8.0"
+google-coroutines = "org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.8.1"
google-firestore = { module = "com.google.firebase:firebase-firestore" }
google-messaging = { module = "com.google.firebase:firebase-messaging" }
google-performance = { module = "com.google.firebase:firebase-perf" }
-google-playservices-auth = "com.google.android.gms:play-services-auth:21.1.1"
+google-playservices-auth = "com.google.android.gms:play-services-auth:21.2.0"
google-remoteConfig = { module = "com.google.firebase:firebase-config" }
google-review = { module = "com.google.android.play:review-ktx", version.ref = "review" }
@@ -150,7 +151,12 @@ icons-feather = { module = "br.com.devsrsouza.compose.icons.android:feather", ve
icons-font-awesome = { module = "br.com.devsrsouza.compose.icons.android:font-awesome", version.ref = "icons" }
icons-tabler = { module = "br.com.devsrsouza.compose.icons.android:tabler-icons", version.ref = "icons" }
-leakCanary = "com.squareup.leakcanary:leakcanary-android:2.13"
+leakCanary = "com.squareup.leakcanary:leakcanary-android:2.14"
+
+media3-datasource-okhttp = { module = "androidx.media3:media3-datasource-okhttp", version.ref = "media3" }
+media3-exoplayer = { module = "androidx.media3:media3-exoplayer", version.ref = "media3" }
+media3-exoplayer-dash = { module = "androidx.media3:media3-exoplayer-dash", version.ref = "media3" }
+media3-ui = { module = "androidx.media3:media3-ui", version.ref = "media3" }
okhttp-loggingInterceptor = { module = "com.squareup.okhttp3:logging-interceptor", version.ref = "okhttp" }
okhttp-okhttp = { module = "com.squareup.okhttp3:okhttp", version.ref = "okhttp" }
@@ -171,4 +177,4 @@ espresso-core = { group = "androidx.test.espresso", name = "espresso-core", vers
uiautomator = { group = "androidx.test.uiautomator", name = "uiautomator", version.ref = "uiautomator" }
benchmark-macro-junit4 = { group = "androidx.benchmark", name = "benchmark-macro-junit4", version.ref = "benchmark-macro-junit4" }
profileinstaller = { group = "androidx.profileinstaller", name = "profileinstaller", version.ref = "profileinstaller" }
-androidx-rules = { group = "androidx.test", name = "rules", version = "1.5.0" }
+androidx-rules = { group = "androidx.test", name = "rules", version = "1.6.0" }
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 92c1ac1bd..81c736bb3 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
diff --git a/navigation/build.gradle b/navigation/build.gradle
index f0129b2a7..b8592b270 100644
--- a/navigation/build.gradle
+++ b/navigation/build.gradle
@@ -1,7 +1,8 @@
plugins {
alias(libs.plugins.android.library)
alias(libs.plugins.kotlin.android)
- id 'kotlin-kapt'
+ alias(libs.plugins.kotlin.compose.compiler)
+ alias(libs.plugins.kotlin.kapt)
alias(libs.plugins.cacheFixPlugin)
}
@@ -10,10 +11,6 @@ android {
compose true
}
- composeOptions {
- kotlinCompilerExtensionVersion libs.versions.composecompiler.get()
- }
-
namespace 'org.kafka.navigation'
}
diff --git a/navigation/src/main/java/org/kafka/navigation/deeplink/DynamicDeepLinkHandler.kt b/navigation/src/main/java/org/kafka/navigation/deeplink/DynamicDeepLinkHandler.kt
deleted file mode 100644
index 3a5108928..000000000
--- a/navigation/src/main/java/org/kafka/navigation/deeplink/DynamicDeepLinkHandler.kt
+++ /dev/null
@@ -1,15 +0,0 @@
-package org.kafka.navigation.deeplink
-
-import android.app.Activity
-import android.content.Intent
-import android.net.Uri
-
-interface DynamicDeepLinkHandler {
- fun handleDeepLink(activity: Activity, intent: Intent)
- fun createDeepLinkUri(link: String): Uri
-
- companion object {
- fun itemDetailLink(itemId: String) =
- Uri.parse("https://www.archive.org/details/?id=$itemId")
- }
-}
diff --git a/navigation/src/main/res/anim/anim_enter_screen.xml b/navigation/src/main/res/anim/anim_enter_screen.xml
deleted file mode 100644
index ba4cec33c..000000000
--- a/navigation/src/main/res/anim/anim_enter_screen.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
diff --git a/navigation/src/main/res/anim/anim_exit_screen.xml b/navigation/src/main/res/anim/anim_exit_screen.xml
deleted file mode 100644
index b0bdbe91d..000000000
--- a/navigation/src/main/res/anim/anim_exit_screen.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
diff --git a/notifications/src/main/res/drawable-anydpi-v24/ic_stat_name.xml b/notifications/src/main/res/drawable-anydpi-v24/ic_stat_name.xml
deleted file mode 100644
index 8732622e0..000000000
--- a/notifications/src/main/res/drawable-anydpi-v24/ic_stat_name.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
-
diff --git a/notifications/src/main/res/drawable-hdpi/ic_stat_name.png b/notifications/src/main/res/drawable-hdpi/ic_stat_name.png
deleted file mode 100644
index da12a115e..000000000
Binary files a/notifications/src/main/res/drawable-hdpi/ic_stat_name.png and /dev/null differ
diff --git a/notifications/src/main/res/drawable-mdpi/ic_stat_name.png b/notifications/src/main/res/drawable-mdpi/ic_stat_name.png
deleted file mode 100644
index 038a1d8fe..000000000
Binary files a/notifications/src/main/res/drawable-mdpi/ic_stat_name.png and /dev/null differ
diff --git a/notifications/src/main/res/drawable-xhdpi/ic_editors_choice.xml b/notifications/src/main/res/drawable-xhdpi/ic_editors_choice.xml
deleted file mode 100644
index 6a9840630..000000000
--- a/notifications/src/main/res/drawable-xhdpi/ic_editors_choice.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
-
-
diff --git a/notifications/src/main/res/drawable-xhdpi/ic_rekhta_r.png b/notifications/src/main/res/drawable-xhdpi/ic_rekhta_r.png
deleted file mode 100644
index 5a5ff6b74..000000000
Binary files a/notifications/src/main/res/drawable-xhdpi/ic_rekhta_r.png and /dev/null differ
diff --git a/ui/auth/build.gradle b/ui/auth/build.gradle
index 0a991d97e..4d2db89d4 100644
--- a/ui/auth/build.gradle
+++ b/ui/auth/build.gradle
@@ -2,7 +2,8 @@ plugins {
alias(libs.plugins.android.library)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.cacheFixPlugin)
- id 'kotlin-kapt'
+ alias(libs.plugins.kotlin.compose.compiler)
+ alias(libs.plugins.kotlin.kapt)
}
android {
@@ -10,10 +11,6 @@ android {
compose true
}
- composeOptions {
- kotlinCompilerExtensionVersion libs.versions.composecompiler.get()
- }
-
namespace 'org.kafka.auth'
}
diff --git a/ui/auth/src/main/java/org/rekhta/ui/auth/LoginWithEmail.kt b/ui/auth/src/main/java/org/rekhta/ui/auth/LoginWithEmail.kt
index aef14cc68..dbf58b85c 100644
--- a/ui/auth/src/main/java/org/rekhta/ui/auth/LoginWithEmail.kt
+++ b/ui/auth/src/main/java/org/rekhta/ui/auth/LoginWithEmail.kt
@@ -10,8 +10,8 @@ import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedTextField
+import androidx.compose.material3.OutlinedTextFieldDefaults
import androidx.compose.material3.Text
-import androidx.compose.material3.TextFieldDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
@@ -174,10 +174,11 @@ internal fun LoginTextField(
else loginTextField.visualTransformation,
onValueChange = { onValueChange(it) },
textStyle = MaterialTheme.typography.titleSmall,
- colors = TextFieldDefaults.outlinedTextFieldColors(
+ colors = OutlinedTextFieldDefaults.colors(
focusedLabelColor = MaterialTheme.colorScheme.secondary,
unfocusedLabelColor = MaterialTheme.colorScheme.secondary,
- containerColor = MaterialTheme.colorScheme.background,
+ unfocusedContainerColor = MaterialTheme.colorScheme.background,
+ focusedContainerColor = MaterialTheme.colorScheme.background,
focusedBorderColor = MaterialTheme.colorScheme.primary,
unfocusedBorderColor = MaterialTheme.colorScheme.surfaceVariant
),
@@ -204,7 +205,6 @@ internal enum class LoginTextField(
val visualTransformation: VisualTransformation,
val imeAction: ImeAction
) {
- Name("Name", KeyboardType.Text, VisualTransformation.None, ImeAction.Next),
Username("Email", KeyboardType.Email, VisualTransformation.None, ImeAction.Next),
Password("Password", KeyboardType.Password, PasswordVisualTransformation(), ImeAction.Done)
}
diff --git a/ui/auth/src/main/java/org/rekhta/ui/auth/feedback/FeedbackViewModel.kt b/ui/auth/src/main/java/org/rekhta/ui/auth/feedback/FeedbackViewModel.kt
index 70d7b6b42..2a1ad4ba4 100644
--- a/ui/auth/src/main/java/org/rekhta/ui/auth/feedback/FeedbackViewModel.kt
+++ b/ui/auth/src/main/java/org/rekhta/ui/auth/feedback/FeedbackViewModel.kt
@@ -7,7 +7,6 @@ import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
-import org.kafka.base.debug
import org.kafka.base.domain.InvokeSuccess
import org.kafka.base.extensions.stateInDefault
import org.kafka.common.ObservableLoadingCounter
diff --git a/ui/auth/src/main/java/org/rekhta/ui/auth/profile/ProfileScreen.kt b/ui/auth/src/main/java/org/rekhta/ui/auth/profile/ProfileScreen.kt
index 4a9c421e9..eb871e1e0 100644
--- a/ui/auth/src/main/java/org/rekhta/ui/auth/profile/ProfileScreen.kt
+++ b/ui/auth/src/main/java/org/rekhta/ui/auth/profile/ProfileScreen.kt
@@ -22,7 +22,6 @@ import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.kafka.data.entities.User
import org.kafka.auth.R
-import org.kafka.common.animation.Delayed
import org.kafka.common.simpleClickable
import org.kafka.ui.components.progress.InfiniteProgressBar
import ui.common.theme.theme.Dimens
diff --git a/ui/common/build.gradle b/ui/common/build.gradle
index 6a6ea0c69..04c3024d1 100644
--- a/ui/common/build.gradle
+++ b/ui/common/build.gradle
@@ -2,7 +2,8 @@ plugins {
alias(libs.plugins.android.library)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.cacheFixPlugin)
- id 'kotlin-kapt'
+ alias(libs.plugins.kotlin.compose.compiler)
+ alias(libs.plugins.kotlin.kapt)
}
android {
@@ -10,10 +11,6 @@ android {
compose true
}
- composeOptions {
- kotlinCompilerExtensionVersion = libs.versions.composecompiler.get()
- }
-
namespace 'org.kafka.common'
}
diff --git a/ui/common/src/debug/res/values/string.xml b/ui/common/src/debug/res/values/string.xml
index 6f61049b9..7abc06d3b 100755
--- a/ui/common/src/debug/res/values/string.xml
+++ b/ui/common/src/debug/res/values/string.xml
@@ -1,4 +1 @@
-
- vipulyaara@gmail.com
- Vipul0
-
+
diff --git a/ui/common/src/main/java/org/kafka/common/ObservableLoadingCounter.kt b/ui/common/src/main/java/org/kafka/common/ObservableLoadingCounter.kt
index 5dbd31008..e5d6fcdfc 100644
--- a/ui/common/src/main/java/org/kafka/common/ObservableLoadingCounter.kt
+++ b/ui/common/src/main/java/org/kafka/common/ObservableLoadingCounter.kt
@@ -43,7 +43,7 @@ suspend fun Flow.collectStatus(
InvokeSuccess -> counter.removeLoader()
is InvokeError -> {
Timber.i(status.throwable)
- uiMessageManager?.emitMessage(status.throwable.toUiMessage())
+ uiMessageManager.emitMessage(status.throwable.toUiMessage())
counter.removeLoader()
}
}
diff --git a/ui/common/src/main/java/org/kafka/common/UiMessage.kt b/ui/common/src/main/java/org/kafka/common/UiMessage.kt
index da566583a..09860e187 100644
--- a/ui/common/src/main/java/org/kafka/common/UiMessage.kt
+++ b/ui/common/src/main/java/org/kafka/common/UiMessage.kt
@@ -30,7 +30,7 @@ class UiMessageManager {
suspend fun emitMessage(message: UiMessage) {
mutex.withLock {
- _messages.value = _messages.value + message
+ _messages.value += message
}
}
diff --git a/ui/common/src/main/java/org/kafka/common/extensions/ComposeExtensions.kt b/ui/common/src/main/java/org/kafka/common/extensions/ComposeExtensions.kt
index d018d63eb..7dd71db33 100644
--- a/ui/common/src/main/java/org/kafka/common/extensions/ComposeExtensions.kt
+++ b/ui/common/src/main/java/org/kafka/common/extensions/ComposeExtensions.kt
@@ -61,7 +61,7 @@ fun AnimatedVisibilityFade(
}
@Composable
-fun collectEvent(
+fun CollectEvent(
flow: Flow,
lifecycle: Lifecycle = LocalLifecycleOwner.current.lifecycle,
minActiveState: Lifecycle.State = Lifecycle.State.STARTED,
diff --git a/ui/common/src/main/java/org/kafka/common/image/Icons.kt b/ui/common/src/main/java/org/kafka/common/image/Icons.kt
index 5d480956e..8aa666228 100644
--- a/ui/common/src/main/java/org/kafka/common/image/Icons.kt
+++ b/ui/common/src/main/java/org/kafka/common/image/Icons.kt
@@ -11,7 +11,6 @@ import compose.icons.FontAwesomeIcons
import compose.icons.TablerIcons
import compose.icons.feathericons.File
import compose.icons.feathericons.Search
-import compose.icons.feathericons.User
import compose.icons.fontawesomeicons.Solid
import compose.icons.fontawesomeicons.solid.FileContract
import compose.icons.fontawesomeicons.solid.Headphones
@@ -20,7 +19,6 @@ import compose.icons.tablericons.ArrowLeft
import compose.icons.tablericons.ArrowRight
import compose.icons.tablericons.Book
import compose.icons.tablericons.Bookmark
-import compose.icons.tablericons.ChevronUpLeft
import compose.icons.tablericons.CircleCheck
import compose.icons.tablericons.CircleX
import compose.icons.tablericons.Clock
@@ -38,6 +36,7 @@ import compose.icons.tablericons.Logout
import compose.icons.tablericons.Message
import compose.icons.tablericons.Microphone
import compose.icons.tablericons.Moon
+import compose.icons.tablericons.Photo
import compose.icons.tablericons.PlayerPause
import compose.icons.tablericons.PlayerPlay
import compose.icons.tablericons.Search
@@ -45,9 +44,7 @@ import compose.icons.tablericons.Share
import compose.icons.tablericons.Sun
import compose.icons.tablericons.Trash
import compose.icons.tablericons.Umbrella
-import compose.icons.tablericons.World
import compose.icons.tablericons.X
-import org.kafka.common.image.kafkaicons.Vinyl
object Icons {
val Home: ImageVector = TablerIcons.Home
@@ -60,11 +57,8 @@ object Icons {
val LibraryActive: ImageVector = TablerIcons.Book
val Profile: ImageVector = FontAwesomeIcons.Solid.UserCircle
val Files: ImageVector = FeatherIcons.File
- val ProfileActive: ImageVector = FeatherIcons.User
- val GoToTop: ImageVector = TablerIcons.ChevronUpLeft
val List: ImageVector = TablerIcons.LayoutList
val Grid: ImageVector = TablerIcons.LayoutGrid
- val Web: ImageVector = TablerIcons.World
val Share: ImageVector = TablerIcons.Share
val Heart = TablerIcons.Heart
val Download = TablerIcons.Download
@@ -88,7 +82,7 @@ object Icons {
val Eye = TablerIcons.Eye
val EyeOff = TablerIcons.EyeOff
val ArrowForward = TablerIcons.ArrowRight
- val Vinyl = KafkaIcons.Vinyl
+ val Photo = TablerIcons.Photo
val Moon = TablerIcons.Moon
val Sun = TablerIcons.Sun
val Logout = TablerIcons.Logout
diff --git a/ui/common/src/main/java/org/kafka/common/image/KafkaIcons.kt b/ui/common/src/main/java/org/kafka/common/image/KafkaIcons.kt
deleted file mode 100644
index 35e8f7daa..000000000
--- a/ui/common/src/main/java/org/kafka/common/image/KafkaIcons.kt
+++ /dev/null
@@ -1,18 +0,0 @@
-package org.kafka.common.image
-
-import androidx.compose.ui.graphics.vector.ImageVector
-import org.kafka.common.image.kafkaicons.Vinyl
-import kotlin.collections.List as ____KtList
-
-object KafkaIcons
-
-private var __KafkaIcons: ____KtList? = null
-
-val KafkaIcons.KafkaIcons: ____KtList
- get() {
- if (__KafkaIcons != null) {
- return __KafkaIcons!!
- }
- __KafkaIcons= listOf(Vinyl)
- return __KafkaIcons!!
- }
diff --git a/ui/common/src/main/java/org/kafka/common/image/kafkaicons/Vinyl.kt b/ui/common/src/main/java/org/kafka/common/image/kafkaicons/Vinyl.kt
deleted file mode 100644
index 857e50abc..000000000
--- a/ui/common/src/main/java/org/kafka/common/image/kafkaicons/Vinyl.kt
+++ /dev/null
@@ -1,57 +0,0 @@
-package org.kafka.common.image.kafkaicons
-
-import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.graphics.PathFillType
-import androidx.compose.ui.graphics.PathFillType.Companion.NonZero
-import androidx.compose.ui.graphics.SolidColor
-import androidx.compose.ui.graphics.StrokeCap
-import androidx.compose.ui.graphics.StrokeCap.Companion.Round
-import androidx.compose.ui.graphics.StrokeJoin
-import androidx.compose.ui.graphics.vector.ImageVector
-import androidx.compose.ui.graphics.vector.ImageVector.Builder
-import androidx.compose.ui.graphics.vector.path
-import androidx.compose.ui.unit.dp
-import org.kafka.common.image.KafkaIcons
-
-public val KafkaIcons.Vinyl: ImageVector
- get() {
- if (_vinyl != null) {
- return _vinyl!!
- }
- _vinyl = Builder(name = "Vinyl", defaultWidth = 24.0.dp, defaultHeight = 24.0.dp,
- viewportWidth = 24.0f, viewportHeight = 24.0f).apply {
- path(fill = SolidColor(Color(0x00000000)), stroke = SolidColor(Color(0xFF000000)),
- strokeLineWidth = 2.0f, strokeLineCap = Round, strokeLineJoin =
- StrokeJoin.Companion.Round, strokeLineMiter = 4.0f, pathFillType = NonZero) {
- moveTo(16.0f, 3.937f)
- arcToRelative(9.0f, 9.0f, 0.0f, true, false, 5.0f, 8.063f)
- }
- path(fill = SolidColor(Color(0x00000000)), stroke = SolidColor(Color(0xFF000000)),
- strokeLineWidth = 2.0f, strokeLineCap = Round, strokeLineJoin =
- StrokeJoin.Companion.Round, strokeLineMiter = 4.0f, pathFillType = NonZero) {
- moveTo(12.0f, 12.0f)
- moveToRelative(-1.0f, 0.0f)
- arcToRelative(1.0f, 1.0f, 0.0f, true, false, 2.0f, 0.0f)
- arcToRelative(1.0f, 1.0f, 0.0f, true, false, -2.0f, 0.0f)
- }
- path(fill = SolidColor(Color(0x00000000)), stroke = SolidColor(Color(0xFF000000)),
- strokeLineWidth = 2.0f, strokeLineCap = Round, strokeLineJoin =
- StrokeJoin.Companion.Round, strokeLineMiter = 4.0f, pathFillType = NonZero) {
- moveTo(20.0f, 4.0f)
- moveToRelative(-1.0f, 0.0f)
- arcToRelative(1.0f, 1.0f, 0.0f, true, false, 2.0f, 0.0f)
- arcToRelative(1.0f, 1.0f, 0.0f, true, false, -2.0f, 0.0f)
- }
- path(fill = SolidColor(Color(0x00000000)), stroke = SolidColor(Color(0xFF000000)),
- strokeLineWidth = 2.0f, strokeLineCap = Round, strokeLineJoin =
- StrokeJoin.Companion.Round, strokeLineMiter = 4.0f, pathFillType = NonZero) {
- moveTo(20.0f, 4.0f)
- lineToRelative(-3.5f, 10.0f)
- lineToRelative(-2.5f, 2.0f)
- }
- }
- .build()
- return _vinyl!!
- }
-
-private var _vinyl: ImageVector? = null
diff --git a/ui/common/src/main/java/org/kafka/common/snackbar/SnackbarManager.kt b/ui/common/src/main/java/org/kafka/common/snackbar/SnackbarManager.kt
index f8e1fd218..850fae533 100644
--- a/ui/common/src/main/java/org/kafka/common/snackbar/SnackbarManager.kt
+++ b/ui/common/src/main/java/org/kafka/common/snackbar/SnackbarManager.kt
@@ -41,7 +41,7 @@ class SnackbarManager @Inject constructor() {
fun addMessage(message: UiMessage) = addMessage(SnackbarMessage(message))
- fun addMessage(message: SnackbarMessage<*>) {
+ private fun addMessage(message: SnackbarMessage<*>) {
if (message.message !in shownMessages) {
messagesChannel.trySend(message)
shownMessages.add(message.message)
diff --git a/ui/common/src/main/java/org/kafka/common/widgets/IconButton.kt b/ui/common/src/main/java/org/kafka/common/widgets/IconButton.kt
index 294f22ca8..68378ce80 100644
--- a/ui/common/src/main/java/org/kafka/common/widgets/IconButton.kt
+++ b/ui/common/src/main/java/org/kafka/common/widgets/IconButton.kt
@@ -5,8 +5,8 @@ import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxScope
import androidx.compose.foundation.layout.size
-import androidx.compose.material.ripple.rememberRipple
import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.ripple
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
@@ -69,7 +69,7 @@ fun IconButton(
role = Role.Button,
onClickLabel = onClickLabel,
interactionSource = interactionSource,
- indication = rememberRipple(
+ indication = ripple(
bounded = false,
color = rippleColor,
radius = rippleRadius
diff --git a/ui/common/src/main/java/org/kafka/common/widgets/Scaffolds.kt b/ui/common/src/main/java/org/kafka/common/widgets/Scaffolds.kt
deleted file mode 100644
index 07cba4ec9..000000000
--- a/ui/common/src/main/java/org/kafka/common/widgets/Scaffolds.kt
+++ /dev/null
@@ -1,35 +0,0 @@
-package org.kafka.common.widgets
-
-import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.padding
-import androidx.compose.material3.ExperimentalMaterial3Api
-import androidx.compose.material3.MaterialTheme
-import androidx.compose.material3.Scaffold
-import androidx.compose.material3.contentColorFor
-import androidx.compose.runtime.Composable
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.graphics.Color
-
-@ExperimentalMaterial3Api
-@Composable
-fun DefaultScaffold(
- modifier: Modifier = Modifier,
- color: Color = MaterialTheme.colorScheme.background,
- topBar: @Composable () -> Unit = {},
- snackbarHost: @Composable () -> Unit = {},
- containerColor: Color = MaterialTheme.colorScheme.background,
- contentColor: Color = contentColorFor(containerColor),
- content: @Composable () -> Unit
-) {
- Scaffold(
- modifier = modifier,
- topBar = topBar,
- containerColor = color,
- contentColor = contentColor,
- snackbarHost = snackbarHost
- ) {
- Box(modifier = Modifier.padding(top = it.calculateTopPadding())) {
- content()
- }
- }
-}
diff --git a/ui/common/src/main/java/org/kafka/common/widgets/Toast.kt b/ui/common/src/main/java/org/kafka/common/widgets/Toast.kt
index 0d4e671dc..1147269ea 100644
--- a/ui/common/src/main/java/org/kafka/common/widgets/Toast.kt
+++ b/ui/common/src/main/java/org/kafka/common/widgets/Toast.kt
@@ -5,5 +5,5 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalContext
@Composable
-fun toast(message: String, duration: Int = Toast.LENGTH_SHORT) =
+fun Toast(message: String, duration: Int = Toast.LENGTH_SHORT) =
Toast.makeText(LocalContext.current, message, duration).show()
diff --git a/ui/common/src/main/res/drawable/ic_kafka_logo_round.xml b/ui/common/src/main/res/drawable/ic_kafka_logo_round.xml
deleted file mode 100644
index 8c28f200f..000000000
--- a/ui/common/src/main/res/drawable/ic_kafka_logo_round.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
diff --git a/ui/common/src/main/res/values-hi/string.xml b/ui/common/src/main/res/values-hi/string.xml
deleted file mode 100644
index d64847a7e..000000000
--- a/ui/common/src/main/res/values-hi/string.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
- प्रोफ़ायल
- ग़ज़ल
- नज़्म
- शेर
- अगला
- हिंदी
- परिणाम
-
- शेर संग्रह
- शायरी संग्रह
- गद्य संग्रह
- तस्वीर शायरी
- क्या आप जानते हैं
-
diff --git a/ui/common/src/main/res/values-ur/string.xml b/ui/common/src/main/res/values-ur/string.xml
deleted file mode 100644
index f25d7617c..000000000
--- a/ui/common/src/main/res/values-ur/string.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
- پروفایل
- غزل
- نزم
- شعر
- اگلا
- نتیجے
- اردو
-
- شعر کلکشن
- شاعری کلکشن
- نثری تحریریں
- تصویری شاعری
- کیا آپ جانتے ہیں
-
diff --git a/ui/common/src/main/res/values/string.xml b/ui/common/src/main/res/values/string.xml
index a06818ce1..41e8e874e 100755
--- a/ui/common/src/main/res/values/string.xml
+++ b/ui/common/src/main/res/values/string.xml
@@ -1,35 +1,6 @@
Rekhta
- vipulyaara@gmail.com
- Vipul0
-
- The server could not complete the request.
- Response from the server was not formatted correctly.
- Message: \"%s\"
- Cannot connect to the Internet.
- Share Via
-
- Sher Collection
- Shayri Collection
- Prose Collection
- Image Shayri
- Did you know
-
- light
- dark
-
- Player
Library
- Profile
- Next
- Previous
- Share
- Like
- Copy
- See Ghazal
-
- Unknown
- Most relevant content
diff --git a/ui/components/build.gradle b/ui/components/build.gradle
index 53a7e3293..e41a0acb2 100644
--- a/ui/components/build.gradle
+++ b/ui/components/build.gradle
@@ -2,8 +2,9 @@ plugins {
alias(libs.plugins.android.library)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.cacheFixPlugin)
- id 'kotlin-kapt'
- id 'kotlinx-serialization'
+ alias(libs.plugins.kotlin.compose.compiler)
+ alias(libs.plugins.kotlin.kapt)
+ alias(libs.plugins.kotlin.serialization)
}
android {
@@ -11,10 +12,6 @@ android {
compose true
}
- composeOptions {
- kotlinCompilerExtensionVersion libs.versions.composecompiler.get()
- }
-
namespace 'org.kafka.ui.components'
}
diff --git a/ui/components/src/main/java/org/kafka/ui/components/Labels.kt b/ui/components/src/main/java/org/kafka/ui/components/Labels.kt
index 9482119ee..9d8acadae 100644
--- a/ui/components/src/main/java/org/kafka/ui/components/Labels.kt
+++ b/ui/components/src/main/java/org/kafka/ui/components/Labels.kt
@@ -1,20 +1,39 @@
package org.kafka.ui.components
-import androidx.compose.foundation.layout.padding
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
-import androidx.compose.ui.unit.dp
+import androidx.compose.ui.text.AnnotatedString
+import androidx.compose.ui.text.style.TextOverflow
@Composable
-fun LabelMedium(text: String, modifier: Modifier = Modifier) {
+fun LabelMedium(
+ text: String,
+ modifier: Modifier = Modifier,
+ maxLines: Int = Int.MAX_VALUE,
+ overflow: TextOverflow = TextOverflow.Clip
+) {
+ LabelMedium(
+ text = AnnotatedString(text),
+ modifier = modifier,
+ maxLines = maxLines,
+ overflow = overflow
+ )
+}
+
+@Composable
+fun LabelMedium(
+ text: AnnotatedString,
+ modifier: Modifier = Modifier,
+ maxLines: Int = Int.MAX_VALUE,
+ overflow: TextOverflow = TextOverflow.Clip
+) {
Text(
text = text,
modifier = modifier,
style = MaterialTheme.typography.titleMedium,
+ maxLines = maxLines,
+ overflow = overflow
)
}
-
-@Composable
-fun Modifier.paddingLabelMedium() = this then Modifier.padding(12.dp)
diff --git a/ui/components/src/main/java/org/kafka/ui/components/MessageBox.kt b/ui/components/src/main/java/org/kafka/ui/components/MessageBox.kt
index 2aebd4651..b26f0d265 100644
--- a/ui/components/src/main/java/org/kafka/ui/components/MessageBox.kt
+++ b/ui/components/src/main/java/org/kafka/ui/components/MessageBox.kt
@@ -25,8 +25,8 @@ fun MessageBox(
modifier: Modifier = Modifier,
leadingIcon: ImageVector? = null,
trailingIcon: ImageVector? = null,
- onClick: () -> Unit = {},
- onIconClick: () -> Unit = onClick
+ onClick: (() -> Unit)? = null,
+ onIconClick: (() -> Unit)? = onClick
) {
Surface(
modifier = modifier,
@@ -40,7 +40,7 @@ fun MessageBox(
Row(
modifier = Modifier
.fillMaxWidth()
- .clickable { onClick() }
+ .then(if (onClick != null) Modifier.clickable { onClick() } else Modifier)
.padding(Dimens.Spacing16),
horizontalArrangement = Arrangement.spacedBy(Dimens.Spacing12),
verticalAlignment = Alignment.CenterVertically
@@ -65,7 +65,7 @@ fun MessageBox(
imageVector = trailingIcon,
modifier = Modifier.size(Dimens.Spacing20),
tint = MaterialTheme.colorScheme.primary,
- onClick = onIconClick
+ onClick = onIconClick ?: {}
)
}
}
diff --git a/ui/components/src/main/java/org/kafka/ui/components/file/DownloadStatusIcons.kt b/ui/components/src/main/java/org/kafka/ui/components/file/DownloadStatusIcons.kt
index d0f16db8b..00e44789e 100644
--- a/ui/components/src/main/java/org/kafka/ui/components/file/DownloadStatusIcons.kt
+++ b/ui/components/src/main/java/org/kafka/ui/components/file/DownloadStatusIcons.kt
@@ -58,7 +58,7 @@ fun DownloadStatusIcons(
modifier = Modifier.align(Alignment.Center),
strokeWidth = 2.dp,
strokeCap = StrokeCap.Round,
- progress = progress
+ progress = { progress }
)
}
diff --git a/ui/components/src/main/java/org/kafka/ui/components/item/CoverImage.kt b/ui/components/src/main/java/org/kafka/ui/components/item/CoverImage.kt
index 3cb3411a5..675dafb2b 100644
--- a/ui/components/src/main/java/org/kafka/ui/components/item/CoverImage.kt
+++ b/ui/components/src/main/java/org/kafka/ui/components/item/CoverImage.kt
@@ -35,12 +35,12 @@ fun CoverImage(
data: Any?,
modifier: Modifier = Modifier,
imageModifier: Modifier = Modifier,
- size: DpSize = DpSize.Unspecified,
+ size: DpSize = CoverDefaults.size,
containerColor: Color = MaterialTheme.colorScheme.surface,
contentColor: Color = MaterialTheme.colorScheme.primary.copy(alpha = 0.4f),
contentScale: ContentScale = ContentScale.FillHeight,
- shape: Shape = RoundedCornerShape(Dimens.Spacing04),
- placeholder: ImageVector = Icons.Vinyl,
+ shape: Shape = CoverDefaults.shape,
+ placeholder: ImageVector = CoverDefaults.placeholder,
iconPadding: Dp = 16.dp,
bitmapPlaceholder: Bitmap? = null,
contentDescription: String? = null,
@@ -119,3 +119,9 @@ private fun Image(
}
}
}
+
+object CoverDefaults {
+ val shape = RoundedCornerShape(Dimens.Spacing04)
+ val size = DpSize.Unspecified
+ val placeholder = Icons.Photo
+}
\ No newline at end of file
diff --git a/ui/components/src/main/java/org/kafka/ui/components/item/FeaturedItem.kt b/ui/components/src/main/java/org/kafka/ui/components/item/FeaturedItem.kt
index 135be754a..ec269423a 100644
--- a/ui/components/src/main/java/org/kafka/ui/components/item/FeaturedItem.kt
+++ b/ui/components/src/main/java/org/kafka/ui/components/item/FeaturedItem.kt
@@ -20,6 +20,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.text.style.TextOverflow
import com.kafka.data.entities.Item
import org.kafka.common.image.Icons
@@ -33,6 +34,7 @@ fun FeaturedItem(
modifier: Modifier = Modifier,
label: String? = null,
imageUrl: String? = null,
+ shape: Shape = CoverDefaults.shape,
onClick: () -> Unit = {}
) {
Surface(
@@ -45,6 +47,7 @@ fun FeaturedItem(
CoverImage(
data = imageUrl ?: item.coverImage,
placeholder = if (item.isAudio) Icons.Audio else Icons.Texts,
+ shape = shape,
modifier = Modifier
.fillMaxWidth()
.aspectRatio(1f)
diff --git a/ui/components/src/main/java/org/kafka/ui/components/placeholder/Placeholder.kt b/ui/components/src/main/java/org/kafka/ui/components/placeholder/Placeholder.kt
index 3b351d8d9..ac42b5de3 100644
--- a/ui/components/src/main/java/org/kafka/ui/components/placeholder/Placeholder.kt
+++ b/ui/components/src/main/java/org/kafka/ui/components/placeholder/Placeholder.kt
@@ -1,4 +1,3 @@
-@file:Suppress("DEPRECATION")
package org.kafka.ui.components.placeholder
import androidx.compose.material3.MaterialTheme
@@ -38,6 +37,7 @@ fun PlaceholderDefaults.fadeHighlightColor(
alpha: Float = 0.3f,
): Color = backgroundColor.copy(alpha = alpha)
+
/**
* Returns the value used as the the `highlightColor` parameter value of
* [PlaceholderHighlight.Companion.shimmer].
diff --git a/ui/components/src/main/java/org/kafka/ui/components/progress/InfiniteProgressBar.kt b/ui/components/src/main/java/org/kafka/ui/components/progress/InfiniteProgressBar.kt
index 0aa31190b..416d0110c 100644
--- a/ui/components/src/main/java/org/kafka/ui/components/progress/InfiniteProgressBar.kt
+++ b/ui/components/src/main/java/org/kafka/ui/components/progress/InfiniteProgressBar.kt
@@ -13,7 +13,6 @@ import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
diff --git a/ui/components/src/main/java/org/kafka/ui/components/snackbar/DismissableSnackbar.kt b/ui/components/src/main/java/org/kafka/ui/components/snackbar/DismissableSnackbar.kt
index b83981cf7..f953de43c 100644
--- a/ui/components/src/main/java/org/kafka/ui/components/snackbar/DismissableSnackbar.kt
+++ b/ui/components/src/main/java/org/kafka/ui/components/snackbar/DismissableSnackbar.kt
@@ -9,7 +9,6 @@ import androidx.compose.material3.Snackbar
import androidx.compose.material3.SnackbarData
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
-import androidx.compose.material3.SwipeToDismiss
import androidx.compose.material3.SwipeToDismissBox
import androidx.compose.material3.SwipeToDismissBoxValue
import androidx.compose.material3.rememberSwipeToDismissBoxState
@@ -31,7 +30,7 @@ fun DismissableSnackbarHost(hostState: SnackbarHostState, modifier: Modifier = M
}
/**
- * Wrapper around [Snackbar] to make it swipe-dismissable, using [SwipeToDismiss].
+ * Wrapper around [Snackbar] to make it swipe-dismissable.
*/
@Composable
fun SwipeDismissSnackbar(
diff --git a/ui/components/src/main/java/org/kafka/ui/components/snackbar/SnackbarMessagesHost.kt b/ui/components/src/main/java/org/kafka/ui/components/snackbar/SnackbarMessagesHost.kt
index e5b903abd..99a07f49b 100644
--- a/ui/components/src/main/java/org/kafka/ui/components/snackbar/SnackbarMessagesHost.kt
+++ b/ui/components/src/main/java/org/kafka/ui/components/snackbar/SnackbarMessagesHost.kt
@@ -7,7 +7,7 @@ import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.platform.LocalContext
import androidx.hilt.navigation.compose.hiltViewModel
import kotlinx.coroutines.launch
-import org.kafka.common.extensions.collectEvent
+import org.kafka.common.extensions.CollectEvent
import org.kafka.common.snackbar.asString
import org.kafka.common.widgets.LocalSnackbarHostState
@@ -23,7 +23,7 @@ internal fun SnackbarMessagesHost(
) {
val coroutine = rememberCoroutineScope()
val context = LocalContext.current
- collectEvent(viewModel.messages) {
+ CollectEvent(viewModel.messages) {
coroutine.launch {
val message = it.message.asString(context)
val actionLabel = it.action?.label?.asString(context)
diff --git a/ui/downloader/build.gradle b/ui/downloader/build.gradle
index 5b7119f6f..aa2b30a47 100644
--- a/ui/downloader/build.gradle
+++ b/ui/downloader/build.gradle
@@ -3,8 +3,9 @@ plugins {
alias(libs.plugins.kotlin.android)
alias(libs.plugins.cacheFixPlugin)
alias(libs.plugins.hilt)
- id 'kotlin-kapt'
- id 'kotlinx-serialization'
+ alias(libs.plugins.kotlin.compose.compiler)
+ alias(libs.plugins.kotlin.kapt)
+ alias(libs.plugins.kotlin.serialization)
}
android {
@@ -13,10 +14,6 @@ android {
buildFeatures {
compose = true
}
-
- composeOptions {
- kotlinCompilerExtensionVersion libs.versions.composecompiler.get()
- }
}
dependencies {
diff --git a/ui/downloader/src/main/java/tm/alashow/datmusic/ui/downloader/DownloaderHost.kt b/ui/downloader/src/main/java/tm/alashow/datmusic/ui/downloader/DownloaderHost.kt
index e53c32805..226409656 100644
--- a/ui/downloader/src/main/java/tm/alashow/datmusic/ui/downloader/DownloaderHost.kt
+++ b/ui/downloader/src/main/java/tm/alashow/datmusic/ui/downloader/DownloaderHost.kt
@@ -20,7 +20,7 @@ import androidx.compose.ui.window.DialogProperties
import androidx.hilt.navigation.compose.hiltViewModel
import com.kafka.ui.downloader.R
import kotlinx.coroutines.launch
-import org.kafka.common.extensions.collectEvent
+import org.kafka.common.extensions.CollectEvent
import timber.log.Timber
import tm.alashow.datmusic.downloader.Downloader
import tm.alashow.datmusic.downloader.DownloaderEvent
@@ -39,7 +39,7 @@ private fun DownloaderHost(
content: @Composable () -> Unit
) {
var downloadsLocationDialogShown by remember { mutableStateOf(false) }
- collectEvent(downloader.downloaderEvents) { event ->
+ CollectEvent(downloader.downloaderEvents) { event ->
when (event) {
DownloaderEvent.ChooseDownloadsLocation -> {
downloadsLocationDialogShown = true
diff --git a/ui/homepage/build.gradle b/ui/homepage/build.gradle
index fefd7bc65..5b7d602fc 100644
--- a/ui/homepage/build.gradle
+++ b/ui/homepage/build.gradle
@@ -2,8 +2,9 @@ plugins {
alias(libs.plugins.android.library)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.cacheFixPlugin)
+ alias(libs.plugins.kotlin.compose.compiler)
+ alias(libs.plugins.kotlin.kapt)
alias(libs.plugins.hilt)
- id 'kotlin-kapt'
}
android {
@@ -11,10 +12,6 @@ android {
compose true
}
- composeOptions {
- kotlinCompilerExtensionVersion libs.versions.composecompiler.get()
- }
-
namespace 'org.kafka.homepage'
}
diff --git a/ui/homepage/src/main/java/org/kafka/homepage/Homepage.kt b/ui/homepage/src/main/java/org/kafka/homepage/Homepage.kt
index 963d8489f..acb85b9c1 100644
--- a/ui/homepage/src/main/java/org/kafka/homepage/Homepage.kt
+++ b/ui/homepage/src/main/java/org/kafka/homepage/Homepage.kt
@@ -33,7 +33,6 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.kafka.data.entities.Homepage
import com.kafka.data.entities.HomepageCollection
import com.kafka.data.entities.Item
-import com.kafka.data.model.homepage.HomepageBanner
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toImmutableList
import org.kafka.common.extensions.AnimatedVisibilityFade
@@ -84,7 +83,6 @@ fun Homepage(viewModel: HomepageViewModel = hiltViewModel()) {
removeRecentItem = viewModel::removeRecentItem,
goToSearch = viewModel::openSearch,
goToSubject = viewModel::openSubject,
- onBannerClick = viewModel::onBannerClick,
openRecentItems = viewModel::openRecentItems,
goToCreator = viewModel::openCreator,
shareApp = { viewModel.shareApp(context) }
@@ -120,7 +118,6 @@ private fun HomepageFeedItems(
goToSearch: () -> Unit,
goToSubject: (String) -> Unit,
goToCreator: (String) -> Unit,
- onBannerClick: (HomepageBanner) -> Unit,
openRecentItems: () -> Unit,
shareApp: () -> Unit
) {
@@ -155,12 +152,6 @@ private fun HomepageFeedItems(
}
when (collection) {
- is HomepageCollection.Banners -> {
- item(key = "carousels", contentType = "carousels") {
- Carousels(carouselItems = collection.items, onBannerClick = onBannerClick)
- }
- }
-
is HomepageCollection.RecentItems -> {
item(key = "recent", contentType = "recent") {
ContinueReading(
@@ -174,7 +165,7 @@ private fun HomepageFeedItems(
}
is HomepageCollection.PersonRow -> {
- item(key = "authors", contentType = "person_row") {
+ item(contentType = "person_row") {
Authors(
titles = collection.items,
images = collection.images,
@@ -184,7 +175,17 @@ private fun HomepageFeedItems(
}
is HomepageCollection.FeaturedItem -> {
- featuredItems(collection, openItemDetail)
+ if (collection.items.size > 1) {
+ item {
+ Carousels(
+ carouselItems = collection.items,
+ images = collection.image,
+ onBannerClick = openItemDetail
+ )
+ }
+ } else {
+ featuredItems(collection = collection, openItemDetail = openItemDetail)
+ }
}
is HomepageCollection.Row -> {
@@ -240,7 +241,7 @@ private fun LazyListScope.featuredItems(
FeaturedItem(
item = item,
label = collection.label,
- imageUrl = collection.image,
+ imageUrl = collection.heroImage,
onClick = { openItemDetail(item.itemId) },
modifier = Modifier
.padding(horizontal = Dimens.Gutter)
diff --git a/ui/homepage/src/main/java/org/kafka/homepage/HomepageViewModel.kt b/ui/homepage/src/main/java/org/kafka/homepage/HomepageViewModel.kt
index ff8409b38..45e75a5d5 100644
--- a/ui/homepage/src/main/java/org/kafka/homepage/HomepageViewModel.kt
+++ b/ui/homepage/src/main/java/org/kafka/homepage/HomepageViewModel.kt
@@ -8,7 +8,6 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.kafka.data.entities.Item
import com.kafka.data.model.SearchFilter
-import com.kafka.data.model.homepage.HomepageBanner
import com.kafka.remote.config.RemoteConfig
import com.kafka.remote.config.isRecommendationRowEnabled
import com.kafka.remote.config.recommendationRowIndex
@@ -146,16 +145,4 @@ class HomepageViewModel @Inject constructor(
analytics.log { this.shareApp() }
context.shareText(context.getString(R.string.share_app_message, Config.PLAY_STORE_URL))
}
-
- fun onBannerClick(banner: HomepageBanner) {
- when (banner.action) {
- HomepageBanner.Action.Search -> navigator.navigate(
- Screen.Search.createRoute(RootScreen.Search, banner.keyword)
- )
-
- HomepageBanner.Action.ItemDetail -> navigator.navigate(
- Screen.ItemDetail.createRoute(navigator.currentRoot.value, banner.keyword.orEmpty())
- )
- }
- }
}
diff --git a/ui/homepage/src/main/java/org/kafka/homepage/components/Carousels.kt b/ui/homepage/src/main/java/org/kafka/homepage/components/Carousels.kt
index fa47453b9..d6824b5bb 100644
--- a/ui/homepage/src/main/java/org/kafka/homepage/components/Carousels.kt
+++ b/ui/homepage/src/main/java/org/kafka/homepage/components/Carousels.kt
@@ -1,76 +1,47 @@
package org.kafka.homepage.components
-import androidx.compose.foundation.clickable
-import androidx.compose.foundation.gestures.snapping.SnapLayoutInfoProvider
-import androidx.compose.foundation.gestures.snapping.rememberSnapFlingBehavior
import androidx.compose.foundation.layout.PaddingValues
-import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.layout.widthIn
import androidx.compose.foundation.lazy.LazyListState
-import androidx.compose.foundation.lazy.LazyRow
-import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material3.carousel.HorizontalMultiBrowseCarousel
+import androidx.compose.material3.carousel.rememberCarouselState
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.remember
-import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import androidx.compose.ui.layout.ContentScale
-import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
-import coil.compose.AsyncImage
-import coil.request.ImageRequest
-import com.kafka.data.model.homepage.HomepageBanner
+import com.kafka.data.entities.Item
import kotlinx.collections.immutable.ImmutableList
-import org.kafka.common.widgets.shadowMaterial
+import org.kafka.ui.components.item.FeaturedItem
import ui.common.theme.theme.Dimens
@Composable
internal fun Carousels(
- carouselItems: ImmutableList,
- onBannerClick: (HomepageBanner) -> Unit,
+ carouselItems: ImmutableList- ,
+ images: List,
+ onBannerClick: (String) -> Unit,
modifier: Modifier = Modifier,
lazyListState: LazyListState = rememberLazyListState()
) {
- LazyRow(
- modifier = modifier.padding(vertical = Dimens.Spacing04),
+ val state = rememberCarouselState { carouselItems.size }
+
+ HorizontalMultiBrowseCarousel(
+ state = state,
+ preferredItemWidth = 350.dp,
+ minSmallItemWidth = 56.dp,
+ maxSmallItemWidth = 72.dp,
+ modifier = modifier.padding(Dimens.Spacing02),
contentPadding = PaddingValues(horizontal = Dimens.Spacing12),
- verticalAlignment = Alignment.CenterVertically,
- state = lazyListState,
- flingBehavior = rememberSnapFlingBehavior(
- snapLayoutInfoProvider = remember(lazyListState) {
- SnapLayoutInfoProvider(lazyListState = lazyListState)
- },
- )
- ) {
- itemsIndexed(carouselItems) { _, item ->
- CarouselItem(item = item, onBannerClick = onBannerClick)
+ itemSpacing = Dimens.Spacing08
+ ) { index ->
+ carouselItems.getOrNull(index)?.let { item ->
+ FeaturedItem(
+ item = item,
+ label = item.title,
+ imageUrl = images.getOrNull(index),
+ onClick = { onBannerClick(item.itemId) },
+ modifier = Modifier.maskClip(shape = RoundedCornerShape(Dimens.Radius20))
+ )
}
}
}
-
-@Composable
-private fun CarouselItem(
- item: HomepageBanner,
- onBannerClick: (HomepageBanner) -> Unit,
- modifier: Modifier = Modifier
-) {
- AsyncImage(
- model = ImageRequest.Builder(LocalContext.current)
- .data(item.imageUrl)
- .crossfade(true)
- .build(),
- contentScale = ContentScale.Crop,
- contentDescription = null,
- modifier = modifier
- .widthIn(min = 324.dp)
- .height(184.dp)
- .padding(Dimens.Spacing02)
- .shadowMaterial(
- elevation = Dimens.Spacing12,
- shape = RoundedCornerShape(Dimens.Spacing08)
- )
- .clickable { onBannerClick(item) }
- )
-}
diff --git a/ui/homepage/src/main/res/values/strings.xml b/ui/homepage/src/main/res/values/strings.xml
index b1d3ed0c0..8e3e82e12 100644
--- a/ui/homepage/src/main/res/values/strings.xml
+++ b/ui/homepage/src/main/res/values/strings.xml
@@ -1,9 +1,6 @@
Reading list
- Cover image
- Favorites
- Editor\'s choice
Find many more on the search page
Logged out successfully
Profile
diff --git a/ui/item/build.gradle b/ui/item/build.gradle
index a625fd113..42d7349c0 100644
--- a/ui/item/build.gradle
+++ b/ui/item/build.gradle
@@ -2,7 +2,8 @@ plugins {
alias(libs.plugins.android.library)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.cacheFixPlugin)
- id 'kotlin-kapt'
+ alias(libs.plugins.kotlin.compose.compiler)
+ alias(libs.plugins.kotlin.kapt)
}
android {
@@ -10,10 +11,6 @@ android {
compose true
}
- composeOptions {
- kotlinCompilerExtensionVersion libs.versions.composecompiler.get()
- }
-
namespace 'org.kafka.item'
}
diff --git a/ui/item/src/main/java/org/kafka/item/detail/ItemDetail.kt b/ui/item/src/main/java/org/kafka/item/detail/ItemDetail.kt
index 2748a6a45..a4eb1e824 100644
--- a/ui/item/src/main/java/org/kafka/item/detail/ItemDetail.kt
+++ b/ui/item/src/main/java/org/kafka/item/detail/ItemDetail.kt
@@ -37,8 +37,11 @@ import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.text.SpanStyle
+import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
+import androidx.compose.ui.text.withStyle
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.Wallpapers
import androidx.hilt.navigation.compose.hiltViewModel
@@ -51,6 +54,7 @@ import org.kafka.base.debug
import org.kafka.common.animation.Delayed
import org.kafka.common.extensions.AnimatedVisibilityFade
import org.kafka.common.extensions.alignCenter
+import org.kafka.common.image.Icons
import org.kafka.common.simpleClickable
import org.kafka.common.test.testTagUi
import org.kafka.common.widgets.LoadImage
@@ -60,6 +64,7 @@ import org.kafka.item.fake.FakeItemData
import org.kafka.item.preloadImages
import org.kafka.navigation.LocalNavigator
import org.kafka.ui.components.LabelMedium
+import org.kafka.ui.components.MessageBox
import org.kafka.ui.components.ProvideScaffoldPadding
import org.kafka.ui.components.item.Item
import org.kafka.ui.components.item.RowItem
@@ -170,14 +175,21 @@ private fun ItemDetail(
onPrimaryAction = onPrimaryAction,
openFiles = openFiles,
isFavorite = state.isFavorite,
+ showDownloads = state.showDownloads,
toggleFavorite = toggleFavorite
)
}
+ if (state.itemDetail!!.isAccessRestricted) {
+ item(span = { GridItemSpan(GridItemSpan) }) {
+ AccessRestricted(state.itemDetail.isAudio) { onPrimaryAction(state.itemDetail.itemId) }
+ }
+ }
+
if (state.hasSubjects) {
item(span = { GridItemSpan(GridItemSpan) }) {
FlowRow(modifier = Modifier.padding(Dimens.Gutter)) {
- state.itemDetail!!.immutableSubjects.forEach {
+ state.itemDetail.immutableSubjects.forEach {
SubjectItem(
text = it,
modifier = Modifier.padding(Dimens.Spacing04),
@@ -200,9 +212,22 @@ private fun ItemDetail(
if (state.hasItemsByCreator) {
item(span = { GridItemSpan(GridItemSpan) }) {
+ val text = buildAnnotatedString {
+ append(stringResource(R.string.more_by))
+ append(" ")
+
+ withStyle(style = SpanStyle(color = MaterialTheme.colorScheme.primary)) {
+ append(state.itemDetail.creator)
+ }
+ }
+
LabelMedium(
- text = stringResource(R.string.more_by_author),
- modifier = Modifier.padding(Dimens.Gutter)
+ text = text,
+ modifier = Modifier
+ .simpleClickable { goToCreator(state.itemDetail.creator) }
+ .padding(Dimens.Gutter),
+ maxLines = 1,
+ overflow = TextOverflow.Ellipsis
)
}
@@ -221,7 +246,7 @@ private fun ItemDetail(
if (state.isLoading) {
item(span = { GridItemSpan(GridItemSpan) }) {
- Delayed(modifier = Modifier.animateItemPlacement()) {
+ Delayed(modifier = Modifier.animateItem()) {
InfiniteProgressBar()
}
}
@@ -318,10 +343,25 @@ private fun RelatedItems(
}
}
+@Composable
+private fun AccessRestricted(isAudio: Boolean, onClick: () -> Unit) {
+ val message = if (isAudio) {
+ stringResource(R.string.audio_access_restricted_message)
+ } else {
+ stringResource(R.string.text_access_restricted_message)
+ }
+
+ MessageBox(
+ text = message,
+ trailingIcon = if (isAudio) null else Icons.ArrowForward,
+ modifier = Modifier.padding(Dimens.Spacing24),
+ onClick = if (isAudio) null else onClick
+ )
+}
+
private const val GridItemSpan = 1
@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO, wallpaper = Wallpapers.GREEN_DOMINATED_EXAMPLE)
-@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO, wallpaper = Wallpapers.BLUE_DOMINATED_EXAMPLE)
@Composable
private fun ItemDetailPreview() {
AppTheme {
diff --git a/ui/item/src/main/java/org/kafka/item/detail/ItemDetailActions.kt b/ui/item/src/main/java/org/kafka/item/detail/ItemDetailActions.kt
index eca562712..966e1b698 100644
--- a/ui/item/src/main/java/org/kafka/item/detail/ItemDetailActions.kt
+++ b/ui/item/src/main/java/org/kafka/item/detail/ItemDetailActions.kt
@@ -38,6 +38,7 @@ fun ItemDetailActions(
onPrimaryAction: (String) -> Unit,
openFiles: (String) -> Unit,
isFavorite: Boolean,
+ showDownloads: Boolean = true,
toggleFavorite: () -> Unit
) {
Box(Modifier.fillMaxWidth()) {
@@ -56,15 +57,17 @@ fun ItemDetailActions(
) { toggleFavorite() }
}
- Box(modifier = Modifier.weight(0.2f)) {
- Icon(
- icon = Icons.Download,
- contentDescription = stringResource(R.string.cd_files),
- modifier = Modifier
- .align(Alignment.Center)
- .testTagUi("download_files"),
- onClicked = { openFiles(itemId) }
- )
+ if (showDownloads) {
+ Box(modifier = Modifier.weight(0.2f)) {
+ Icon(
+ icon = Icons.Download,
+ contentDescription = stringResource(R.string.cd_files),
+ modifier = Modifier
+ .align(Alignment.Center)
+ .testTagUi("download_files"),
+ onClicked = { openFiles(itemId) }
+ )
+ }
}
FloatingButton(
diff --git a/ui/item/src/main/java/org/kafka/item/detail/ItemDetailViewModel.kt b/ui/item/src/main/java/org/kafka/item/detail/ItemDetailViewModel.kt
index b6b80b611..33d9a5a29 100644
--- a/ui/item/src/main/java/org/kafka/item/detail/ItemDetailViewModel.kt
+++ b/ui/item/src/main/java/org/kafka/item/detail/ItemDetailViewModel.kt
@@ -163,7 +163,7 @@ class ItemDetailViewModel @Inject constructor(
addRecentItem(itemId)
if (state.value.downloadItem == null && remoteConfig.isOnlineReaderEnabled()) {
- analytics.log { readItem(itemId = itemId, type = "online") }
+ logOnlineReader(itemDetail = itemDetail)
navigator.navigate(OnlineReader.createRoute(currentRoot, itemDetail.itemId))
} else {
analytics.log { readItem(itemId = itemId, type = "offline") }
@@ -256,6 +256,16 @@ class ItemDetailViewModel @Inject constructor(
else -> null
}
+ private fun logOnlineReader(itemDetail: ItemDetail) {
+ analytics.log {
+ readItem(
+ itemId = itemDetail.itemId,
+ type = "online",
+ isRestrictedAccess = itemDetail.isAccessRestricted
+ )
+ }
+ }
+
private fun ctaText(itemDetail: ItemDetail, isResumableAudio: Boolean) =
if (itemDetail.isAudio) {
if (isResumableAudio) {
diff --git a/ui/item/src/main/java/org/kafka/item/detail/ItemDetailViewState.kt b/ui/item/src/main/java/org/kafka/item/detail/ItemDetailViewState.kt
index 11ffc4916..631fbb6e0 100644
--- a/ui/item/src/main/java/org/kafka/item/detail/ItemDetailViewState.kt
+++ b/ui/item/src/main/java/org/kafka/item/detail/ItemDetailViewState.kt
@@ -22,6 +22,9 @@ data class ItemDetailViewState(
val hasSubjects
get() = !itemDetail?.subject.isNullOrEmpty()
+ val showDownloads
+ get() = itemDetail?.isAccessRestricted == false || itemDetail?.isAudio == true
+
val isFullScreenLoading: Boolean
get() {
debug { "isFullScreenLoading $isLoading $itemDetail" }
diff --git a/ui/item/src/main/java/org/kafka/item/fake/FakeItemData.kt b/ui/item/src/main/java/org/kafka/item/fake/FakeItemData.kt
index 1a1cbb7e6..cdbd4e0aa 100644
--- a/ui/item/src/main/java/org/kafka/item/fake/FakeItemData.kt
+++ b/ui/item/src/main/java/org/kafka/item/fake/FakeItemData.kt
@@ -39,5 +39,6 @@ object FakeItemData {
coverImage = coverUrl,
description = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec euismod, nisl eget aliquam ultricies, nunc nisl aliquet nunc, vitae aliquam nisl nisl eu nunc. Donec euismod, nisl eget aliquam ultricies, nunc nisl aliquet nunc, vitae aliquam nisl nisl eu nunc.",
subject = listOf("Insect", "Existential", "Classics", "Fiction"),
+ isAccessRestricted = true
)
}
\ No newline at end of file
diff --git a/ui/item/src/main/java/org/kafka/item/files/File.kt b/ui/item/src/main/java/org/kafka/item/files/File.kt
index c2bf657c7..61eb44607 100644
--- a/ui/item/src/main/java/org/kafka/item/files/File.kt
+++ b/ui/item/src/main/java/org/kafka/item/files/File.kt
@@ -18,7 +18,6 @@ import androidx.compose.ui.res.stringResource
import com.kafka.data.entities.File
import com.kafka.data.feature.item.DownloadInfo
import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.launch
import org.kafka.common.image.Icons
import org.kafka.common.widgets.IconButton
import org.kafka.common.widgets.IconResource
diff --git a/ui/item/src/main/res/values/strings.xml b/ui/item/src/main/res/values/strings.xml
index b94fb9d15..2e2ca1b09 100644
--- a/ui/item/src/main/res/values/strings.xml
+++ b/ui/item/src/main/res/values/strings.xml
@@ -4,7 +4,6 @@
Play
Resume
Read
- More by author
"\n Check out %1$s on Kafka\n \n %2$s\n "
Back
Files
@@ -14,4 +13,7 @@
Download file
Favorite
You might also like
+ This item has restricted access. You can borrow it for free by logging into the website.
+ More by
+ This item is available with audio samples only
diff --git a/ui/library/build.gradle b/ui/library/build.gradle
index 14fa3482b..010e53c25 100644
--- a/ui/library/build.gradle
+++ b/ui/library/build.gradle
@@ -2,7 +2,8 @@ plugins {
alias(libs.plugins.android.library)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.cacheFixPlugin)
- id 'kotlin-kapt'
+ alias(libs.plugins.kotlin.compose.compiler)
+ alias(libs.plugins.kotlin.kapt)
}
android {
@@ -10,9 +11,6 @@ android {
compose true
}
- composeOptions {
- kotlinCompilerExtensionVersion libs.versions.composecompiler.get()
- }
namespace 'org.kafka.favorites'
}
diff --git a/ui/library/src/main/java/org/kafka/library/downloads/DownloadItem.kt b/ui/library/src/main/java/org/kafka/library/downloads/DownloadItem.kt
index 56843e21e..9eea005d6 100644
--- a/ui/library/src/main/java/org/kafka/library/downloads/DownloadItem.kt
+++ b/ui/library/src/main/java/org/kafka/library/downloads/DownloadItem.kt
@@ -91,7 +91,7 @@ private fun Progress(progress: Float) {
verticalAlignment = Alignment.CenterVertically
) {
LinearProgressIndicator(
- progress = progress,
+ progress = { progress },
modifier = Modifier
.height(Dimens.Spacing04)
.weight(1f)
diff --git a/ui/library/src/main/res/values/strings.xml b/ui/library/src/main/res/values/strings.xml
index 602f7cf49..15ef1ff9a 100644
--- a/ui/library/src/main/res/values/strings.xml
+++ b/ui/library/src/main/res/values/strings.xml
@@ -1,8 +1,6 @@
- No favorite items
Your favorite items will appear here
- No downloaded items
Your downloaded items will appear here
Downloads are saved on your device. They can be opened or shared freely using any files app.
Log in to sync your favorite items to your account.
diff --git a/ui/reader/build.gradle b/ui/reader/build.gradle
index 46f0f915d..cb273ada1 100644
--- a/ui/reader/build.gradle
+++ b/ui/reader/build.gradle
@@ -2,7 +2,8 @@ plugins {
alias(libs.plugins.android.library)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.cacheFixPlugin)
- id 'kotlin-kapt'
+ alias(libs.plugins.kotlin.compose.compiler)
+ alias(libs.plugins.kotlin.kapt)
alias(libs.plugins.hilt)
}
@@ -11,9 +12,6 @@ android {
compose true
}
- composeOptions {
- kotlinCompilerExtensionVersion libs.versions.composecompiler.get()
- }
namespace 'org.kafka.reader'
}
diff --git a/ui/reader/src/main/res/layout/view_reader.xml b/ui/reader/src/main/res/layout/view_reader.xml
deleted file mode 100644
index 668d0e76a..000000000
--- a/ui/reader/src/main/res/layout/view_reader.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
diff --git a/ui/reader/src/main/res/raw/pdfnet.res b/ui/reader/src/main/res/raw/pdfnet.res
deleted file mode 100644
index b2490c31c..000000000
Binary files a/ui/reader/src/main/res/raw/pdfnet.res and /dev/null differ
diff --git a/ui/search/build.gradle b/ui/search/build.gradle
index 381403e09..424f62a4e 100644
--- a/ui/search/build.gradle
+++ b/ui/search/build.gradle
@@ -2,7 +2,8 @@ plugins {
alias(libs.plugins.android.library)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.cacheFixPlugin)
- id 'kotlin-kapt'
+ alias(libs.plugins.kotlin.compose.compiler)
+ alias(libs.plugins.kotlin.kapt)
}
android {
@@ -10,10 +11,6 @@ android {
compose true
}
- composeOptions {
- kotlinCompilerExtensionVersion libs.versions.composecompiler.get()
- }
-
namespace 'org.kafka.search'
}
diff --git a/ui/search/src/main/java/com.kafka.search/RecentSearches.kt b/ui/search/src/main/java/com.kafka.search/RecentSearches.kt
index e4a97fda9..9b134a722 100644
--- a/ui/search/src/main/java/com.kafka.search/RecentSearches.kt
+++ b/ui/search/src/main/java/com.kafka.search/RecentSearches.kt
@@ -15,6 +15,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
+import com.kafka.data.entities.RecentSearch
import org.kafka.common.animation.Delayed
import org.kafka.common.image.Icons
import org.kafka.common.widgets.IconResource
@@ -24,8 +25,8 @@ import ui.common.theme.theme.Dimens
@Composable
fun RecentSearches(
- recentSearches: List,
- onSearchClicked: (String) -> Unit,
+ recentSearches: List,
+ onSearchClicked: (RecentSearch) -> Unit,
onRemoveSearch: (String) -> Unit,
modifier: Modifier = Modifier,
contentPadding: PaddingValues = PaddingValues(),
@@ -34,17 +35,17 @@ fun RecentSearches(
LazyColumn(contentPadding = contentPadding) {
item {
LabelMedium(
- stringResource(R.string.recent_searches),
- Modifier.padding(Dimens.Spacing16)
+ text = stringResource(R.string.recent_searches),
+ modifier = Modifier.padding(Dimens.Spacing16)
)
}
- items(recentSearches, key = { it }) {
+ items(recentSearches) { recentSearch ->
RecentSearchItem(
- searchTerm = it,
+ recentSearch = recentSearch,
onSearchClicked = onSearchClicked,
onRemoveSearch = onRemoveSearch,
- modifier = Modifier.animateItemPlacement()
+ modifier = Modifier.animateItem()
)
}
}
@@ -52,29 +53,29 @@ fun RecentSearches(
}
@Composable
- fun RecentSearchItem(
- searchTerm: String,
+fun RecentSearchItem(
+ recentSearch: RecentSearch,
modifier: Modifier = Modifier,
- onSearchClicked: (String) -> Unit,
+ onSearchClicked: (RecentSearch) -> Unit,
onRemoveSearch: (String) -> Unit
) {
SelectionContainer {
Row(
modifier = modifier
- .clickable(onClick = { onSearchClicked(searchTerm) })
+ .clickable(onClick = { onSearchClicked(recentSearch) })
.padding(horizontal = Dimens.Spacing24, vertical = Dimens.Spacing08),
verticalAlignment = Alignment.CenterVertically
) {
Text(
modifier = Modifier.weight(1f),
- text = searchTerm,
+ text = recentSearch.searchTerm,
style = MaterialTheme.typography.titleSmall,
color = MaterialTheme.colorScheme.onSurface
)
IconResource(
modifier = Modifier
- .clickable(onClick = { onRemoveSearch(searchTerm) })
+ .clickable(onClick = { onRemoveSearch(recentSearch.searchTerm) })
.padding(10.dp)
.size(Dimens.Spacing24),
imageVector = Icons.XCircle
diff --git a/ui/search/src/main/java/com.kafka.search/SearchFilter.kt b/ui/search/src/main/java/com.kafka.search/SearchFilter.kt
index 1bcb3e342..1184be27a 100644
--- a/ui/search/src/main/java/com.kafka.search/SearchFilter.kt
+++ b/ui/search/src/main/java/com.kafka.search/SearchFilter.kt
@@ -20,6 +20,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import com.kafka.data.model.MediaType
import com.kafka.data.model.SearchFilter
import org.kafka.common.image.Icons
import org.kafka.common.simpleClickable
@@ -35,7 +36,28 @@ internal fun SearchFilterChips(
items(SearchFilter.entries) { filter ->
val selected = selectedFilters.contains(filter)
FilterChip(
- filter = filter,
+ title = filter.name,
+ selected = selected,
+ modifier = Modifier
+ .padding(horizontal = Dimens.Spacing02)
+ .animateContentSize(),
+ onClick = { onFilterClicked(filter) },
+ )
+ }
+ }
+}
+
+@Composable
+internal fun MediaTypeChips(
+ selectedMediaTypes: List,
+ onFilterClicked: (MediaType) -> Unit,
+ modifier: Modifier = Modifier
+) {
+ Row(modifier = modifier) {
+ MediaType.entries.forEach { filter ->
+ val selected = selectedMediaTypes.contains(filter)
+ FilterChip(
+ title = filter.name,
selected = selected,
modifier = Modifier
.padding(horizontal = Dimens.Spacing02)
@@ -49,22 +71,22 @@ internal fun SearchFilterChips(
@Composable
private fun FilterChip(
modifier: Modifier,
- filter: SearchFilter,
+ title: String,
selected: Boolean,
onClick: () -> Unit
) {
val boarderColor by animateColorAsState(
- if (selected) colorScheme.secondaryContainer else colorScheme.surfaceVariant
+ if (selected) colorScheme.secondaryContainer else colorScheme.surfaceVariant, label = ""
)
val containerColor by animateColorAsState(
- if (selected) colorScheme.secondaryContainer else colorScheme.background
+ if (selected) colorScheme.secondaryContainer else colorScheme.background, label = ""
)
Surface(
modifier = modifier,
shape = RoundedCornerShape(Dimens.RadiusMedium),
color = containerColor,
- border = BorderStroke(Dimens.Spacing01, boarderColor)
+ border = BorderStroke(Dimens.Spacing01, boarderColor),
) {
Row(
modifier = Modifier
@@ -81,7 +103,7 @@ private fun FilterChip(
)
}
Text(
- text = filter.name,
+ text = title,
style = MaterialTheme.typography.labelMedium,
color = contentColorFor(containerColor)
)
diff --git a/ui/search/src/main/java/com.kafka.search/SearchScreen.kt b/ui/search/src/main/java/com.kafka.search/SearchScreen.kt
index 72b543da4..f03ac56f2 100644
--- a/ui/search/src/main/java/com.kafka.search/SearchScreen.kt
+++ b/ui/search/src/main/java/com.kafka.search/SearchScreen.kt
@@ -22,6 +22,7 @@ import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
+import com.kafka.data.model.MediaType
import com.kafka.data.model.SearchFilter
import org.kafka.common.extensions.AnimatedVisibilityFade
import org.kafka.common.extensions.rememberMutableState
@@ -46,11 +47,13 @@ fun SearchScreen() {
searchText = searchViewState.keyword,
setSearchText = { searchViewModel.setQuery(it) },
searchViewState = searchViewState,
- selectedFilters = searchViewState.filters,
+ selectedFilters = searchViewState.selectedFilters,
onFilterClicked = { searchViewModel.toggleFilter(it) },
- onSearchClicked = {
- searchViewModel.setQuery(it)
- searchViewModel.search(it, searchViewState.filters)
+ selectedMediaTypes = searchViewModel.selectedMediaTypes,
+ onMediaTypeClicked = { searchViewModel.toggleMediaType(it) },
+ onSearchClicked = { query, filters, mediaTypes ->
+ searchViewModel.setQuery(query)
+ searchViewModel.search(query, filters, mediaTypes)
},
removeRecentSearch = { searchViewModel.removeRecentSearch(it) },
openItemDetail = { searchViewModel.openItemDetail(it) }
@@ -66,7 +69,9 @@ private fun Search(
searchViewState: SearchViewState,
selectedFilters: List,
onFilterClicked: (SearchFilter) -> Unit,
- onSearchClicked: (String) -> Unit,
+ selectedMediaTypes: List,
+ onMediaTypeClicked: (MediaType) -> Unit,
+ onSearchClicked: (String, List, List) -> Unit,
removeRecentSearch: (String) -> Unit,
openItemDetail: (String) -> Unit
) {
@@ -90,7 +95,9 @@ private fun Search(
AnimatedVisibilityFade(searchText.isEmpty() && searchViewState.canShowRecentSearches) {
RecentSearches(
recentSearches = searchViewState.recentSearches!!,
- onSearchClicked = onSearchClicked,
+ onSearchClicked = { search ->
+ onSearchClicked(search.searchTerm, selectedFilters, selectedMediaTypes)
+ },
onRemoveSearch = removeRecentSearch,
contentPadding = paddingValues
)
@@ -102,7 +109,7 @@ private fun Search(
SearchWidget(
searchText = searchText,
setSearchText = setSearchText,
- onImeAction = onSearchClicked,
+ onImeAction = { query -> onSearchClicked(query, selectedFilters, selectedMediaTypes) },
modifier = Modifier.padding(top = topScaffoldPadding())
)
@@ -113,7 +120,16 @@ private fun Search(
.fillMaxWidth()
.padding(horizontal = Dimens.Spacing12, vertical = Dimens.Spacing08)
) {
- SearchFilterChips(selectedFilters = selectedFilters, onFilterClicked = onFilterClicked)
+ Column(verticalArrangement = Arrangement.spacedBy(Dimens.Spacing08)) {
+ SearchFilterChips(
+ selectedFilters = selectedFilters,
+ onFilterClicked = onFilterClicked
+ )
+ MediaTypeChips(
+ selectedMediaTypes = selectedMediaTypes,
+ onFilterClicked = onMediaTypeClicked
+ )
+ }
InfiniteProgressBarSmall(
show = searchViewState.isLoading,
modifier = Modifier.height(Dimens.Spacing24)
diff --git a/ui/search/src/main/java/com.kafka.search/SearchViewModel.kt b/ui/search/src/main/java/com.kafka.search/SearchViewModel.kt
index 61b6ff734..08f08f016 100644
--- a/ui/search/src/main/java/com.kafka.search/SearchViewModel.kt
+++ b/ui/search/src/main/java/com.kafka.search/SearchViewModel.kt
@@ -1,8 +1,10 @@
package com.kafka.search
+import androidx.compose.runtime.mutableStateListOf
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
+import com.kafka.data.model.MediaType
import com.kafka.data.model.SearchFilter
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.StateFlow
@@ -38,6 +40,10 @@ class SearchViewModel @Inject constructor(
private val savedStateHandle: SavedStateHandle,
) : ViewModel() {
private val keywordInitialValue = savedStateHandle.get(extraKeyword).orEmpty()
+ internal val selectedMediaTypes = mutableStateListOf()
+ .apply { addAll(MediaType.entries) }
+ private val selectedFilters
+ get() = savedStateHandle.get(extraFilters) ?: SearchFilter.allString()
val state: StateFlow = combine(
savedStateHandle.getStateFlow(extraKeyword, ""),
@@ -49,7 +55,7 @@ class SearchViewModel @Inject constructor(
) { keyword, filters, items, recentSearches, isLoading ->
SearchViewState(
keyword = keyword,
- filters = filters,
+ selectedFilters = filters,
items = items,
recentSearches = recentSearches,
isLoading = isLoading
@@ -57,22 +63,40 @@ class SearchViewModel @Inject constructor(
}.stateInDefault(scope = viewModelScope, initialValue = SearchViewState())
init {
- val filters = savedStateHandle.get(extraFilters) ?: SearchFilter.allString()
- search(keywordInitialValue, SearchFilter.from(filters))
+ search(
+ keyword = keywordInitialValue,
+ filters = SearchFilter.from(selectedFilters),
+ mediaTypes = selectedMediaTypes
+ )
observeRecentSearch(Unit)
}
- fun search(keyword: String, filters: List) {
- observeSearchItems(ObserveSearchItems.Params(keyword, filters))
+ fun search(
+ keyword: String = state.value.keyword,
+ filters: List = SearchFilter.from(selectedFilters),
+ mediaTypes: List = selectedMediaTypes
+ ) {
+ observeSearchItems(ObserveSearchItems.Params(keyword, filters, mediaTypes.toList()))
viewModelScope.launch {
- searchQueryItems(SearchQueryItems.Params(keyword, filters))
- .collectStatus(loadingState, snackbarManager)
+ searchQueryItems(
+ SearchQueryItems.Params(
+ keyword = keyword,
+ searchFilter = filters,
+ mediaTypes = mediaTypes.toList()
+ )
+ ).collectStatus(loadingState, snackbarManager)
}
if (keyword.isNotEmpty()) {
- analytics.log { searchQuery(keyword, filters.map { it.name }) }
+ analytics.log {
+ searchQuery(
+ keyword = keyword,
+ filters = filters.map { it.name },
+ mediaTypes = mediaTypes.map { it.value }
+ )
+ }
addRecentSearch(keyword)
}
}
@@ -83,19 +107,43 @@ class SearchViewModel @Inject constructor(
private fun addRecentSearch(keyword: String) {
viewModelScope.launch {
- addRecentSearch.invoke(keyword).collect()
+ val selectedFilters = state.value.selectedFilters
+ val params = AddRecentSearch.Params(
+ searchTerm = keyword,
+ filters = selectedFilters,
+ mediaTypes = selectedMediaTypes.toList()
+ )
+ addRecentSearch.invoke(params).collect()
}
}
fun toggleFilter(filter: SearchFilter) {
- val filters = state.value.filters.toMutableList()
- if (filters.contains(filter)) {
- filters.remove(filter)
+ val selectedFilters = state.value.selectedFilters.toMutableList()
+ if (selectedFilters.contains(filter)) {
+ selectedFilters.remove(filter)
} else {
- filters.add(filter)
+ selectedFilters.add(filter)
}
- savedStateHandle[extraFilters] = SearchFilter.toString(filters)
+ savedStateHandle[extraFilters] = SearchFilter.toString(selectedFilters)
+
+ if (state.value.keyword.isNotEmpty()) {
+ search(filters = selectedFilters)
+ }
+ }
+
+ fun toggleMediaType(mediaType: MediaType) {
+ if (selectedMediaTypes.contains(mediaType)) {
+ if (selectedMediaTypes.size > 1) {
+ selectedMediaTypes.remove(mediaType)
+ }
+ } else {
+ selectedMediaTypes.add(mediaType)
+ }
+
+ if (state.value.keyword.isNotEmpty()) {
+ search(mediaTypes = selectedMediaTypes)
+ }
}
fun removeRecentSearch(keyword: String) {
diff --git a/ui/search/src/main/java/com.kafka.search/SearchViewState.kt b/ui/search/src/main/java/com.kafka.search/SearchViewState.kt
index 2fdd7efe9..fe663ce4f 100644
--- a/ui/search/src/main/java/com.kafka.search/SearchViewState.kt
+++ b/ui/search/src/main/java/com.kafka.search/SearchViewState.kt
@@ -1,13 +1,14 @@
package com.kafka.search
import com.kafka.data.entities.Item
+import com.kafka.data.entities.RecentSearch
import com.kafka.data.model.SearchFilter
data class SearchViewState(
val keyword: String = "",
- val filters: List = SearchFilter.all(),
+ val selectedFilters: List = SearchFilter.all(),
val items: List
- ? = null,
- val recentSearches: List? = null,
+ val recentSearches: List? = null,
val isLoading: Boolean = false
) {
val canShowRecentSearches: Boolean
diff --git a/ui/search/src/main/res/values/strings.xml b/ui/search/src/main/res/values/strings.xml
index 23450ea19..9b3381cd2 100644
--- a/ui/search/src/main/res/values/strings.xml
+++ b/ui/search/src/main/res/values/strings.xml
@@ -2,6 +2,5 @@
Search...
Recent searches
- Try different spellings or write in different languages to get more accurate results.
Clear text
diff --git a/ui/theme/build.gradle b/ui/theme/build.gradle
index a70db5fdf..f9f609351 100644
--- a/ui/theme/build.gradle
+++ b/ui/theme/build.gradle
@@ -2,8 +2,9 @@ plugins {
alias(libs.plugins.android.library)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.cacheFixPlugin)
- id 'kotlin-kapt'
- id 'kotlinx-serialization'
+ alias(libs.plugins.kotlin.compose.compiler)
+ alias(libs.plugins.kotlin.kapt)
+ alias(libs.plugins.kotlin.serialization)
}
android {
@@ -11,9 +12,6 @@ android {
compose true
}
- composeOptions {
- kotlinCompilerExtensionVersion libs.versions.composecompiler.get()
- }
namespace 'ui.common.theme'
}
diff --git a/ui/theme/src/main/java/ui/common/theme/theme/Color.kt b/ui/theme/src/main/java/ui/common/theme/theme/Color.kt
index af27ef1ef..33226e9d2 100644
--- a/ui/theme/src/main/java/ui/common/theme/theme/Color.kt
+++ b/ui/theme/src/main/java/ui/common/theme/theme/Color.kt
@@ -71,36 +71,3 @@ internal val LightAppColors = lightColorScheme(
onError = white,
outline = darkGrey800
)
-
-val pastelColors = listOf(
- Color(0xFFD8A7B1), // Pastel pink
- Color(0xFFAACFCF), // Pastel blue
- Color(0xFFEFD9C1), // Pastel peach
- Color(0xFFB5EAD7), // Pastel green
- Color(0xFFDAC4F7), // Pastel lavender
- Color(0xFFF3D9E9), // Pastel rose
- Color(0xFFD5E5E7), // Pastel turquoise
- Color(0xFFE9EBF8), // Pastel lilac
- Color(0xFFEAD3CB), // Pastel coral
- Color(0xFFB9D1EA), // Pastel sky blue
- Color(0xFFE2B6C9), // Pastel mauve
- Color(0xFFC3E6CB), // Pastel mint
- Color(0xFFE5D9AA), // Pastel yellow
- Color(0xFFC1C6E4), // Pastel periwinkle
- Color(0xFFE3D0BA), // Pastel apricot
- Color(0xFFC1E0E3), // Pastel aqua
- Color(0xFFF4DFE6), // Pastel blush
- Color(0xFFD8ECC3), // Pastel pistachio
- Color(0xFFE1D0F5), // Pastel lavender pink
- Color(0xFFF5E1D1), // Pastel peach pink
- Color(0xFFC9E3E8), // Pastel sky
- Color(0xFFE0C9E3), // Pastel lavender
- Color(0xFFF2D7CB), // Pastel salmon
- Color(0xFFD5E8D4), // Pastel mint green
- Color(0xFFE8D2E2), // Pastel orchid
- Color(0xFFE3E8C9), // Pastel lime
- Color(0xFFF5E8D9), // Pastel peach
- Color(0xFFD9E5F5), // Pastel cornflower
- Color(0xFFF5E5D9), // Pastel beige
- Color(0xFFE5D9F5) // Pastel violet
-)
diff --git a/ui/theme/src/main/java/ui/common/theme/theme/Dimens.kt b/ui/theme/src/main/java/ui/common/theme/theme/Dimens.kt
index f839f8d3f..38957827d 100644
--- a/ui/theme/src/main/java/ui/common/theme/theme/Dimens.kt
+++ b/ui/theme/src/main/java/ui/common/theme/theme/Dimens.kt
@@ -33,6 +33,7 @@ object Dimens {
val Radius08 = Spacing08
val Radius12 = Spacing12
val Radius16 = Spacing16
+ val Radius20 = Spacing20
val Gutter = 16.dp
diff --git a/ui/theme/src/main/java/ui/common/theme/theme/EnglishTypography.kt b/ui/theme/src/main/java/ui/common/theme/theme/EnglishTypography.kt
deleted file mode 100644
index a30e88199..000000000
--- a/ui/theme/src/main/java/ui/common/theme/theme/EnglishTypography.kt
+++ /dev/null
@@ -1,124 +0,0 @@
-package ui.common.theme.theme
-
-import androidx.compose.material3.Typography
-import androidx.compose.ui.text.TextStyle
-import androidx.compose.ui.text.font.FontStyle
-import androidx.compose.ui.text.font.FontWeight
-import androidx.compose.ui.unit.sp
-
-internal object EnglishTypography {
-
- val BodyLarge = TextStyle(
- fontFamily = DefaultFont,
- fontWeight = FontWeight.Medium,
- fontSize = TypeScale.BodyLargeSize,
- lineHeight = TypeScale.BodyLargeLineHeight,
- letterSpacing = TypeScale.BodyLargeTracking,
- )
- val BodyMedium = TextStyle(
- fontFamily = DefaultFont,
- fontWeight = FontWeight.Normal,
- fontSize = 14.sp,
- lineHeight = TypeScale.BodyMediumLineHeight,
- )
- val BodySmall = TextStyle(
- fontFamily = DefaultFont,
- fontWeight = FontWeight.Normal,
- fontSize = 13.sp,
- lineHeight = 16.sp,
- )
- val DisplayLarge = TextStyle(
- fontFamily = DefaultFont,
- fontWeight = FontWeight.Light,
- fontSize = 16.sp,
- fontStyle = FontStyle.Italic,
- lineHeight = TypeScale.DisplayLargeLineHeight,
- letterSpacing = TypeScale.DisplayLargeTracking,
- )
- val ContentProse = TextStyle(
- fontFamily = ProseFont,
- fontWeight = FontWeight.Normal,
- fontSize = 16.sp,
- lineHeight = 22.0.sp,
- )
- val DisplaySmall = TextStyle(
- fontFamily = DefaultFont,
- fontWeight = FontWeight.SemiBold,
- fontSize = TypeScale.DisplaySmallSize,
- lineHeight = TypeScale.DisplaySmallLineHeight,
- letterSpacing = TypeScale.DisplaySmallTracking,
- )
- val HeadlineLarge = TextStyle(
- fontFamily = DefaultFont,
- fontWeight = FontWeight.Bold,
- fontSize = TypeScale.HeadlineLargeSize,
- lineHeight = TypeScale.HeadlineLargeLineHeight,
- letterSpacing = TypeScale.HeadlineLargeTracking,
- )
- val HeadlineMedium = TextStyle(
- fontFamily = DefaultFont,
- fontWeight = TypeScale.HeadlineMediumWeight,
- fontSize = TypeScale.HeadlineMediumSize,
- lineHeight = TypeScale.HeadlineMediumLineHeight,
- )
- val HeadlineSmall = TextStyle(
- fontFamily = Poppins,
- fontWeight = TypeScale.HeadlineSmallWeight,
- fontSize = 20.sp,
- letterSpacing = TypeScale.HeadlineSmallTracking,
- )
- val LabelLarge = TextStyle(
- fontFamily = DefaultFont,
- fontWeight = TypeScale.LabelLargeWeight,
- fontSize = TypeScale.LabelLargeSize,
- lineHeight = TypeScale.LabelLargeLineHeight,
- )
- val LabelMedium = TextStyle(
- fontFamily = DefaultFont,
- fontWeight = FontWeight.Medium,
- fontSize = TypeScale.LabelMediumSize,
- lineHeight = TypeScale.LabelMediumLineHeight,
- )
- val LabelSmall = TextStyle(
- fontFamily = DefaultFont,
- fontWeight = FontWeight.Bold,
- fontSize = TypeScale.LabelSmallSize,
- lineHeight = TypeScale.LabelSmallLineHeight,
- )
- val TitleLarge = TextStyle(
- fontFamily = DefaultFont,
- fontWeight = FontWeight.Medium,
- fontSize = 20.sp,
- lineHeight = TypeScale.TitleLargeLineHeight,
- )
- val TitleMedium = TextStyle(
- fontFamily = DefaultFont,
- fontWeight = TypeScale.TitleMediumWeight,
- fontSize = 16.sp,
- lineHeight = TypeScale.TitleMediumLineHeight,
- )
- val TitleSmall = TextStyle(
- fontFamily = DefaultFont,
- fontWeight = FontWeight.Medium,
- fontSize = 14.sp,
- lineHeight = TypeScale.TitleSmallLineHeight,
- )
-}
-
-val TypographyEnglish = Typography(
- displayLarge = EnglishTypography.DisplayLarge,
- displayMedium = EnglishTypography.ContentProse,
- displaySmall = EnglishTypography.DisplaySmall,
- headlineLarge = EnglishTypography.HeadlineLarge,
- headlineMedium = EnglishTypography.HeadlineMedium,
- headlineSmall = EnglishTypography.HeadlineSmall,
- titleLarge = EnglishTypography.TitleLarge,
- titleMedium = EnglishTypography.TitleMedium,
- titleSmall = EnglishTypography.TitleSmall,
- bodyLarge = EnglishTypography.BodyLarge,
- bodyMedium = EnglishTypography.BodyMedium,
- bodySmall = EnglishTypography.BodySmall,
- labelLarge = EnglishTypography.LabelLarge,
- labelMedium = EnglishTypography.LabelMedium,
- labelSmall = EnglishTypography.LabelSmall,
-)
diff --git a/ui/theme/src/main/java/ui/common/theme/theme/TypeScale.kt b/ui/theme/src/main/java/ui/common/theme/theme/TypeScale.kt
deleted file mode 100644
index 64ff3569e..000000000
--- a/ui/theme/src/main/java/ui/common/theme/theme/TypeScale.kt
+++ /dev/null
@@ -1,40 +0,0 @@
-package ui.common.theme.theme
-
-import androidx.compose.ui.text.font.FontWeight
-import androidx.compose.ui.unit.sp
-
-internal object TypeScale {
- val BodyLargeLineHeight = 24.0.sp
- val BodyLargeSize = 16.sp
- val BodyLargeTracking = 0.5.sp
- val BodyMediumLineHeight = 20.0.sp
- val DisplayLargeLineHeight = 48.0.sp
- val DisplayLargeTracking = (-0.2).sp
- val DisplaySmallLineHeight = 44.0.sp
- val DisplaySmallSize = 24.sp
- val DisplaySmallTracking = 0.0.sp
- val HeadlineLargeLineHeight = 40.0.sp
- val HeadlineLargeSize = 32.sp
- val HeadlineLargeTracking = 0.0.sp
- val HeadlineMediumLineHeight = 28.0.sp
- val HeadlineMediumSize = 24.sp
- val HeadlineMediumWeight = FontWeight.Bold
- val HeadlineSmallTracking = 0.0.sp
- val HeadlineSmallWeight = Typeface.WeightBold
- val LabelLargeLineHeight = 20.0.sp
- val LabelLargeSize = 14.sp
- val LabelLargeWeight = Typeface.WeightMedium
- val LabelMediumLineHeight = 16.0.sp
- val LabelMediumSize = 13.sp
- val LabelSmallLineHeight = 16.0.sp
- val LabelSmallSize = 11.sp
- val TitleLargeLineHeight = 28.0.sp
- val TitleMediumLineHeight = 24.0.sp
- val TitleMediumWeight = Typeface.WeightMedium
- val TitleSmallLineHeight = 16.0.sp
-}
-
-internal object Typeface {
- val WeightBold = FontWeight.Bold
- val WeightMedium = FontWeight.Medium
-}
diff --git a/ui/webview/build.gradle b/ui/webview/build.gradle
index 4451b8692..061ebc247 100644
--- a/ui/webview/build.gradle
+++ b/ui/webview/build.gradle
@@ -2,7 +2,8 @@ plugins {
alias(libs.plugins.android.library)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.cacheFixPlugin)
- id 'kotlin-kapt'
+ alias(libs.plugins.kotlin.compose.compiler)
+ alias(libs.plugins.kotlin.kapt)
}
android {
@@ -10,9 +11,6 @@ android {
compose true
}
- composeOptions {
- kotlinCompilerExtensionVersion libs.versions.composecompiler.get()
- }
namespace 'org.kafka.webview'
}