Skip to content

Commit 2f54009

Browse files
committed
Issue #17: Add setting option to change font family
1 parent 27c449a commit 2f54009

14 files changed

Lines changed: 242 additions & 57 deletions

File tree

app/src/main/java/com/amrdeveloper/linkhub/ui/explorer/ExplorerFragment.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,10 @@ class ExplorerFragment : Fragment() {
3333

3434
val safeArguments by navArgs<ExplorerFragmentArgs>()
3535
setContent {
36-
LinkhubAppTheme(isSystemInDarkTheme = uiPreferences.getThemeType() == Theme.DARK) {
36+
LinkhubAppTheme(
37+
isSystemInDarkTheme = uiPreferences.getThemeType() == Theme.DARK,
38+
fontFamilyName = uiPreferences.getFontFamilyName()
39+
) {
3740
ExplorerScreen(
3841
currentFolder = safeArguments.folder,
3942
viewModel = viewModel(),

app/src/main/java/com/amrdeveloper/linkhub/ui/folder/FolderFragment.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,10 @@ class FolderFragment : Fragment() {
3333
)
3434

3535
setContent {
36-
LinkhubAppTheme(isSystemInDarkTheme = uiPreferences.getThemeType() == Theme.DARK) {
36+
LinkhubAppTheme(
37+
isSystemInDarkTheme = uiPreferences.getThemeType() == Theme.DARK,
38+
fontFamilyName = uiPreferences.getFontFamilyName()
39+
) {
3740
FolderScreen(
3841
currentFolder = safeArguments.folder,
3942
viewModel = viewModel(),

app/src/main/java/com/amrdeveloper/linkhub/ui/folders/FoldersFragment.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,10 @@ class FoldersFragment : Fragment() {
3131
)
3232

3333
setContent {
34-
LinkhubAppTheme(isSystemInDarkTheme = uiPreferences.getThemeType() == Theme.DARK) {
34+
LinkhubAppTheme(
35+
isSystemInDarkTheme = uiPreferences.getThemeType() == Theme.DARK,
36+
fontFamilyName = uiPreferences.getFontFamilyName()
37+
) {
3538
FoldersScreen(
3639
viewModel = viewModel(),
3740
uiPreferences = uiPreferences,

app/src/main/java/com/amrdeveloper/linkhub/ui/home/HomeFragment.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,10 @@ class HomeFragment : Fragment() {
3131
)
3232

3333
setContent {
34-
LinkhubAppTheme(isSystemInDarkTheme = uiPreferences.getThemeType() == Theme.DARK) {
34+
LinkhubAppTheme(
35+
isSystemInDarkTheme = uiPreferences.getThemeType() == Theme.DARK,
36+
fontFamilyName = uiPreferences.getFontFamilyName()
37+
) {
3538
HomeScreen(
3639
viewModel = viewModel(),
3740
navController = findNavController(),

app/src/main/java/com/amrdeveloper/linkhub/ui/link/LinkFragment.kt

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,24 +24,24 @@ class LinkFragment : Fragment() {
2424
lateinit var uiPreferences: UiPreferences
2525

2626
override fun onCreateView(
27-
inflater: LayoutInflater,
28-
container: ViewGroup?,
29-
savedInstanceState: Bundle?
27+
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
3028
): View {
31-
val safeArguments by navArgs<LinkFragmentArgs>()
29+
val safeArguments by navArgs<LinkFragmentArgs>()
3230
return ComposeView(requireContext()).apply {
3331
setViewCompositionStrategy(
3432
ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed
3533
)
3634

3735
val sharedLink = arguments?.getString("shared_link")
3836
val isSharedLink = sharedLink != null
39-
val currentLink =
40-
if (isSharedLink) Link(title = "", subtitle = "", url = sharedLink)
41-
else safeArguments.link
37+
val currentLink = if (isSharedLink) Link(title = "", subtitle = "", url = sharedLink)
38+
else safeArguments.link
4239

4340
setContent {
44-
LinkhubAppTheme(isSystemInDarkTheme = uiPreferences.getThemeType() == Theme.DARK) {
41+
LinkhubAppTheme(
42+
isSystemInDarkTheme = uiPreferences.getThemeType() == Theme.DARK,
43+
fontFamilyName = uiPreferences.getFontFamilyName()
44+
) {
4545
LinkScreen(
4646
currentLink = currentLink,
4747
isSharedLink = isSharedLink,

app/src/main/java/com/amrdeveloper/linkhub/ui/setting/SettingFragment.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,10 @@ class SettingFragment : Fragment() {
3131
)
3232

3333
setContent {
34-
LinkhubAppTheme(isSystemInDarkTheme = uiPreferences.getThemeType() == Theme.DARK) {
34+
LinkhubAppTheme(
35+
isSystemInDarkTheme = uiPreferences.getThemeType() == Theme.DARK,
36+
fontFamilyName = uiPreferences.getFontFamilyName()
37+
) {
3538
SettingsScreen(
3639
uiPreferences = uiPreferences,
3740
navController = findNavController()

app/src/main/java/com/amrdeveloper/linkhub/ui/setting/SettingsScreen.kt

Lines changed: 124 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,17 @@ import androidx.compose.foundation.layout.Column
66
import androidx.compose.foundation.layout.Row
77
import androidx.compose.foundation.layout.Spacer
88
import androidx.compose.foundation.layout.fillMaxWidth
9+
import androidx.compose.foundation.layout.heightIn
910
import androidx.compose.foundation.layout.padding
1011
import androidx.compose.foundation.layout.size
1112
import androidx.compose.foundation.layout.width
13+
import androidx.compose.foundation.layout.widthIn
1214
import androidx.compose.foundation.shape.RoundedCornerShape
1315
import androidx.compose.material3.Card
1416
import androidx.compose.material3.CardDefaults
17+
import androidx.compose.material3.DropdownMenuItem
18+
import androidx.compose.material3.ExperimentalMaterial3Api
19+
import androidx.compose.material3.ExposedDropdownMenuBox
1520
import androidx.compose.material3.Icon
1621
import androidx.compose.material3.MaterialTheme
1722
import androidx.compose.material3.Switch
@@ -34,6 +39,7 @@ import androidx.navigation.NavController
3439
import com.amrdeveloper.linkhub.BuildConfig
3540
import com.amrdeveloper.linkhub.R
3641
import com.amrdeveloper.linkhub.data.Theme
42+
import com.amrdeveloper.linkhub.ui.theme.supportedFontFamilies
3743
import com.amrdeveloper.linkhub.util.UiPreferences
3844
import com.amrdeveloper.linkhub.util.openLinkIntent
3945
import com.amrdeveloper.linkhub.util.packageName
@@ -60,13 +66,15 @@ fun SettingsScreen(
6066
}
6167

6268
Column(modifier = Modifier.padding(8.dp)) {
63-
TextMenuOption(
69+
// Info section
70+
SimpleSettingOption(
6471
text = "Version ${BuildConfig.VERSION_NAME}",
6572
icon = R.drawable.ic_version,
6673
onClick = {}
6774
)
6875

69-
TextSwitchMenuOption(
76+
// UI Settings section
77+
SwitchSettingOption(
7078
text = "Dark mode",
7179
icon = R.drawable.ic_dark_mode,
7280
isChecked = uiPreferences.getThemeType() == Theme.DARK,
@@ -80,7 +88,18 @@ fun SettingsScreen(
8088
}
8189
)
8290

83-
TextSwitchMenuOption(
91+
DropdownSettingOption(
92+
text = "Font family",
93+
icon = R.drawable.ic_font,
94+
defaultSelectedIndex = supportedFontFamilies.keys.indexOf(uiPreferences.getFontFamilyName())
95+
.coerceAtLeast(0),
96+
options = supportedFontFamilies.keys.toList(),
97+
onOptionSelected = { fondFamily ->
98+
uiPreferences.setFontFamilyName(fondFamily)
99+
}
100+
)
101+
102+
SwitchSettingOption(
84103
text = "Show Counter",
85104
icon = R.drawable.ic_click,
86105
isChecked = uiPreferences.isClickCounterEnabled(),
@@ -89,7 +108,7 @@ fun SettingsScreen(
89108
}
90109
)
91110

92-
TextSwitchMenuOption(
111+
SwitchSettingOption(
93112
text = "Auto saving",
94113
icon = R.drawable.ic_save,
95114
isChecked = uiPreferences.isAutoSavingEnabled(),
@@ -98,7 +117,7 @@ fun SettingsScreen(
98117
}
99118
)
100119

101-
TextSwitchMenuOption(
120+
SwitchSettingOption(
102121
text = "Remember last folder",
103122
icon = R.drawable.ic_folders,
104123
isChecked = uiPreferences.isDefaultFolderEnabled(),
@@ -107,50 +126,50 @@ fun SettingsScreen(
107126
}
108127
)
109128

110-
TextMenuOption(
129+
SimpleSettingOption(
111130
text = "Password",
112131
icon = R.drawable.ic_password,
113132
onClick = { navController.navigate(R.id.configPasswordFragment) }
114133
)
115134

116-
TextMenuOption(
135+
SimpleSettingOption(
117136
text = "Import/Export",
118137
icon = R.drawable.ic_import_export,
119138
onClick = { navController.navigate(R.id.importExportFragment) }
120139
)
121140

122-
// Open source
123-
TextMenuOption(
141+
// Open source section
142+
SimpleSettingOption(
124143
text = "Source code",
125144
icon = R.drawable.ic_code,
126145
onClick = { selectedUrlOptionToOpen = REPOSITORY_URL }
127146
)
128147

129-
TextMenuOption(
148+
SimpleSettingOption(
130149
text = "Sponsor",
131150
icon = R.drawable.ic_github_sponsor,
132151
onClick = {
133152
selectedUrlOptionToOpen = REPOSITORY_SPONSORSHIP_URL
134153
}
135154
)
136155

137-
TextMenuOption(
156+
SimpleSettingOption(
138157
text = "Contributors",
139158
icon = R.drawable.ic_team,
140159
onClick = {
141160
selectedUrlOptionToOpen = REPOSITORY_CONTRIBUTORS_URL
142161
}
143162
)
144163

145-
TextMenuOption(
164+
SimpleSettingOption(
146165
text = "Issues",
147166
icon = R.drawable.ic_problems,
148167
onClick = {
149168
selectedUrlOptionToOpen = REPOSITORY_ISSUES_URL
150169
}
151170
)
152171

153-
TextMenuOption(
172+
SimpleSettingOption(
154173
text = "Share",
155174
icon = R.drawable.ic_share,
156175
onClick = { selectedUrlOptionToOpen = PLAY_STORE_URL }
@@ -159,19 +178,15 @@ fun SettingsScreen(
159178
}
160179

161180
@Composable
162-
private fun TextMenuOption(text: String, icon: Int, onClick: () -> Unit = {}) {
181+
private fun SimpleSettingOption(text: String, icon: Int, onClick: () -> Unit = {}) {
163182
Card(
164183
modifier = Modifier
165184
.fillMaxWidth()
166185
.clickable { onClick() }
167186
.padding(4.dp),
168187
shape = RoundedCornerShape(12.dp),
169-
colors = CardDefaults.cardColors(
170-
containerColor = MaterialTheme.colorScheme.surfaceVariant,
171-
),
172-
elevation = CardDefaults.cardElevation(
173-
defaultElevation = 6.dp
174-
)
188+
colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surfaceVariant),
189+
elevation = CardDefaults.cardElevation(defaultElevation = 6.dp)
175190
) {
176191
Row(
177192
verticalAlignment = Alignment.CenterVertically,
@@ -195,7 +210,7 @@ private fun TextMenuOption(text: String, icon: Int, onClick: () -> Unit = {}) {
195210
}
196211

197212
@Composable
198-
private fun TextSwitchMenuOption(
213+
private fun SwitchSettingOption(
199214
text: String,
200215
icon: Int,
201216
isChecked: Boolean = false,
@@ -249,3 +264,91 @@ private fun TextSwitchMenuOption(
249264
}
250265
}
251266
}
267+
268+
@OptIn(ExperimentalMaterial3Api::class)
269+
@Composable
270+
private fun DropdownSettingOption(
271+
text: String,
272+
icon: Int,
273+
options: List<String>,
274+
defaultSelectedIndex: Int = 0,
275+
onOptionSelected: (String) -> Unit = {}
276+
) {
277+
var expanded by remember { mutableStateOf(false) }
278+
var selectedIndex by remember { mutableStateOf(defaultSelectedIndex) }
279+
280+
Card(
281+
modifier = Modifier
282+
.fillMaxWidth()
283+
.padding(4.dp),
284+
shape = RoundedCornerShape(12.dp),
285+
colors = CardDefaults.cardColors(
286+
containerColor = MaterialTheme.colorScheme.surfaceVariant,
287+
),
288+
elevation = CardDefaults.cardElevation(
289+
defaultElevation = 6.dp
290+
)
291+
) {
292+
Row(
293+
verticalAlignment = Alignment.CenterVertically,
294+
modifier = Modifier.padding(8.dp)
295+
) {
296+
Icon(
297+
painter = painterResource(icon),
298+
contentDescription = "Font Icon",
299+
tint = Color.Unspecified,
300+
modifier = Modifier.size(20.dp)
301+
)
302+
303+
Spacer(modifier = Modifier.width(8.dp))
304+
305+
Text(
306+
text = text,
307+
style = MaterialTheme.typography.bodyLarge
308+
)
309+
310+
Spacer(modifier = Modifier.weight(1f))
311+
312+
ExposedDropdownMenuBox(
313+
expanded = expanded,
314+
onExpandedChange = { expanded = !expanded }) {
315+
316+
Row(
317+
modifier = Modifier.clickable {
318+
expanded = true
319+
},
320+
verticalAlignment = Alignment.CenterVertically
321+
) {
322+
Icon(
323+
painter = painterResource(R.drawable.ic_arrow_down),
324+
contentDescription = "Arrow down",
325+
tint = Color.Unspecified,
326+
modifier = Modifier.size(20.dp)
327+
)
328+
Spacer(modifier = Modifier.width(4.dp))
329+
Text(options[selectedIndex])
330+
}
331+
332+
ExposedDropdownMenu(
333+
expanded = expanded,
334+
onDismissRequest = { expanded = false },
335+
modifier = Modifier
336+
.heightIn(max = 200.dp)
337+
.widthIn(min = 100.dp)
338+
) {
339+
options.forEachIndexed { index, selectionOption ->
340+
DropdownMenuItem(
341+
text = { Text(selectionOption) },
342+
onClick = {
343+
expanded = false
344+
selectedIndex = index
345+
onOptionSelected(selectionOption)
346+
},
347+
)
348+
}
349+
}
350+
}
351+
}
352+
}
353+
354+
}

app/src/main/java/com/amrdeveloper/linkhub/ui/theme/Theme.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import androidx.compose.material3.MaterialTheme
55
import androidx.compose.material3.darkColorScheme
66
import androidx.compose.material3.lightColorScheme
77
import androidx.compose.runtime.Composable
8+
import androidx.compose.ui.text.font.FontFamily
89

910
private val LightColors = lightColorScheme(
1011
primary = lightBlue600,
@@ -35,11 +36,12 @@ private val DarkColors = darkColorScheme(
3536
@Composable
3637
fun LinkhubAppTheme(
3738
isSystemInDarkTheme: Boolean = isSystemInDarkTheme(),
39+
fontFamilyName: String = "Default",
3840
content: @Composable () -> Unit
3941
) {
4042
MaterialTheme(
4143
colorScheme = if (isSystemInDarkTheme) DarkColors else LightColors,
42-
typography = Typography,
44+
typography = getLinkhubTypography(supportedFontFamilies[fontFamilyName] ?: FontFamily.Default),
4345
content = content
4446
)
4547
}

0 commit comments

Comments
 (0)