From 1d916de81ef7aef40fe17954b73a6e2a0dc48105 Mon Sep 17 00:00:00 2001 From: Philipp Heckel Date: Tue, 15 Feb 2022 16:16:46 -0500 Subject: [PATCH] Default server; works like a charm; now we just need the wording in the "add dialog" to be just right --- .../main/java/io/heckel/ntfy/db/Repository.kt | 19 ++--- .../java/io/heckel/ntfy/ui/AddFragment.kt | 8 +-- .../java/io/heckel/ntfy/ui/DetailActivity.kt | 13 ---- .../java/io/heckel/ntfy/ui/MainActivity.kt | 6 +- .../io/heckel/ntfy/ui/SettingsActivity.kt | 44 +----------- .../java/io/heckel/ntfy/ui/ShareActivity.kt | 33 ++++++--- .../io/heckel/ntfy/up/BroadcastReceiver.kt | 6 +- app/src/main/res/layout/activity_share.xml | 4 +- .../preference_category_material_edited.xml | 69 ------------------- .../preference_dialog_edittext_edited.xml | 3 +- .../main/res/menu/menu_detail_action_bar.xml | 2 - app/src/main/res/values/strings.xml | 21 ++---- app/src/main/res/xml/main_preferences.xml | 37 ++-------- 13 files changed, 53 insertions(+), 212 deletions(-) delete mode 100644 app/src/main/res/layout/preference_category_material_edited.xml diff --git a/app/src/main/java/io/heckel/ntfy/db/Repository.kt b/app/src/main/java/io/heckel/ntfy/db/Repository.kt index bd14638..e4ff638 100644 --- a/app/src/main/java/io/heckel/ntfy/db/Repository.kt +++ b/app/src/main/java/io/heckel/ntfy/db/Repository.kt @@ -293,20 +293,6 @@ class Repository(private val sharedPrefs: SharedPreferences, private val databas .apply() } - fun getUnifiedPushEnabled(): Boolean { - return sharedPrefs.getBoolean(SHARED_PREFS_UNIFIED_PUSH_ENABLED, true) // Enabled by default - } - - fun setUnifiedPushEnabled(enabled: Boolean) { - sharedPrefs.edit() - .putBoolean(SHARED_PREFS_UNIFIED_PUSH_ENABLED, enabled) - .apply() - } - - fun getUnifiedPushBaseUrl(): String? { - return sharedPrefs.getString(SHARED_PREFS_UNIFIED_PUSH_BASE_URL, null) - } - fun setUnifiedPushBaseUrl(baseUrl: String) { if (baseUrl == "") { sharedPrefs @@ -321,17 +307,20 @@ class Repository(private val sharedPrefs: SharedPreferences, private val databas } fun getDefaultBaseUrl(): String? { - return sharedPrefs.getString(SHARED_PREFS_DEFAULT_BASE_URL, null) + return sharedPrefs.getString(SHARED_PREFS_DEFAULT_BASE_URL, null) ?: + sharedPrefs.getString(SHARED_PREFS_UNIFIED_PUSH_BASE_URL, null) // Fall back to UP URL, removed when default is set! } fun setDefaultBaseUrl(baseUrl: String) { if (baseUrl == "") { sharedPrefs .edit() + .remove(SHARED_PREFS_UNIFIED_PUSH_BASE_URL) // Remove legacy key .remove(SHARED_PREFS_DEFAULT_BASE_URL) .apply() } else { sharedPrefs.edit() + .remove(SHARED_PREFS_UNIFIED_PUSH_BASE_URL) // Remove legacy key .putString(SHARED_PREFS_DEFAULT_BASE_URL, baseUrl) .apply() } diff --git a/app/src/main/java/io/heckel/ntfy/ui/AddFragment.kt b/app/src/main/java/io/heckel/ntfy/ui/AddFragment.kt index f71f7dd..89e8192 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/AddFragment.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/AddFragment.kt @@ -367,11 +367,7 @@ class AddFragment : DialogFragment() { activity.runOnUiThread { val topic = subscribeTopicText.text.toString() val baseUrl = getBaseUrl() - val instant = if (!BuildConfig.FIREBASE_AVAILABLE || subscribeUseAnotherServerCheckbox.isChecked) { - true - } else { - subscribeInstantDeliveryCheckbox.isChecked - } + val instant = !BuildConfig.FIREBASE_AVAILABLE || baseUrl != appBaseUrl subscribeListener.onSubscribe(topic, baseUrl, instant) dialog?.dismiss() } @@ -381,7 +377,7 @@ class AddFragment : DialogFragment() { return if (subscribeUseAnotherServerCheckbox.isChecked) { subscribeBaseUrlText.text.toString() } else { - return repository.getDefaultBaseUrl() ?: appBaseUrl + return defaultBaseUrl ?: appBaseUrl } } diff --git a/app/src/main/java/io/heckel/ntfy/ui/DetailActivity.kt b/app/src/main/java/io/heckel/ntfy/ui/DetailActivity.kt index 362be6d..29288e6 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/DetailActivity.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/DetailActivity.kt @@ -265,10 +265,6 @@ class DetailActivity : AppCompatActivity(), ActionMode.Callback, NotificationFra onInstantEnableClick(enable = false) true } - R.id.detail_menu_instant_info -> { - onInstantInfoClick() - true - } R.id.detail_menu_copy_url -> { onCopyUrlClick() true @@ -419,28 +415,19 @@ class DetailActivity : AppCompatActivity(), ActionMode.Callback, NotificationFra } } - private fun onInstantInfoClick() { - Log.d(TAG, "Showing instant info toast") - Toast.makeText(this@DetailActivity, getString(R.string.detail_instant_info), Toast.LENGTH_LONG) - .show() - } - private fun showHideInstantMenuItems(enable: Boolean) { subscriptionInstant = enable runOnUiThread { val appBaseUrl = getString(R.string.app_base_url) val enableInstantItem = menu.findItem(R.id.detail_menu_enable_instant) val disableInstantItem = menu.findItem(R.id.detail_menu_disable_instant) - val instantInfoItem = menu.findItem(R.id.detail_menu_instant_info) val allowToggleInstant = BuildConfig.FIREBASE_AVAILABLE && subscriptionBaseUrl == appBaseUrl if (allowToggleInstant) { enableInstantItem?.isVisible = !subscriptionInstant disableInstantItem?.isVisible = subscriptionInstant - instantInfoItem?.isVisible = false } else { enableInstantItem?.isVisible = false disableInstantItem?.isVisible = false - instantInfoItem?.isVisible = BuildConfig.FIREBASE_AVAILABLE } } } diff --git a/app/src/main/java/io/heckel/ntfy/ui/MainActivity.kt b/app/src/main/java/io/heckel/ntfy/ui/MainActivity.kt index e5c3cf8..02cc46f 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/MainActivity.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/MainActivity.kt @@ -371,7 +371,7 @@ class MainActivity : AppCompatActivity(), ActionMode.Callback, AddFragment.Subsc } override fun onSubscribe(topic: String, baseUrl: String, instant: Boolean) { - Log.d(TAG, "Adding subscription ${topicShortUrl(baseUrl, topic)}") + Log.d(TAG, "Adding subscription ${topicShortUrl(baseUrl, topic)} (instant = $instant)") // Add subscription to database val subscription = Subscription( @@ -390,7 +390,7 @@ class MainActivity : AppCompatActivity(), ActionMode.Callback, AddFragment.Subsc // Subscribe to Firebase topic if ntfy.sh (even if instant, just to be sure!) if (baseUrl == appBaseUrl) { - Log.d(TAG, "Subscribing to Firebase") + Log.d(TAG, "Subscribing to Firebase topic $topic") messenger.subscribe(topic) } @@ -401,7 +401,7 @@ class MainActivity : AppCompatActivity(), ActionMode.Callback, AddFragment.Subsc val notifications = api.poll(subscription.id, subscription.baseUrl, subscription.topic, user) notifications.forEach { notification -> repository.addNotification(notification) } } catch (e: Exception) { - Log.e(TAG, "Unable to fetch notifications: ${e.stackTrace}") + Log.e(TAG, "Unable to fetch notifications: ${e.message}", e) } } diff --git a/app/src/main/java/io/heckel/ntfy/ui/SettingsActivity.kt b/app/src/main/java/io/heckel/ntfy/ui/SettingsActivity.kt index faa7d5e..5afca96 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/SettingsActivity.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/SettingsActivity.kt @@ -283,50 +283,8 @@ class SettingsActivity : AppCompatActivity(), PreferenceFragmentCompat.OnPrefere } } - // UnifiedPush enabled - val upEnabledPrefId = context?.getString(R.string.settings_unified_push_enabled_key) ?: return - val upEnabled: SwitchPreference? = findPreference(upEnabledPrefId) - upEnabled?.isChecked = repository.getUnifiedPushEnabled() - upEnabled?.preferenceDataStore = object : PreferenceDataStore() { - override fun putBoolean(key: String?, value: Boolean) { - repository.setUnifiedPushEnabled(value) - } - override fun getBoolean(key: String?, defValue: Boolean): Boolean { - return repository.getUnifiedPushEnabled() - } - } - upEnabled?.summaryProvider = Preference.SummaryProvider { pref -> - if (pref.isChecked) { - getString(R.string.settings_unified_push_enabled_summary_on) - } else { - getString(R.string.settings_unified_push_enabled_summary_off) - } - } - - // UnifiedPush Base URL - val appBaseUrl = context?.getString(R.string.app_base_url) ?: return - val upBaseUrlPrefId = context?.getString(R.string.settings_unified_push_base_url_key) ?: return - val upBaseUrl: EditTextPreference? = findPreference(upBaseUrlPrefId) - upBaseUrl?.text = repository.getUnifiedPushBaseUrl() ?: "" - upBaseUrl?.preferenceDataStore = object : PreferenceDataStore() { - override fun putString(key: String, value: String?) { - val baseUrl = value ?: return - repository.setUnifiedPushBaseUrl(baseUrl) - } - override fun getString(key: String, defValue: String?): String? { - return repository.getUnifiedPushBaseUrl() - } - } - upBaseUrl?.summaryProvider = Preference.SummaryProvider { pref -> - if (TextUtils.isEmpty(pref.text)) { - getString(R.string.settings_unified_push_base_url_default_summary, appBaseUrl) - } else { - pref.text - } - } - - // Default Base URL + val appBaseUrl = getString(R.string.app_base_url) val defaultBaseUrlPrefId = context?.getString(R.string.settings_advanced_default_base_url_key) ?: return val defaultBaseUrl: EditTextPreference? = findPreference(defaultBaseUrlPrefId) defaultBaseUrl?.text = repository.getDefaultBaseUrl() ?: "" diff --git a/app/src/main/java/io/heckel/ntfy/ui/ShareActivity.kt b/app/src/main/java/io/heckel/ntfy/ui/ShareActivity.kt index ababf3b..3f6dd2c 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/ShareActivity.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/ShareActivity.kt @@ -29,6 +29,7 @@ class ShareActivity : AppCompatActivity() { // Context-dependent things private lateinit var appBaseUrl: String + private var defaultBaseUrl: String? = null // UI elements private lateinit var menu: Menu @@ -42,7 +43,7 @@ class ShareActivity : AppCompatActivity() { private lateinit var baseUrlLayout: TextInputLayout private lateinit var baseUrlText: AutoCompleteTextView private lateinit var useAnotherServerCheckbox: CheckBox - private lateinit var lastTopicsList: RecyclerView + private lateinit var suggestedTopicsList: RecyclerView private lateinit var progress: ProgressBar private lateinit var errorText: TextView private lateinit var errorImage: ImageView @@ -62,6 +63,7 @@ class ShareActivity : AppCompatActivity() { // Context-dependent things appBaseUrl = getString(R.string.app_base_url) + defaultBaseUrl = repository.getDefaultBaseUrl() // UI elements val root: View = findViewById(R.id.share_root_view) @@ -76,8 +78,9 @@ class ShareActivity : AppCompatActivity() { baseUrlLayout.makeEndIconSmaller(resources) // Hack! baseUrlText = findViewById(R.id.share_base_url_text) baseUrlText.background = root.background + baseUrlText.hint = defaultBaseUrl ?: appBaseUrl useAnotherServerCheckbox = findViewById(R.id.share_use_another_server_checkbox) - lastTopicsList = findViewById(R.id.share_last_topics) + suggestedTopicsList = findViewById(R.id.share_suggested_topics) progress = findViewById(R.id.share_progress) progress.visibility = View.GONE errorText = findViewById(R.id.share_error_text) @@ -113,19 +116,25 @@ class ShareActivity : AppCompatActivity() { val lastShareTopics = repository.getLastShareTopics() val subscribedTopics = subscriptions .map { topicUrl(it.baseUrl, it.topic) } + .toSet() .subtract(lastShareTopics.toSet()) - val suggestedTopics = lastShareTopics.reversed() + subscribedTopics - val baseUrls = suggestedTopics + val suggestedTopics = (lastShareTopics.reversed() + subscribedTopics).distinct() + val baseUrlsRaw = suggestedTopics .mapNotNull { try { splitTopicUrl(it).first } catch (_: Exception) { null } } - .filterNot { it == appBaseUrl } - lastTopicsList.adapter = TopicAdapter(suggestedTopics) { topicUrl -> + .distinct() + val baseUrls = if (defaultBaseUrl != null) { + baseUrlsRaw.filterNot { it == defaultBaseUrl } + } else { + baseUrlsRaw.filterNot { it == appBaseUrl } + } + suggestedTopicsList.adapter = TopicAdapter(suggestedTopics) { topicUrl -> try { val (baseUrl, topic) = splitTopicUrl(topicUrl) topicText.text = topic - if (baseUrl == appBaseUrl) { + if (baseUrl == defaultBaseUrl) { useAnotherServerCheckbox.isChecked = false } else { useAnotherServerCheckbox.isChecked = true @@ -143,7 +152,8 @@ class ShareActivity : AppCompatActivity() { useAnotherServerCheckbox.isChecked = if (suggestedTopics.isNotEmpty()) { try { val (baseUrl, _) = splitTopicUrl(suggestedTopics.first()) - baseUrl != appBaseUrl + val defaultUrl = defaultBaseUrl ?: appBaseUrl + baseUrl != defaultUrl } catch (_: Exception) { false } @@ -254,6 +264,11 @@ class ShareActivity : AppCompatActivity() { val topic = topicText.text.toString() val message = contentText.text.toString() progress.visibility = View.VISIBLE + contentText.isEnabled = false + topicText.isEnabled = false + useAnotherServerCheckbox.isEnabled = false + baseUrlText.isEnabled = false + suggestedTopicsList.isEnabled = false lifecycleScope.launch(Dispatchers.IO) { val user = repository.getUser(baseUrl) try { @@ -316,7 +331,7 @@ class ShareActivity : AppCompatActivity() { return if (useAnotherServerCheckbox.isChecked) { baseUrlText.text.toString() } else { - getString(R.string.app_base_url) + defaultBaseUrl ?: appBaseUrl } } diff --git a/app/src/main/java/io/heckel/ntfy/up/BroadcastReceiver.kt b/app/src/main/java/io/heckel/ntfy/up/BroadcastReceiver.kt index 619e40e..339b772 100644 --- a/app/src/main/java/io/heckel/ntfy/up/BroadcastReceiver.kt +++ b/app/src/main/java/io/heckel/ntfy/up/BroadcastReceiver.kt @@ -38,8 +38,8 @@ class BroadcastReceiver : android.content.BroadcastReceiver() { val repository = app.repository val distributor = Distributor(app) Log.d(TAG, "REGISTER received for app $appId (connectorToken=$connectorToken)") - if (!repository.getUnifiedPushEnabled() || appId.isBlank()) { - Log.w(TAG, "Refusing registration: UnifiedPush disabled or empty application") + if (appId.isBlank()) { + Log.w(TAG, "Refusing registration: Empty application") distributor.sendRegistrationRefused(appId, connectorToken) return } @@ -58,7 +58,7 @@ class BroadcastReceiver : android.content.BroadcastReceiver() { } // Add subscription - val baseUrl = repository.getUnifiedPushBaseUrl() ?: context.getString(R.string.app_base_url) + val baseUrl = repository.getDefaultBaseUrl() ?: context.getString(R.string.app_base_url) val topic = UP_PREFIX + randomString(TOPIC_RANDOM_ID_LENGTH) val endpoint = topicUrlUp(baseUrl, topic) val subscription = Subscription( diff --git a/app/src/main/res/layout/activity_share.xml b/app/src/main/res/layout/activity_share.xml index a37d64d..dae99ae 100644 --- a/app/src/main/res/layout/activity_share.xml +++ b/app/src/main/res/layout/activity_share.xml @@ -137,7 +137,7 @@ + android:layout_marginTop="10dp" app:layout_constraintTop_toBottomOf="@id/share_suggested_topics"/> - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/preference_dialog_edittext_edited.xml b/app/src/main/res/layout/preference_dialog_edittext_edited.xml index 9c0628e..b55bb63 100644 --- a/app/src/main/res/layout/preference_dialog_edittext_edited.xml +++ b/app/src/main/res/layout/preference_dialog_edittext_edited.xml @@ -39,7 +39,8 @@ android:layout_marginRight="24dp" android:layout_marginStart="24dp" android:layout_marginEnd="24dp" - android:layout_marginBottom="4dp" + android:layout_marginBottom="2dp" + android:layout_marginTop="4dp" android:layout_width="match_parent" android:layout_height="wrap_content" android:textColor="?android:attr/textColorSecondary"/> diff --git a/app/src/main/res/menu/menu_detail_action_bar.xml b/app/src/main/res/menu/menu_detail_action_bar.xml index cbce6f5..a4c0390 100644 --- a/app/src/main/res/menu/menu_detail_action_bar.xml +++ b/app/src/main/res/menu/menu_detail_action_bar.xml @@ -9,8 +9,6 @@ app:showAsAction="ifRoom" android:icon="@drawable/ic_bolt_outline_white_24dp"/> - diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e2a6b8b..3e5a379 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -82,10 +82,10 @@ Topic name, e.g. phils_alerts Use another server - You can subscribe to topics from your own server. This option requires a foreground service. + You can subscribe to topics from another server. This option requires a foreground service. - You can subscribe to topics from your own server. Type the server URL below. + You can subscribe to topics from another server. Type the server URL below. Instant delivery in doze mode @@ -133,7 +133,6 @@ Copied to clipboard Instant delivery enabled Instant delivery disabled - Instant delivery is enabled Tags: %1$s Notification deleted Undo @@ -166,7 +165,6 @@ Notifications disabled until %1$s Enable instant delivery Disable instant delivery - Instant delivery enabled Send test notification Copy topic address Clear all notifications @@ -226,6 +224,7 @@ Settings + General Notifications MutedUntil Pause notifications @@ -289,20 +288,10 @@ Add users Add new user Create a new user for a new server - UnifiedPush - Allows other apps to use ntfy as a message distributor. Find out more at unifiedpush.org. - UnifiedPushEnabled - Allow distributor use - Apps can use ntfy as distributor - Apps cannot use ntfy as distributor - UnifiedPushBaseURL - Server URL - Set the root server URL to be used for new UnifiedPush topics here. - %1$s (default) Advanced DefaultBaseURL - Default Server URL - Set the default server URL to be used for new topics here. Topics on other hosts can still be subscribed to using the "use another server" checkbox. + Default server + To use your own server as a default when subscribing to new topics and/or sharing to topics, enter the server base URL. %1$s (default) BroadcastEnabled Broadcast messages diff --git a/app/src/main/res/xml/main_preferences.xml b/app/src/main/res/xml/main_preferences.xml index 5178ff0..aa91e04 100644 --- a/app/src/main/res/xml/main_preferences.xml +++ b/app/src/main/res/xml/main_preferences.xml @@ -1,8 +1,6 @@ - + - + + - - - - - - -