feat: font scaler added
This commit is contained in:
@@ -12,8 +12,11 @@ import androidx.activity.compose.setContent
|
|||||||
import androidx.activity.enableEdgeToEdge
|
import androidx.activity.enableEdgeToEdge
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
|
import androidx.compose.runtime.CompositionLocalProvider
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
|
import androidx.compose.ui.unit.Density
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import com.approagency.pharmacy.data.local.SessionManager
|
import com.approagency.pharmacy.data.local.SessionManager
|
||||||
@@ -52,11 +55,22 @@ class MainActivity : ComponentActivity(), OtpAutofillController {
|
|||||||
enableEdgeToEdge()
|
enableEdgeToEdge()
|
||||||
setContent {
|
setContent {
|
||||||
val themeMode by session.themeMode.collectAsState()
|
val themeMode by session.themeMode.collectAsState()
|
||||||
|
val fontScale by session.fontScale.collectAsState()
|
||||||
DrugTheme(themeMode = themeMode) {
|
DrugTheme(themeMode = themeMode) {
|
||||||
|
// مقیاسِ متنِ انتخابیِ کاربر روی fontScaleِ سیستم اعمال میشود
|
||||||
|
// تا کلِ متنهای اپ یکجا بزرگ/کوچک شوند.
|
||||||
|
val density = LocalDensity.current
|
||||||
|
CompositionLocalProvider(
|
||||||
|
LocalDensity provides Density(
|
||||||
|
density = density.density,
|
||||||
|
fontScale = density.fontScale * fontScale.scale
|
||||||
|
)
|
||||||
|
) {
|
||||||
AppNavGraph()
|
AppNavGraph()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* هنگام شروع اپ و هر بار بازگشت به اپ (مثلاً پس از بازگشت از درگاه پرداختِ
|
* هنگام شروع اپ و هر بار بازگشت به اپ (مثلاً پس از بازگشت از درگاه پرداختِ
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.approagency.pharmacy.data.local
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
|
import com.approagency.pharmacy.domain.model.FontScale
|
||||||
import com.approagency.pharmacy.domain.model.ThemeMode
|
import com.approagency.pharmacy.domain.model.ThemeMode
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
@@ -128,6 +129,20 @@ class SessionManager(context: Context) {
|
|||||||
runCatching { ThemeMode.valueOf(prefs.getString(KEY_THEME_MODE, null) ?: ThemeMode.SYSTEM.name) }
|
runCatching { ThemeMode.valueOf(prefs.getString(KEY_THEME_MODE, null) ?: ThemeMode.SYSTEM.name) }
|
||||||
.getOrDefault(ThemeMode.SYSTEM)
|
.getOrDefault(ThemeMode.SYSTEM)
|
||||||
|
|
||||||
|
// ---------- اندازهٔ متن ----------
|
||||||
|
|
||||||
|
private val _fontScale = MutableStateFlow(readFontScale())
|
||||||
|
val fontScale: StateFlow<FontScale> = _fontScale.asStateFlow()
|
||||||
|
|
||||||
|
fun setFontScale(scale: FontScale) {
|
||||||
|
prefs.edit().putString(KEY_FONT_SCALE, scale.name).apply()
|
||||||
|
_fontScale.value = scale
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun readFontScale(): FontScale =
|
||||||
|
runCatching { FontScale.valueOf(prefs.getString(KEY_FONT_SCALE, null) ?: FontScale.NORMAL.name) }
|
||||||
|
.getOrDefault(FontScale.NORMAL)
|
||||||
|
|
||||||
private fun readAccount() = AccountState(
|
private fun readAccount() = AccountState(
|
||||||
isLoggedIn = !token.isNullOrBlank(),
|
isLoggedIn = !token.isNullOrBlank(),
|
||||||
mobile = prefs.getString(KEY_MOBILE, null),
|
mobile = prefs.getString(KEY_MOBILE, null),
|
||||||
@@ -147,5 +162,6 @@ class SessionManager(context: Context) {
|
|||||||
const val KEY_SUB_TITLE = "subscription_title"
|
const val KEY_SUB_TITLE = "subscription_title"
|
||||||
const val KEY_SUB_EXPIRE = "subscription_expire_at"
|
const val KEY_SUB_EXPIRE = "subscription_expire_at"
|
||||||
const val KEY_THEME_MODE = "theme_mode"
|
const val KEY_THEME_MODE = "theme_mode"
|
||||||
|
const val KEY_FONT_SCALE = "font_scale"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package com.approagency.pharmacy.domain.model
|
||||||
|
|
||||||
|
/**
|
||||||
|
* اندازهٔ متنِ انتخابیِ کاربر (بهویژه برای کاربرانِ مسنتر).
|
||||||
|
* [scale] ضریبی است که روی fontScaleِ دستگاه اعمال میشود.
|
||||||
|
*/
|
||||||
|
enum class FontScale(val scale: Float, val label: String) {
|
||||||
|
NORMAL(1.0f, "معمولی"),
|
||||||
|
LARGE(1.2f, "بزرگ"),
|
||||||
|
XLARGE(1.45f, "خیلی بزرگ")
|
||||||
|
}
|
||||||
@@ -39,6 +39,7 @@ fun MainContainer(
|
|||||||
val account by session.account.collectAsState()
|
val account by session.account.collectAsState()
|
||||||
val sheetVisible by sheetController.visible.collectAsState()
|
val sheetVisible by sheetController.visible.collectAsState()
|
||||||
val themeMode by session.themeMode.collectAsState()
|
val themeMode by session.themeMode.collectAsState()
|
||||||
|
val fontScale by session.fontScale.collectAsState()
|
||||||
|
|
||||||
val drawerState = rememberDrawerState(DrawerValue.Closed)
|
val drawerState = rememberDrawerState(DrawerValue.Closed)
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
@@ -59,6 +60,8 @@ fun MainContainer(
|
|||||||
appVersion = appVersion,
|
appVersion = appVersion,
|
||||||
themeMode = themeMode,
|
themeMode = themeMode,
|
||||||
onThemeModeChange = { session.setThemeMode(it) },
|
onThemeModeChange = { session.setThemeMode(it) },
|
||||||
|
fontScale = fontScale,
|
||||||
|
onFontScaleChange = { session.setFontScale(it) },
|
||||||
onLogout = { showLogoutConfirm = true }
|
onLogout = { showLogoutConfirm = true }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package com.approagency.pharmacy.presentation.account
|
package com.approagency.pharmacy.presentation.account
|
||||||
|
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.rememberScrollState
|
||||||
|
import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
@@ -43,6 +45,7 @@ import androidx.compose.ui.text.font.FontWeight
|
|||||||
import androidx.compose.ui.unit.LayoutDirection
|
import androidx.compose.ui.unit.LayoutDirection
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import com.approagency.pharmacy.data.local.AccountState
|
import com.approagency.pharmacy.data.local.AccountState
|
||||||
|
import com.approagency.pharmacy.domain.model.FontScale
|
||||||
import com.approagency.pharmacy.domain.model.ThemeMode
|
import com.approagency.pharmacy.domain.model.ThemeMode
|
||||||
import com.vada.caller.ui.theme.dime
|
import com.vada.caller.ui.theme.dime
|
||||||
|
|
||||||
@@ -60,6 +63,8 @@ fun AccountDrawer(
|
|||||||
appVersion: String,
|
appVersion: String,
|
||||||
themeMode: ThemeMode,
|
themeMode: ThemeMode,
|
||||||
onThemeModeChange: (ThemeMode) -> Unit,
|
onThemeModeChange: (ThemeMode) -> Unit,
|
||||||
|
fontScale: FontScale,
|
||||||
|
onFontScaleChange: (FontScale) -> Unit,
|
||||||
onLogout: () -> Unit
|
onLogout: () -> Unit
|
||||||
) {
|
) {
|
||||||
ModalDrawerSheet(
|
ModalDrawerSheet(
|
||||||
@@ -71,6 +76,7 @@ fun AccountDrawer(
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxHeight()
|
.fillMaxHeight()
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
|
.verticalScroll(rememberScrollState())
|
||||||
.padding(horizontal = MaterialTheme.dime.lg, vertical = MaterialTheme.dime.xl)
|
.padding(horizontal = MaterialTheme.dime.lg, vertical = MaterialTheme.dime.xl)
|
||||||
) {
|
) {
|
||||||
Header(account)
|
Header(account)
|
||||||
@@ -121,7 +127,18 @@ fun AccountDrawer(
|
|||||||
Spacer(Modifier.height(MaterialTheme.dime.sm))
|
Spacer(Modifier.height(MaterialTheme.dime.sm))
|
||||||
ThemeModeSelector(selected = themeMode, onSelect = onThemeModeChange)
|
ThemeModeSelector(selected = themeMode, onSelect = onThemeModeChange)
|
||||||
|
|
||||||
Spacer(Modifier.weight(1f))
|
Spacer(Modifier.height(MaterialTheme.dime.lg))
|
||||||
|
|
||||||
|
// اندازهٔ متن (برای کاربرانِ مسنتر)
|
||||||
|
Text(
|
||||||
|
text = "اندازهٔ متن",
|
||||||
|
style = MaterialTheme.typography.titleSmall,
|
||||||
|
fontWeight = FontWeight.Bold
|
||||||
|
)
|
||||||
|
Spacer(Modifier.height(MaterialTheme.dime.sm))
|
||||||
|
FontScaleSelector(selected = fontScale, onSelect = onFontScaleChange)
|
||||||
|
|
||||||
|
Spacer(Modifier.height(MaterialTheme.dime.xl))
|
||||||
|
|
||||||
if (account.isLoggedIn) {
|
if (account.isLoggedIn) {
|
||||||
OutlinedButton(
|
OutlinedButton(
|
||||||
@@ -267,3 +284,23 @@ private fun ThemeModeSelector(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
|
@Composable
|
||||||
|
private fun FontScaleSelector(
|
||||||
|
selected: FontScale,
|
||||||
|
onSelect: (FontScale) -> Unit
|
||||||
|
) {
|
||||||
|
val options = FontScale.entries
|
||||||
|
SingleChoiceSegmentedButtonRow(modifier = Modifier.fillMaxWidth()) {
|
||||||
|
options.forEachIndexed { index, option ->
|
||||||
|
SegmentedButton(
|
||||||
|
selected = selected == option,
|
||||||
|
onClick = { onSelect(option) },
|
||||||
|
shape = SegmentedButtonDefaults.itemShape(index, options.size),
|
||||||
|
icon = {},
|
||||||
|
label = { Text(option.label, style = MaterialTheme.typography.labelSmall) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user