compose: about: Initial migration
Signed-off-by: Aayush Gupta <aayushgupta219@gmail.com>
This commit is contained in:
@@ -12,7 +12,10 @@ import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.requiredSize
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
@@ -20,11 +23,16 @@ import androidx.compose.material3.VerticalDivider
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.dimensionResource
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import coil3.compose.AsyncImage
|
||||
import coil3.request.ImageRequest
|
||||
import coil3.request.crossfade
|
||||
import com.aurora.store.R
|
||||
import com.aurora.store.data.model.Link
|
||||
|
||||
@@ -40,13 +48,19 @@ fun LinkComposable(modifier: Modifier = Modifier, link: Link, onClick: () -> Uni
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.clickable(onClick = onClick)
|
||||
.padding(dimensionResource(R.dimen.padding_small)),
|
||||
.padding(dimensionResource(R.dimen.padding_medium)),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(dimensionResource(R.dimen.margin_medium))
|
||||
) {
|
||||
Icon(
|
||||
painter = painterResource(link.icon),
|
||||
contentDescription = null
|
||||
AsyncImage(
|
||||
model = ImageRequest.Builder(LocalContext.current)
|
||||
.data(link.icon)
|
||||
.build(),
|
||||
contentDescription = null,
|
||||
contentScale = ContentScale.Crop,
|
||||
modifier = Modifier
|
||||
.requiredSize(dimensionResource(R.dimen.icon_size_default))
|
||||
.clip(CircleShape)
|
||||
)
|
||||
VerticalDivider(
|
||||
modifier = Modifier
|
||||
@@ -64,7 +78,7 @@ fun LinkComposable(modifier: Modifier = Modifier, link: Link, onClick: () -> Uni
|
||||
Text(
|
||||
text = link.subtitle,
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
maxLines = 1,
|
||||
maxLines = 2,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import androidx.navigation3.ui.NavDisplay
|
||||
import androidx.navigation3.ui.rememberSceneSetupNavEntryDecorator
|
||||
import com.aurora.store.MainActivity
|
||||
import com.aurora.store.R
|
||||
import com.aurora.store.compose.ui.about.AboutScreen
|
||||
import com.aurora.store.compose.ui.accounts.AccountsScreen
|
||||
import com.aurora.store.compose.ui.blacklist.BlacklistScreen
|
||||
import com.aurora.store.compose.ui.details.AppDetailsScreen
|
||||
@@ -109,6 +110,10 @@ fun NavDisplay(startDestination: NavKey) {
|
||||
onNavigateToSplash = { activity?.startActivity(splashIntent) }
|
||||
)
|
||||
}
|
||||
|
||||
entry<Screen.About> {
|
||||
AboutScreen(onNavigateUp = { onNavigateUp() })
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@@ -44,4 +44,7 @@ sealed class Screen : NavKey, Parcelable {
|
||||
|
||||
@Serializable
|
||||
data object Accounts : Screen()
|
||||
|
||||
@Serializable
|
||||
data object About : Screen()
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 The Calyx Institute
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
package com.aurora.store.compose.ui.about
|
||||
|
||||
import androidx.compose.material3.AlertDialog
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.aurora.store.R
|
||||
|
||||
/**
|
||||
* Dialog for displaying information about Aurora Store
|
||||
* @param onDismiss Callback on dismiss
|
||||
*/
|
||||
@Composable
|
||||
fun AboutDialog(onDismiss: () -> Unit = {}) {
|
||||
AlertDialog(
|
||||
title = { Text(text = stringResource(R.string.about_aurora_store_title)) },
|
||||
text = {
|
||||
Text(text = stringResource(R.string.about_aurora_store_summary))
|
||||
},
|
||||
onDismissRequest = onDismiss,
|
||||
confirmButton = {
|
||||
TextButton(onClick = onDismiss) {
|
||||
Text(text = stringResource(android.R.string.ok))
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
private fun AboutDialogPreview() {
|
||||
AboutDialog()
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 The Calyx Institute
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
package com.aurora.store.compose.ui.about
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.requiredSize
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.dimensionResource
|
||||
import androidx.compose.ui.res.stringArrayResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import coil3.compose.AsyncImage
|
||||
import coil3.request.ImageRequest
|
||||
import com.aurora.extensions.browse
|
||||
import com.aurora.store.BuildConfig.VERSION_CODE
|
||||
import com.aurora.store.BuildConfig.VERSION_NAME
|
||||
import com.aurora.store.R
|
||||
import com.aurora.store.compose.composables.LinkComposable
|
||||
import com.aurora.store.compose.composables.TopAppBarComposable
|
||||
import com.aurora.store.compose.ui.accounts.LogoutDialog
|
||||
import com.aurora.store.data.model.Link
|
||||
import com.aurora.store.data.providers.AccountProvider
|
||||
|
||||
@Composable
|
||||
fun AboutScreen(onNavigateUp: () -> Unit) {
|
||||
var shouldShowAboutDialog by rememberSaveable { mutableStateOf(false) }
|
||||
|
||||
if (shouldShowAboutDialog) {
|
||||
AboutDialog(onDismiss = { shouldShowAboutDialog = false })
|
||||
}
|
||||
|
||||
ScreenContent(
|
||||
onNavigateUp = onNavigateUp,
|
||||
onAboutAurora = { shouldShowAboutDialog = true }
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ScreenContent(onNavigateUp: () -> Unit = {}, onAboutAurora: () -> Unit = {}) {
|
||||
val context = LocalContext.current
|
||||
|
||||
val linkURLS = stringArrayResource(R.array.link_urls)
|
||||
val linkTitles = stringArrayResource(R.array.link_titles)
|
||||
val linkSummary = stringArrayResource(R.array.link_subtitle)
|
||||
val linkIcons = intArrayOf(
|
||||
R.drawable.ic_about,
|
||||
R.drawable.ic_help,
|
||||
R.drawable.ic_xda,
|
||||
R.drawable.ic_telegram,
|
||||
R.drawable.ic_gitlab,
|
||||
R.drawable.ic_fdroid,
|
||||
R.drawable.ic_bitcoin_btc,
|
||||
R.drawable.ic_bitcoin_bch,
|
||||
R.drawable.ic_ethereum_eth,
|
||||
R.drawable.ic_bhim,
|
||||
R.drawable.ic_paypal,
|
||||
R.drawable.ic_libera_pay,
|
||||
)
|
||||
|
||||
val links = linkURLS.mapIndexed { index, url ->
|
||||
Link(
|
||||
id = index,
|
||||
title = linkTitles[index],
|
||||
subtitle = linkSummary[index],
|
||||
url = url,
|
||||
icon = linkIcons[index]
|
||||
)
|
||||
}
|
||||
|
||||
Scaffold(
|
||||
topBar = {
|
||||
TopAppBarComposable(
|
||||
title = stringResource(R.string.title_about),
|
||||
onNavigateUp = onNavigateUp
|
||||
)
|
||||
}
|
||||
) { paddingValues ->
|
||||
LazyColumn(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(paddingValues),
|
||||
verticalArrangement = Arrangement.spacedBy(dimensionResource(R.dimen.margin_xxsmall))
|
||||
) {
|
||||
stickyHeader {
|
||||
Surface(modifier = Modifier.fillMaxWidth()) {
|
||||
BrandHeader()
|
||||
}
|
||||
}
|
||||
items(items = links, key = { item -> item.id }) { link ->
|
||||
LinkComposable(
|
||||
link = link,
|
||||
onClick = {
|
||||
when (link.id) {
|
||||
0 -> onAboutAurora()
|
||||
else -> context.browse(link.url)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun BrandHeader() {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(dimensionResource(R.dimen.margin_medium)),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.spacedBy(dimensionResource(R.dimen.margin_xxsmall))
|
||||
) {
|
||||
AsyncImage(
|
||||
model = ImageRequest.Builder(LocalContext.current)
|
||||
.data(R.mipmap.ic_launcher)
|
||||
.build(),
|
||||
contentDescription = null,
|
||||
contentScale = ContentScale.Crop,
|
||||
modifier = Modifier
|
||||
.requiredSize(dimensionResource(R.dimen.icon_size))
|
||||
.clip(CircleShape)
|
||||
)
|
||||
Text(
|
||||
text = stringResource(R.string.app_name),
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
Text(
|
||||
text = stringResource(R.string.version, VERSION_NAME, VERSION_CODE),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
Text(
|
||||
text = stringResource(R.string.made_with_love, String(Character.toChars(0x2764))),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
private fun AboutScreenPreview() {
|
||||
ScreenContent()
|
||||
}
|
||||
@@ -15,8 +15,8 @@ import com.aurora.store.R
|
||||
|
||||
/**
|
||||
* Dialog for confirming log out
|
||||
* @param onConfirm Callback when the token has been entered
|
||||
* @param onDismiss Callback when the dialog has been dismissed
|
||||
* @param onConfirm Callback on confirmation
|
||||
* @param onDismiss Callback on dismiss
|
||||
*/
|
||||
@Composable
|
||||
fun LogoutDialog(onConfirm: () -> Unit = {}, onDismiss: () -> Unit = {}) {
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
* Aurora Store
|
||||
* Copyright (C) 2021, Rahul Kumar Patel <whyorean@gmail.com>
|
||||
*
|
||||
* Aurora Store is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Aurora Store is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Aurora Store. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.aurora.store.view.epoxy.views.preference
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import coil3.load
|
||||
import com.airbnb.epoxy.CallbackProp
|
||||
import com.airbnb.epoxy.ModelProp
|
||||
import com.airbnb.epoxy.ModelView
|
||||
import com.aurora.extensions.hide
|
||||
import com.aurora.extensions.show
|
||||
import com.aurora.store.data.model.Link
|
||||
import com.aurora.store.databinding.ViewLinkBinding
|
||||
import com.aurora.store.view.epoxy.views.BaseModel
|
||||
import com.aurora.store.view.epoxy.views.BaseView
|
||||
|
||||
@ModelView(
|
||||
autoLayout = ModelView.Size.MATCH_WIDTH_WRAP_HEIGHT,
|
||||
baseModelClass = BaseModel::class
|
||||
)
|
||||
class LinkView @JvmOverloads constructor(
|
||||
context: Context?,
|
||||
attrs: AttributeSet? = null,
|
||||
defStyleAttr: Int = 0
|
||||
) : BaseView<ViewLinkBinding>(context, attrs, defStyleAttr) {
|
||||
|
||||
@ModelProp
|
||||
fun link(link: Link) {
|
||||
binding.line1.text = link.title
|
||||
binding.line2.text = link.subtitle
|
||||
|
||||
if (link.url.startsWith("http") || link.url.startsWith("upi")) {
|
||||
binding.line3.hide()
|
||||
} else {
|
||||
binding.line3.show()
|
||||
binding.line3.text = link.url
|
||||
}
|
||||
|
||||
binding.imgIcon.load(link.icon)
|
||||
}
|
||||
|
||||
@CallbackProp
|
||||
fun click(onClickListener: OnClickListener?) {
|
||||
binding.root.setOnClickListener(onClickListener)
|
||||
}
|
||||
}
|
||||
@@ -1,114 +0,0 @@
|
||||
/*
|
||||
* Aurora Store
|
||||
* Copyright (C) 2021, Rahul Kumar Patel <whyorean@gmail.com>
|
||||
*
|
||||
* Aurora Store is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Aurora Store is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Aurora Store. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.aurora.store.view.ui.about
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import coil3.load
|
||||
import com.aurora.extensions.browse
|
||||
import com.aurora.extensions.copyToClipBoard
|
||||
import com.aurora.store.BuildConfig
|
||||
import com.aurora.store.R
|
||||
import com.aurora.store.data.model.Link
|
||||
import com.aurora.store.databinding.FragmentAboutBinding
|
||||
import com.aurora.store.view.epoxy.views.preference.LinkViewModel_
|
||||
import com.aurora.store.view.ui.commons.BaseFragment
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
|
||||
@AndroidEntryPoint
|
||||
class AboutFragment : BaseFragment<FragmentAboutBinding>() {
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
// Toolbar
|
||||
binding.toolbar.setNavigationOnClickListener { findNavController().navigateUp() }
|
||||
|
||||
// About Details
|
||||
binding.imgIcon.load(R.mipmap.ic_launcher)
|
||||
binding.line2.text = view.context.getString(
|
||||
R.string.version,
|
||||
BuildConfig.VERSION_NAME,
|
||||
BuildConfig.VERSION_CODE
|
||||
)
|
||||
binding.line3.text = getString(R.string.made_with_love, String(Character.toChars(0x2764)))
|
||||
|
||||
binding.epoxyRecycler.layoutManager =
|
||||
LinearLayoutManager(view.context, RecyclerView.VERTICAL, false)
|
||||
|
||||
updateController()
|
||||
}
|
||||
|
||||
private fun updateController() {
|
||||
val linkURLS = resources.getStringArray(R.array.link_urls)
|
||||
val linkTitles = resources.getStringArray(R.array.link_titles)
|
||||
val linkSummary = resources.getStringArray(R.array.link_subtitle)
|
||||
|
||||
val linkIcons = intArrayOf(
|
||||
R.drawable.ic_menu_about,
|
||||
R.drawable.ic_help,
|
||||
R.drawable.ic_xda,
|
||||
R.drawable.ic_telegram,
|
||||
R.drawable.ic_gitlab,
|
||||
R.drawable.ic_fdroid,
|
||||
R.drawable.ic_bitcoin_btc,
|
||||
R.drawable.ic_bitcoin_bch,
|
||||
R.drawable.ic_ethereum_eth,
|
||||
R.drawable.ic_bhim,
|
||||
R.drawable.ic_paypal,
|
||||
R.drawable.ic_libera_pay,
|
||||
)
|
||||
|
||||
binding.epoxyRecycler.withModels {
|
||||
for (i in linkURLS.indices) {
|
||||
val link = Link(
|
||||
id = i,
|
||||
title = linkTitles[i],
|
||||
subtitle = linkSummary[i],
|
||||
url = linkURLS[i],
|
||||
icon = linkIcons[i]
|
||||
)
|
||||
add(
|
||||
LinkViewModel_()
|
||||
.id(i)
|
||||
.link(link)
|
||||
.click { _ ->
|
||||
if (link.id == 0) {
|
||||
findNavController().navigate(R.id.aboutDialog)
|
||||
} else {
|
||||
processUrl(link.url)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun processUrl(url: String) {
|
||||
when {
|
||||
url.startsWith("http") -> context?.browse(url)
|
||||
url.startsWith("upi") -> context?.browse(url)
|
||||
else -> context?.copyToClipBoard(url)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -453,10 +453,10 @@ class MoreDialogFragment : DialogFragment() {
|
||||
icon = R.drawable.ic_menu_settings,
|
||||
destinationID = R.id.settingsFragment
|
||||
),
|
||||
ViewOption(
|
||||
ComposeOption(
|
||||
title = R.string.title_about,
|
||||
icon = R.drawable.ic_menu_about,
|
||||
destinationID = R.id.aboutFragment
|
||||
screen = Screen.About
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ abstract class BaseFlavouredSplashFragment : BaseFragment<FragmentSplashBinding>
|
||||
findNavController().navigate(R.id.settingsFragment)
|
||||
}
|
||||
|
||||
R.id.menu_about -> findNavController().navigate(R.id.aboutFragment)
|
||||
R.id.menu_about -> requireContext().navigate(Screen.About)
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user