Skip to content

Commit

Permalink
refactor: Implement the subscribe button in Jetpack Compose
Browse files Browse the repository at this point in the history
  • Loading branch information
Isira-Seneviratne committed Jun 12, 2024
1 parent a7dbff0 commit 5c68bb9
Show file tree
Hide file tree
Showing 10 changed files with 222 additions and 53 deletions.
20 changes: 20 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ android {
versionName = "0.23.2"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
resValue("string", "app_name", "LibreTube")
vectorDrawables {
useSupportLibrary = true
}

ksp {
arg("room.schemaLocation", "$projectDir/schemas")
Expand Down Expand Up @@ -69,6 +72,9 @@ android {

packaging {
jniLibs.excludes.add("lib/armeabi-v7a/*_neon.so")
resources {
excludes += "/META-INF/{AL2.0,LGPL2.1}"
}
}

tasks.register("testClasses")
Expand All @@ -80,9 +86,13 @@ android {

buildFeatures {
buildConfig = true
compose = true
}

namespace = "com.github.libretube"
composeOptions {
kotlinCompilerExtensionVersion = "1.5.14"
}
}

dependencies {
Expand Down Expand Up @@ -126,12 +136,22 @@ dependencies {
implementation(libs.kotlinx.serialization)
implementation(libs.kotlinx.datetime)
implementation(libs.kotlinx.serialization.retrofit)
implementation(libs.androidx.activity.compose)
implementation(platform(libs.androidx.compose.bom))
implementation(libs.androidx.ui)
implementation(libs.androidx.ui.graphics)
implementation(libs.androidx.ui.tooling.preview)
implementation(libs.androidx.material3)
androidTestImplementation(platform(libs.androidx.compose.bom))
androidTestImplementation(libs.androidx.ui.test.junit4)

/* Cronet and Coil */
coreLibraryDesugaring(libs.desugaring)
implementation(libs.cronet.embedded)
implementation(libs.cronet.okhttp)
implementation(libs.coil)
debugImplementation(libs.androidx.ui.tooling)
debugImplementation(libs.androidx.ui.test.manifest)

/* Room */
ksp(libs.room.compiler)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -552,7 +552,7 @@ class MainActivity : BaseActivity() {
}
}

override fun onNewIntent(intent: Intent?) {
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
this.intent = intent
loadIntentData()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package com.github.libretube.ui.compose

import androidx.compose.foundation.layout.Row
import androidx.compose.material3.Button
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import com.github.libretube.R
import com.github.libretube.api.SubscriptionHelper
import com.github.libretube.constants.PreferenceKeys
import com.github.libretube.helpers.PreferenceHelper
import kotlinx.coroutines.launch

@Composable
fun SubscribeButton(channelId: String) {

Check failure on line 25 in app/src/main/java/com/github/libretube/ui/compose/SubscribeButton.kt

View workflow job for this annotation

GitHub Actions / Check Code Quality

[ktlint] reported by reviewdog 🐶 Function name should start with a lowercase letter (except factory methods) and use camel case Raw Output: app/src/main/java/com/github/libretube/ui/compose/SubscribeButton.kt:25:5: error: Function name should start with a lowercase letter (except factory methods) and use camel case (standard:function-naming)
val scope = rememberCoroutineScope()
var isSubscribed by rememberSaveable { mutableStateOf(false) }
var shouldNotify by rememberSaveable { mutableStateOf(false) }

LaunchedEffect(true) {
isSubscribed = SubscriptionHelper.isSubscribed(channelId) ?: false
shouldNotify = PreferenceHelper.isChannelNotificationIgnorable(channelId)
}

Row {
if (isSubscribed && PreferenceHelper.getBoolean(PreferenceKeys.NOTIFICATION_ENABLED, true)) {
IconButton(onClick = {
shouldNotify = !shouldNotify
PreferenceHelper.toggleIgnorableNotificationChannel(channelId)
}) {
val icon = if (shouldNotify) R.drawable.ic_bell else R.drawable.ic_notification
Icon(painter = painterResource(icon), contentDescription = null)
}
}
Button(onClick = {
scope.launch {
if (isSubscribed) {
SubscriptionHelper.unsubscribe(channelId)
} else {
SubscriptionHelper.subscribe(channelId)
}
isSubscribed = !isSubscribed
}
}) {
Text(stringResource(if (isSubscribed) R.string.unsubscribe else R.string.subscribe))
}
}
}

@Preview
@Composable
fun PreviewSubscribeButton() {

Check failure on line 62 in app/src/main/java/com/github/libretube/ui/compose/SubscribeButton.kt

View workflow job for this annotation

GitHub Actions / Check Code Quality

[ktlint] reported by reviewdog 🐶 Function name should start with a lowercase letter (except factory methods) and use camel case Raw Output: app/src/main/java/com/github/libretube/ui/compose/SubscribeButton.kt:62:5: error: Function name should start with a lowercase letter (except factory methods) and use camel case (standard:function-naming)
SubscribeButton("@CNN")
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ import com.github.libretube.helpers.NavigationHelper
import com.github.libretube.obj.ShareData
import com.github.libretube.ui.adapters.VideosAdapter
import com.github.libretube.ui.base.DynamicLayoutManagerFragment
import com.github.libretube.ui.compose.SubscribeButton
import com.github.libretube.ui.dialogs.ShareDialog
import com.github.libretube.ui.extensions.setupSubscriptionButton
import com.github.libretube.ui.sheets.AddChannelToGroupSheet
import com.github.libretube.util.deArrow
import com.google.android.material.tabs.TabLayoutMediator
Expand Down Expand Up @@ -156,11 +156,9 @@ class ChannelFragment : DynamicLayoutManagerFragment() {

val channelId = channelId ?: return@launch

binding.channelSubscribe.setupSubscriptionButton(
channelId,
channelName,
binding.notificationBell
)
binding.subscriptionButton.setContent {
SubscribeButton(channelId)
}

binding.channelShare.setOnClickListener {
val bundle = bundleOf(
Expand Down
11 changes: 11 additions & 0 deletions app/src/main/java/com/github/libretube/ui/theme/Color.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.github.libretube.ui.theme

import androidx.compose.ui.graphics.Color

val Purple80 = Color(0xFFD0BCFF)
val PurpleGrey80 = Color(0xFFCCC2DC)
val Pink80 = Color(0xFFEFB8C8)

val Purple40 = Color(0xFF6650a4)
val PurpleGrey40 = Color(0xFF625b71)
val Pink40 = Color(0xFF7D5260)

Check failure on line 11 in app/src/main/java/com/github/libretube/ui/theme/Color.kt

View workflow job for this annotation

GitHub Actions / Check Code Quality

[ktlint] reported by reviewdog 🐶 File must end with a newline (\n) Raw Output: app/src/main/java/com/github/libretube/ui/theme/Color.kt:11:30: error: File must end with a newline (\n) (standard:final-newline)
58 changes: 58 additions & 0 deletions app/src/main/java/com/github/libretube/ui/theme/Theme.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package com.github.libretube.ui.theme

import android.app.Activity

Check failure on line 3 in app/src/main/java/com/github/libretube/ui/theme/Theme.kt

View workflow job for this annotation

GitHub Actions / Check Code Quality

[ktlint] reported by reviewdog 🐶 Unused import Raw Output: app/src/main/java/com/github/libretube/ui/theme/Theme.kt:3:1: error: Unused import (standard:no-unused-imports)
import android.os.Build
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.darkColorScheme
import androidx.compose.material3.dynamicDarkColorScheme
import androidx.compose.material3.dynamicLightColorScheme
import androidx.compose.material3.lightColorScheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalContext

private val DarkColorScheme = darkColorScheme(

Check failure on line 14 in app/src/main/java/com/github/libretube/ui/theme/Theme.kt

View workflow job for this annotation

GitHub Actions / Check Code Quality

[ktlint] reported by reviewdog 🐶 A multiline expression should start on a new line Raw Output: app/src/main/java/com/github/libretube/ui/theme/Theme.kt:14:31: error: A multiline expression should start on a new line (standard:multiline-expression-wrapping)
primary = Purple80,
secondary = PurpleGrey80,
tertiary = Pink80

Check failure on line 17 in app/src/main/java/com/github/libretube/ui/theme/Theme.kt

View workflow job for this annotation

GitHub Actions / Check Code Quality

[ktlint] reported by reviewdog 🐶 Missing trailing comma before ")" Raw Output: app/src/main/java/com/github/libretube/ui/theme/Theme.kt:17:22: error: Missing trailing comma before ")" (standard:trailing-comma-on-call-site)
)

private val LightColorScheme = lightColorScheme(

Check failure on line 20 in app/src/main/java/com/github/libretube/ui/theme/Theme.kt

View workflow job for this annotation

GitHub Actions / Check Code Quality

[ktlint] reported by reviewdog 🐶 A multiline expression should start on a new line Raw Output: app/src/main/java/com/github/libretube/ui/theme/Theme.kt:20:32: error: A multiline expression should start on a new line (standard:multiline-expression-wrapping)
primary = Purple40,
secondary = PurpleGrey40,
tertiary = Pink40

Check failure on line 23 in app/src/main/java/com/github/libretube/ui/theme/Theme.kt

View workflow job for this annotation

GitHub Actions / Check Code Quality

[ktlint] reported by reviewdog 🐶 Missing trailing comma before ")" Raw Output: app/src/main/java/com/github/libretube/ui/theme/Theme.kt:23:22: error: Missing trailing comma before ")" (standard:trailing-comma-on-call-site)

Check failure on line 24 in app/src/main/java/com/github/libretube/ui/theme/Theme.kt

View workflow job for this annotation

GitHub Actions / Check Code Quality

[ktlint] reported by reviewdog 🐶 Unexpected blank line(s) in value argument list Raw Output: app/src/main/java/com/github/libretube/ui/theme/Theme.kt:24:1: error: Unexpected blank line(s) in value argument list (standard:no-blank-line-in-list)
/* Other default colors to override
background = Color(0xFFFFFBFE),
surface = Color(0xFFFFFBFE),
onPrimary = Color.White,
onSecondary = Color.White,
onTertiary = Color.White,
onBackground = Color(0xFF1C1B1F),
onSurface = Color(0xFF1C1B1F),
*/
)

@Composable
fun LibreTubeTheme(
darkTheme: Boolean = isSystemInDarkTheme(),
// Dynamic color is available on Android 12+
dynamicColor: Boolean = true,
content: @Composable () -> Unit
) {
val colorScheme = when {
dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
val context = LocalContext.current
if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
}

darkTheme -> DarkColorScheme
else -> LightColorScheme
}

MaterialTheme(
colorScheme = colorScheme,
typography = Typography,
content = content
)
}
34 changes: 34 additions & 0 deletions app/src/main/java/com/github/libretube/ui/theme/Type.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.github.libretube.ui.theme

import androidx.compose.material3.Typography
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.sp

// Set of Material typography styles to start with
val Typography = Typography(
bodyLarge = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.Normal,
fontSize = 16.sp,
lineHeight = 24.sp,
letterSpacing = 0.5.sp
)
/* Other default text styles to override
titleLarge = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.Normal,
fontSize = 22.sp,
lineHeight = 28.sp,
letterSpacing = 0.sp
),
labelSmall = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.Medium,
fontSize = 11.sp,
lineHeight = 16.sp,
letterSpacing = 0.5.sp
)
*/
)
61 changes: 16 additions & 45 deletions app/src/main/res/layout/fragment_channel.xml
Original file line number Diff line number Diff line change
Expand Up @@ -82,57 +82,28 @@
</LinearLayout>

<com.google.android.material.button.MaterialButton
android:id="@+id/channel_subscribe"
style="@style/PlayerActionsButton"
android:id="@+id/channel_share"
style="@style/ElevatedIconButton"
android:tooltipText="@string/share"
app:icon="@drawable/ic_share"
tools:targetApi="m" />

<androidx.compose.ui.platform.ComposeView
android:id="@+id/subscription_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:stateListAnimator="@null"
android:text="@string/subscribe"
android:layout_height="wrap_content" />

<com.google.android.material.button.MaterialButton
android:id="@+id/add_to_group"
style="@style/PlayerActionsButton"
android:text="@string/add_to_group"
android:textSize="12sp"
android:tooltipText="@string/add_to_group"
app:icon="@drawable/ic_add"
tools:targetApi="m" />

</LinearLayout>

<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="none">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">

<com.google.android.material.button.MaterialButton
android:id="@+id/channel_share"
style="@style/PlayerActionsButton"
android:text="@string/share"
android:textSize="12sp"
android:tooltipText="@string/share"
app:icon="@drawable/ic_share"
tools:targetApi="m" />

<com.google.android.material.button.MaterialButton
android:id="@+id/notification_bell"
style="@style/PlayerActionsButton"
android:text="@string/notifications"
android:textSize="12sp"
android:tooltipText="@string/notifications"
app:icon="@drawable/ic_notification"
tools:targetApi="m" />

<com.google.android.material.button.MaterialButton
android:id="@+id/add_to_group"
style="@style/PlayerActionsButton"
android:text="@string/add_to_group"
android:textSize="12sp"
android:tooltipText="@string/add_to_group"
app:icon="@drawable/ic_add"
tools:targetApi="m" />

</LinearLayout>

</HorizontalScrollView>

<com.github.libretube.ui.views.ExpandableTextView
android:id="@+id/channel_description"
android:layout_width="match_parent"
Expand Down
4 changes: 3 additions & 1 deletion app/src/main/res/values/themes.xml
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,9 @@

<item name="android:windowFrame">@null</item>
<item name="android:windowTitleStyle">@style/RtlOverlay.DialogWindowTitle.AppCompat</item>
<item name="android:windowTitleBackgroundStyle">@style/Base.DialogWindowTitleBackground.AppCompat</item>
<item name="android:windowTitleBackgroundStyle">
@style/Base.DialogWindowTitleBackground.AppCompat
</item>
<item name="android:windowBackground">@drawable/abc_dialog_material_background</item>
<item name="android:windowIsFloating">true</item>
<item name="android:backgroundDimEnabled">true</item>
Expand Down
11 changes: 11 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ profileinstaller = "1.3.1"
paging = "3.3.0"
collection = "1.4.0"
swiperefreshlayout = "1.1.0"
activityCompose = "1.9.0"
composeBom = "2024.05.00"

[libraries]
androidx-activity = { group = "androidx.activity", name = "activity-ktx", version.ref = "activity" }
Expand Down Expand Up @@ -81,6 +83,15 @@ androidx-profileinstaller = { group = "androidx.profileinstaller", name = "profi
androidx-paging = { group = "androidx.paging", name = "paging-runtime-ktx", version.ref = "paging" }
androidx-collection = { group = "androidx.collection", name = "collection", version.ref = "collection" }
androidx-swiperefreshlayout = { group = "androidx.swiperefreshlayout", name = "swiperefreshlayout", version.ref = "swiperefreshlayout" }
androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" }
androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" }
androidx-ui = { group = "androidx.compose.ui", name = "ui" }
androidx-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" }
androidx-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" }
androidx-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" }
androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
androidx-material3 = { group = "androidx.compose.material3", name = "material3" }

[plugins]
androidTest = { id = "com.android.test", version.ref = "gradle" }
Expand Down

0 comments on commit 5c68bb9

Please sign in to comment.