Skip to content

Commit

Permalink
Notifications settings
Browse files Browse the repository at this point in the history
  • Loading branch information
KoalaSat committed Oct 25, 2024
1 parent d3f9557 commit 00e9961
Show file tree
Hide file tree
Showing 8 changed files with 366 additions and 71 deletions.
75 changes: 74 additions & 1 deletion app/src/main/java/com/koalasat/pokey/models/EncryptedStorage.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,22 @@ import androidx.security.crypto.MasterKey

object PrefKeys {
const val NOSTR_PUBKEY = "nostr_pubkey"
const val NOTIFY_REPLIES = "notify_replies"
const val NOTIFY_PRIVATE = "notify_private"
const val NOTIFY_ZAPS = "notify_zaps"
const val NOTIFY_QUOTES = "notify_quotes"
const val NOTIFY_REACTIONS = "notify_reactions"
const val NOTIFY_MENTIONS = "notify_mentions"
const val NOTIFY_REPOSTS = "notify_reposts"
}
object DefaultKeys {
const val NOTIFY_REPLIES = true
const val NOTIFY_REACTIONS = true
const val NOTIFY_PRIVATE = true
const val NOTIFY_ZAPS = true
const val NOTIFY_QUOTES = true
const val NOTIFY_MENTIONS = true
const val NOTIFY_REPOSTS = true
}

