Skip to content

Commit

Permalink
🎨 Improvements
Browse files Browse the repository at this point in the history
* Improved share cards
* Fixed card storage on a10 #39
* Fixed search becoming unreliable #37
  • Loading branch information
shub39 committed Oct 15, 2024
1 parent 668557f commit 4303c25
Show file tree
Hide file tree
Showing 10 changed files with 140 additions and 119 deletions.
2 changes: 1 addition & 1 deletion app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ android {
minSdk = 29
targetSdk = 35
versionCode = 233
versionName = "2.3.3"
versionName = "2.3.4"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
Expand Down
16 changes: 0 additions & 16 deletions app/src/main/java/com/shub39/rush/database/SettingsDataStore.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import android.content.Context
import android.util.Log
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb
import androidx.datastore.preferences.core.booleanPreferencesKey
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.intPreferencesKey
import androidx.datastore.preferences.core.stringPreferencesKey
Expand All @@ -28,7 +27,6 @@ object SettingsDataStore {
private val CARD_BACKGROUND = intPreferencesKey("card_background")
private val CARD_CONTENT = intPreferencesKey("card_content")
private val LYRICS_COLOR = stringPreferencesKey("lyrics_color")
private val LARGE_CARD = booleanPreferencesKey("large_card")

fun getLyricsColorFlow(context: Context): Flow<String> = context.dataStore.data
.catch {
Expand All @@ -38,14 +36,6 @@ object SettingsDataStore {
preferences[LYRICS_COLOR] ?: "muted"
}

fun getLargeCardFlow(context: Context): Flow<Boolean> = context.dataStore.data
.catch {
Log.e(TAG, it.message, it)
}
.map { preferences ->
preferences[LARGE_CARD] ?: false
}

fun getCardBackgroundFlow(context: Context): Flow<Int> = context.dataStore.data
.catch {
Log.e(TAG, it.message, it)
Expand Down Expand Up @@ -122,12 +112,6 @@ object SettingsDataStore {
}
}

suspend fun setLargeCard(context: Context, newLargeCard: Boolean) {
context.dataStore.edit { settings ->
settings[LARGE_CARD] = newLargeCard
}
}

suspend fun setLyricsColor(context: Context, new: String) {
context.dataStore.edit { settings ->
settings[LYRICS_COLOR] = new
Expand Down
57 changes: 44 additions & 13 deletions app/src/main/java/com/shub39/rush/logic/UILogic.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ package com.shub39.rush.logic

import android.content.ClipData
import android.content.ClipboardManager
import android.content.ContentValues
import android.content.Context
import android.content.Intent
import android.graphics.Bitmap
import android.media.MediaScannerConnection
import android.net.Uri
import android.os.Environment
import android.provider.MediaStore
import android.widget.Toast
import androidx.core.content.FileProvider
import com.shub39.rush.database.Lyric
Expand All @@ -16,6 +17,7 @@ import java.io.FileOutputStream
import java.io.IOException

object UILogic {
// Break lyrics into a list of lines with index
fun breakLyrics(lyrics: String): List<Map.Entry<Int, String>> {
val lines = lyrics.lines()
val map = mutableMapOf<Int, String>()
Expand All @@ -25,6 +27,7 @@ object UILogic {
return map.entries.toList()
}

// Update the selected lines map with the given key and value and handle exceptions
fun updateSelectedLines(
selectedLines: Map<Int, String>,
key: Int,
Expand All @@ -44,15 +47,26 @@ object UILogic {
clipboard.setPrimaryClip(clip)
}

/*
* Parse the synced lyrics data and convert them into a simpler format to show in the UI
* Removes lines with same times because it caused crashes when passing the time as key in LazyColumn
*/
fun parseLyrics(lyricsString: String): List<Lyric> {
val seenTimes = mutableSetOf<Long>()

return lyricsString.lines().mapNotNull { line ->
val parts = line.split("] ")
if (parts.size == 2) {
val time = parts[0].removePrefix("[").split(":").let { (minutes, seconds) ->
minutes.toLong() * 60 * 1000 + (seconds.toDouble() * 1000).toLong()
}
val text = parts[1]
Lyric(time, text)
if (time in seenTimes) {
null
} else {
seenTimes.add(time)
val text = parts[1]
Lyric(time, text)
}
} else {
null
}
Expand Down Expand Up @@ -90,31 +104,48 @@ object UILogic {
&& filename.endsWith(".png")
}

/*
* Converts a given Bitmap into a png image and opens dialog to share the image
* if shareToPictures is True then it stores the image in /Pictures/Rush in internal storage
*/
fun shareImage(context: Context, bitmap: Bitmap, name: String, saveToPictures: Boolean = false) {
val file: File = if (saveToPictures) {
val picturesDir = File(
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
"Rush"
)
picturesDir.mkdirs()
File(picturesDir, name)
val resolver = context.contentResolver
val contentValues = ContentValues().apply {
put(MediaStore.MediaColumns.DISPLAY_NAME, name)
put(MediaStore.MediaColumns.MIME_TYPE, "image/png")
put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_PICTURES + "/Rush")
}
val uri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues)
uri?.let {
val stream = resolver.openOutputStream(it)
if (stream != null) {
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream)
}
stream?.close()
} ?: run {
Toast.makeText(context, "Error saving image", Toast.LENGTH_SHORT).show()
return
}
File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), name)
} else {
val cachePath = File(context.cacheDir, "images")
cachePath.mkdirs()
File(cachePath, name)
}

try {
val stream = FileOutputStream(file)
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream)
stream.close()
if (!saveToPictures) {
val stream = FileOutputStream(file)
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream)
stream.close()
}
} catch (e: IOException) {
e.printStackTrace()
return
}

if (saveToPictures) {
MediaScannerConnection.scanFile(context, arrayOf(file.toString()), null, null)
Toast.makeText(context, "Image saved to Pictures/$name", Toast.LENGTH_SHORT).show()
} else {
val contentUri: Uri =
Expand Down
32 changes: 6 additions & 26 deletions app/src/main/java/com/shub39/rush/ui/component/CardEditRow.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import com.shub39.rush.R
Expand All @@ -20,18 +21,16 @@ fun CardEditRow(
modifier: Modifier,
corners: Boolean = false,
colors: Boolean = false,
// large: Boolean = false
tint: Color
) {
val context = LocalContext.current
val coroutineScope = rememberCoroutineScope()

val cardColorFlow = remember { SettingsDataStore.getCardColorFlow(context) }
val cardCornersFlow = remember { SettingsDataStore.getCardRoundnessFlow(context) }
// val cardSizeFlow = remember { SettingsDataStore.getLargeCardFlow(context) }

val cardColorType by cardColorFlow.collectAsState(initial = "")
val cardCornersType by cardCornersFlow.collectAsState(initial = "")
// val largeCard by cardSizeFlow.collectAsState(initial = false)

Row(
modifier = modifier
Expand Down Expand Up @@ -59,32 +58,12 @@ fun CardEditRow(
"Rounded" -> painterResource(id = R.drawable.baseline_circle_24)
else -> painterResource(id = R.drawable.baseline_square_24)
},
contentDescription = null
contentDescription = null,
tint = tint
)
}
}

// if (large) {
// IconButton(
// onClick = {
// coroutineScope.launch {
// when (largeCard) {
// true -> SettingsDataStore.setLargeCard(context, false)
// false -> SettingsDataStore.setLargeCard(context, true)
// }
// }
// }
// ) {
// Icon(
// painter = when (largeCard) {
// true -> painterResource(id = R.drawable.round_fullscreen_24)
// else -> painterResource(id = R.drawable.round_fullscreen_exit_24)
// },
// contentDescription = null
// )
// }
// }

if (colors) {
IconButton(
onClick = {
Expand All @@ -105,7 +84,8 @@ fun CardEditRow(
"Custom" -> painterResource(id = R.drawable.baseline_edit_square_24)
else -> painterResource(id = R.drawable.round_disabled_by_default_24)
},
contentDescription = null
contentDescription = null,
tint = tint
)
}
}
Expand Down
28 changes: 21 additions & 7 deletions app/src/main/java/com/shub39/rush/ui/component/RushedShareCard.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,12 @@ import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Card
import androidx.compose.material3.CardColors
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.blur
Expand Down Expand Up @@ -54,7 +57,8 @@ fun RushedShareCard(
Brush.verticalGradient(
colors = listOf(
Color.Transparent,
cardColors.containerColor.copy(0.5f)
cardColors.containerColor.copy(0.3f),
cardColors.containerColor
)
)
)
Expand All @@ -68,7 +72,8 @@ fun RushedShareCard(
.background(
Brush.verticalGradient(
colors = listOf(
cardColors.containerColor.copy(0.5f),
cardColors.containerColor,
cardColors.containerColor.copy(0.3f),
Color.Transparent
)
)
Expand All @@ -87,10 +92,19 @@ fun RushedShareCard(
.wrapContentHeight()
) {
items(sortedLines.values.toList()) {
var variant by remember { mutableStateOf(false) }

Card(
modifier = Modifier.padding(bottom = 10.dp),
modifier = Modifier.padding(bottom = 8.dp),
shape = MaterialTheme.shapes.small,
colors = cardColors
colors = when (variant) {
true -> CardDefaults.cardColors(
containerColor = cardColors.contentColor,
contentColor = cardColors.containerColor
)
else -> cardColors
},
onClick = { variant = !variant }
) {
Text(
text = it,
Expand All @@ -101,7 +115,7 @@ fun RushedShareCard(
bottom = 4.dp
),
fontWeight = FontWeight.Bold,
style = MaterialTheme.typography.bodyLarge
style = MaterialTheme.typography.bodyMedium
)
}
}
Expand Down Expand Up @@ -139,8 +153,8 @@ fun RushedShareCard(
CardEditRow(
modifier = Modifier.align(Alignment.BottomEnd),
colors = true,
corners = true
// large = true
corners = true,
tint = cardColors.contentColor
)
}
}
14 changes: 12 additions & 2 deletions app/src/main/java/com/shub39/rush/ui/component/SearchSheet.kt
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ import androidx.compose.ui.unit.dp
import com.shub39.rush.R
import com.shub39.rush.viewmodel.RushViewModel
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch

@OptIn(ExperimentalMaterial3Api::class)
Expand All @@ -69,6 +71,7 @@ fun SearchSheet(
) {
val keyboardController = LocalSoftwareKeyboardController.current
val focusRequester = remember { FocusRequester() }
var searchJob: Job? by remember { mutableStateOf(null) }

LaunchedEffect(Unit) {
focusRequester.requestFocus()
Expand Down Expand Up @@ -131,8 +134,15 @@ fun SearchSheet(
},
onValueChange = {
query = it
rushViewModel.searchSong(it, false)
rushViewModel.localSearch(it)
searchJob?.cancel()

searchJob = coroutineScope.launch {
delay(500)
if (it.isNotEmpty()) {
rushViewModel.localSearch(it)
rushViewModel.searchSong(it, false)
}
}
},
shape = MaterialTheme.shapes.extraLarge,
label = { Text(stringResource(id = R.string.search)) },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ fun SpotifyShareCard(
modifier = Modifier.align(Alignment.BottomEnd),
colors = true,
corners = true,
// large = true
tint = cardColors.contentColor
)
}
}
Loading

0 comments on commit 4303c25

Please sign in to comment.