diff --git a/app/src/main/java/ua/acclorite/book_story/domain/model/Badge.kt b/app/src/main/java/ua/acclorite/book_story/domain/model/Badge.kt new file mode 100644 index 00000000..db28da0b --- /dev/null +++ b/app/src/main/java/ua/acclorite/book_story/domain/model/Badge.kt @@ -0,0 +1,15 @@ +package ua.acclorite.book_story.domain.model + +import androidx.annotation.DrawableRes +import androidx.annotation.StringRes +import androidx.compose.runtime.Immutable +import androidx.compose.ui.graphics.vector.ImageVector + +@Immutable +data class Badge( + val id: String, + val imageVector: ImageVector?, + @DrawableRes val drawable: Int?, + @StringRes val contentDescription: Int, + val url: String? +) \ No newline at end of file diff --git a/app/src/main/java/ua/acclorite/book_story/domain/util/Constants.kt b/app/src/main/java/ua/acclorite/book_story/domain/util/Constants.kt index e7b10eeb..bb6e9577 100644 --- a/app/src/main/java/ua/acclorite/book_story/domain/util/Constants.kt +++ b/app/src/main/java/ua/acclorite/book_story/domain/util/Constants.kt @@ -1,10 +1,13 @@ package ua.acclorite.book_story.domain.util +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Person import androidx.compose.ui.text.font.Font import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.text.font.FontWeight import ua.acclorite.book_story.R +import ua.acclorite.book_story.domain.model.Badge import ua.acclorite.book_story.domain.model.Book import ua.acclorite.book_story.domain.model.Category import ua.acclorite.book_story.domain.model.Credit @@ -110,6 +113,45 @@ object Constants { ), ) + // About Badges + val ABOUT_BADGES = listOf( + Badge( + id = "x", + drawable = R.drawable.x_logo, + imageVector = null, + contentDescription = R.string.x_content_desc, + url = "https://www.x.com/acclorite" + ), + Badge( + id = "reddit", + drawable = R.drawable.reddit, + imageVector = null, + contentDescription = R.string.reddit_content_desc, + url = "https://www.reddit.com/user/Acclorite/" + ), + Badge( + id = "tryzub", + drawable = R.drawable.tryzub, + imageVector = null, + contentDescription = R.string.tryzub_content_desc, + url = null + ), + Badge( + id = "github_project", + drawable = R.drawable.github, + imageVector = null, + contentDescription = R.string.github_project_content_desc, + url = "https://www.github.com/Acclorite/book-story" + ), + Badge( + id = "github_profile", + drawable = null, + imageVector = Icons.Default.Person, + contentDescription = R.string.github_profile_content_desc, + url = "https://www.github.com/Acclorite" + ), + ) + // Fonts for Reader val FONTS = listOf( FontWithName( diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/components/CustomIconButton.kt b/app/src/main/java/ua/acclorite/book_story/presentation/components/CustomIconButton.kt index 0ebf50c0..b2c20ae1 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/components/CustomIconButton.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/components/CustomIconButton.kt @@ -1,5 +1,6 @@ package ua.acclorite.book_story.presentation.components +import androidx.annotation.DrawableRes import androidx.annotation.StringRes import androidx.compose.material3.Icon import androidx.compose.material3.IconButton @@ -13,10 +14,20 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.focus.focusProperties import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource /** - * Custom Icon Button. Can be disabled after click, so user can't press button fast 2 or 3 times. + * Custom Icon Button. + * Can be disabled after click, so user can't press button fast 2 or 3 times. + * + * @param modifier [Modifier]. + * @param icon ImageVector Icon. + * @param contentDescription Content description (tooltip text). + * @param disableOnClick Whether button disables after first click. + * @param enabled Whether button enabled. + * @param color Color of the Icon. + * @param onClick OnClick callback. */ @Composable fun CustomIconButton( @@ -50,4 +61,50 @@ fun CustomIconButton( ) } } +} + +/** + * Custom Icon Button. + * Can be disabled after click, so user can't press button fast 2 or 3 times. + * + * @param modifier [Modifier]. + * @param icon Drawable Icon. + * @param contentDescription Content description (tooltip text). + * @param disableOnClick Whether button disables after first click. + * @param enabled Whether button enabled. + * @param color Color of the Icon. + * @param onClick OnClick callback. + */ +@Composable +fun CustomIconButton( + modifier: Modifier = Modifier, + @DrawableRes icon: Int, + @StringRes contentDescription: Int, + disableOnClick: Boolean, + enabled: Boolean = true, + color: Color = LocalContentColor.current, + onClick: () -> Unit +) { + var isClicked by remember { mutableStateOf(false) } + CustomTooltip(text = stringResource(id = contentDescription)) { + IconButton( + enabled = enabled && !isClicked, + modifier = Modifier.focusProperties { + canFocus = false + }, + onClick = { + if (disableOnClick) { + isClicked = true + } + onClick() + } + ) { + Icon( + painter = painterResource(id = icon), + modifier = modifier, + contentDescription = stringResource(id = contentDescription), + tint = color + ) + } + } } \ No newline at end of file diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/about/AboutScreen.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/about/AboutScreen.kt index 31ca46d5..d7ea1bc5 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/screens/about/AboutScreen.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/about/AboutScreen.kt @@ -40,6 +40,7 @@ import ua.acclorite.book_story.presentation.data.LocalNavigator import ua.acclorite.book_story.presentation.data.Screen import ua.acclorite.book_story.presentation.screens.about.components.AboutItem import ua.acclorite.book_story.presentation.screens.about.components.AboutUpdateDialog +import ua.acclorite.book_story.presentation.screens.about.components.badges.AboutBadges import ua.acclorite.book_story.presentation.screens.about.data.AboutEvent import ua.acclorite.book_story.presentation.screens.about.data.AboutState import ua.acclorite.book_story.presentation.screens.about.data.AboutViewModel @@ -117,7 +118,7 @@ private fun AboutScreen( contentDescription = stringResource(id = R.string.app_icon_content_desc), modifier = Modifier .padding(14.dp) - .size(160.dp), + .size(120.dp), tint = MaterialTheme.colorScheme.onSurfaceVariant ) } @@ -190,12 +191,12 @@ private fun AboutScreen( item { AboutItem( - title = stringResource(id = R.string.project_page_option), + title = stringResource(id = R.string.whats_new_option), description = null ) { onEvent( AboutEvent.OnNavigateToBrowserPage( - context.getString(R.string.project_page), + context.getString(R.string.releases_page), context, noAppsFound = { Toast.makeText( @@ -253,19 +254,8 @@ private fun AboutScreen( } item { - AboutItem( - title = stringResource(id = R.string.slava_ukraini_option), - description = null - ) { - Toast.makeText( - context, - context.getString(R.string.slava_ukraini_option_desc), - Toast.LENGTH_SHORT - ).show() - } + AboutBadges(onEvent = onEvent) } - - item { Spacer(modifier = Modifier.height(48.dp)) } } } } \ No newline at end of file diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/about/components/badges/AboutBadgeItem.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/about/components/badges/AboutBadgeItem.kt new file mode 100644 index 00000000..bb93ce94 --- /dev/null +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/about/components/badges/AboutBadgeItem.kt @@ -0,0 +1,43 @@ +package ua.acclorite.book_story.presentation.screens.about.components.badges + +import androidx.compose.foundation.layout.size +import androidx.compose.material3.MaterialTheme +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import ua.acclorite.book_story.domain.model.Badge +import ua.acclorite.book_story.presentation.components.CustomIconButton + +/** + * About Badge Item. + * + * @param badge [Badge]. + * @param onClick OnClick callback. + */ +@Composable +fun AboutBadgeItem( + badge: Badge, + onClick: () -> Unit +) { + if (badge.imageVector == null && badge.drawable != null) { + CustomIconButton( + modifier = Modifier.size(22.dp), + icon = badge.drawable, + contentDescription = badge.contentDescription, + disableOnClick = false, + color = MaterialTheme.colorScheme.primary + ) { + onClick() + } + } else if (badge.imageVector != null && badge.drawable == null) { + CustomIconButton( + modifier = Modifier.size(22.dp), + icon = badge.imageVector, + contentDescription = badge.contentDescription, + disableOnClick = false, + color = MaterialTheme.colorScheme.primary + ) { + onClick() + } + } +} \ No newline at end of file diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/screens/about/components/badges/AboutBadges.kt b/app/src/main/java/ua/acclorite/book_story/presentation/screens/about/components/badges/AboutBadges.kt new file mode 100644 index 00000000..89eac78f --- /dev/null +++ b/app/src/main/java/ua/acclorite/book_story/presentation/screens/about/components/badges/AboutBadges.kt @@ -0,0 +1,77 @@ +package ua.acclorite.book_story.presentation.screens.about.components.badges + +import android.widget.Toast +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.LazyRow +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import ua.acclorite.book_story.R +import ua.acclorite.book_story.domain.util.Constants +import ua.acclorite.book_story.presentation.components.customItems +import ua.acclorite.book_story.presentation.screens.about.data.AboutEvent + +/** + * About Badges. + * Links all ways to contact me. + * + * @param onEvent [AboutEvent] callback. + * @param verticalPadding Vertical item padding. + */ +@Composable +fun AboutBadges( + onEvent: (AboutEvent) -> Unit, + verticalPadding: Dp = 18.dp +) { + val context = LocalContext.current + + Box( + modifier = Modifier.fillMaxWidth(), + contentAlignment = Alignment.Center + ) { + LazyRow( + Modifier + .padding(horizontal = 18.dp, vertical = verticalPadding), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(13.dp) + ) { + customItems(Constants.ABOUT_BADGES, key = { it.id }) { badge -> + AboutBadgeItem(badge = badge) { + when (badge.id) { + "tryzub" -> { + Toast.makeText( + context, + context.getString(R.string.slava_ukraini), + Toast.LENGTH_SHORT + ).show() + } + + else -> { + badge.url?.let { + onEvent( + AboutEvent.OnNavigateToBrowserPage( + it, + context, + noAppsFound = { + Toast.makeText( + context, + context.getString(R.string.error_no_browser), + Toast.LENGTH_SHORT + ).show() + } + ) + ) + } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/github.xml b/app/src/main/res/drawable/github.xml new file mode 100644 index 00000000..85acf69d --- /dev/null +++ b/app/src/main/res/drawable/github.xml @@ -0,0 +1,14 @@ + + + + + diff --git a/app/src/main/res/drawable/reddit.xml b/app/src/main/res/drawable/reddit.xml new file mode 100644 index 00000000..665e0eaa --- /dev/null +++ b/app/src/main/res/drawable/reddit.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + diff --git a/app/src/main/res/drawable/tryzub.xml b/app/src/main/res/drawable/tryzub.xml new file mode 100644 index 00000000..176f1594 --- /dev/null +++ b/app/src/main/res/drawable/tryzub.xml @@ -0,0 +1,13 @@ + + + + + diff --git a/app/src/main/res/drawable/x_logo.xml b/app/src/main/res/drawable/x_logo.xml new file mode 100644 index 00000000..85cf4d58 --- /dev/null +++ b/app/src/main/res/drawable/x_logo.xml @@ -0,0 +1,11 @@ + + + + + diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 05ffe763..94afd041 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -293,12 +293,11 @@ Book\'s Story v%1$s Натисніть, щоб перевірити на оновлення Повідомити про помилку - Сторінка проєкта + Що нового Підтримати мою роботу Ліцензії з відкритим кодом Заслуги - Слава Україні! - Героям Слава! 🇺🇦🐉 + Слава Україні! Дизайн @@ -485,5 +484,8 @@ Скинути початковий посібник Вийти з режиму редагування Відкрити в браузері + Тризуб + GitHub Проєкт + GitHub Профіль \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7b107349..45864a72 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -20,9 +20,6 @@ https://www.github.com/Acclorite/book-story/issues - - https://www.github.com/Acclorite/book-story - https://www.buymeacoffee.com/acclorite @@ -311,12 +308,11 @@ Book\'s Story v%1$s Click to check for updates Report a bug - Project\'s page + What\'s new Support my work Open source licenses Credits - Slava Ukraini! - Heroyam Slava! 🇺🇦🐉 + Slava Ukraini! Design @@ -504,5 +500,10 @@ Reset start guide Exit editing mode Open in web + X + Reddit + Tryzub + GitHub Project + GitHub Profile \ No newline at end of file