Skip to content

Commit 4e63b65

Browse files
committed
Enhancement: Beautiful About page with gradient header, stats cards, and modern link items
1 parent b4f583d commit 4e63b65

File tree

8 files changed

+582
-184
lines changed

8 files changed

+582
-184
lines changed

app/src/main/java/com/appcontrolx/ui/AboutFragment.kt

Lines changed: 69 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,74 +1,125 @@
11
package com.appcontrolx.ui
22

33
import android.content.Intent
4+
import android.content.pm.PackageManager
45
import android.net.Uri
56
import android.os.Build
67
import android.os.Bundle
78
import android.view.LayoutInflater
89
import android.view.View
910
import android.view.ViewGroup
1011
import androidx.fragment.app.Fragment
12+
import androidx.lifecycle.lifecycleScope
1113
import com.appcontrolx.R
1214
import com.appcontrolx.databinding.FragmentAboutBinding
1315
import com.appcontrolx.service.PermissionBridge
16+
import dagger.hilt.android.AndroidEntryPoint
17+
import kotlinx.coroutines.Dispatchers
18+
import kotlinx.coroutines.launch
19+
import kotlinx.coroutines.withContext
20+
import timber.log.Timber
1421

22+
@AndroidEntryPoint
1523
class AboutFragment : Fragment() {
1624

1725
private var _binding: FragmentAboutBinding? = null
18-
private val binding get() = _binding!!
26+
private val binding get() = _binding
1927

20-
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
28+
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
2129
_binding = FragmentAboutBinding.inflate(inflater, container, false)
22-
return binding.root
30+
return _binding?.root
2331
}
2432

2533
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
2634
super.onViewCreated(view, savedInstanceState)
2735

2836
setupAppInfo()
2937
setupSystemInfo()
38+
setupStats()
3039
setupLinks()
3140
}
3241

3342
private fun setupAppInfo() {
34-
val packageInfo = requireContext().packageManager
35-
.getPackageInfo(requireContext().packageName, 0)
36-
37-
binding.tvVersion.text = getString(R.string.about_version_format,
38-
packageInfo.versionName, packageInfo.longVersionCode)
43+
val b = binding ?: return
44+
try {
45+
val packageInfo = requireContext().packageManager
46+
.getPackageInfo(requireContext().packageName, 0)
47+
48+
b.tvVersion.text = getString(R.string.about_version_format,
49+
packageInfo.versionName, packageInfo.longVersionCode)
50+
} catch (e: Exception) {
51+
Timber.e(e, "Failed to get package info")
52+
}
3953

4054
// Current mode
41-
val mode = PermissionBridge().detectMode()
42-
binding.tvCurrentMode.text = mode.displayName()
55+
val mode = PermissionBridge(requireContext()).detectMode()
56+
b.tvCurrentMode.text = mode.displayName()
4357
}
4458

4559
private fun setupSystemInfo() {
46-
binding.tvDeviceInfo.text = getString(R.string.about_device_format,
47-
Build.MANUFACTURER, Build.MODEL)
48-
binding.tvAndroidVersion.text = getString(R.string.about_android_format,
60+
val b = binding ?: return
61+
b.tvDeviceInfo.text = getString(R.string.about_device_format,
62+
Build.MANUFACTURER.replaceFirstChar { it.uppercase() }, Build.MODEL)
63+
b.tvAndroidVersion.text = getString(R.string.about_android_format,
4964
Build.VERSION.RELEASE, Build.VERSION.SDK_INT)
5065
}
5166

67+
private fun setupStats() {
68+
val b = binding ?: return
69+
70+
lifecycleScope.launch {
71+
val (userApps, systemApps) = withContext(Dispatchers.IO) {
72+
val pm = requireContext().packageManager
73+
val packages = pm.getInstalledPackages(0)
74+
75+
var user = 0
76+
var system = 0
77+
78+
packages.forEach { pkg ->
79+
if ((pkg.applicationInfo.flags and android.content.pm.ApplicationInfo.FLAG_SYSTEM) != 0) {
80+
system++
81+
} else {
82+
user++
83+
}
84+
}
85+
86+
Pair(user, system)
87+
}
88+
89+
b.tvUserAppsCount.text = userApps.toString()
90+
b.tvSystemAppsCount.text = systemApps.toString()
91+
92+
// Actions count from prefs (placeholder for now)
93+
b.tvActionsCount.text = "0"
94+
}
95+
}
96+
5297
private fun setupLinks() {
53-
binding.btnGithub.setOnClickListener {
98+
val b = binding ?: return
99+
100+
b.btnGithub.setOnClickListener {
54101
openUrl("https://github.com/risunCode/AppControl-X")
55102
}
56103

57-
binding.btnShare.setOnClickListener {
104+
b.btnShare.setOnClickListener {
58105
shareApp()
59106
}
60107

61-
binding.btnRate.setOnClickListener {
108+
b.btnRate.setOnClickListener {
62109
openUrl("https://github.com/risunCode/AppControl-X/stargazers")
63110
}
64111

65-
binding.btnBugReport.setOnClickListener {
112+
b.btnBugReport.setOnClickListener {
66113
openUrl("https://github.com/risunCode/AppControl-X/issues/new")
67114
}
68115
}
69116

70117
private fun openUrl(url: String) {
71-
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url)))
118+
try {
119+
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url)))
120+
} catch (e: Exception) {
121+
Timber.e(e, "Failed to open URL: $url")
122+
}
72123
}
73124

