diff --git a/art/soundbound-feature.jpg b/art/soundbound-feature.jpg new file mode 100644 index 00000000..dd46eb77 Binary files /dev/null and b/art/soundbound-feature.jpg differ diff --git a/common/compose/src/androidMain/kotlin/com/shabinder/common/uikit/AndroidImages.kt b/common/compose/src/androidMain/kotlin/com/shabinder/common/uikit/AndroidImages.kt index a9eb45ce..a77af03f 100644 --- a/common/compose/src/androidMain/kotlin/com/shabinder/common/uikit/AndroidImages.kt +++ b/common/compose/src/androidMain/kotlin/com/shabinder/common/uikit/AndroidImages.kt @@ -78,6 +78,9 @@ actual fun HeartIcon() = painterResource(R.drawable.ic_heart) @Composable actual fun SpotifyLogo() = getCachedPainter(R.drawable.ic_spotify_logo) +@Composable +actual fun SoundboundLogo() = getCachedPainter(R.drawable.soundbound_app_logo) + @Composable actual fun SaavnLogo() = getCachedPainter(R.drawable.ic_jio_saavn_logo) diff --git a/common/compose/src/commonMain/kotlin/com/shabinder/common/uikit/ExpectImages.kt b/common/compose/src/commonMain/kotlin/com/shabinder/common/uikit/ExpectImages.kt index 557bfb49..ae1b6f68 100644 --- a/common/compose/src/commonMain/kotlin/com/shabinder/common/uikit/ExpectImages.kt +++ b/common/compose/src/commonMain/kotlin/com/shabinder/common/uikit/ExpectImages.kt @@ -55,6 +55,9 @@ expect fun SpotiFlyerLogo(): Painter @Composable expect fun SpotifyLogo(): Painter +@Composable +expect fun SoundboundLogo(): Painter + @Composable expect fun SaavnLogo(): Painter diff --git a/common/compose/src/commonMain/kotlin/com/shabinder/common/uikit/configurations/Color.kt b/common/compose/src/commonMain/kotlin/com/shabinder/common/uikit/configurations/Color.kt index 41500af1..b47df623 100644 --- a/common/compose/src/commonMain/kotlin/com/shabinder/common/uikit/configurations/Color.kt +++ b/common/compose/src/commonMain/kotlin/com/shabinder/common/uikit/configurations/Color.kt @@ -22,6 +22,7 @@ import androidx.compose.ui.graphics.Color val colorPrimary = Color(0xFFFC5C7D) val colorPrimaryDark = Color(0xFFCE1CFF) val colorAccent = Color(0xFF9AB3FF) +val colorSoundbound = Color(0xFF4b9fff) val colorAccentVariant = Color(0xFF3457D5) val colorRedError = Color(0xFFFF9494) val colorSuccessGreen = Color(0xFF59C351) diff --git a/common/compose/src/commonMain/kotlin/com/shabinder/common/uikit/screens/SpotiFlyerMainUi.kt b/common/compose/src/commonMain/kotlin/com/shabinder/common/uikit/screens/SpotiFlyerMainUi.kt index eab0877b..ae644ac2 100644 --- a/common/compose/src/commonMain/kotlin/com/shabinder/common/uikit/screens/SpotiFlyerMainUi.kt +++ b/common/compose/src/commonMain/kotlin/com/shabinder/common/uikit/screens/SpotiFlyerMainUi.kt @@ -42,6 +42,7 @@ import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.foundation.verticalScroll +import androidx.compose.material.ButtonDefaults import androidx.compose.material.Card import androidx.compose.material.Icon import androidx.compose.material.MaterialTheme @@ -53,12 +54,14 @@ import androidx.compose.material.TabPosition import androidx.compose.material.TabRow import androidx.compose.material.TabRowDefaults.tabIndicatorOffset import androidx.compose.material.Text +import androidx.compose.material.TextButton import androidx.compose.material.TextField import androidx.compose.material.TextFieldDefaults.textFieldColors import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.History import androidx.compose.material.icons.outlined.Info import androidx.compose.material.icons.rounded.CardGiftcard +import androidx.compose.material.icons.rounded.ChevronRight import androidx.compose.material.icons.rounded.Edit import androidx.compose.material.icons.rounded.Flag import androidx.compose.material.icons.rounded.Insights @@ -71,6 +74,7 @@ import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.style.TextAlign @@ -81,9 +85,8 @@ import com.arkivanov.decompose.extensions.compose.jetbrains.subscribeAsState import com.shabinder.common.core_components.picture.Picture import com.shabinder.common.main.SpotiFlyerMain import com.shabinder.common.main.SpotiFlyerMain.HomeCategory -import com.shabinder.common.models.DownloadRecord import com.shabinder.common.models.Actions -import com.shabinder.common.models.spotify.Source +import com.shabinder.common.models.DownloadRecord import com.shabinder.common.translations.Strings import com.shabinder.common.uikit.GaanaLogo import com.shabinder.common.uikit.GithubLogo @@ -91,12 +94,14 @@ import com.shabinder.common.uikit.ImageLoad import com.shabinder.common.uikit.SaavnLogo import com.shabinder.common.uikit.ShareImage import com.shabinder.common.uikit.SoundCloudLogo +import com.shabinder.common.uikit.SoundboundLogo import com.shabinder.common.uikit.SpotifyLogo import com.shabinder.common.uikit.VerticalScrollbar import com.shabinder.common.uikit.YoutubeLogo import com.shabinder.common.uikit.YoutubeMusicLogo import com.shabinder.common.uikit.configurations.SpotiFlyerShapes import com.shabinder.common.uikit.configurations.SpotiFlyerTypography +import com.shabinder.common.uikit.configurations.black import com.shabinder.common.uikit.configurations.colorAccent import com.shabinder.common.uikit.configurations.colorOffWhite import com.shabinder.common.uikit.configurations.colorPrimary @@ -134,6 +139,7 @@ fun SpotiFlyerMainContent(component: SpotiFlyerMain) { openDonationDialog() } ) + HomeCategory.History -> HistoryColumn( model.records.sortedByDescending { it.id }, component::loadImage, @@ -247,7 +253,11 @@ fun SearchPanel( ) ) ) { - Text(text = Strings.search(), style = SpotiFlyerTypography.h6, modifier = Modifier.padding(4.dp)) + Text( + text = Strings.search(), + style = SpotiFlyerTypography.h6, + modifier = Modifier.padding(4.dp) + ) } } } @@ -264,6 +274,82 @@ fun AboutColumn( val stateVertical = rememberScrollState(0) Column(modifier.fillMaxSize().padding(8.dp).verticalScroll(stateVertical)) { + Card( + modifier = modifier.fillMaxWidth(), + border = BorderStroke(1.dp, Color.Gray) + ) { + Column(modifier.padding(12.dp).clickable( + onClick = { + Actions.instance.openPlatform( + "in.shabinder.soundbound", + "https://soundbound.app" + ) + } + )) { + Row { + Image( + painter = SoundboundLogo(), + "${Strings.open()} Soundbound", + ) + + Spacer(modifier = Modifier.padding(start = 16.dp)) + + Column( + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center, + modifier = Modifier.weight(1f) + ) { + Text( + text = "Get Soundbound", + style = SpotiFlyerTypography.h4, + color = colorAccent + ) + + Spacer(modifier = Modifier.padding(top = 8.dp)) + + Text( + text = "No BOUNDs to,\nyour Music & SOUNDs.", + style = SpotiFlyerTypography.h6, + textAlign = TextAlign.Center, + fontStyle = FontStyle.Italic, + color = colorOffWhite, + modifier = Modifier.align(Alignment.CenterHorizontally) + .padding(top = 4.dp) + ) + } + } + + TextButton( + onClick = { + Actions.instance.openPlatform( + "in.shabinder.soundbound", + "https://soundbound.app" + ) + }, + modifier = Modifier.fillMaxWidth() + .padding(vertical = 8.dp, horizontal = 16.dp), + colors = ButtonDefaults.textButtonColors( + contentColor = black, + backgroundColor = colorAccent + ) + ) { + Text( + text = Strings.open(), + style = SpotiFlyerTypography.body1, + modifier = Modifier.padding(vertical = 4.dp), + fontWeight = FontWeight.SemiBold + ) + + Icon( + Icons.Rounded.ChevronRight, + Strings.open(), + tint = black, + modifier = Modifier + ) + } + } + } + Spacer(modifier = Modifier.padding(top = 8.dp)) Card( modifier = modifier.fillMaxWidth(), border = BorderStroke(1.dp, Color.Gray) @@ -275,13 +361,21 @@ fun AboutColumn( color = colorAccent ) Spacer(modifier = Modifier.padding(top = 12.dp)) - Row(horizontalArrangement = Arrangement.Center, modifier = modifier.fillMaxWidth()) { + Row( + horizontalArrangement = Arrangement.Center, + modifier = modifier.fillMaxWidth() + ) { Icon( SpotifyLogo(), "${Strings.open()} Spotify", tint = Color.Unspecified, modifier = Modifier.clip(SpotiFlyerShapes.small).clickable( - onClick = { Actions.instance.openPlatform("com.spotify.music", "https://open.spotify.com") } + onClick = { + Actions.instance.openPlatform( + "com.spotify.music", + "https://open.spotify.com" + ) + } ) ) Spacer(modifier = modifier.padding(start = 16.dp)) @@ -290,7 +384,12 @@ fun AboutColumn( "${Strings.open()} Gaana", tint = Color.Unspecified, modifier = Modifier.clip(SpotiFlyerShapes.small).clickable( - onClick = { Actions.instance.openPlatform("com.gaana", "https://www.gaana.com") } + onClick = { + Actions.instance.openPlatform( + "com.gaana", + "https://www.gaana.com" + ) + } ) ) Spacer(modifier = modifier.padding(start = 16.dp)) @@ -299,7 +398,12 @@ fun AboutColumn( "${Strings.open()} Jio Saavn", tint = Color.Unspecified, modifier = Modifier.clickable( - onClick = { Actions.instance.openPlatform("com.jio.media.jiobeats", "https://www.jiosaavn.com/") } + onClick = { + Actions.instance.openPlatform( + "com.jio.media.jiobeats", + "https://www.jiosaavn.com/" + ) + } ) ) Spacer(modifier = modifier.padding(start = 16.dp)) @@ -308,7 +412,12 @@ fun AboutColumn( "${Strings.open()} Youtube", tint = Color.Unspecified, modifier = Modifier.clip(SpotiFlyerShapes.small).clickable( - onClick = { Actions.instance.openPlatform("com.google.android.youtube", "https://m.youtube.com") } + onClick = { + Actions.instance.openPlatform( + "com.google.android.youtube", + "https://m.youtube.com" + ) + } ) ) Spacer(modifier = modifier.padding(start = 12.dp)) @@ -317,18 +426,31 @@ fun AboutColumn( "${Strings.open()} Youtube Music", tint = Color.Unspecified, modifier = Modifier.clip(SpotiFlyerShapes.small).clickable( - onClick = { Actions.instance.openPlatform("com.google.android.apps.youtube.music", "https://music.youtube.com/") } + onClick = { + Actions.instance.openPlatform( + "com.google.android.apps.youtube.music", + "https://music.youtube.com/" + ) + } ) ) } Spacer(modifier = Modifier.padding(top = 8.dp)) - Row(horizontalArrangement = Arrangement.Center, modifier = modifier.fillMaxWidth()) { + Row( + horizontalArrangement = Arrangement.Center, + modifier = modifier.fillMaxWidth() + ) { Icon( SoundCloudLogo(), "${Strings.open()} Sound Cloud", tint = Color.Unspecified, modifier = Modifier.clip(SpotiFlyerShapes.medium).clickable( - onClick = { Actions.instance.openPlatform("com.soundcloud.android", "https://soundcloud.com/") } + onClick = { + Actions.instance.openPlatform( + "com.soundcloud.android", + "https://soundcloud.com/" + ) + } ) ) } @@ -349,11 +471,21 @@ fun AboutColumn( Row( verticalAlignment = Alignment.CenterVertically, modifier = Modifier.fillMaxWidth().clickable( - onClick = { Actions.instance.openPlatform("", "https://github.com/Shabinder/SpotiFlyer") } + onClick = { + Actions.instance.openPlatform( + "", + "https://github.com/Shabinder/SpotiFlyer" + ) + } ) .padding(vertical = 6.dp) ) { - Icon(GithubLogo(), Strings.openProjectRepo(), Modifier.size(32.dp), tint = Color(0xFFCCCCCC)) + Icon( + GithubLogo(), + Strings.openProjectRepo(), + Modifier.size(32.dp), + tint = Color(0xFFCCCCCC) + ) Spacer(modifier = Modifier.padding(start = 16.dp)) Column { Text( @@ -368,10 +500,19 @@ fun AboutColumn( } Row( modifier = modifier.fillMaxWidth().padding(vertical = 6.dp) - .clickable(onClick = { Actions.instance.openPlatform("", "https://github.com/Shabinder/SpotiFlyer/blob/main/CONTRIBUTING.md") }), + .clickable(onClick = { + Actions.instance.openPlatform( + "", + "https://github.com/Shabinder/SpotiFlyer/blob/main/CONTRIBUTING.md" + ) + }), verticalAlignment = Alignment.CenterVertically ) { - Icon(Icons.Rounded.Flag, Strings.help() + Strings.translate(), Modifier.size(32.dp)) + Icon( + Icons.Rounded.Flag, + Strings.help() + Strings.translate(), + Modifier.size(32.dp) + ) Spacer(modifier = Modifier.padding(start = 16.dp)) Column { Text( @@ -390,7 +531,11 @@ fun AboutColumn( .clickable(onClick = openDonationDialog), verticalAlignment = Alignment.CenterVertically ) { - Icon(Icons.Rounded.CardGiftcard, Strings.supportDeveloper(), Modifier.size(32.dp)) + Icon( + Icons.Rounded.CardGiftcard, + Strings.supportDeveloper(), + Modifier.size(32.dp) + ) Spacer(modifier = Modifier.padding(start = 16.dp)) Column { Text( @@ -413,7 +558,11 @@ fun AboutColumn( ), verticalAlignment = Alignment.CenterVertically ) { - Icon(Icons.Rounded.Share, Strings.share() + Strings.title() + "App", Modifier.size(32.dp)) + Icon( + Icons.Rounded.Share, + Strings.share() + Strings.title() + "App", + Modifier.size(32.dp) + ) Spacer(modifier = Modifier.padding(start = 16.dp)) Column { Text( @@ -435,7 +584,11 @@ fun AboutColumn( ), verticalAlignment = Alignment.CenterVertically ) { - Icon(Icons.Rounded.Insights, Strings.analytics() + Strings.status(), Modifier.size(32.dp)) + Icon( + Icons.Rounded.Insights, + Strings.analytics() + Strings.status(), + Modifier.size(32.dp) + ) Spacer(modifier = Modifier.padding(start = 16.dp)) Column( Modifier.weight(1f) @@ -474,12 +627,22 @@ fun HistoryColumn( ) { Crossfade(list) { if (it.isEmpty()) { - Column(Modifier.padding(8.dp).fillMaxSize(), verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally) { + Column( + Modifier.padding(8.dp).fillMaxSize(), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally + ) { Icon( - Icons.Outlined.Info, Strings.noHistoryAvailable(), modifier = Modifier.size(80.dp), + Icons.Outlined.Info, + Strings.noHistoryAvailable(), + modifier = Modifier.size(80.dp), colorOffWhite ) - Text(Strings.noHistoryAvailable(), style = SpotiFlyerTypography.h4.copy(fontWeight = FontWeight.Light), textAlign = TextAlign.Center) + Text( + Strings.noHistoryAvailable(), + style = SpotiFlyerTypography.h4.copy(fontWeight = FontWeight.Light), + textAlign = TextAlign.Center + ) } } else { Box { @@ -521,22 +684,38 @@ fun DownloadRecordItem( loadImage: suspend (String) -> Picture, onItemClicked: (String) -> Unit ) { - Row(verticalAlignment = Alignment.CenterVertically, modifier = Modifier.fillMaxWidth().padding(end = 8.dp)) { + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.fillMaxWidth().padding(end = 8.dp) + ) { ImageLoad( item.coverUrl, { loadImage(item.coverUrl) }, Strings.albumArt(), modifier = Modifier.height(70.dp).width(70.dp).clip(SpotiFlyerShapes.medium) ) - Column(modifier = Modifier.padding(horizontal = 8.dp).height(60.dp).weight(1f), verticalArrangement = Arrangement.SpaceEvenly) { - Text(item.name, maxLines = 1, overflow = TextOverflow.Ellipsis, style = SpotiFlyerTypography.h6, color = colorAccent) + Column( + modifier = Modifier.padding(horizontal = 8.dp).height(60.dp).weight(1f), + verticalArrangement = Arrangement.SpaceEvenly + ) { + Text( + item.name, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + style = SpotiFlyerTypography.h6, + color = colorAccent + ) Row( horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.Bottom, modifier = Modifier.padding(horizontal = 8.dp).fillMaxSize() ) { Text(item.type, fontSize = 13.sp, color = colorOffWhite) - Text("${Strings.tracks()}: ${item.totalFiles}", fontSize = 13.sp, color = colorOffWhite) + Text( + "${Strings.tracks()}: ${item.totalFiles}", + fontSize = 13.sp, + color = colorOffWhite + ) } } Image( diff --git a/common/compose/src/desktopMain/kotlin/com/shabinder/common/uikit/DesktopImages.kt b/common/compose/src/desktopMain/kotlin/com/shabinder/common/uikit/DesktopImages.kt index 125a1763..bc4975f4 100644 --- a/common/compose/src/desktopMain/kotlin/com/shabinder/common/uikit/DesktopImages.kt +++ b/common/compose/src/desktopMain/kotlin/com/shabinder/common/uikit/DesktopImages.kt @@ -82,6 +82,10 @@ actual fun HeartIcon() = actual fun SpotifyLogo() = getCachedPainter("drawable/ic_spotify_logo.xml") +@Composable +actual fun SoundboundLogo() = + getCachedPainter("drawable/soundbound_app_logo.xml") + @Composable actual fun SaavnLogo() = getCachedPainter("drawable/ic_jio_saavn_logo.xml") diff --git a/common/data-models/src/main/res/drawable/soundbound_app_logo.xml b/common/data-models/src/main/res/drawable/soundbound_app_logo.xml new file mode 100644 index 00000000..58048a82 --- /dev/null +++ b/common/data-models/src/main/res/drawable/soundbound_app_logo.xml @@ -0,0 +1,14 @@ + + + + + diff --git a/fastlane/metadata/android/en-US/changelogs/32.txt b/fastlane/metadata/android/en-US/changelogs/32.txt new file mode 100644 index 00000000..619a08a9 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/32.txt @@ -0,0 +1 @@ + - Soundbound Feature Graphic. \ No newline at end of file