Add Icon Picker
This commit is contained in:
parent
e1b8fd9d28
commit
9637d8a85e
9 changed files with 209 additions and 44 deletions
|
|
@ -0,0 +1,58 @@
|
|||
package com.deniscerri.ytdl.ui.adapter
|
||||
|
||||
import android.app.Activity
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.deniscerri.ytdl.R
|
||||
import com.deniscerri.ytdl.databinding.AppIconItemBinding
|
||||
import com.deniscerri.ytdl.util.ThemeUtil
|
||||
|
||||
class IconsSheetAdapter(val activity: Activity) : RecyclerView.Adapter<IconsSheetAdapter.IconsSheetViewHolder>() {
|
||||
|
||||
class IconsSheetViewHolder(
|
||||
val binding: AppIconItemBinding
|
||||
) : RecyclerView.ViewHolder(binding.root)
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): IconsSheetViewHolder {
|
||||
val binding = AppIconItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
||||
return IconsSheetViewHolder(binding)
|
||||
}
|
||||
|
||||
override fun getItemCount() = availableIcons.size
|
||||
|
||||
override fun onBindViewHolder(holder: IconsSheetViewHolder, position: Int) {
|
||||
val appIcon = availableIcons[position]
|
||||
holder.binding.apply {
|
||||
iconIV.setImageResource(appIcon.iconResource)
|
||||
iconName.text = root.context.getString(appIcon.nameResource)
|
||||
root.setOnClickListener {
|
||||
val preferences = androidx.preference.PreferenceManager.getDefaultSharedPreferences(activity)
|
||||
preferences.edit().putString("ytdlnis_icon", appIcon.activityAlias).apply()
|
||||
val theme = preferences.getString("ytdlnis_theme", "System")!!
|
||||
ThemeUtil.updateAppIcon(activity, theme,appIcon.activityAlias)
|
||||
activity.recreate()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
sealed class AppIcon(
|
||||
@StringRes val nameResource: Int,
|
||||
@DrawableRes val iconResource: Int,
|
||||
val activityAlias: String
|
||||
) {
|
||||
object Default : AppIcon(R.string.auto, R.mipmap.ic_launcher, "default")
|
||||
object DefaultLight : AppIcon(R.string.light, R.mipmap.ic_launcher_light, "Light")
|
||||
object DefaultDark : AppIcon(R.string.dark, R.mipmap.ic_launcher_dark, "Dark")
|
||||
}
|
||||
|
||||
val availableIcons = listOf(
|
||||
AppIcon.Default,
|
||||
AppIcon.DefaultLight,
|
||||
AppIcon.DefaultDark
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -12,6 +12,9 @@ import android.net.Uri
|
|||
import android.os.Bundle
|
||||
import android.os.PowerManager
|
||||
import android.provider.Settings
|
||||
import android.util.DisplayMetrics
|
||||
import android.view.ViewGroup
|
||||
import android.view.Window
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import androidx.core.os.LocaleListCompat
|
||||
|
|
@ -24,6 +27,7 @@ import androidx.preference.MultiSelectListPreference
|
|||
import androidx.preference.Preference
|
||||
import androidx.preference.PreferenceManager
|
||||
import androidx.preference.SwitchPreferenceCompat
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.ItemTouchHelper
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
|
|
@ -32,11 +36,13 @@ import androidx.work.WorkManager
|
|||
import com.deniscerri.ytdl.R
|
||||
import com.deniscerri.ytdl.database.viewmodel.ResultViewModel
|
||||
import com.deniscerri.ytdl.databinding.NavOptionsItemBinding
|
||||
import com.deniscerri.ytdl.ui.adapter.IconsSheetAdapter
|
||||
import com.deniscerri.ytdl.ui.adapter.NavBarOptionsAdapter
|
||||
import com.deniscerri.ytdl.util.NavbarUtil
|
||||
import com.deniscerri.ytdl.util.ThemeUtil
|
||||
import com.deniscerri.ytdl.util.UiUtil
|
||||
import com.deniscerri.ytdl.util.UpdateUtil
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
|
|
@ -202,6 +208,33 @@ class GeneralSettingsFragment : BaseSettingsFragment() {
|
|||
}
|
||||
}
|
||||
|
||||
findPreference<Preference>("ytdlnis_icon")?.apply {
|
||||
val currentValue = preferences.getString("ytdlnis_icon", "default")
|
||||
IconsSheetAdapter.availableIcons.firstOrNull { it.activityAlias == currentValue }?.let {
|
||||
summary = getString(it.nameResource)
|
||||
}
|
||||
|
||||
setOnPreferenceClickListener {
|
||||
val bottomSheet = BottomSheetDialog(context)
|
||||
bottomSheet.requestWindowFeature(Window.FEATURE_NO_TITLE)
|
||||
bottomSheet.setContentView(R.layout.generic_list)
|
||||
|
||||
val recycler = bottomSheet.findViewById<RecyclerView>(R.id.download_recyclerview)!!
|
||||
recycler.layoutManager = GridLayoutManager(context, 3)
|
||||
recycler.adapter = IconsSheetAdapter(requireActivity())
|
||||
|
||||
bottomSheet.show()
|
||||
val displayMetrics = DisplayMetrics()
|
||||
requireActivity().windowManager.defaultDisplay.getMetrics(displayMetrics)
|
||||
bottomSheet.behavior.peekHeight = displayMetrics.heightPixels
|
||||
bottomSheet.window!!.setLayout(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.MATCH_PARENT
|
||||
)
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
findPreference<ListPreference>("theme_accent")?.apply {
|
||||
summary = entry
|
||||
setOnPreferenceChangeListener { _, _ ->
|
||||
|
|
|
|||
|
|
@ -113,61 +113,23 @@ object ThemeUtil {
|
|||
activity.theme.applyStyle(R.style.Pure, true)
|
||||
}
|
||||
|
||||
//disable old icons
|
||||
for (appIcon in availableIcons) {
|
||||
val activityClass = "com.deniscerri.ytdl." + appIcon.activityAlias
|
||||
|
||||
// remove old icons
|
||||
activity.packageManager.setComponentEnabledSetting(
|
||||
ComponentName(activity.packageName, activityClass),
|
||||
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
|
||||
PackageManager.DONT_KILL_APP
|
||||
)
|
||||
}
|
||||
|
||||
when (sharedPreferences.getString("ytdlnis_theme", "System")!!) {
|
||||
"System" -> {
|
||||
//set dynamic icon
|
||||
activity.packageManager.setComponentEnabledSetting(
|
||||
ComponentName(activity.packageName, "com.deniscerri.ytdl.Default"),
|
||||
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
|
||||
PackageManager.DONT_KILL_APP
|
||||
)
|
||||
|
||||
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
|
||||
}
|
||||
val theme = sharedPreferences.getString("ytdlnis_theme", "System")!!
|
||||
when (theme) {
|
||||
"Light" -> {
|
||||
//set light icon
|
||||
activity.packageManager.setComponentEnabledSetting(
|
||||
ComponentName(activity.packageName, "com.deniscerri.ytdl.LightIcon"),
|
||||
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
|
||||
PackageManager.DONT_KILL_APP
|
||||
)
|
||||
|
||||
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
|
||||
}
|
||||
"Dark" -> {
|
||||
//set dark icon
|
||||
activity.packageManager.setComponentEnabledSetting(
|
||||
ComponentName(activity.packageName, "com.deniscerri.ytdl.DarkIcon"),
|
||||
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
|
||||
PackageManager.DONT_KILL_APP
|
||||
)
|
||||
|
||||
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
|
||||
}
|
||||
// or "System"
|
||||
else -> {
|
||||
//set dynamic icon
|
||||
activity.packageManager.setComponentEnabledSetting(
|
||||
ComponentName(activity.packageName, "com.deniscerri.ytdl.Default"),
|
||||
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
|
||||
PackageManager.DONT_KILL_APP
|
||||
)
|
||||
|
||||
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
val iconMode = sharedPreferences.getString("ytdlnis_icon", "default")!!
|
||||
updateAppIcon(activity,theme, iconMode)
|
||||
}
|
||||
|
||||
fun getThemeColor(context: Context, colorCode: Int): Int {
|
||||
|
|
@ -192,4 +154,52 @@ object ThemeUtil {
|
|||
return "<span style='color:$hexColor';>YTDL</span>nis"
|
||||
.parseAsHtml(HtmlCompat.FROM_HTML_MODE_COMPACT)
|
||||
}
|
||||
|
||||
|
||||
fun updateAppIcon(activity: Activity, theme: String, appIconMode: String) {
|
||||
//disable old icons
|
||||
for (appIcon in availableIcons) {
|
||||
val activityClass = "com.deniscerri.ytdl." + appIcon.activityAlias
|
||||
|
||||
// remove old icons
|
||||
activity.packageManager.setComponentEnabledSetting(
|
||||
ComponentName(activity.packageName, activityClass),
|
||||
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
|
||||
PackageManager.DONT_KILL_APP
|
||||
)
|
||||
}
|
||||
|
||||
var iconMode = appIconMode
|
||||
if (appIconMode == "default") {
|
||||
iconMode = theme
|
||||
}
|
||||
|
||||
when (iconMode) {
|
||||
"Light" -> {
|
||||
//set light icon
|
||||
activity.packageManager.setComponentEnabledSetting(
|
||||
ComponentName(activity.packageName, "com.deniscerri.ytdl.LightIcon"),
|
||||
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
|
||||
PackageManager.DONT_KILL_APP
|
||||
)
|
||||
}
|
||||
"Dark" -> {
|
||||
//set dark icon
|
||||
activity.packageManager.setComponentEnabledSetting(
|
||||
ComponentName(activity.packageName, "com.deniscerri.ytdl.DarkIcon"),
|
||||
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
|
||||
PackageManager.DONT_KILL_APP
|
||||
)
|
||||
}
|
||||
// or "System"
|
||||
else -> {
|
||||
//set dynamic icon
|
||||
activity.packageManager.setComponentEnabledSetting(
|
||||
ComponentName(activity.packageName, "com.deniscerri.ytdl.Default"),
|
||||
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
|
||||
PackageManager.DONT_KILL_APP
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
10
app/src/main/res/drawable/ic_frame.xml
Normal file
10
app/src/main/res/drawable/ic_frame.xml
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="?android:colorAccent"
|
||||
android:viewportWidth="48"
|
||||
android:viewportHeight="48">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M13.05,21.7 L24.05,4 35.05,21.7ZM35.3,44Q31.6,44 29.1,41.5Q26.6,39 26.6,35.3Q26.6,31.6 29.1,29.1Q31.6,26.6 35.3,26.6Q39,26.6 41.5,29.1Q44,31.6 44,35.3Q44,39 41.5,41.5Q39,44 35.3,44ZM6,42.75V27.55H21.2V42.75Z" />
|
||||
</vector>
|
||||
10
app/src/main/res/drawable/rounded_ripple.xml
Normal file
10
app/src/main/res/drawable/rounded_ripple.xml
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="?attr/colorControlHighlight">
|
||||
<item android:id="@android:id/mask">
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="#000000" />
|
||||
<corners android:radius="15dp" />
|
||||
</shape>
|
||||
</item>
|
||||
</ripple>
|
||||
31
app/src/main/res/layout/app_icon_item.xml
Normal file
31
app/src/main/res/layout/app_icon_item.xml
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="10dp"
|
||||
android:background="@drawable/rounded_ripple"
|
||||
android:orientation="vertical"
|
||||
android:paddingVertical="10dp">
|
||||
|
||||
<com.google.android.material.imageview.ShapeableImageView
|
||||
android:id="@+id/iconIV"
|
||||
android:layout_width="75dp"
|
||||
android:layout_height="75dp"
|
||||
android:layout_gravity="center"
|
||||
android:padding="10dp"
|
||||
app:shapeAppearance="@style/CircleImageView"
|
||||
tools:src="@mipmap/ic_launcher" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/iconName"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
tools:text="YTDLnis"
|
||||
android:textSize="11sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
|
@ -506,4 +506,5 @@
|
|||
<string name="potoken_guide">Auth\n-----------------------\n1. Click \'Auth\' to open the sign in page in WebView.\n2. Sign in to your Google Account.\n3. Play any video that supports auto-translated subtitles.\n4. Turn on auto-translated subtitles and see if it works.\n\t4.1 If auto-translated subtitles don\'t work, switch to another video that supports auto-translated subtitles and try step 4 again.\n5. Click OK.\n\nNo Auth\n-----------------------\n1. Click \'No Auth\'.\n2. Write any youtube video url\n3. Wait for the video to load and play the video for at least 3 seconds.\n4. Click OK.</string>
|
||||
<string name="no_auth">No Auth</string>
|
||||
<string name="auth">Auth</string>
|
||||
<string name="app_icon">App Icon</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -33,6 +33,11 @@
|
|||
<item name="cornerSize">5dp</item>
|
||||
</style>
|
||||
|
||||
<style name="CircleImageView">
|
||||
<item name="cornerFamily">rounded</item>
|
||||
<item name="cornerSize">50%</item>
|
||||
</style>
|
||||
|
||||
<style name="ShapeAppearanceOverlay.Avatar2" parent="ShapeAppearance.MaterialComponents.SmallComponent">
|
||||
<item name="cornerFamily">rounded</item>
|
||||
<item name="cornerSize">7dp</item>
|
||||
|
|
|
|||
|
|
@ -21,6 +21,13 @@
|
|||
app:summary="@string/defaultValue"
|
||||
app:title="@string/Theme" />
|
||||
|
||||
<Preference
|
||||
android:defaultValue="default"
|
||||
android:icon="@drawable/ic_frame"
|
||||
android:title="@string/app_icon"
|
||||
android:summary="@string/defaultValue"
|
||||
app:key="ytdlnis_icon" />
|
||||
|
||||
<ListPreference
|
||||
android:entries="@array/accents"
|
||||
android:entryValues="@array/accents_values"
|
||||
|
|
|
|||
Loading…
Reference in a new issue