74125
private fun shareApp() {
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<shape xmlns:android="http://schemas.android.com/apk/res/android">
3+
<gradient
4+
android:type="linear"
5+
android:angle="135"
6+
android:startColor="#1976D2"
7+
android:centerColor="#1565C0"
8+
android:endColor="#0D47A1" />
9+
</shape>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
3+
android:width="24dp"
4+
android:height="24dp"
5+
android:viewportWidth="24"
6+
android:viewportHeight="24">
7+
<path
8+
android:fillColor="@android:color/black"
9+
android:pathData="M20,8h-2.81c-0.45,-0.78 -1.07,-1.45 -1.82,-1.96L17,4.41 15.59,3l-2.17,2.17C12.96,5.06 12.49,5 12,5c-0.49,0 -0.96,0.06 -1.41,0.17L8.41,3 7,4.41l1.62,1.63C7.88,6.55 7.26,7.22 6.81,8H4v2h2.09c-0.05,0.33 -0.09,0.66 -0.09,1v1H4v2h2v1c0,0.34 0.04,0.67 0.09,1H4v2h2.81c1.04,1.79 2.97,3 5.19,3s4.15,-1.21 5.19,-3H20v-2h-2.09c0.05,-0.33 0.09,-0.66 0.09,-1v-1h2v-2h-2v-1c0,-0.34 -0.04,-0.67 -0.09,-1H20V8zM14,16h-4v-2h4v2zM14,12h-4v-2h4v2z"/>
10+
</vector>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
3+
android:width="24dp"
4+
android:height="24dp"
5+
android:viewportWidth="24"
6+
android:viewportHeight="24">
7+
<path
8+
android:fillColor="@android:color/black"
9+
android:pathData="M12,2A10,10 0 0,0 2,12C2,16.42 4.87,20.17 8.84,21.5C9.34,21.58 9.5,21.27 9.5,21C9.5,20.77 9.5,20.14 9.5,19.31C6.73,19.91 6.14,17.97 6.14,17.97C5.68,16.81 5.03,16.5 5.03,16.5C4.12,15.88 5.1,15.9 5.1,15.9C6.1,15.97 6.63,16.93 6.63,16.93C7.5,18.45 8.97,18 9.54,17.76C9.63,17.11 9.89,16.67 10.17,16.42C7.95,16.17 5.62,15.31 5.62,11.5C5.62,10.39 6,9.5 6.65,8.79C6.55,8.54 6.2,7.5 6.75,6.15C6.75,6.15 7.59,5.88 9.5,7.17C10.29,6.95 11.15,6.84 12,6.84C12.85,6.84 13.71,6.95 14.5,7.17C16.41,5.88 17.25,6.15 17.25,6.15C17.8,7.5 17.45,8.54 17.35,8.79C18,9.5 18.38,10.39 18.38,11.5C18.38,15.32 16.04,16.16 13.81,16.41C14.17,16.72 14.5,17.33 14.5,18.26C14.5,19.6 14.5,20.68 14.5,21C14.5,21.27 14.66,21.59 15.17,21.5C19.14,20.16 22,16.42 22,12A10,10 0 0,0 12,2Z"/>
10+
</vector>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
3+
android:width="24dp"
4+
android:height="24dp"
5+
android:viewportWidth="24"
6+
android:viewportHeight="24">
7+
<path
8+
android:fillColor="@android:color/black"
9+
android:pathData="M18,16.08c-0.76,0 -1.44,0.3 -1.96,0.77L8.91,12.7c0.05,-0.23 0.09,-0.46 0.09,-0.7s-0.04,-0.47 -0.09,-0.7l7.05,-4.11c0.54,0.5 1.25,0.81 2.04,0.81 1.66,0 3,-1.34 3,-3s-1.34,-3 -3,-3 -3,1.34 -3,3c0,0.24 0.04,0.47 0.09,0.7L8.04,9.81C7.5,9.31 6.79,9 6,9c-1.66,0 -3,1.34 -3,3s1.34,3 3,3c0.79,0 1.5,-0.31 2.04,-0.81l7.12,4.16c-0.05,0.21 -0.08,0.43 -0.08,0.65 0,1.61 1.31,2.92 2.92,2.92 1.61,0 2.92,-1.31 2.92,-2.92s-1.31,-2.92 -2.92,-2.92z"/>
10+
</vector>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
3+
android:width="24dp"
4+
android:height="24dp"
5+
android:viewportWidth="24"
6+
android:viewportHeight="24">
7+
<path
8+
android:fillColor="@android:color/black"
9+
android:pathData="M12,17.27L18.18,21l-1.64,-7.03L22,9.24l-7.19,-0.61L12,2 9.19,8.63 2,9.24l5.46,4.73L5.82,21z"/>
10+
</vector>

0 commit comments

Comments
 (0)