Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 18261263 authored by Philipp Heckel's avatar Philipp Heckel
Browse files

Polish

parent a498d68b
Loading
Loading
Loading
Loading
+38 −27
Original line number Diff line number Diff line
package io.heckel.ntfy.ui

import android.content.ContentResolver
import android.graphics.BitmapFactory
import android.net.Uri
import android.os.Bundle
import android.widget.Toast
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
@@ -67,6 +69,7 @@ class DetailSettingsActivity : AppCompatActivity() {
    }

    class SettingsFragment : PreferenceFragmentCompat() {
        private lateinit var resolver: ContentResolver
        private lateinit var repository: Repository
        private lateinit var serviceManager: SubscriberServiceManager
        private lateinit var subscription: Subscription
@@ -81,6 +84,7 @@ class DetailSettingsActivity : AppCompatActivity() {
            // Dependencies (Fragments need a default constructor)
            repository = Repository.getInstance(requireActivity())
            serviceManager = SubscriberServiceManager(requireActivity())
            resolver = requireContext().applicationContext.contentResolver

            // Create result launcher for custom icon (must be created in onCreatePreferences() directly)
            iconSetLauncher = createIconPickLauncher()
@@ -251,28 +255,26 @@ class DetailSettingsActivity : AppCompatActivity() {
        private fun loadIconRemovePref() {
            val prefId = context?.getString(R.string.detail_settings_appearance_icon_remove_key) ?: return
            iconRemovePref = findPreference(prefId) ?: return
            iconRemovePref.isVisible = subscription.icon != null
            iconRemovePref.preferenceDataStore = object : PreferenceDataStore() { } // Dummy store to protect from accidentally overwriting
            iconRemovePref.onPreferenceClickListener = Preference.OnPreferenceClickListener { _ ->
                iconRemovePref.isVisible = false
                iconSetPref.isVisible = true
                deleteIcon(subscription.icon)
                save(subscription.copy(icon = null))
                true
            }

            // FIXME

            // Set icon (if it exists)
            if (subscription.icon != null) {
                try {
                    val resolver = requireContext().applicationContext.contentResolver
                    val bitmapStream = resolver.openInputStream(Uri.parse(subscription.icon))
                    val bitmap = BitmapFactory.decodeStream(bitmapStream)
                    iconRemovePref.icon = bitmap.toDrawable(resources)
                } catch (e: Exception) {
                    // FIXME

                    Log.w(TAG, "Unable to set icon ${subscription.icon}", e)
                }
            }
            iconRemovePref.isVisible = subscription.icon != null
            iconRemovePref.preferenceDataStore = object : PreferenceDataStore() { } // Dummy store to protect from accidentally overwriting
            iconRemovePref.onPreferenceClickListener = Preference.OnPreferenceClickListener { _ ->
                save(subscription.copy(icon = null))
                iconRemovePref.isVisible = false
                iconSetPref.isVisible = true
                true
            }
        }

        private fun createIconPickLauncher(): ActivityResultLauncher<String> {
@@ -281,45 +283,54 @@ class DetailSettingsActivity : AppCompatActivity() {
                    return@registerForActivityResult
                }
                lifecycleScope.launch(Dispatchers.IO) {
                    val outputUri = createUri() ?: return@launch
                    try {
                        // Write to cache storage
                        val resolver = requireContext().applicationContext.contentResolver
                        val inputStream = resolver.openInputStream(inputUri) ?: throw IOException("Couldn't open content URI for reading")
                        val outputUri = createUri()
                        val outputStream = resolver.openOutputStream(outputUri) ?: throw IOException("Couldn't open content URI for writing")
                        inputStream.copyTo(outputStream)
                        save(subscription.copy(icon = outputUri.toString()))

                        // FIXME
                        // FIXME

                        iconSetPref.isVisible = false
                        inputStream.use {
                            it.copyTo(outputStream)
                        }

                        // Read image and set as preference icon
                        val bitmapStream = resolver.openInputStream(Uri.parse(outputUri.toString()))
                        val bitmap = BitmapFactory.decodeStream(bitmapStream)

                        // Display "remove" preference
                        iconRemovePref.icon = bitmap.toDrawable(resources)
                        iconRemovePref.isVisible = true
                        iconSetPref.isVisible = false

                        // Finally, save (this is last!)
                        save(subscription.copy(icon = outputUri.toString()))
                    } catch (e: Exception) {
                        Log.w(TAG, "Saving icon failed", e)
                        requireActivity().runOnUiThread {
                            // FIXME TOAST
                            Toast.makeText(context, getString(R.string.detail_settings_appearance_icon_error_saving, e.message), Toast.LENGTH_LONG).show()
                        }
                    }
                }
            }
        }

        private fun createUri(): Uri {
        private fun createUri(): Uri? {
            val dir = File(requireContext().cacheDir, SUBSCRIPTION_ICONS)
            if (!dir.exists() && !dir.mkdirs()) {
                throw Exception("Cannot create cache directory for attachments: $dir")
                return null
            }
            val file =  File(dir, subscription.id.toString())
            return FileProvider.getUriForFile(requireContext(), DownloadWorker.FILE_PROVIDER_AUTHORITY, file)
        }

        private fun loadBitmap() {
            // FIXME
        private fun deleteIcon(uri: String?) {
            if (uri == null) {
                return
            }
            try {
                resolver.delete(Uri.parse(uri), null, null)
            } catch (e: Exception) {
                Log.w(TAG, "Unable to delete $uri", e)
            }
        }

        private fun save(newSubscription: Subscription, refresh: Boolean = false) {
+10 −0
Original line number Diff line number Diff line
package io.heckel.ntfy.ui

import android.content.Context
import android.net.Uri
import androidx.lifecycle.LiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import io.heckel.ntfy.db.*
import io.heckel.ntfy.up.Distributor
import io.heckel.ntfy.util.Log
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlin.collections.List
@@ -32,6 +34,14 @@ class SubscriptionsViewModel(private val repository: Repository) : ViewModel() {
        }
        repository.removeAllNotifications(subscriptionId)
        repository.removeSubscription(subscriptionId)
        if (subscription.icon != null) {
            val resolver = context.applicationContext.contentResolver
            try {
                resolver.delete(Uri.parse(subscription.icon), null, null)
            } catch (_: Exception) {
                // Don't care
            }
        }
    }

    suspend fun get(baseUrl: String, topic: String): Subscription? {
+1 −1
Original line number Diff line number Diff line
@@ -12,7 +12,7 @@
            android:layout_height="35dp" app:srcCompat="@drawable/ic_sms_gray_24dp"
            android:id="@+id/main_item_image" app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            android:layout_marginTop="13dp"/>
            android:layout_marginTop="17dp" android:scaleType="fitStart"/>
    <TextView
            android:text="ntfy.sh/example"
            android:layout_width="0dp"
+2 −1
Original line number Diff line number Diff line
@@ -341,8 +341,9 @@
    <string name="detail_settings_notifications_instant_summary_off">Notifications are delivered using Firebase. Delivery may be delayed, but consumes less battery.</string>
    <string name="detail_settings_appearance_header">Appearance</string>
    <string name="detail_settings_appearance_icon_title">Subscription icon</string>
    <string name="detail_settings_appearance_icon_set_summary_set">This icon is displayed in notifications. Tap to remove it.</string>
    <string name="detail_settings_appearance_icon_set_summary_set">This icon is displayed in notifications to this topic. Tap to remove it.</string>
    <string name="detail_settings_appearance_icon_set_summary_no_set">Set an icon to be displayed in notifications</string>
    <string name="detail_settings_appearance_icon_error_saving">Unable to save icon: %1$s</string>
    <string name="detail_settings_global_setting_title">Use global setting</string>
    <string name="detail_settings_global_setting_suffix">global</string>