diff --git a/app/src/main/java/com/michatec/radio/CustomThemeFragment.kt b/app/src/main/java/com/michatec/radio/CustomThemeFragment.kt new file mode 100644 index 0000000..48bc09a --- /dev/null +++ b/app/src/main/java/com/michatec/radio/CustomThemeFragment.kt @@ -0,0 +1,207 @@ +package com.michatec.radio + +import android.content.ClipData +import android.content.ClipboardManager +import android.content.Context +import android.content.pm.PackageManager +import android.graphics.Color +import android.graphics.drawable.GradientDrawable +import android.os.Bundle +import android.text.Editable +import android.text.TextWatcher +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.SeekBar +import android.widget.Toast +import androidx.appcompat.app.AppCompatActivity +import androidx.core.graphics.toColorInt +import androidx.fragment.app.Fragment +import androidx.recyclerview.widget.GridLayoutManager +import androidx.recyclerview.widget.RecyclerView +import com.google.android.material.textfield.TextInputEditText +import com.michatec.radio.helpers.PreferencesHelper +import com.michatec.radio.helpers.ThemeHelper + +class CustomThemeFragment : Fragment() { + + private lateinit var colorPreview: View + private lateinit var hexCode: TextInputEditText + private lateinit var seekRed: SeekBar + private lateinit var seekGreen: SeekBar + private lateinit var seekBlue: SeekBar + private lateinit var recyclerView: RecyclerView + + private var currentColor: Int = Color.BLACK + private var isUpdatingFromHex = false + + private fun applyColor( + color: Int + ) { + updateSeekBars(color) + updatePreview(color) + } + + private val isAndroidTV: Boolean by lazy { + requireContext().packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK) + } + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + return inflater.inflate(R.layout.fragment_custom_theme, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + (activity as? AppCompatActivity)?.supportActionBar?.title = getString(R.string.pref_custom_theme_title) + + colorPreview = view.findViewById(R.id.color_preview) + hexCode = view.findViewById(R.id.hex_code) + seekRed = view.findViewById(R.id.seek_red) + seekGreen = view.findViewById(R.id.seek_green) + seekBlue = view.findViewById(R.id.seek_blue) + recyclerView = view.findViewById(R.id.color_recycler_view) + + currentColor = PreferencesHelper.loadCustomThemeColor(requireContext()) + + applyColor(currentColor) + + val seekBarListener = object : SeekBar.OnSeekBarChangeListener { + override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) { + if (fromUser) { + val r = seekRed.progress + val g = seekGreen.progress + val b = seekBlue.progress + currentColor = Color.rgb(r, g, b) + updatePreview(currentColor) + PreferencesHelper.saveCustomTheme(currentColor, -1) + (recyclerView.adapter as? ColorAdapter)?.resetSelection() + } + } + override fun onStartTrackingTouch(seekBar: SeekBar?) {} + override fun onStopTrackingTouch(seekBar: SeekBar?) {} + } + + seekRed.setOnSeekBarChangeListener(seekBarListener) + seekGreen.setOnSeekBarChangeListener(seekBarListener) + seekBlue.setOnSeekBarChangeListener(seekBarListener) + + // Clipboard logic (Non-TV) + if (!isAndroidTV) { + hexCode.setOnClickListener { + copyToClipboard(hexCode.text.toString()) + } + hexCode.addTextChangedListener(object : TextWatcher { + override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {} + override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { + if (!isUpdatingFromHex) { + try { + val color = s.toString().toColorInt() + currentColor = color + isUpdatingFromHex = true + applyColor(color) + PreferencesHelper.saveCustomTheme(currentColor, -1) + (recyclerView.adapter as? ColorAdapter)?.resetSelection() + isUpdatingFromHex = false + } catch (_: Exception) {} + } + } + override fun afterTextChanged(s: Editable?) {} + }) + } else { + hexCode.isFocusable = false + hexCode.isFocusableInTouchMode = false + } + + setupRecyclerView() + } + + private fun copyToClipboard(text: String) { + val clipboard = requireContext().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager + val clip = ClipData.newPlainText(getString(R.string.hex_code), text) + clipboard.setPrimaryClip(clip) + Toast.makeText(requireContext(), R.string.toastmessage_copied_to_clipboard, Toast.LENGTH_SHORT).show() + } + + private fun updateSeekBars(color: Int) { + seekRed.progress = Color.red(color) + seekGreen.progress = Color.green(color) + seekBlue.progress = Color.blue(color) + } + + private fun updatePreview(color: Int) { + colorPreview.setBackgroundColor(color) + if (!isUpdatingFromHex) { + isUpdatingFromHex = true + hexCode.setText(String.format("#%08X", 0xFFFFFF and color)) + isUpdatingFromHex = false + } + } + + private fun setupRecyclerView() { + recyclerView.layoutManager = GridLayoutManager(requireContext(), 5) + val colors = ThemeHelper.getPredefinedColors(requireContext()) + val adapter = ColorAdapter(colors) { color, index -> + currentColor = color + applyColor(color) + PreferencesHelper.saveCustomTheme(currentColor, index) + } + recyclerView.adapter = adapter + } + + private inner class ColorAdapter( + private val colors: List, + private val onColorSelected: (Int, Int) -> Unit + ) : RecyclerView.Adapter() { + + private var selectedPosition: Int = -1 + + init { + selectedPosition = PreferencesHelper.loadCustomThemeIndex() + } + + fun resetSelection() { + val oldPos = selectedPosition + selectedPosition = -1 + if (oldPos != -1) notifyItemChanged(oldPos) + } + + inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) { + val circle: View = view.findViewById(R.id.color_circle) + init { + view.isFocusable = true + view.isFocusableInTouchMode = isAndroidTV + view.setOnClickListener { + val pos = bindingAdapterPosition + if (pos != RecyclerView.NO_POSITION) { + val oldPos = selectedPosition + selectedPosition = pos + if (oldPos != -1) notifyItemChanged(oldPos) + notifyItemChanged(selectedPosition) + onColorSelected(colors[pos], pos) + } + } + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + val view = LayoutInflater.from(parent.context) + .inflate(R.layout.element_color_circle, parent, false) + return ViewHolder(view) + } + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + val color = colors[position] + val drawable = holder.circle.background as GradientDrawable + drawable.setColor(color) + + // Set selection state + holder.itemView.isSelected = (position == selectedPosition) + } + + override fun getItemCount() = colors.size + } +} diff --git a/app/src/main/java/com/michatec/radio/Keys.kt b/app/src/main/java/com/michatec/radio/Keys.kt index 75c0dd2..74c5f49 100644 --- a/app/src/main/java/com/michatec/radio/Keys.kt +++ b/app/src/main/java/com/michatec/radio/Keys.kt @@ -92,6 +92,9 @@ object Keys { const val PREF_PRESET_DRC: String = "PRESET_DRC" const val PREF_PRESET_STEREO_WIDTH: String = "PRESET_STEREO_WIDTH" const val PREF_LANGUAGE_SELECTED: String = "PRESET_LANGUAGE_SELECTED" + const val PREF_CUSTOM_THEME_COLOR: String = "CUSTOM_THEME_COLOR" + const val PREF_CUSTOM_THEME_ENABLED: String = "CUSTOM_THEME_ENABLED" + const val PREF_CUSTOM_THEME_INDEX: String = "CUSTOM_THEME_INDEX" // default const values const val DEFAULT_SIZE_OF_METADATA_HISTORY: Int = 25 diff --git a/app/src/main/java/com/michatec/radio/MainActivity.kt b/app/src/main/java/com/michatec/radio/MainActivity.kt index b108974..fa67f2a 100644 --- a/app/src/main/java/com/michatec/radio/MainActivity.kt +++ b/app/src/main/java/com/michatec/radio/MainActivity.kt @@ -7,6 +7,7 @@ import android.content.SharedPreferences import android.content.pm.PackageManager import android.content.res.Configuration import android.net.Uri +import android.util.TypedValue import android.os.Build import android.os.Bundle import android.os.Handler @@ -28,6 +29,7 @@ import com.michatec.radio.helpers.AppThemeHelper import com.michatec.radio.helpers.FileHelper import com.michatec.radio.helpers.LanguageHelper import com.michatec.radio.helpers.PreferencesHelper +import com.michatec.radio.helpers.ThemeHelper import org.woheller69.freeDroidWarn.FreeDroidWarn import java.util.Locale @@ -38,6 +40,7 @@ class MainActivity : AppCompatActivity() { /* Main class variables */ private lateinit var appBarConfiguration: AppBarConfiguration + private lateinit var mainRoot: View // Check if the device running the app is an Android TV instance private val isAndroidTV: Boolean by lazy { @@ -94,6 +97,8 @@ class MainActivity : AppCompatActivity() { // set up views setContentView(R.layout.activity_main) + mainRoot = findViewById(R.id.main_root) + applyCustomTheme() // create .nomedia file - if not yet existing FileHelper.createNomediaFile(getExternalFilesDir(null)) @@ -136,6 +141,33 @@ class MainActivity : AppCompatActivity() { } } + private fun applyCustomTheme() { + val enabled = PreferencesHelper.loadCustomThemeEnabled() + if (enabled) { + var color = PreferencesHelper.loadCustomThemeColor(this) + val index = PreferencesHelper.loadCustomThemeIndex() + + if (index != -1) { + // Color belongs to a predefined group. Update it based on current mode. + val colors = ThemeHelper.getPredefinedColors(this) + if (index < colors.size) { + val updatedColor = colors[index] + if (updatedColor != color) { + color = updatedColor + // Save the updated color to keep preferences in sync with the current mode + PreferencesHelper.saveCustomThemeColor(color) + } + } + } + mainRoot.setBackgroundColor(color) + } else { + // Reset to default theme background color + val typedValue = TypedValue() + theme.resolveAttribute(android.R.attr.colorBackground, typedValue, true) + mainRoot.setBackgroundColor(typedValue.data) + } + } + /* Overrides onResume from AppCompatActivity */ override fun onResume() { @@ -176,6 +208,9 @@ class MainActivity : AppCompatActivity() { Keys.PREF_LANGUAGE_SELECTED -> { LanguageHelper.setLanguage(this, PreferencesHelper.loadSelectedLanguage()) } + Keys.PREF_CUSTOM_THEME_COLOR, Keys.PREF_CUSTOM_THEME_ENABLED, Keys.PREF_CUSTOM_THEME_INDEX -> { + applyCustomTheme() + } } } /* diff --git a/app/src/main/java/com/michatec/radio/PlayerFragment.kt b/app/src/main/java/com/michatec/radio/PlayerFragment.kt index 2d44236..11eac22 100644 --- a/app/src/main/java/com/michatec/radio/PlayerFragment.kt +++ b/app/src/main/java/com/michatec/radio/PlayerFragment.kt @@ -308,6 +308,9 @@ class PlayerFragment : Fragment(), if (key == Keys.PREF_PLAYER_METADATA_HISTORY) { requestMetadataUpdate() } + if (key == Keys.PREF_CUSTOM_THEME_COLOR || key == Keys.PREF_CUSTOM_THEME_ENABLED || key == Keys.PREF_CUSTOM_THEME_INDEX) { + layout.applyCustomTheme(activity as Context) + } } diff --git a/app/src/main/java/com/michatec/radio/SettingsFragment.kt b/app/src/main/java/com/michatec/radio/SettingsFragment.kt index 124b41c..288c50d 100644 --- a/app/src/main/java/com/michatec/radio/SettingsFragment.kt +++ b/app/src/main/java/com/michatec/radio/SettingsFragment.kt @@ -265,6 +265,7 @@ class SettingsFragment : PreferenceFragmentCompat(), YesNoDialog.YesNoDialogList return@setOnPreferenceClickListener true } + // set up "Visualizer" preference entry val preferenceVisualizer = Preference(context) preferenceVisualizer.title = getString(R.string.pref_visualizer_title) preferenceVisualizer.setIcon(R.drawable.ic_visualizer_24dp) @@ -349,6 +350,7 @@ class SettingsFragment : PreferenceFragmentCompat(), YesNoDialog.YesNoDialogList return@setOnPreferenceClickListener true } + // set up "Language Selection" preference val preferenceLanguageSelection = Preference(context) preferenceLanguageSelection.title = getString(R.string.pref_language_selection_title) preferenceLanguageSelection.setIcon(R.drawable.ic_language_24dp) @@ -361,6 +363,61 @@ class SettingsFragment : PreferenceFragmentCompat(), YesNoDialog.YesNoDialogList return@setOnPreferenceClickListener true } + // set up "Custom Theme" preference + val preferenceCustomTheme = Preference(context) + preferenceCustomTheme.title = getString(R.string.pref_custom_theme_title) + preferenceCustomTheme.setIcon(R.drawable.ic_rbrush_24dp) + preferenceCustomTheme.summary = getString(R.string.pref_custom_theme_summary) + preferenceCustomTheme.isEnabled = PreferencesHelper.loadCustomThemeEnabled() + preferenceCustomTheme.setOnPreferenceClickListener { + findNavController().navigate(R.id.action_settings_to_cstheme) + return@setOnPreferenceClickListener true + } + + // set up "Custom Theme Enabled" preference + val preferenceCustomThemeEnabled = MarqueeSwitchPreference(context) + preferenceCustomThemeEnabled.title = getString(R.string.pref_custom_theme_enabled_title) + preferenceCustomThemeEnabled.setIcon(R.drawable.ic_rbrush_24dp) + preferenceCustomThemeEnabled.summaryOn = getString(R.string.pref_custom_theme_enabled_summary) + preferenceCustomThemeEnabled.summaryOff = getString(R.string.pref_custom_theme_disabled_summary) + preferenceCustomThemeEnabled.key = Keys.PREF_CUSTOM_THEME_ENABLED + preferenceCustomThemeEnabled.setDefaultValue(PreferencesHelper.loadCustomThemeEnabled()) + preferenceCustomThemeEnabled.setOnPreferenceChangeListener { _, newValue -> + when (newValue) { + true -> { + // enable custom theme + preferenceCustomTheme.isEnabled = true + } + false -> { + // disable custom theme + preferenceCustomTheme.isEnabled = false + } + } + return@setOnPreferenceChangeListener true + } + + // set up "Share the App" preference + val preferenceShareApp = Preference(context) + preferenceShareApp.title = getString(R.string.pref_share_app_title) + preferenceShareApp.setIcon(R.drawable.ic_share_24dp) + preferenceShareApp.summary = getString(R.string.pref_share_app_summary) + preferenceShareApp.setOnPreferenceClickListener { + val shareIntent = Intent().apply { + action = Intent.ACTION_SEND + type = "text/plain" + putExtra(Intent.EXTRA_SUBJECT, context.getString(R.string.app_name)) + putExtra(Intent.EXTRA_TEXT, getString(R.string.pref_share_app_share_text)) + } + startActivity(shareIntent) + if (!isAndroidTV && isPermissionGranted(activity as Context, android.Manifest.permission.POST_NOTIFICATIONS)) { + NotificationSys.showNotification( + context, + getString(R.string.pref_share_app_thank_title), + getString(R.string.pref_share_app_thank_message) + ) + } + return@setOnPreferenceClickListener true + } // set preference categories val preferenceCategoryGeneral = PreferenceCategory(activity as Context) @@ -384,10 +441,13 @@ class SettingsFragment : PreferenceFragmentCompat(), YesNoDialog.YesNoDialogList // setup preference screen screen.addPreference(preferenceAppVersion) + screen.addPreference(preferenceShareApp) screen.addPreference(preferenceCategoryGeneral) preferenceCategoryGeneral.addPreference(preferenceThemeSelection) preferenceCategoryGeneral.addPreference(preferenceLanguageSelection) + preferenceCategoryGeneral.addPreference(preferenceCustomThemeEnabled) + preferenceCategoryGeneral.addPreference(preferenceCustomTheme) if (!isAndroidTV && isPermissionGranted(activity as Context, android.Manifest.permission.POST_NOTIFICATIONS)) { preferenceCategoryGeneral.addPreference(preferenceTestNotification) diff --git a/app/src/main/java/com/michatec/radio/dialogs/LanguageSelectionDialog.kt b/app/src/main/java/com/michatec/radio/dialogs/LanguageSelectionDialog.kt index cbdc30d..e52cb10 100644 --- a/app/src/main/java/com/michatec/radio/dialogs/LanguageSelectionDialog.kt +++ b/app/src/main/java/com/michatec/radio/dialogs/LanguageSelectionDialog.kt @@ -39,6 +39,7 @@ class LanguageSelectionDialog(private var languageSelectionDialogListener: Langu Language("de", R.string.pref_language_de), Language("fr", R.string.pref_language_fr), Language("ru", R.string.pref_language_ru), + Language("uk", R.string.pref_language_uk), Language("ja", R.string.pref_language_ja), Language("nl", R.string.pref_language_nl), Language("pl", R.string.pref_language_pl), diff --git a/app/src/main/java/com/michatec/radio/helpers/PreferencesHelper.kt b/app/src/main/java/com/michatec/radio/helpers/PreferencesHelper.kt index 03e847e..c767366 100644 --- a/app/src/main/java/com/michatec/radio/helpers/PreferencesHelper.kt +++ b/app/src/main/java/com/michatec/radio/helpers/PreferencesHelper.kt @@ -4,12 +4,14 @@ import android.content.Context import android.content.SharedPreferences import android.content.pm.PackageManager import android.util.Log +import android.util.TypedValue import androidx.core.content.edit import androidx.preference.PreferenceManager import com.google.gson.Gson import com.michatec.radio.Keys import com.michatec.radio.ui.PlayerState -import java.util.* +import java.util.Calendar +import java.util.Date /* @@ -362,4 +364,33 @@ object PreferencesHelper { } } + /* Loads custom theme color */ + fun loadCustomThemeColor(context: Context): Int { + val typedValue = TypedValue() + context.theme.resolveAttribute(android.R.attr.colorBackground, typedValue, true) + return sharedPreferences.getInt(Keys.PREF_CUSTOM_THEME_COLOR, typedValue.data) + } + + /* Saves custom theme color */ + fun saveCustomThemeColor(color: Int) { + sharedPreferences.edit { putInt(Keys.PREF_CUSTOM_THEME_COLOR, color) } + } + + /* Loads custom theme index (predefined color index) */ + fun loadCustomThemeIndex(): Int { + return sharedPreferences.getInt(Keys.PREF_CUSTOM_THEME_INDEX, -1) + } + + /* Saves custom theme color and index together */ + fun saveCustomTheme(color: Int, index: Int) { + sharedPreferences.edit { + putInt(Keys.PREF_CUSTOM_THEME_COLOR, color) + putInt(Keys.PREF_CUSTOM_THEME_INDEX, index) + } + } + + /* Loads whether custom theme is enabled */ + fun loadCustomThemeEnabled(): Boolean { + return sharedPreferences.getBoolean(Keys.PREF_CUSTOM_THEME_ENABLED, false) + } } diff --git a/app/src/main/java/com/michatec/radio/helpers/ThemeHelper.kt b/app/src/main/java/com/michatec/radio/helpers/ThemeHelper.kt new file mode 100644 index 0000000..3fa6330 --- /dev/null +++ b/app/src/main/java/com/michatec/radio/helpers/ThemeHelper.kt @@ -0,0 +1,40 @@ +package com.michatec.radio.helpers + +import android.content.Context +import android.content.res.Configuration +import androidx.core.graphics.toColorInt + +object ThemeHelper { + fun getPredefinedColors(context: Context): List { + val isDarkMode = (context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES + return if (isDarkMode) { + // Darker colors for dark mode background + listOf( + "#FF1D3E66".toColorInt(), // Default Dark + "#FF3E1D1D".toColorInt(), // Red Dark + "#FF1D3E3E".toColorInt(), // Teal Dark + "#FF3E1D2E".toColorInt(), // Pink Dark + "#FF001A33".toColorInt(), // Dark Blue Dark + "#FF1D3E1D".toColorInt(), // Green Dark + "#FF3E2E1D".toColorInt(), // Orange Dark + "#FF2E1D1D".toColorInt(), // Brown Dark + "#FF1D242E".toColorInt(), // Blue Grey Dark + "#FF000000".toColorInt() // Black + ) + } else { + // Lighter colors for light mode background + listOf( + "#FFDAE2FF".toColorInt(), // Light Default + "#FFFF897D".toColorInt(), // Light Red + "#FF4DB6AC".toColorInt(), // Light Teal + "#FFF48FB1".toColorInt(), // Light Pink + "#FF90CAF9".toColorInt(), // Light Blue + "#FFA5D6A7".toColorInt(), // Light Green + "#FFFFAB91".toColorInt(), // Light Orange + "#FFBCAAA4".toColorInt(), // Light Brown + "#FFB0BEC5".toColorInt(), // Light Blue Grey + "#FFFFFFFF".toColorInt() // White + ) + } + } +} diff --git a/app/src/main/java/com/michatec/radio/ui/LayoutHolder.kt b/app/src/main/java/com/michatec/radio/ui/LayoutHolder.kt index dfdd369..a432f07 100644 --- a/app/src/main/java/com/michatec/radio/ui/LayoutHolder.kt +++ b/app/src/main/java/com/michatec/radio/ui/LayoutHolder.kt @@ -6,7 +6,6 @@ import android.content.Context import android.content.Intent import android.content.pm.PackageManager import android.graphics.drawable.AnimatedVectorDrawable -import java.util.Locale import android.view.View import android.view.animation.Animation import android.view.animation.AnimationUtils @@ -31,7 +30,9 @@ import com.michatec.radio.core.Station import com.michatec.radio.helpers.DateTimeHelper import com.michatec.radio.helpers.ImageHelper import com.michatec.radio.helpers.PreferencesHelper +import com.michatec.radio.helpers.ThemeHelper import com.michatec.radio.helpers.UiHelper +import java.util.Locale /* @@ -122,6 +123,9 @@ data class LayoutHolder(var rootView: View) { CastButtonFactory.setUpMediaRouteButton(rootView.context, it) } + // Apply custom theme color + applyCustomTheme(rootView.context) + // set layout for player setupBottomSheet() } @@ -182,6 +186,9 @@ data class LayoutHolder(var rootView: View) { // update bitrate sheetBitrateView?.text = bitrateText + // update custom theme + applyCustomTheme(context) + // update click listeners sheetStreamingLinkHeadline?.setOnClickListener { copyToClipboard( @@ -309,6 +316,28 @@ data class LayoutHolder(var rootView: View) { isBuffering = buffering } + /* Applies custom theme color to the UI */ + fun applyCustomTheme(context: Context) { + val enabled = PreferencesHelper.loadCustomThemeEnabled() + if (enabled) { + var customColor = PreferencesHelper.loadCustomThemeColor(context) + val index = PreferencesHelper.loadCustomThemeIndex() + + if (index != -1) { + val colors = ThemeHelper.getPredefinedColors(context) + if (index < colors.size) { + customColor = colors[index] + } + } + + rootView.setBackgroundColor(customColor) + recyclerView.setBackgroundColor(customColor) + } else { + rootView.setBackgroundResource(android.R.color.transparent) + recyclerView.setBackgroundResource(android.R.color.transparent) + } + } + /* Toggles visibility of the download progress indicator */ fun toggleDownloadProgressIndicator() { when (PreferencesHelper.loadActiveDownloads()) { diff --git a/app/src/main/res/drawable/ic_rbrush_24dp.xml b/app/src/main/res/drawable/ic_rbrush_24dp.xml new file mode 100644 index 0000000..c40d16c --- /dev/null +++ b/app/src/main/res/drawable/ic_rbrush_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_share_24dp.xml b/app/src/main/res/drawable/ic_share_24dp.xml index 65972b5..fdfc322 100644 --- a/app/src/main/res/drawable/ic_share_24dp.xml +++ b/app/src/main/res/drawable/ic_share_24dp.xml @@ -4,6 +4,6 @@ android:viewportWidth="24" android:viewportHeight="24"> diff --git a/app/src/main/res/drawable/selector_color_circle.xml b/app/src/main/res/drawable/selector_color_circle.xml new file mode 100644 index 0000000..00dca7d --- /dev/null +++ b/app/src/main/res/drawable/selector_color_circle.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/shape_color_circle.xml b/app/src/main/res/drawable/shape_color_circle.xml new file mode 100644 index 0000000..abdbe77 --- /dev/null +++ b/app/src/main/res/drawable/shape_color_circle.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable/shape_rgb_controls_border.xml b/app/src/main/res/drawable/shape_rgb_controls_border.xml new file mode 100644 index 0000000..785b6d6 --- /dev/null +++ b/app/src/main/res/drawable/shape_rgb_controls_border.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/src/main/res/layout-television/fragment_custom_theme.xml b/app/src/main/res/layout-television/fragment_custom_theme.xml new file mode 100644 index 0000000..d0cf4f6 --- /dev/null +++ b/app/src/main/res/layout-television/fragment_custom_theme.xml @@ -0,0 +1,145 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index a574d07..fac6df5 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -2,6 +2,7 @@ + + + + + diff --git a/app/src/main/res/layout/fragment_custom_theme.xml b/app/src/main/res/layout/fragment_custom_theme.xml new file mode 100644 index 0000000..3484255 --- /dev/null +++ b/app/src/main/res/layout/fragment_custom_theme.xml @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/navigation/nav_graph_main.xml b/app/src/main/res/navigation/nav_graph_main.xml index 6687fb5..cb9ae25 100644 --- a/app/src/main/res/navigation/nav_graph_main.xml +++ b/app/src/main/res/navigation/nav_graph_main.xml @@ -32,6 +32,9 @@ + @@ -52,4 +55,11 @@ android:name="com.michatec.radio.AddStationFragment" android:label="Add Station" tools:layout="@layout/dialog_find_station" /> + + + diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml index 2fcebfe..10fb440 100644 --- a/app/src/main/res/values-da/strings.xml +++ b/app/src/main/res/values-da/strings.xml @@ -159,4 +159,23 @@ Cast Spektrumanalysator Vis spektrumanalysatoren. + + Del app + Anbefal denne app til en ven. + Tjek denne fantastiske radio-app ud: https://github.com/michatec/Radio + Tak skal du have! + En stor tak til dig fra udviklerne. + + + Aktiverer fanen for brugerdefineret tema. + Deaktiverer fanen for brugerdefineret tema. + Tilpas applikationens baggrundsfarve. + Brugerdefineret tema + Aktiver brugerdefineret tema + Foruddefinerede farver (Lys/Mørk): + Brugerdefineret RGB (tilpas venligst til appen): + Rød + Grøn + Blå + Hex-kode diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 1771d47..aa857ef 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -160,5 +160,24 @@ Streamen Spektrumanzeige Sehe die Spektrumanzeige. + App teilen + Empfehle diese App einem Freund. + Schau dir diese tolle Radio-App an: https://github.com/michatec/Radio + Vielen Dank! + Ein großes Dankeschön von den Entwicklern. + Lade… + + + Aktiviert den Tab für das benutzerdefinierte Design. + Deaktiviert den Tab für das benutzerdefinierte Design. + Passen Sie die Hintergrundfarbe der Anwendung an. + Benutzerdefiniertes Design + Benutzerdefiniertes Design aktivieren + Vordefinierte Farben (Hell/Dunkel): + Benutzerdefiniertes RGB (bitte an die App anpassen): + Rot + Grün + Blau + Hex-Code diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index 978abcd..cc47f7f 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -161,4 +161,23 @@ Μετάδοση Αναλυτής Φάσματος Εμφάνιση του Αναλυτή Φάσματος. + + Κοινοποίηση Εφαρμογής + Προτείνετε αυτήν την εφαρμογή σε έναν φίλο. + Δείτε αυτήν την καταπληκτική εφαρμογή ραδιοφώνου: https://github.com/michatec/Radio + Σας ευχαριστούμε! + Ένα μεγάλο ευχαριστώ από τους προγραμματιστές. + + + Ενεργοποιεί την καρτέλα προσαρμοσμένου θέματος. + Απενεργοποιεί την καρτέλα προσαρμοσμένου θέματος. + Προσαρμόστε το χρώμα φόντου της εφαρμογής. + Προσαρμοσμένο Θέμα + Ενεργοποίηση Προσαρμοσμένου Θέματος + Προκαθορισμένα Χρώματα (Φωτεινό/Σκοτεινό): + Προσαρμοσμένο RGB (παρακαλώ προσαρμόστε στην εφαρμογή): + Κόκκινο + Πράσινο + Μπλε + Κωδικός Hex diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 4f7ec8d..2ffb752 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -159,4 +159,23 @@ Diffuser Analyseur de spectre Afficher l analyseur de spectre. + + Partager l\'application + Recommandez cette application à un ami. + Découvrez cette super application radio : https://github.com/michatec/Radio + Merci beaucoup ! + Un grand merci de la part des développeurs. + + + Active l\'onglet du thème personnalisé. + Désactive l\'onglet du thème personnalisé. + Personnalisez la couleur d\'arrière-plan de l\'application. + Thème personnalisé + Activer le thème personnalisé + Couleurs prédéfinies (Clair/Sombre) : + RGB personnalisé (veuillez l\'adapter à l\'application) : + Rouge + Vert + Bleu + Code Hex diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 26e6542..086ee8d 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -160,4 +160,23 @@ キャスト スペクトラムアナライザー スペクトラムアナライザーを表示します。 + + アプリを共有 + このアプリを友達に勧める。 + この素晴らしいラジオアプリをチェックしてみてください: https://github.com/michatec/Radio + ありがとうございます! + 開発者一同より、心から感謝申し上げます。 + + + カスタムテーマタブを有効にします。 + カスタムテーマタブを無効にします。 + アプリケーションの背景色をカスタマイズします。 + カスタムテーマ + カスタムテーマを有効にする + 事前定義された色(ライト/ダーク): + カスタムRGB(アプリに合わせて調整してください): + + + + Hexコード diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 55cb525..4279a2b 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -161,4 +161,23 @@ Cast Spectrum Analyser Toon de Spectrum Analyser. + + App delen + Beveel deze app aan bij een vriend. + Bekijk deze geweldige radio-app: https://github.com/michatec/Radio + Bedankt! + Een groot dankjewel van de ontwikkelaars. + + + Schakelt het tabblad voor het aangepaste thema in. + Schakelt het tabblad voor het aangepaste thema uit. + Pas de achtergrondkleur van de applicatie aan. + Aangepast Thema + Aangepast Thema Inschakelen + Vooraf gedefinieerde kleuren (Licht/Donker): + Aangepaste RGB (pas deze aan de app aan): + Rood + Groen + Blauw + Hex-code diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index ef16cd9..c93e042 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -161,4 +161,23 @@ Przesyłanie Analizator Widma Pokaż Analizator Widma. + + Udostępnij aplikację + Poleć tę aplikację znajomemu. + Sprawdź tę świetną aplikację radiową: https://github.com/michatec/Radio + Dziękujemy! + Wielkie podziękowania od deweloperów. + + + Włącza kartę motywu niestandardowego. + Wyłącza kartę motywu niestandardowego. + Dostosuj kolor tła aplikacji. + Motyw niestandardowy + Włącz motyw niestandardowy + Predefiniowane kolory (Jasny/Ciemny): + Niestandardowy RGB (proszę dostosować do aplikacji): + Czerwony + Zielony + Niebieski + Kod Hex diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 656e660..0dbc2e8 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -161,4 +161,23 @@ Трансляция Анализатор спектра Показать анализатор спектра. + + Поделиться приложением + Рекомендовать это приложение другу. + Посмотрите это классное радио-приложение: https://github.com/michatec/Radio + Спасибо! + Большое спасибо от разработчиков. + + + Включает вкладку пользовательской темы. + Отключает вкладку пользовательской темы. + Настройка цвета фона приложения. + Пользовательская тема + Включить пользовательскую тему + Предустановленные цвета (Светлые/Темные): + Пользовательский RGB (пожалуйста, адаптируйте к приложению): + Красный + Зеленый + Синий + Hex-код diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index beea9f2..4ef70ea 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -161,4 +161,23 @@ Трансляція Аналізатор спектру Показати аналізатор спектру. + + Поділитися застосунком + Рекомендувати цей застосунок другу. + Подивіться на цей чудовий радіозастосунок: https://github.com/michatec/Radio + Дякуємо! + Велике спасибі вам від розробників. + + + Вмикає вкладку користувацької теми. + Вимикає вкладку користувацької теми. + Налаштуйте колір фону застосунку. + Користувацька тема + Увімкнути користувацьку тему + Попередньо визначені кольори (Світлі/Темні): + Власний RGB (будь ласка, адаптуйте до застосунку): + Червоний + Зелений + Синій + Hex-код diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6170666..4fece11 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -74,6 +74,7 @@ 🇵🇱 Polski 🇬🇷 Ελληνικά 🇩🇰 Dansk + 🇺🇦 Українська @@ -148,6 +149,11 @@ Update Station Images Test Notification Test whether the notification system works. + Share App + Recommend this app to a friend. + Check out this awesome radio app: https://github.com/michatec/Radio + Thank You! + A big thank you to you from the developers. 00:00 @@ -197,4 +203,17 @@ Cast Spectrum Analyzer Show the Spectrum Analyzer. + + + Enables the custom theme tab. + Disables the custom theme tab. + Customize the application background color. + Custom Theme + Enable Custom Theme + Predefined Colors (Light/Dark): + Custom RGB (please adapt to the app): + Red + Green + Blue + Hex Code