mirror of
https://github.com/kavishdevar/librepods.git
synced 2026-02-10 19:52:24 +00:00
move to haze for blurring
This commit is contained in:
@@ -14,7 +14,7 @@ android {
|
|||||||
minSdk = 28
|
minSdk = 28
|
||||||
targetSdk = 35
|
targetSdk = 35
|
||||||
versionCode = 1
|
versionCode = 1
|
||||||
versionName = "0.0.2-beta"
|
versionName = "0.0.2-beta3"
|
||||||
|
|
||||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||||
}
|
}
|
||||||
@@ -54,6 +54,8 @@ dependencies {
|
|||||||
implementation(libs.annotations)
|
implementation(libs.annotations)
|
||||||
implementation(libs.androidx.navigation.compose)
|
implementation(libs.androidx.navigation.compose)
|
||||||
implementation(libs.androidx.constraintlayout)
|
implementation(libs.androidx.constraintlayout)
|
||||||
|
implementation(libs.haze)
|
||||||
|
implementation(libs.haze.materials)
|
||||||
testImplementation(libs.junit)
|
testImplementation(libs.junit)
|
||||||
androidTestImplementation(libs.androidx.junit)
|
androidTestImplementation(libs.androidx.junit)
|
||||||
androidTestImplementation(libs.androidx.espresso.core)
|
androidTestImplementation(libs.androidx.espresso.core)
|
||||||
@@ -61,5 +63,4 @@ dependencies {
|
|||||||
androidTestImplementation(libs.androidx.ui.test.junit4)
|
androidTestImplementation(libs.androidx.ui.test.junit4)
|
||||||
debugImplementation(libs.androidx.ui.tooling)
|
debugImplementation(libs.androidx.ui.tooling)
|
||||||
debugImplementation(libs.androidx.ui.test.manifest)
|
debugImplementation(libs.androidx.ui.test.manifest)
|
||||||
implementation("com.github.prime-zs.toolkit:core-ktx:2.1.0")
|
|
||||||
}
|
}
|
||||||
@@ -12,7 +12,6 @@ import android.content.IntentFilter
|
|||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.ParcelUuid
|
import android.os.ParcelUuid
|
||||||
import android.util.Log
|
|
||||||
import androidx.annotation.RequiresApi
|
import androidx.annotation.RequiresApi
|
||||||
import androidx.compose.animation.core.animateDpAsState
|
import androidx.compose.animation.core.animateDpAsState
|
||||||
import androidx.compose.foundation.Image
|
import androidx.compose.foundation.Image
|
||||||
@@ -87,9 +86,11 @@ import androidx.compose.ui.tooling.preview.Preview
|
|||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
import com.primex.core.ExperimentalToolkitApi
|
import dev.chrisbanes.haze.HazeState
|
||||||
import com.primex.core.blur.newBackgroundBlur
|
import dev.chrisbanes.haze.haze
|
||||||
import me.kavishdevar.aln.AirPodsService
|
import dev.chrisbanes.haze.hazeChild
|
||||||
|
import dev.chrisbanes.haze.materials.CupertinoMaterials
|
||||||
|
import dev.chrisbanes.haze.materials.ExperimentalHazeMaterialsApi
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
|
|
||||||
@@ -500,14 +501,16 @@ fun AccessibilitySettings(service: AirPodsService, sharedPreferences: SharedPref
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class, ExperimentalToolkitApi::class)
|
@OptIn(ExperimentalMaterial3Api::class, ExperimentalHazeMaterialsApi::class)
|
||||||
@SuppressLint("MissingPermission", "NewApi")
|
@SuppressLint("MissingPermission", "NewApi")
|
||||||
@Composable
|
@Composable
|
||||||
fun AirPodsSettingsScreen(device: BluetoothDevice?, service: AirPodsService,
|
fun AirPodsSettingsScreen(dev: BluetoothDevice?, service: AirPodsService,
|
||||||
navController: NavController, isConnected: Boolean) {
|
navController: NavController, isConnected: Boolean) {
|
||||||
val sharedPreferences = LocalContext.current.getSharedPreferences("settings", MODE_PRIVATE)
|
val sharedPreferences = LocalContext.current.getSharedPreferences("settings", MODE_PRIVATE)
|
||||||
|
var device by remember { mutableStateOf(dev) }
|
||||||
var deviceName by remember { mutableStateOf(TextFieldValue(sharedPreferences.getString("name", device?.name ?: "") ?: "")) }
|
var deviceName by remember { mutableStateOf(TextFieldValue(sharedPreferences.getString("name", device?.name ?: "") ?: "")) }
|
||||||
val verticalScrollState = rememberScrollState()
|
val verticalScrollState = rememberScrollState()
|
||||||
|
val hazeState = remember { HazeState() }
|
||||||
@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
|
@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
|
||||||
Scaffold(
|
Scaffold(
|
||||||
containerColor = if (MaterialTheme.colorScheme.surface.luminance() < 0.5) Color(
|
containerColor = if (MaterialTheme.colorScheme.surface.luminance() < 0.5) Color(
|
||||||
@@ -517,73 +520,93 @@ fun AirPodsSettingsScreen(device: BluetoothDevice?, service: AirPodsService,
|
|||||||
),
|
),
|
||||||
topBar = {
|
topBar = {
|
||||||
val darkMode = MaterialTheme.colorScheme.surface.luminance() < 0.5
|
val darkMode = MaterialTheme.colorScheme.surface.luminance() < 0.5
|
||||||
CenterAlignedTopAppBar(
|
val mdensity = remember { mutableFloatStateOf(1f) }
|
||||||
title = {
|
CenterAlignedTopAppBar(
|
||||||
Text(
|
title = {
|
||||||
text = if (device != null) LocalContext.current.getSharedPreferences("settings", MODE_PRIVATE).getString("name", device.name).toString() else "",
|
Text(
|
||||||
color = if (MaterialTheme.colorScheme.surface.luminance() < 0.5) Color.White else Color.Black,
|
text = deviceName.text
|
||||||
)
|
)
|
||||||
},
|
|
||||||
modifier = Modifier
|
|
||||||
.newBackgroundBlur(
|
|
||||||
radius = 24.dp,
|
|
||||||
downsample = 0.5f,
|
|
||||||
)
|
|
||||||
.drawBehind {
|
|
||||||
val strokeWidth = 0.7.dp.value * density
|
|
||||||
val y = size.height - strokeWidth / 2
|
|
||||||
if (verticalScrollState.value > 55.dp.value * density) {
|
|
||||||
drawLine(
|
|
||||||
if (darkMode) Color.DarkGray else Color.LightGray,
|
|
||||||
Offset(0f, y),
|
|
||||||
Offset(size.width, y),
|
|
||||||
strokeWidth
|
|
||||||
)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
colors = TopAppBarDefaults.centerAlignedTopAppBarColors(
|
modifier = Modifier
|
||||||
containerColor = if (MaterialTheme.colorScheme.surface.luminance() < 0.5) Color.Black.copy(0.3f) else Color(0xFFF2F2F7).copy(0.2f),
|
.hazeChild(
|
||||||
),
|
state = hazeState,
|
||||||
actions = {
|
style = CupertinoMaterials.thin(),
|
||||||
val context = LocalContext.current
|
block = {
|
||||||
IconButton(
|
// make the background transparent when not scrolled yet
|
||||||
onClick = {
|
alpha = if (verticalScrollState.value > 55.dp.value * mdensity.floatValue) 1f else 0f
|
||||||
val bluetoothAdapter = context.getSystemService(BluetoothManager::class.java).adapter
|
}
|
||||||
bluetoothAdapter.bondedDevices.forEach { device ->
|
)
|
||||||
if (device.uuids.contains(ParcelUuid.fromString("74ec2172-0bad-4d01-8f77-997b2be0722a"))) {
|
.drawBehind {
|
||||||
bluetoothAdapter.getProfileProxy(context, object : BluetoothProfile.ServiceListener {
|
mdensity.value = density
|
||||||
override fun onServiceConnected(profile: Int, proxy: BluetoothProfile) {
|
val strokeWidth = 0.7.dp.value * density
|
||||||
if (profile == BluetoothProfile.A2DP) {
|
val y = size.height - strokeWidth / 2
|
||||||
val connectedDevices = proxy.connectedDevices
|
if (verticalScrollState.value > 55.dp.value * density) {
|
||||||
if (connectedDevices.isNotEmpty()) {
|
drawLine(
|
||||||
service.connectToSocket(device)
|
if (darkMode) Color.DarkGray else Color.LightGray,
|
||||||
}
|
Offset(0f, y),
|
||||||
}
|
Offset(size.width, y),
|
||||||
bluetoothAdapter.closeProfileProxy(profile, proxy)
|
strokeWidth
|
||||||
}
|
)
|
||||||
|
|
||||||
override fun onServiceDisconnected(profile: Int) { }
|
|
||||||
}, BluetoothProfile.A2DP)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
colors = IconButtonDefaults.iconButtonColors(
|
colors = TopAppBarDefaults.centerAlignedTopAppBarColors(
|
||||||
containerColor = Color.Transparent,
|
containerColor = Color.Transparent
|
||||||
contentColor = if (MaterialTheme.colorScheme.surface.luminance() < 0.5) Color.White else Color.Black
|
),
|
||||||
)
|
actions = {
|
||||||
) {
|
val context = LocalContext.current
|
||||||
Icon(
|
IconButton(
|
||||||
imageVector = Icons.Default.Refresh,
|
onClick = {
|
||||||
contentDescription = "Settings",
|
val bluetoothAdapter =
|
||||||
)
|
context.getSystemService(BluetoothManager::class.java).adapter
|
||||||
|
bluetoothAdapter.bondedDevices.forEach { d ->
|
||||||
|
if (d.uuids.contains(ParcelUuid.fromString("74ec2172-0bad-4d01-8f77-997b2be0722a"))) {
|
||||||
|
bluetoothAdapter.getProfileProxy(
|
||||||
|
context,
|
||||||
|
object : BluetoothProfile.ServiceListener {
|
||||||
|
override fun onServiceConnected(
|
||||||
|
profile: Int,
|
||||||
|
proxy: BluetoothProfile
|
||||||
|
) {
|
||||||
|
if (profile == BluetoothProfile.A2DP) {
|
||||||
|
val connectedDevices =
|
||||||
|
proxy.connectedDevices
|
||||||
|
if (connectedDevices.isNotEmpty()) {
|
||||||
|
service.connectToSocket(d)
|
||||||
|
device = d
|
||||||
|
deviceName = TextFieldValue(d.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bluetoothAdapter.closeProfileProxy(
|
||||||
|
profile,
|
||||||
|
proxy
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onServiceDisconnected(profile: Int) {}
|
||||||
|
},
|
||||||
|
BluetoothProfile.A2DP
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
colors = IconButtonDefaults.iconButtonColors(
|
||||||
|
containerColor = Color.Transparent,
|
||||||
|
contentColor = if (MaterialTheme.colorScheme.surface.luminance() < 0.5) Color.White else Color.Black
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Default.Refresh,
|
||||||
|
contentDescription = "Settings",
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
)
|
|
||||||
}
|
}
|
||||||
) { paddingValues ->
|
) { paddingValues ->
|
||||||
if (isConnected == true) {
|
if (isConnected == true) {
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
.haze(hazeState)
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.padding(horizontal = 16.dp)
|
.padding(horizontal = 16.dp)
|
||||||
.verticalScroll(
|
.verticalScroll(
|
||||||
@@ -840,7 +863,7 @@ fun NoiseControlSlider(service: AirPodsService, sharedPreferences: SharedPrefere
|
|||||||
@Preview
|
@Preview
|
||||||
@Composable
|
@Composable
|
||||||
fun Preview() {
|
fun Preview() {
|
||||||
IndependentToggle("Case Charging Sounds", AirPodsService(), "setCaseChargingSounds", LocalContext.current.getSharedPreferences("settings", Context.MODE_PRIVATE))
|
IndependentToggle("Case Charging Sounds", AirPodsService(), "setCaseChargingSounds", LocalContext.current.getSharedPreferences("settings", MODE_PRIVATE))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
|
@file:OptIn(ExperimentalHazeMaterialsApi::class)
|
||||||
|
|
||||||
package me.kavishdevar.aln
|
package me.kavishdevar.aln
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
import android.content.BroadcastReceiver
|
import android.content.BroadcastReceiver
|
||||||
import android.content.ComponentName
|
import android.content.ComponentName
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
@@ -15,8 +18,10 @@ import androidx.compose.foundation.layout.Box
|
|||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.ExperimentalLayoutApi
|
import androidx.compose.foundation.layout.ExperimentalLayoutApi
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.imePadding
|
import androidx.compose.foundation.layout.imePadding
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
@@ -35,6 +40,7 @@ import androidx.compose.material3.Text
|
|||||||
import androidx.compose.material3.TextField
|
import androidx.compose.material3.TextField
|
||||||
import androidx.compose.material3.TextFieldDefaults
|
import androidx.compose.material3.TextFieldDefaults
|
||||||
import androidx.compose.material3.TopAppBar
|
import androidx.compose.material3.TopAppBar
|
||||||
|
import androidx.compose.material3.TopAppBarDefaults
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.mutableStateListOf
|
import androidx.compose.runtime.mutableStateListOf
|
||||||
@@ -51,10 +57,17 @@ import androidx.compose.ui.text.input.TextFieldValue
|
|||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
|
import dev.chrisbanes.haze.HazeState
|
||||||
|
import dev.chrisbanes.haze.haze
|
||||||
|
import dev.chrisbanes.haze.hazeChild
|
||||||
|
import dev.chrisbanes.haze.materials.CupertinoMaterials
|
||||||
|
import dev.chrisbanes.haze.materials.ExperimentalHazeMaterialsApi
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class, ExperimentalLayoutApi::class)
|
@OptIn(ExperimentalMaterial3Api::class, ExperimentalLayoutApi::class)
|
||||||
|
@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
|
||||||
@Composable
|
@Composable
|
||||||
fun DebugScreen(navController: NavController) {
|
fun DebugScreen(navController: NavController) {
|
||||||
|
val hazeState = remember { HazeState() }
|
||||||
Scaffold(
|
Scaffold(
|
||||||
topBar = {
|
topBar = {
|
||||||
TopAppBar(
|
TopAppBar(
|
||||||
@@ -65,7 +78,15 @@ fun DebugScreen(navController: NavController) {
|
|||||||
}) {
|
}) {
|
||||||
Icon(Icons.AutoMirrored.Filled.ArrowBack, null)
|
Icon(Icons.AutoMirrored.Filled.ArrowBack, null)
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
modifier = Modifier
|
||||||
|
.hazeChild(
|
||||||
|
state = hazeState,
|
||||||
|
style = CupertinoMaterials.thin()
|
||||||
|
),
|
||||||
|
colors = TopAppBarDefaults.topAppBarColors(
|
||||||
|
containerColor = Color.Transparent
|
||||||
|
)
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
containerColor = if (MaterialTheme.colorScheme.surface.luminance() < 0.5) Color(0xFF000000)
|
containerColor = if (MaterialTheme.colorScheme.surface.luminance() < 0.5) Color(0xFF000000)
|
||||||
@@ -97,13 +118,15 @@ fun DebugScreen(navController: NavController) {
|
|||||||
listState.animateScrollToItem(text.size - 1)
|
listState.animateScrollToItem(text.size - 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.padding(paddingValues)
|
// .padding(paddingValues)
|
||||||
.imePadding(), // Ensures padding for keyboard visibility
|
.imePadding()
|
||||||
|
.haze(hazeState)
|
||||||
|
.padding(top = 0.dp)
|
||||||
) {
|
) {
|
||||||
|
Spacer(modifier = Modifier.height(55.dp))
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
state = listState,
|
state = listState,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ import androidx.navigation.compose.composable
|
|||||||
import androidx.navigation.compose.rememberNavController
|
import androidx.navigation.compose.rememberNavController
|
||||||
import com.google.accompanist.permissions.ExperimentalPermissionsApi
|
import com.google.accompanist.permissions.ExperimentalPermissionsApi
|
||||||
import com.google.accompanist.permissions.rememberMultiplePermissionsState
|
import com.google.accompanist.permissions.rememberMultiplePermissionsState
|
||||||
import com.primex.core.ExperimentalToolkitApi
|
|
||||||
import me.kavishdevar.aln.ui.theme.ALNTheme
|
import me.kavishdevar.aln.ui.theme.ALNTheme
|
||||||
|
|
||||||
lateinit var serviceConnection: ServiceConnection
|
lateinit var serviceConnection: ServiceConnection
|
||||||
@@ -42,7 +41,6 @@ lateinit var connectionStatusReceiver: BroadcastReceiver
|
|||||||
|
|
||||||
@ExperimentalMaterial3Api
|
@ExperimentalMaterial3Api
|
||||||
class MainActivity : ComponentActivity() {
|
class MainActivity : ComponentActivity() {
|
||||||
@OptIn(ExperimentalToolkitApi::class)
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
enableEdgeToEdge()
|
enableEdgeToEdge()
|
||||||
@@ -138,7 +136,7 @@ fun Main() {
|
|||||||
composable("settings") {
|
composable("settings") {
|
||||||
if (airPodsService.value != null) {
|
if (airPodsService.value != null) {
|
||||||
AirPodsSettingsScreen(
|
AirPodsSettingsScreen(
|
||||||
device = airPodsService.value?.device,
|
dev = airPodsService.value?.device,
|
||||||
service = airPodsService.value!!,
|
service = airPodsService.value!!,
|
||||||
navController = navController,
|
navController = navController,
|
||||||
isConnected = isConnected.value
|
isConnected = isConnected.value
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ composeBom = "2024.11.00"
|
|||||||
annotations = "26.0.0"
|
annotations = "26.0.0"
|
||||||
navigationCompose = "2.8.4"
|
navigationCompose = "2.8.4"
|
||||||
constraintlayout = "2.2.0"
|
constraintlayout = "2.2.0"
|
||||||
|
haze = "1.1.1"
|
||||||
|
hazeMaterials = "1.1.1"
|
||||||
|
|
||||||
[libraries]
|
[libraries]
|
||||||
accompanist-permissions = { module = "com.google.accompanist:accompanist-permissions", version.ref = "accompanistPermissions" }
|
accompanist-permissions = { module = "com.google.accompanist:accompanist-permissions", version.ref = "accompanistPermissions" }
|
||||||
@@ -34,6 +36,8 @@ androidx-material3 = { group = "androidx.compose.material3", name = "material3"
|
|||||||
annotations = { group = "org.jetbrains", name = "annotations", version.ref = "annotations" }
|
annotations = { group = "org.jetbrains", name = "annotations", version.ref = "annotations" }
|
||||||
androidx-navigation-compose = { group = "androidx.navigation", name = "navigation-compose", version.ref = "navigationCompose" }
|
androidx-navigation-compose = { group = "androidx.navigation", name = "navigation-compose", version.ref = "navigationCompose" }
|
||||||
androidx-constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" }
|
androidx-constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" }
|
||||||
|
haze = { group = "dev.chrisbanes.haze", name = "haze", version.ref = "haze" }
|
||||||
|
haze-materials = { group = "dev.chrisbanes.haze", name = "haze-materials", version.ref = "hazeMaterials" }
|
||||||
|
|
||||||
[plugins]
|
[plugins]
|
||||||
android-application = { id = "com.android.application", version.ref = "agp" }
|
android-application = { id = "com.android.application", version.ref = "agp" }
|
||||||
|
|||||||
Reference in New Issue
Block a user