object EncryptedStorage {
Expand All @@ -19,6 +35,21 @@ object EncryptedStorage {
private val _pubKey = MutableLiveData<String>()
val pubKey: LiveData<String> get() = _pubKey

private val _notifyReplies = MutableLiveData<Boolean>().apply { DefaultKeys.NOTIFY_REPLIES }
val notifyReplies: LiveData<Boolean> get() = _notifyReplies
private val _notifyReactions = MutableLiveData<Boolean>().apply { DefaultKeys.NOTIFY_REACTIONS }
val notifyReactions: LiveData<Boolean> get() = _notifyReactions
private val _notifyPrivate = MutableLiveData<Boolean>().apply { DefaultKeys.NOTIFY_PRIVATE }
val notifyPrivate: LiveData<Boolean> get() = _notifyPrivate
private val _notifyZaps = MutableLiveData<Boolean>().apply { DefaultKeys.NOTIFY_ZAPS }
val notifyZaps: LiveData<Boolean> get() = _notifyZaps
private val _notifyQuotes = MutableLiveData<Boolean>().apply { DefaultKeys.NOTIFY_QUOTES }
val notifyQuotes: LiveData<Boolean> get() = _notifyQuotes
private val _notifyMentions = MutableLiveData<Boolean>().apply { DefaultKeys.NOTIFY_MENTIONS }
val notifyMentions: LiveData<Boolean> get() = _notifyMentions
private val _notifyResposts = MutableLiveData<Boolean>().apply { DefaultKeys.NOTIFY_REPOSTS }
val notifyResposts: LiveData<Boolean> get() = _notifyResposts

fun init(context: Context) {
val masterKey: MasterKey =
MasterKey.Builder(context, MasterKey.DEFAULT_MASTER_KEY_ALIAS)
Expand All @@ -33,11 +64,53 @@ object EncryptedStorage {
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM,
) as EncryptedSharedPreferences

_pubKey.value = sharedPreferences.getString(PrefKeys.NOSTR_PUBKEY, "").toString()
_pubKey.value = sharedPreferences.getString(PrefKeys.NOSTR_PUBKEY, "")
_notifyReplies.value = sharedPreferences.getBoolean(PrefKeys.NOTIFY_REPLIES, DefaultKeys.NOTIFY_REPLIES)
_notifyReactions.value = sharedPreferences.getBoolean(PrefKeys.NOTIFY_REACTIONS, DefaultKeys.NOTIFY_REACTIONS)
_notifyPrivate.value = sharedPreferences.getBoolean(PrefKeys.NOTIFY_PRIVATE, DefaultKeys.NOTIFY_PRIVATE)
_notifyZaps.value = sharedPreferences.getBoolean(PrefKeys.NOTIFY_ZAPS, DefaultKeys.NOTIFY_ZAPS)
_notifyQuotes.value = sharedPreferences.getBoolean(PrefKeys.NOTIFY_QUOTES, DefaultKeys.NOTIFY_QUOTES)
_notifyMentions.value = sharedPreferences.getBoolean(PrefKeys.NOTIFY_MENTIONS, DefaultKeys.NOTIFY_MENTIONS)
_notifyResposts.value = sharedPreferences.getBoolean(PrefKeys.NOTIFY_REPOSTS, DefaultKeys.NOTIFY_REPOSTS)
}

fun updatePubKey(newValue: String) {
sharedPreferences.edit().putString(PrefKeys.NOSTR_PUBKEY, newValue).apply()
_pubKey.value = newValue
}

fun updateNotifyReplies(newValue: Boolean) {
sharedPreferences.edit().putBoolean(PrefKeys.NOTIFY_REPLIES, newValue).apply()
_notifyReplies.value = newValue
}

fun updateNotifyReactions(newValue: Boolean) {
sharedPreferences.edit().putBoolean(PrefKeys.NOTIFY_REACTIONS, newValue).apply()
_notifyReactions.value = newValue
}

fun updateNotifyPrivate(newValue: Boolean) {
sharedPreferences.edit().putBoolean(PrefKeys.NOTIFY_PRIVATE, newValue).apply()
_notifyPrivate.value = newValue
}

fun updateNotifyZaps(newValue: Boolean) {
sharedPreferences.edit().putBoolean(PrefKeys.NOTIFY_ZAPS, newValue).apply()
_notifyZaps.value = newValue
}

fun updateNotifyQuotes(newValue: Boolean) {
sharedPreferences.edit().putBoolean(PrefKeys.NOTIFY_QUOTES, newValue).apply()
_notifyQuotes.value = newValue
}

fun updateNotifyMentions(newValue: Boolean) {
sharedPreferences.edit().putBoolean(PrefKeys.NOTIFY_MENTIONS, newValue).apply()
_notifyMentions.value = newValue
}

fun updateNotifyReposts(newValue: Boolean) {
sharedPreferences.edit().putBoolean(PrefKeys.NOTIFY_REPOSTS, newValue).apply()
_notifyResposts.value = newValue
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import com.vitorpamplona.ammolite.relays.TypedFilter
import com.vitorpamplona.ammolite.relays.filters.EOSETime
import com.vitorpamplona.ammolite.relays.filters.SincePerRelayFilter
import com.vitorpamplona.quartz.encoders.Hex
import com.vitorpamplona.quartz.encoders.LnInvoiceUtil
import com.vitorpamplona.quartz.encoders.Nip19Bech32
import com.vitorpamplona.quartz.encoders.Nip19Bech32.uriToRoute
import com.vitorpamplona.quartz.encoders.toNote
Expand Down Expand Up @@ -334,37 +335,61 @@ class NotificationsService : Service() {
val pubKey = EncryptedStorage.pubKey
var nip32Bech32 = ""

if (event.kind == 1) {
title = if (event.content().contains("nostr:$pubKey")) {
getString(R.string.new_mention)
} else if (event.content().contains("nostr:nevent1")) {
getString(R.string.new_quote)
} else {
getString(R.string.new_reply)
when (event.kind) {
1 -> {
title = when {
event.content().contains("nostr:$pubKey") -> {
if (!EncryptedStorage.notifyMentions.value!!) return@launch
getString(R.string.new_mention)
}
event.content().contains("nostr:nevent1") -> {
if (!EncryptedStorage.notifyQuotes.value!!) return@launch
getString(R.string.new_quote)
}
else -> {
if (!EncryptedStorage.notifyReplies.value!!) return@launch
getString(R.string.new_reply)
}
}
text = event.content().replace(Regex("nostr:[a-zA-Z0-9]+"), "")
nip32Bech32 = Hex.decode(event.id).toNote()
}
6 -> {
if (!EncryptedStorage.notifyResposts.value!!) return@launch

title = getString(R.string.new_repost)
nip32Bech32 = Hex.decode(event.id).toNote()
}
text = event.content().replace(Regex("nostr:[a-zA-Z0-9]+"), "")
nip32Bech32 = Hex.decode(event.id).toNote()
} else if (event.kind == 6) {
title = getString(R.string.new_repost)
nip32Bech32 = Hex.decode(event.id).toNote()
} else if (event.kind == 4 || event.kind == 13) {
title = getString(R.string.new_private)
nip32Bech32 = Hex.decode(event.pubKey).toNpub()
} else if (event.kind == 7) {
title = getString(R.string.new_reaction)
text = if (event.content.isEmpty() || event.content == "+") {
"\uFE0F"
} else {
event.content
4, 13 -> {
if (!EncryptedStorage.notifyPrivate.value!!) return@launch

title = getString(R.string.new_private)
nip32Bech32 = Hex.decode(event.pubKey).toNpub()
}
7 -> {
if (!EncryptedStorage.notifyReactions.value!!) return@launch

title = getString(R.string.new_reaction)
text = if (event.content.isEmpty() || event.content == "+") {
"\uFE0F"
} else {
event.content
}
val taggedEvent = event.taggedEvents().first()
nip32Bech32 = Hex.decode(taggedEvent).toNote()
}
9735 -> {
if (!EncryptedStorage.notifyZaps.value!!) return@launch

title = getString(R.string.new_zap)
val bolt11 = event.firstTag("bolt11")
if (!bolt11.isNullOrEmpty()) {
val sats = LnInvoiceUtil.getAmountInSats(bolt11)
text = "$sats Sats"
}
}
val taggedEvent = event.taggedEvents().first()
nip32Bech32 = Hex.decode(taggedEvent).toNote()
} else if (event.kind == 9735) {
title = getString(R.string.new_zap)
var sats = event.zapraiserAmount()
text = "$sats Sats"
}
Log.d("Pokey", nip32Bech32)

if (title.isEmpty()) return@launch

displayNoteNotification(title, text, nip32Bech32, event)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,37 +1,88 @@
package com.koalasat.pokey.ui.notifications

import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import com.koalasat.pokey.databinding.FragmentNotificationsBinding
import com.koalasat.pokey.models.EncryptedStorage

class NotificationsFragment : Fragment() {

private var _binding: FragmentNotificationsBinding? = null

// This property is only valid between onCreateView and
// onDestroyView.
private val binding get() = _binding!!

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?,
): View {
val notificationsViewModel =
val viewModel =
ViewModelProvider(this).get(NotificationsViewModel::class.java)

_binding = FragmentNotificationsBinding.inflate(inflater, container, false)
val root: View = binding.root

val textView: TextView = binding.textNotifications
notificationsViewModel.text.observe(viewLifecycleOwner) {
textView.text = it
viewModel.newReplies.value.apply { EncryptedStorage.notifyReplies.value }
binding.newReplies.setOnCheckedChangeListener { _, isChecked ->
viewModel.updateNotifyReplies(isChecked)
}
viewModel.newReplies.observe(viewLifecycleOwner) { value ->
binding.newReplies.isChecked = value
}

viewModel.newZaps.value.apply { EncryptedStorage.notifyZaps.value }
binding.newZaps.setOnCheckedChangeListener { _, isChecked ->
viewModel.updateNotifyZaps(isChecked)
}
viewModel.newZaps.observe(viewLifecycleOwner) { value ->
Log.d("Pokey", "binding.newZaps.isChecked" + binding.newZaps.isChecked)
binding.newZaps.isChecked = value
}

viewModel.newReactions.value.apply { EncryptedStorage.notifyReactions.value }
binding.newReactions.setOnCheckedChangeListener { _, isChecked ->
viewModel.updateNotifyReactions(isChecked)
}
viewModel.newReactions.observe(viewLifecycleOwner) { value ->
binding.newReactions.isChecked = value
}

viewModel.newPrivate.value.apply { EncryptedStorage.notifyPrivate.value }
binding.newPrivate.setOnCheckedChangeListener { _, isChecked ->
viewModel.updateNotifyPrivate(isChecked)
}
viewModel.newPrivate.observe(viewLifecycleOwner) { value ->
binding.newPrivate.isChecked = value
}

viewModel.newQuotes.value.apply { EncryptedStorage.notifyQuotes.value }
binding.newQuotes.setOnCheckedChangeListener { _, isChecked ->
viewModel.updateNotifyQuotes(isChecked)
}
viewModel.newQuotes.observe(viewLifecycleOwner) { value ->
binding.newQuotes.isChecked = value
}

viewModel.newMentions.value.apply { EncryptedStorage.notifyMentions.value }
binding.newMentions.setOnCheckedChangeListener { _, isChecked ->
viewModel.updateNotifyMentions(isChecked)
}
viewModel.newMentions.observe(viewLifecycleOwner) { value ->
binding.newMentions.isChecked = value
}

viewModel.newReposts.value.apply { EncryptedStorage.notifyResposts.value }
binding.newReposts.setOnCheckedChangeListener { _, isChecked ->
viewModel.updateNotifyReposts(isChecked)
}
viewModel.newReposts.observe(viewLifecycleOwner) { value ->
binding.newReposts.isChecked = value
}

return root
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,93 @@
package com.koalasat.pokey.ui.notifications

import android.util.Log
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.koalasat.pokey.models.EncryptedStorage

class NotificationsViewModel : ViewModel() {

private val _text = MutableLiveData<String>().apply {
value = "Coming Soon!"
private val _newReplies = MutableLiveData<Boolean>().apply { value = EncryptedStorage.notifyReplies.value }
val newReplies: LiveData<Boolean> = _newReplies

private val _newZaps = MutableLiveData<Boolean>().apply { value = EncryptedStorage.notifyZaps.value }
val newZaps: LiveData<Boolean> = _newZaps

private val _newQuotes = MutableLiveData<Boolean>().apply { value = EncryptedStorage.notifyQuotes.value }
val newQuotes: LiveData<Boolean> = _newQuotes

private val _newReactions = MutableLiveData<Boolean>().apply { value = EncryptedStorage.notifyReactions.value }
val newReactions: LiveData<Boolean> = _newReactions

private val _newPrivate = MutableLiveData<Boolean>().apply { value = EncryptedStorage.notifyPrivate.value }
val newPrivate: LiveData<Boolean> = _newPrivate

private val _newMentions = MutableLiveData<Boolean>().apply { value = EncryptedStorage.notifyMentions.value }
val newMentions: LiveData<Boolean> = _newMentions

private val _newReposts = MutableLiveData<Boolean>().apply { value = EncryptedStorage.notifyResposts.value }
val newReposts: LiveData<Boolean> = _newReposts

init {
EncryptedStorage.notifyReplies.observeForever { value ->
_newReplies.value = value
}
Log.d("Pokey", "_newZaps.value" + _newZaps.value)
EncryptedStorage.notifyZaps.observeForever { value ->
_newZaps.value = value
Log.d("Pokey", "observeForever" + value)
}
EncryptedStorage.notifyQuotes.observeForever { value ->
_newQuotes.value = value
}
EncryptedStorage.notifyReactions.observeForever { value ->
_newReactions.value = value
}
EncryptedStorage.notifyPrivate.observeForever { value ->
_newPrivate.value = value
}
EncryptedStorage.notifyMentions.observeForever { value ->
_newMentions.value = value
}
EncryptedStorage.notifyResposts.observeForever { value ->
_newReposts.value = value
}
}

fun updateNotifyReplies(value: Boolean) {
_newReplies.value = value
EncryptedStorage.updateNotifyReplies(value)
}

fun updateNotifyReactions(value: Boolean) {
_newReactions.value = value
EncryptedStorage.updateNotifyReactions(value)
}

fun updateNotifyPrivate(value: Boolean) {
_newPrivate.value = value
EncryptedStorage.updateNotifyPrivate(value)
}

fun updateNotifyZaps(value: Boolean) {
_newZaps.value = value
Log.d("Pokey", "updateNotifyZaps" + value)
EncryptedStorage.updateNotifyZaps(value)
}

fun updateNotifyQuotes(value: Boolean) {
_newQuotes.value = value
EncryptedStorage.updateNotifyQuotes(value)
}

fun updateNotifyMentions(value: Boolean) {
_newMentions.value = value
EncryptedStorage.updateNotifyMentions(value)
}

fun updateNotifyReposts(value: Boolean) {
_newReposts.value = value
EncryptedStorage.updateNotifyReposts(value)
}
val text: LiveData<String> = _text
}
Loading

0 comments on commit 00e9961

Please sign in to comment.