Fixed Linted issuse related to Magic numbers and long methods and did the requested changes

This commit is contained in:
Soumen Pal 2025-03-07 23:02:09 +05:30 committed by Kelson
parent 00330273d2
commit 55b6ab129d
6 changed files with 231 additions and 196 deletions

View File

@ -1,74 +0,0 @@
/*
* Kiwix Android
* Copyright (c) 2019 Kiwix <android.kiwix.org>
* This program 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 3 of the License, or
* (at your option) any later version.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package org.kiwix.kiwixmobile.core.help
import android.animation.ObjectAnimator
import android.text.method.LinkMovementMethod
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.core.view.isGone
import androidx.recyclerview.widget.RecyclerView
import org.kiwix.kiwixmobile.core.base.adapter.BaseViewHolder
import org.kiwix.kiwixmobile.core.databinding.ItemHelpBinding
import org.kiwix.kiwixmobile.core.utils.AnimationUtils.collapse
import org.kiwix.kiwixmobile.core.utils.AnimationUtils.expand
internal class HelpAdapter(titleDescriptionMap: Map<String, String>) :
RecyclerView.Adapter<HelpAdapter.Item>() {
private var helpItems = titleDescriptionMap.map { (key, value) -> HelpItem(key, value) }
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): Item = Item(ItemHelpBinding.inflate(LayoutInflater.from(parent.context), parent, false))
override fun onBindViewHolder(
holder: Item,
position: Int
) {
holder.bind(helpItems[position])
}
override fun getItemCount(): Int = helpItems.size
internal inner class Item(private val itemHelpBinding: ItemHelpBinding) :
BaseViewHolder<HelpItem>(itemHelpBinding.root) {
@SuppressWarnings("MagicNumber")
fun toggleDescriptionVisibility() {
if (itemHelpBinding.itemHelpDescription.isGone) {
ObjectAnimator.ofFloat(itemHelpBinding.itemHelpToggleExpand, "rotation", 0f, 180f).start()
itemHelpBinding.itemHelpDescription.expand()
} else {
ObjectAnimator.ofFloat(itemHelpBinding.itemHelpToggleExpand, "rotation", 180f, 360f).start()
itemHelpBinding.itemHelpDescription.collapse()
}
}
override fun bind(item: HelpItem) {
itemHelpBinding.itemHelpTitle.setOnClickListener { toggleDescriptionVisibility() }
itemHelpBinding.itemHelpToggleExpand.setOnClickListener { toggleDescriptionVisibility() }
itemHelpBinding.itemHelpDescription.apply {
text = item.description
movementMethod = LinkMovementMethod.getInstance()
}
itemHelpBinding.itemHelpTitle.text = item.title
}
}
}
class HelpItem(val title: String, val description: String)

View File

@ -25,14 +25,16 @@ import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxHeight
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.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
@ -47,10 +49,12 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.colorResource import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import androidx.navigation.NavController import androidx.navigation.NavController
@ -58,56 +62,104 @@ import org.kiwix.kiwixmobile.core.R
import org.kiwix.kiwixmobile.core.error.DiagnosticReportActivity import org.kiwix.kiwixmobile.core.error.DiagnosticReportActivity
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.start import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.start
@OptIn(ExperimentalMaterial3Api::class) val SendDiagnosticReportFontSize = 18.sp
@Composable @Composable
fun HelpScreen( fun HelpScreen(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
data: List<HelpScreenItemDataClass>, data: List<HelpScreenItemDataClass>,
navController: NavController navController: NavController
) { ) {
val context = LocalContext.current
val isDarkTheme = isSystemInDarkTheme() val isDarkTheme = isSystemInDarkTheme()
val backgroundColor = val backgroundColor =
if (isDarkTheme) colorResource(id = R.color.mine_shaft_gray900) else Color.White if (isDarkTheme) colorResource(id = R.color.mine_shaft_gray900) else Color.White
val dividerColor = val dividerColor =
if (isDarkTheme) colorResource(id = R.color.mine_shaft_gray600) else colorResource( if (isDarkTheme) colorResource(id = R.color.mine_shaft_gray600)
id = R.color.mine_shaft_gray350 else colorResource(id = R.color.mine_shaft_gray350)
)
Scaffold( Scaffold(
modifier = Modifier.fillMaxSize(), modifier = Modifier.fillMaxSize(),
topBar = { topBar = {
TopAppBar( Row(
title = { modifier = Modifier.fillMaxWidth(),
Text( verticalAlignment = Alignment.CenterVertically
modifier = modifier.padding(start = 16.dp), ) {
text = stringResource(id = R.string.menu_help), HelpTopAppBar(navController)
color = Color.White // Set title text color to white }
)
}, },
navigationIcon = { containerColor = backgroundColor
IconButton(onClick = navController::popBackStack) { ) { innerPadding ->
Icon( HelpContent(data, dividerColor, innerPadding)
imageVector = Icons.Filled.ArrowBack, }
contentDescription = "Back", }
tint = Color.White // Set navigation icon color to white
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun HelpTopAppBar(navController: NavController) {
// Retrieve the actionBarSize from the current theme
val context = LocalContext.current
val actionBarHeight = with(LocalDensity.current) {
// Obtain the height defined in the theme (usually 56dp on phones)
val styledAttributes =
context.theme.obtainStyledAttributes(intArrayOf(android.R.attr.actionBarSize))
styledAttributes.getDimension(0, 0f).toDp().also { styledAttributes.recycle() }
}
TopAppBar(
modifier = Modifier.height(actionBarHeight), // set the height here
title = {
Row(
modifier = Modifier.fillMaxSize(),
verticalAlignment = Alignment.CenterVertically
) {
Text(
modifier = Modifier.padding(
start = dimensionResource(R.dimen.activity_horizontal_margin)
),
text = stringResource(id = R.string.menu_help),
color = Color.White,
fontWeight = FontWeight.SemiBold
) )
} }
}, },
colors = TopAppBarDefaults.topAppBarColors( navigationIcon = {
containerColor = Color.Black // Set top app bar background color to black Row(modifier = Modifier.fillMaxHeight(), verticalAlignment = Alignment.CenterVertically) {
IconButton(onClick = navController::popBackStack) {
Icon(
imageVector = Icons.AutoMirrored.Filled.ArrowBack,
contentDescription = "Back_Navigation",
tint = Color.White
) )
) }
}, }
containerColor = backgroundColor
) {
},
colors = TopAppBarDefaults.topAppBarColors(
containerColor = Color.Black
)
)
}
@Composable
fun HelpContent(
data: List<HelpScreenItemDataClass>,
dividerColor: Color,
innerPadding: androidx.compose.foundation.layout.PaddingValues
) {
Column( Column(
modifier = Modifier modifier = Modifier
.padding(it) .padding(innerPadding)
) { ) {
SendReportRow()
HelpItemList(data, dividerColor)
}
}
@Composable
fun SendReportRow() {
val context = LocalContext.current
val isDarkTheme = isSystemInDarkTheme()
Row( Row(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
@ -119,23 +171,26 @@ fun HelpScreen(
) { ) {
Image( Image(
painter = painterResource(R.drawable.ic_feedback_orange_24dp), painter = painterResource(R.drawable.ic_feedback_orange_24dp),
contentDescription = "Feedback", contentDescription = stringResource(R.string.send_report),
modifier = Modifier modifier = Modifier
.padding(16.dp) .padding(dimensionResource(R.dimen.activity_horizontal_margin))
) )
Text( Text(
text = stringResource(R.string.send_report), text = stringResource(R.string.send_report),
color = if (isDarkTheme) Color.LightGray else Color.DarkGray, color = if (isDarkTheme) Color.LightGray else Color.DarkGray,
fontSize = 18.sp fontSize = SendDiagnosticReportFontSize
) )
} }
}
@Composable
fun HelpItemList(data: List<HelpScreenItemDataClass>, dividerColor: Color) {
LazyColumn( LazyColumn(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
) { ) {
itemsIndexed(data, key = { _, item -> item.title }) { index, item -> itemsIndexed(data, key = { _, item -> item.title }) { _, item ->
HorizontalDivider( HorizontalDivider(
color = dividerColor color = dividerColor
) )
@ -148,5 +203,3 @@ fun HelpScreen(
} }
} }
} }
}
}

View File

@ -46,10 +46,23 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.Dp
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 org.kiwix.kiwixmobile.core.R
// Define constants for spacing, font sizes, etc.
private val HelpItemTitleFontSize = 22.sp
private val HelpItemDescriptionFontSize = 17.sp
private val IconSize = 36.dp
private const val HelpItemAnimationDuration = 300
private const val HelpItemArrowRotationOpen = 180f
private const val HelpItemArrowRotationClosed = 0f
@Composable @Composable
fun HelpScreenItem( fun HelpScreenItem(
@ -58,68 +71,82 @@ fun HelpScreenItem(
initiallyOpened: Boolean = false initiallyOpened: Boolean = false
) { ) {
var isOpen by remember { mutableStateOf(initiallyOpened) } var isOpen by remember { mutableStateOf(initiallyOpened) }
val isDarkTheme = isSystemInDarkTheme() val itemColor = if (isSystemInDarkTheme()) Color.White else Color.Black
val itemColor = if (isDarkTheme) Color.White else Color.Black
val arrowRotation by animateFloatAsState(
targetValue = if (isOpen) 180f else 0f,
animationSpec = tween(300),
label = "arrowRotation"
)
val interactionSource = remember(::MutableInteractionSource) val topPadding: Dp = dimensionResource(id = R.dimen.dimen_medium_padding)
val horizontalPadding: Dp = dimensionResource(id = R.dimen.activity_horizontal_margin)
Column( Column(
modifier = modifier modifier = modifier
.fillMaxWidth() .fillMaxWidth(),
.padding(top = 12.dp),
verticalArrangement = Arrangement.Center, verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally horizontalAlignment = Alignment.CenterHorizontally
) { ) {
HelpItemHeader(data.title, isOpen, itemColor, horizontalPadding) { isOpen = !isOpen }
AnimatedVisibility(visible = isOpen) {
Spacer(modifier = Modifier.height(topPadding))
HelpItemDescription(data.description, itemColor, horizontalPadding)
}
}
}
@Composable
fun HelpItemHeader(
title: String,
isOpen: Boolean,
itemColor: Color,
horizontalPadding: Dp,
onToggle: () -> Unit
) {
val arrowRotation by animateFloatAsState(
targetValue = if (isOpen) HelpItemArrowRotationOpen else HelpItemArrowRotationClosed,
animationSpec = tween(HelpItemAnimationDuration),
label = "arrowRotation"
)
val interactionSource = remember(::MutableInteractionSource)
Row( Row(
horizontalArrangement = Arrangement.SpaceBetween, horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.clickable(interactionSource = interactionSource, indication = null, onClick = { .clickable(interactionSource = interactionSource, indication = null, onClick = onToggle)
isOpen = !isOpen .padding(horizontal = horizontalPadding, vertical = horizontalPadding)
})
.padding(horizontal = 16.dp)
) { ) {
Text( Text(
text = data.title, text = title,
fontSize = 18.sp, fontSize = HelpItemTitleFontSize,
color = itemColor, color = itemColor,
fontWeight = FontWeight.SemiBold fontWeight = FontWeight.Normal
) )
Icon( Icon(
imageVector = Icons.Default.KeyboardArrowDown, imageVector = Icons.Default.KeyboardArrowDown,
contentDescription = "Open or Close DropDown", contentDescription = stringResource(R.string.expand),
modifier = Modifier modifier = Modifier
.graphicsLayer { .graphicsLayer {
rotationZ = arrowRotation rotationZ = arrowRotation
} }
.size(46.dp), .size(IconSize),
tint = itemColor tint = itemColor
) )
} }
}
Spacer(modifier = Modifier.height(12.dp)) @Composable
fun HelpItemDescription(description: String, itemColor: Color, horizontalPadding: Dp) {
AnimatedVisibility(visible = isOpen) {
Box( Box(
contentAlignment = Alignment.Center, contentAlignment = Alignment.Center,
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(start = 16.dp, end = 16.dp) .padding(start = horizontalPadding, end = horizontalPadding)
) { ) {
Text( Text(
text = data.description, text = description,
fontSize = 16.sp, fontSize = HelpItemDescriptionFontSize,
textAlign = TextAlign.Left, textAlign = TextAlign.Left,
color = itemColor, color = itemColor,
modifier = Modifier.padding(bottom = 8.dp) modifier = Modifier.padding(bottom = horizontalPadding),
fontWeight = FontWeight.Normal
) )
} }
} }
}
}

View File

@ -18,5 +18,5 @@
package org.kiwix.kiwixmobile.core.help package org.kiwix.kiwixmobile.core.help
//same as HelpItem data class in HelpAdapter.kt // same as HelpItem data class in earlier in XML
data class HelpScreenItemDataClass(val title: String, val description: String) data class HelpScreenItemDataClass(val title: String, val description: String)

View File

@ -20,4 +20,32 @@ package org.kiwix.kiwixmobile.custom.help
import org.kiwix.kiwixmobile.core.help.HelpFragment import org.kiwix.kiwixmobile.core.help.HelpFragment
class CustomHelpFragment : HelpFragment() class CustomHelpFragment : HelpFragment() {
override val navHostFragmentId: Int
get() = org.kiwix.kiwixmobile.custom.R.id.custom_nav_controller
override fun rawTitleDescriptionMap() =
if (sharedPreferenceUtil.isPlayStoreBuildWithAndroid11OrAbove()) {
listOf(
org.kiwix.kiwixmobile.core.R.string.help_2 to
org.kiwix.kiwixmobile.core.R.array.description_help_2,
org.kiwix.kiwixmobile.core.R.string.help_5 to
org.kiwix.kiwixmobile.core.R.array.description_help_5,
org.kiwix.kiwixmobile.core.R.string.how_to_update_content to
org.kiwix.kiwixmobile.core.R.array.update_content_description,
org.kiwix.kiwixmobile.core.R.string.why_copy_move_files_to_app_directory to
getString(
org.kiwix.kiwixmobile.core.R.string.copy_move_files_to_app_directory_description
)
)
} else {
listOf(
org.kiwix.kiwixmobile.core.R.string.help_2 to
org.kiwix.kiwixmobile.core.R.array.description_help_2,
org.kiwix.kiwixmobile.core.R.string.help_5 to
org.kiwix.kiwixmobile.core.R.array.description_help_5,
org.kiwix.kiwixmobile.core.R.string.how_to_update_content to
org.kiwix.kiwixmobile.core.R.array.update_content_description
)
}
}

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<lint> <lint>
<issue id="PrivateResource" severity="warning" />
<issue id="TypographyQuotes" severity="warning"> <issue id="TypographyQuotes" severity="warning">
<ignore path="**-qq/**.xml" /> <ignore path="**-qq/**.xml" />
<ignore path="**-iw/**.xml" /> <ignore path="**-iw/**.xml" />