Preferences dialog
This commit is contained in:
parent
72393ec0af
commit
2bc87013d5
13 changed files with 291 additions and 32 deletions
|
@ -67,6 +67,7 @@ dependencies {
|
||||||
|
|
||||||
// WorkManager
|
// WorkManager
|
||||||
implementation "androidx.work:work-runtime-ktx:2.6.0"
|
implementation "androidx.work:work-runtime-ktx:2.6.0"
|
||||||
|
implementation 'androidx.preference:preference:1.1.1'
|
||||||
|
|
||||||
// Room (SQLite)
|
// Room (SQLite)
|
||||||
def roomVersion = "2.3.0"
|
def roomVersion = "2.3.0"
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
|
||||||
<uses-permission android:name="android.permission.WAKE_LOCK"/>
|
<uses-permission android:name="android.permission.WAKE_LOCK"/>
|
||||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
|
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
|
||||||
<uses-permission android:name="android.permission.VIBRATE" />
|
<uses-permission android:name="android.permission.VIBRATE"/>
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:name=".app.Application"
|
android:name=".app.Application"
|
||||||
|
@ -23,6 +23,7 @@
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/AppTheme"
|
android:theme="@style/AppTheme"
|
||||||
android:usesCleartextTraffic="true">
|
android:usesCleartextTraffic="true">
|
||||||
|
|
||||||
<!-- Main activity -->
|
<!-- Main activity -->
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.MainActivity"
|
android:name=".ui.MainActivity"
|
||||||
|
@ -43,32 +44,51 @@
|
||||||
android:value=".ui.MainActivity"/>
|
android:value=".ui.MainActivity"/>
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
|
<!-- Settings activity -->
|
||||||
|
<activity
|
||||||
|
android:name=".ui.SettingsActivity"
|
||||||
|
android:parentActivityName=".ui.MainActivity">
|
||||||
|
<meta-data
|
||||||
|
android:name="android.support.PARENT_ACTIVITY"
|
||||||
|
android:value=".ui.MainActivity"/>
|
||||||
|
</activity>
|
||||||
|
|
||||||
<!-- Subscriber foreground service for hosts other than ntfy.sh -->
|
<!-- Subscriber foreground service for hosts other than ntfy.sh -->
|
||||||
<service android:name=".service.SubscriberService"/>
|
<service android:name=".service.SubscriberService"/>
|
||||||
|
|
||||||
<!-- Subscriber service restart on reboot -->
|
<!-- Subscriber service restart on reboot -->
|
||||||
<receiver android:name=".service.SubscriberService$BootStartReceiver" android:enabled="true">
|
<receiver
|
||||||
|
android:name=".service.SubscriberService$BootStartReceiver"
|
||||||
|
android:enabled="true">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.BOOT_COMPLETED"/>
|
<action android:name="android.intent.action.BOOT_COMPLETED"/>
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</receiver>
|
</receiver>
|
||||||
|
|
||||||
<!-- Subscriber service restart on destruction -->
|
<!-- Subscriber service restart on destruction -->
|
||||||
<receiver android:name=".service.SubscriberService$AutoRestartReceiver" android:enabled="true"
|
<receiver
|
||||||
android:exported="false"/>
|
android:name=".service.SubscriberService$AutoRestartReceiver"
|
||||||
|
android:enabled="true"
|
||||||
|
android:exported="false"/>
|
||||||
|
|
||||||
<!-- Broadcast receiver to send messages via intents -->
|
<!-- Broadcast receiver to send messages via intents -->
|
||||||
<receiver android:name=".msg.BroadcastService$BroadcastReceiver" android:enabled="true" android:exported="true">
|
<receiver
|
||||||
|
android:name=".msg.BroadcastService$BroadcastReceiver"
|
||||||
|
android:enabled="true"
|
||||||
|
android:exported="true">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="io.heckel.ntfy.SEND_MESSAGE"/>
|
<action android:name="io.heckel.ntfy.SEND_MESSAGE"/>
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</receiver>
|
</receiver>
|
||||||
|
|
||||||
<!-- Broadcast receiver for UnifiedPush; must match https://github.com/UnifiedPush/UP-spec/blob/main/specifications.md -->
|
<!-- Broadcast receiver for UnifiedPush; must match https://github.com/UnifiedPush/UP-spec/blob/main/specifications.md -->
|
||||||
<receiver android:name=".up.BroadcastReceiver" android:enabled="true" android:exported="true">
|
<receiver
|
||||||
|
android:name=".up.BroadcastReceiver"
|
||||||
|
android:enabled="true"
|
||||||
|
android:exported="true">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="org.unifiedpush.android.distributor.REGISTER" />
|
<action android:name="org.unifiedpush.android.distributor.REGISTER"/>
|
||||||
<action android:name="org.unifiedpush.android.distributor.UNREGISTER" />
|
<action android:name="org.unifiedpush.android.distributor.UNREGISTER"/>
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</receiver>
|
</receiver>
|
||||||
|
|
||||||
|
@ -80,7 +100,6 @@
|
||||||
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
|
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</service>
|
</service>
|
||||||
|
|
||||||
<meta-data
|
<meta-data
|
||||||
android:name="firebase_analytics_collection_enabled"
|
android:name="firebase_analytics_collection_enabled"
|
||||||
android:value="false"/>
|
android:value="false"/>
|
||||||
|
@ -88,5 +107,4 @@
|
||||||
android:name="com.google.firebase.messaging.default_notification_icon"
|
android:name="com.google.firebase.messaging.default_notification_icon"
|
||||||
android:resource="@drawable/ic_notification"/>
|
android:resource="@drawable/ic_notification"/>
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|
|
@ -4,6 +4,7 @@ import android.content.SharedPreferences
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import androidx.annotation.WorkerThread
|
import androidx.annotation.WorkerThread
|
||||||
import androidx.lifecycle.*
|
import androidx.lifecycle.*
|
||||||
|
import androidx.preference.PreferenceManager
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
import java.util.concurrent.atomic.AtomicLong
|
import java.util.concurrent.atomic.AtomicLong
|
||||||
|
|
||||||
|
@ -142,12 +143,32 @@ class Repository(private val sharedPrefs: SharedPreferences, private val subscri
|
||||||
.apply()
|
.apply()
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun isMuted(subscriptionId: Long): Boolean {
|
|
||||||
if (isGlobalMuted()) {
|
fun getUnifiedPushEnabled(): Boolean {
|
||||||
return true
|
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
|
||||||
|
.edit()
|
||||||
|
.remove(SHARED_PREFS_UNIFIED_PUSH_BASE_URL)
|
||||||
|
.apply()
|
||||||
|
} else {
|
||||||
|
sharedPrefs.edit()
|
||||||
|
.putString(SHARED_PREFS_UNIFIED_PUSH_BASE_URL, baseUrl)
|
||||||
|
.apply()
|
||||||
}
|
}
|
||||||
val s = getSubscription(subscriptionId) ?: return true
|
|
||||||
return s.mutedUntil == 1L || (s.mutedUntil > 1L && s.mutedUntil > System.currentTimeMillis()/1000)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isGlobalMuted(): Boolean {
|
fun isGlobalMuted(): Boolean {
|
||||||
|
@ -242,6 +263,8 @@ class Repository(private val sharedPrefs: SharedPreferences, private val subscri
|
||||||
const val SHARED_PREFS_POLL_WORKER_VERSION = "PollWorkerVersion"
|
const val SHARED_PREFS_POLL_WORKER_VERSION = "PollWorkerVersion"
|
||||||
const val SHARED_PREFS_AUTO_RESTART_WORKER_VERSION = "AutoRestartWorkerVersion"
|
const val SHARED_PREFS_AUTO_RESTART_WORKER_VERSION = "AutoRestartWorkerVersion"
|
||||||
const val SHARED_PREFS_MUTED_UNTIL_TIMESTAMP = "MutedUntil"
|
const val SHARED_PREFS_MUTED_UNTIL_TIMESTAMP = "MutedUntil"
|
||||||
|
const val SHARED_PREFS_UNIFIED_PUSH_ENABLED = "UnifiedPushEnabled"
|
||||||
|
const val SHARED_PREFS_UNIFIED_PUSH_BASE_URL = "UnifiedPushBaseURL"
|
||||||
|
|
||||||
private const val TAG = "NtfyRepository"
|
private const val TAG = "NtfyRepository"
|
||||||
private var instance: Repository? = null
|
private var instance: Repository? = null
|
||||||
|
|
|
@ -420,7 +420,6 @@ class DetailActivity : AppCompatActivity(), ActionMode.Callback, NotificationFra
|
||||||
val formattedDate = formatDateShort(subscriptionMutedUntil)
|
val formattedDate = formatDateShort(subscriptionMutedUntil)
|
||||||
notificationsDisabledUntilItem?.title = getString(R.string.detail_menu_notifications_disabled_until, formattedDate)
|
notificationsDisabledUntilItem?.title = getString(R.string.detail_menu_notifications_disabled_until, formattedDate)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -232,6 +232,10 @@ class MainActivity : AppCompatActivity(), ActionMode.Callback, AddFragment.Subsc
|
||||||
onNotificationSettingsClick(enable = true)
|
onNotificationSettingsClick(enable = true)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
R.id.main_menu_settings -> {
|
||||||
|
startActivity(Intent(this, SettingsActivity::class.java))
|
||||||
|
true
|
||||||
|
}
|
||||||
R.id.main_menu_source -> {
|
R.id.main_menu_source -> {
|
||||||
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.main_menu_source_url))))
|
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.main_menu_source_url))))
|
||||||
true
|
true
|
||||||
|
|
88
app/src/main/java/io/heckel/ntfy/ui/SettingsActivity.kt
Normal file
88
app/src/main/java/io/heckel/ntfy/ui/SettingsActivity.kt
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
package io.heckel.ntfy.ui
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.text.TextUtils
|
||||||
|
import android.util.Log
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.preference.*
|
||||||
|
import io.heckel.ntfy.BuildConfig
|
||||||
|
import io.heckel.ntfy.R
|
||||||
|
import io.heckel.ntfy.app.Application
|
||||||
|
import io.heckel.ntfy.data.Repository
|
||||||
|
|
||||||
|
class SettingsActivity : AppCompatActivity() {
|
||||||
|
private val repository by lazy { (application as Application).repository }
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
setContentView(R.layout.activity_settings)
|
||||||
|
|
||||||
|
Log.d(MainActivity.TAG, "Create $this")
|
||||||
|
|
||||||
|
if (savedInstanceState == null) {
|
||||||
|
supportFragmentManager
|
||||||
|
.beginTransaction()
|
||||||
|
.replace(R.id.settings_layout, SettingsFragment(repository))
|
||||||
|
.commit()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Action bar
|
||||||
|
title = getString(R.string.settings_title)
|
||||||
|
|
||||||
|
// Show 'Back' button
|
||||||
|
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
class SettingsFragment(val repository: Repository) : PreferenceFragmentCompat() {
|
||||||
|
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||||
|
setPreferencesFromResource(R.xml.main_preferences, rootKey)
|
||||||
|
|
||||||
|
// UnifiedPush Enabled
|
||||||
|
val upEnabledPrefId = context?.getString(R.string.pref_unified_push_enabled) ?: 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<SwitchPreference> { 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.pref_unified_push_base_url) ?: 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<EditTextPreference> { pref ->
|
||||||
|
if (TextUtils.isEmpty(pref.text)) {
|
||||||
|
getString(R.string.settings_unified_push_base_url_default_summary, appBaseUrl)
|
||||||
|
} else {
|
||||||
|
pref.text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Version
|
||||||
|
val versionPrefId = context?.getString(R.string.pref_version) ?: return
|
||||||
|
val versionPref: Preference? = findPreference(versionPrefId)
|
||||||
|
versionPref?.summary = getString(R.string.settings_about_version_format, BuildConfig.VERSION_NAME, BuildConfig.FLAVOR)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,9 +3,9 @@ package io.heckel.ntfy.up
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
import androidx.preference.PreferenceManager
|
||||||
import io.heckel.ntfy.R
|
import io.heckel.ntfy.R
|
||||||
import io.heckel.ntfy.app.Application
|
import io.heckel.ntfy.app.Application
|
||||||
import io.heckel.ntfy.data.Repository
|
|
||||||
import io.heckel.ntfy.data.Subscription
|
import io.heckel.ntfy.data.Subscription
|
||||||
import io.heckel.ntfy.service.SubscriberServiceManager
|
import io.heckel.ntfy.service.SubscriberServiceManager
|
||||||
import io.heckel.ntfy.util.randomString
|
import io.heckel.ntfy.util.randomString
|
||||||
|
@ -34,8 +34,8 @@ class BroadcastReceiver : android.content.BroadcastReceiver() {
|
||||||
val repository = app.repository
|
val repository = app.repository
|
||||||
val distributor = Distributor(app)
|
val distributor = Distributor(app)
|
||||||
Log.d(TAG, "REGISTER received for app $appId (connectorToken=$connectorToken)")
|
Log.d(TAG, "REGISTER received for app $appId (connectorToken=$connectorToken)")
|
||||||
if (appId.isBlank()) {
|
if (!repository.getUnifiedPushEnabled() || appId.isBlank()) {
|
||||||
Log.w(TAG, "Refusing registration: empty application")
|
Log.w(TAG, "Refusing registration: UnifiedPush disabled or empty application")
|
||||||
distributor.sendRegistrationRefused(appId, connectorToken)
|
distributor.sendRegistrationRefused(appId, connectorToken)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -54,8 +54,8 @@ class BroadcastReceiver : android.content.BroadcastReceiver() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add subscription
|
// Add subscription
|
||||||
val baseUrl = context.getString(R.string.app_base_url) // FIXME
|
val baseUrl = repository.getUnifiedPushBaseUrl() ?: context.getString(R.string.app_base_url)
|
||||||
val topic = UP_PREFIX + randomString(TOPIC_LENGTH)
|
val topic = UP_PREFIX + randomString(TOPIC_RANDOM_ID_LENGTH)
|
||||||
val endpoint = topicUrlUp(baseUrl, topic)
|
val endpoint = topicUrlUp(baseUrl, topic)
|
||||||
val subscription = Subscription(
|
val subscription = Subscription(
|
||||||
id = Random.nextLong(),
|
id = Random.nextLong(),
|
||||||
|
@ -105,6 +105,6 @@ class BroadcastReceiver : android.content.BroadcastReceiver() {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "NtfyUpBroadcastRecv"
|
private const val TAG = "NtfyUpBroadcastRecv"
|
||||||
private const val UP_PREFIX = "up"
|
private const val UP_PREFIX = "up"
|
||||||
private const val TOPIC_LENGTH = 16
|
private const val TOPIC_RANDOM_ID_LENGTH = 12
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
9
app/src/main/res/layout/activity_settings.xml
Normal file
9
app/src/main/res/layout/activity_settings.xml
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<LinearLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/settings_layout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"/>
|
||||||
|
</LinearLayout>
|
|
@ -24,12 +24,13 @@
|
||||||
android:textColor="@color/primaryTextColor" android:layout_marginTop="10dp"
|
android:textColor="@color/primaryTextColor" android:layout_marginTop="10dp"
|
||||||
app:layout_constraintEnd_toStartOf="@+id/main_item_instant_image"/>
|
app:layout_constraintEnd_toStartOf="@+id/main_item_instant_image"/>
|
||||||
<TextView
|
<TextView
|
||||||
android:text="89 notifications"
|
android:text="89 notifications, reconnecting ... This may wrap in the case of UnifiedPush"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content" android:id="@+id/main_item_status"
|
android:layout_height="wrap_content" android:id="@+id/main_item_status"
|
||||||
app:layout_constraintStart_toStartOf="@+id/main_item_text"
|
app:layout_constraintStart_toStartOf="@+id/main_item_text"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/main_item_text" app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintTop_toBottomOf="@+id/main_item_text" app:layout_constraintBottom_toBottomOf="parent"
|
||||||
android:layout_marginBottom="10dp"/>
|
android:layout_marginBottom="10dp" app:layout_constrainedWidth="true"
|
||||||
|
app:layout_constraintEnd_toStartOf="@id/main_item_new" android:layout_marginEnd="10dp"/>
|
||||||
<ImageView
|
<ImageView
|
||||||
android:layout_width="20dp"
|
android:layout_width="20dp"
|
||||||
android:layout_height="24dp" app:srcCompat="@drawable/ic_notifications_off_time_gray_outline_24dp"
|
android:layout_height="24dp" app:srcCompat="@drawable/ic_notifications_off_time_gray_outline_24dp"
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
This is a slightly edited copy of the original Android project layout
|
||||||
|
to make wrapping the summary line work.
|
||||||
|
|
||||||
|
~ Copyright (C) 2015 The Android Open Source Project
|
||||||
|
~
|
||||||
|
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
~ you may not use this file except in compliance with the License.
|
||||||
|
~ You may obtain a copy of the License at
|
||||||
|
~
|
||||||
|
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
~
|
||||||
|
~ Unless required by applicable law or agreed to in writing, software
|
||||||
|
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
~ See the License for the specific language governing permissions and
|
||||||
|
~ limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingLeft="?android:attr/listPreferredItemPaddingLeft"
|
||||||
|
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
|
||||||
|
android:paddingRight="?android:attr/listPreferredItemPaddingRight"
|
||||||
|
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
|
||||||
|
android:background="?android:attr/selectableItemBackground"
|
||||||
|
android:baselineAligned="false"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:gravity="center_vertical">
|
||||||
|
|
||||||
|
<include layout="@layout/image_frame"/>
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:paddingTop="8dp"
|
||||||
|
android:paddingBottom="8dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@android:id/title"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="start"
|
||||||
|
android:textAlignment="viewStart"
|
||||||
|
style="@style/PreferenceCategoryTitleTextStyle"/>
|
||||||
|
|
||||||
|
<!-- EDITED singleLine -->
|
||||||
|
<TextView
|
||||||
|
android:id="@android:id/summary"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:singleLine="false"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_below="@android:id/title"
|
||||||
|
android:layout_alignLeft="@android:id/title"
|
||||||
|
android:layout_alignStart="@android:id/title"
|
||||||
|
android:layout_gravity="start"
|
||||||
|
android:textAlignment="viewStart"
|
||||||
|
android:textColor="?android:attr/textColorSecondary"
|
||||||
|
android:maxLines="10"
|
||||||
|
style="@style/PreferenceSummaryTextStyle"/>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
</LinearLayout>
|
|
@ -5,6 +5,7 @@
|
||||||
app:showAsAction="ifRoom" android:icon="@drawable/ic_notifications_off_time_white_outline_24dp"/>
|
app:showAsAction="ifRoom" android:icon="@drawable/ic_notifications_off_time_white_outline_24dp"/>
|
||||||
<item android:id="@+id/main_menu_notifications_disabled_forever" android:title="@string/detail_menu_notifications_disabled_forever"
|
<item android:id="@+id/main_menu_notifications_disabled_forever" android:title="@string/detail_menu_notifications_disabled_forever"
|
||||||
app:showAsAction="ifRoom" android:icon="@drawable/ic_notifications_off_white_outline_24dp"/>
|
app:showAsAction="ifRoom" android:icon="@drawable/ic_notifications_off_white_outline_24dp"/>
|
||||||
|
<item android:id="@+id/main_menu_settings" android:title="@string/main_menu_settings_title"/>
|
||||||
<item android:id="@+id/main_menu_source" android:title="@string/main_menu_source_title"/>
|
<item android:id="@+id/main_menu_source" android:title="@string/main_menu_source_title"/>
|
||||||
<item android:id="@+id/main_menu_website" android:title="@string/main_menu_website_title"/>
|
<item android:id="@+id/main_menu_website" android:title="@string/main_menu_website_title"/>
|
||||||
</menu>
|
</menu>
|
||||||
|
|
|
@ -16,7 +16,8 @@
|
||||||
<string name="channel_subscriber_notification_text">You are subscribed to instant delivery topics</string>
|
<string name="channel_subscriber_notification_text">You are subscribed to instant delivery topics</string>
|
||||||
<string name="channel_subscriber_notification_text_one">You are subscribed to one instant delivery topic</string>
|
<string name="channel_subscriber_notification_text_one">You are subscribed to one instant delivery topic</string>
|
||||||
<string name="channel_subscriber_notification_text_two">You are subscribed to two instant delivery topics</string>
|
<string name="channel_subscriber_notification_text_two">You are subscribed to two instant delivery topics</string>
|
||||||
<string name="channel_subscriber_notification_text_three">You are subscribed to three instant delivery topics</string>
|
<string name="channel_subscriber_notification_text_three">You are subscribed to three instant delivery topics
|
||||||
|
</string>
|
||||||
<string name="channel_subscriber_notification_text_four">You are subscribed to four instant delivery topics</string>
|
<string name="channel_subscriber_notification_text_four">You are subscribed to four instant delivery topics</string>
|
||||||
<string name="channel_subscriber_notification_text_more">You are subscribed to %1$d instant delivery topics</string>
|
<string name="channel_subscriber_notification_text_more">You are subscribed to %1$d instant delivery topics</string>
|
||||||
|
|
||||||
|
@ -30,6 +31,7 @@
|
||||||
<string name="main_menu_notifications_enabled">Notifications enabled</string>
|
<string name="main_menu_notifications_enabled">Notifications enabled</string>
|
||||||
<string name="main_menu_notifications_disabled_forever">Notifications disabled</string>
|
<string name="main_menu_notifications_disabled_forever">Notifications disabled</string>
|
||||||
<string name="main_menu_notifications_disabled_until">Notifications disabled until %1$s</string>
|
<string name="main_menu_notifications_disabled_until">Notifications disabled until %1$s</string>
|
||||||
|
<string name="main_menu_settings_title">Settings</string>
|
||||||
<string name="main_menu_source_title">Report a bug</string>
|
<string name="main_menu_source_title">Report a bug</string>
|
||||||
<string name="main_menu_source_url">https://heckel.io/ntfy-android</string>
|
<string name="main_menu_source_url">https://heckel.io/ntfy-android</string>
|
||||||
<string name="main_menu_website_title">Visit ntfy.sh</string>
|
<string name="main_menu_website_title">Visit ntfy.sh</string>
|
||||||
|
@ -55,7 +57,8 @@
|
||||||
Click the button below to create or subscribe to a topic. After that, you can send
|
Click the button below to create or subscribe to a topic. After that, you can send
|
||||||
messages via PUT or POST and you\'ll receive notifications on your phone.
|
messages via PUT or POST and you\'ll receive notifications on your phone.
|
||||||
</string>
|
</string>
|
||||||
<string name="main_how_to_link">For more detailed instructions, check out the ntfy.sh website and documentation.</string>
|
<string name="main_how_to_link">For more detailed instructions, check out the ntfy.sh website and documentation.
|
||||||
|
</string>
|
||||||
<string name="main_unified_push_toast">This subscription is managed by %1$s via UnifiedPush</string>
|
<string name="main_unified_push_toast">This subscription is managed by %1$s via UnifiedPush</string>
|
||||||
|
|
||||||
<!-- Add dialog -->
|
<!-- Add dialog -->
|
||||||
|
@ -81,10 +84,13 @@
|
||||||
<!-- Detail activity -->
|
<!-- Detail activity -->
|
||||||
<string name="detail_deep_link_subscribed_toast_message">Subscribed to topic %1$s</string>
|
<string name="detail_deep_link_subscribed_toast_message">Subscribed to topic %1$s</string>
|
||||||
<string name="detail_no_notifications_text">You haven\'t received any notifications for this topic yet.</string>
|
<string name="detail_no_notifications_text">You haven\'t received any notifications for this topic yet.</string>
|
||||||
<string name="detail_how_to_intro">To send notifications to this topic, simply PUT or POST to the topic URL.</string>
|
<string name="detail_how_to_intro">To send notifications to this topic, simply PUT or POST to the topic URL.
|
||||||
|
</string>
|
||||||
<string name="detail_how_to_example"><![CDATA[ Example (using curl):<br/><tt>$ curl -d \"Hi\" %1$s</tt> ]]></string>
|
<string name="detail_how_to_example"><![CDATA[ Example (using curl):<br/><tt>$ curl -d \"Hi\" %1$s</tt> ]]></string>
|
||||||
<string name="detail_how_to_link">For more detailed instructions, check out the ntfy.sh website and documentation.</string>
|
<string name="detail_how_to_link">For more detailed instructions, check out the ntfy.sh website and documentation.
|
||||||
<string name="detail_clear_dialog_message">Do you really want to delete all of the notifications in this topic?</string>
|
</string>
|
||||||
|
<string name="detail_clear_dialog_message">Do you really want to delete all of the notifications in this topic?
|
||||||
|
</string>
|
||||||
<string name="detail_clear_dialog_permanently_delete">Permanently delete</string>
|
<string name="detail_clear_dialog_permanently_delete">Permanently delete</string>
|
||||||
<string name="detail_clear_dialog_cancel">Cancel</string>
|
<string name="detail_clear_dialog_cancel">Cancel</string>
|
||||||
<string name="detail_delete_dialog_message">
|
<string name="detail_delete_dialog_message">
|
||||||
|
@ -94,7 +100,9 @@
|
||||||
<string name="detail_delete_dialog_permanently_delete">Permanently delete</string>
|
<string name="detail_delete_dialog_permanently_delete">Permanently delete</string>
|
||||||
<string name="detail_delete_dialog_cancel">Cancel</string>
|
<string name="detail_delete_dialog_cancel">Cancel</string>
|
||||||
<string name="detail_test_title">Test: You can set a title if you like</string>
|
<string name="detail_test_title">Test: You can set a title if you like</string>
|
||||||
<string name="detail_test_message">This is a test notification from the Ntfy Android app. It has a priority of %1$d. If you send another one, it may look different.</string>
|
<string name="detail_test_message">This is a test notification from the Ntfy Android app. It has a priority of %1$d.
|
||||||
|
If you send another one, it may look different.
|
||||||
|
</string>
|
||||||
<string name="detail_test_message_error">Could not send test message: %1$s</string>
|
<string name="detail_test_message_error">Could not send test message: %1$s</string>
|
||||||
<string name="detail_copied_to_clipboard_message">Copied to clipboard</string>
|
<string name="detail_copied_to_clipboard_message">Copied to clipboard</string>
|
||||||
<string name="detail_instant_delivery_enabled">Instant delivery enabled</string>
|
<string name="detail_instant_delivery_enabled">Instant delivery enabled</string>
|
||||||
|
@ -136,4 +144,22 @@
|
||||||
<string name="notification_dialog_8h">8 hours</string>
|
<string name="notification_dialog_8h">8 hours</string>
|
||||||
<string name="notification_dialog_tomorrow">Until tomorrow</string>
|
<string name="notification_dialog_tomorrow">Until tomorrow</string>
|
||||||
<string name="notification_dialog_forever">Forever</string>
|
<string name="notification_dialog_forever">Forever</string>
|
||||||
|
|
||||||
|
<!-- Settings -->
|
||||||
|
<string name="settings_title">Settings</string>
|
||||||
|
<string name="settings_unified_push_header">UnifiedPush</string>
|
||||||
|
<string name="settings_unified_push_header_summary">Allows other apps to use ntfy as a message distributor. Find out more at unifiedpush.org.</string>
|
||||||
|
<string name="settings_unified_push_enabled_title">Enabled</string>
|
||||||
|
<string name="settings_unified_push_enabled_summary_on">Apps can use ntfy as distributor</string>
|
||||||
|
<string name="settings_unified_push_enabled_summary_off">Apps cannot use ntfy as distributor</string>
|
||||||
|
<string name="settings_unified_push_base_url_title">Server URL</string>
|
||||||
|
<string name="settings_unified_push_base_url_default_summary">%1$s (default)</string>
|
||||||
|
<string name="settings_about_header">About</string>
|
||||||
|
<string name="settings_about_version">Version</string>
|
||||||
|
<string name="settings_about_version_format">ntfy %1$s (%2$s)</string>
|
||||||
|
|
||||||
|
<!-- Preferences IDs -->
|
||||||
|
<string name="pref_unified_push_enabled">UnifiedPushEnabled</string>
|
||||||
|
<string name="pref_unified_push_base_url">UnifiedPushBaseURL</string>
|
||||||
|
<string name="pref_version">Version</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
21
app/src/main/res/xml/main_preferences.xml
Normal file
21
app/src/main/res/xml/main_preferences.xml
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
<PreferenceScreen xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
app:title="@string/settings_title">
|
||||||
|
<PreferenceCategory
|
||||||
|
app:title="@string/settings_unified_push_header"
|
||||||
|
app:summary="@string/settings_unified_push_header_summary"
|
||||||
|
app:layout="@layout/preference_category_material_edited">
|
||||||
|
<SwitchPreference
|
||||||
|
app:key="@string/pref_unified_push_enabled"
|
||||||
|
app:title="@string/settings_unified_push_enabled_title"
|
||||||
|
app:enabled="true"/>
|
||||||
|
<EditTextPreference
|
||||||
|
app:key="@string/pref_unified_push_base_url"
|
||||||
|
app:title="@string/settings_unified_push_base_url_title"
|
||||||
|
app:dependency="@string/pref_unified_push_enabled"/>
|
||||||
|
</PreferenceCategory>
|
||||||
|
<PreferenceCategory app:title="@string/settings_about_header">
|
||||||
|
<Preference
|
||||||
|
app:key="@string/pref_version"
|
||||||
|
app:title="@string/settings_about_version"/>
|
||||||
|
</PreferenceCategory>
|
||||||
|
</PreferenceScreen>
|
Loading…
Reference in a new issue