diff --git a/app/src/main/java/com/vitorpamplona/amethyst/MultiPlayerPlaybackManager.kt b/app/src/main/java/com/vitorpamplona/amethyst/MultiPlayerPlaybackManager.kt index 1a47d215a..a610b8a47 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/MultiPlayerPlaybackManager.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/MultiPlayerPlaybackManager.kt @@ -92,9 +92,7 @@ class MultiPlayerPlaybackManager( override fun onPlaybackStateChanged(playbackState: Int) { when (playbackState) { STATE_IDLE -> { - if (player.currentPosition > 5 * 60) { // 5 seconds - cachedPositions.add(uri, player.currentPosition) - } + cachedPositions.add(uri, player.currentPosition) } STATE_READY -> { cachedPositions.get(uri)?.let { lastPosition -> @@ -104,9 +102,7 @@ class MultiPlayerPlaybackManager( } } else -> { - if (player.currentPosition > 5 * 60) { // 5 seconds - cachedPositions.add(uri, player.currentPosition) - } + cachedPositions.add(uri, player.currentPosition) } } } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt b/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt index dcf4198d0..904ac6cbe 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt @@ -2046,7 +2046,7 @@ class Account( val event = if (note is AddressableNote) { BookmarkListEvent.create( "bookmark", - bookmarks?.taggedEvents() ?: emptyList(), + bookmarks?.taggedEvents()?.minus(note.address.toTag()) ?: emptyList(), bookmarks?.taggedUsers() ?: emptyList(), bookmarks?.taggedAddresses()?.minus(note.address), diff --git a/app/src/main/java/com/vitorpamplona/amethyst/model/User.kt b/app/src/main/java/com/vitorpamplona/amethyst/model/User.kt index 732a1f1c6..0d15a10cc 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/model/User.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/model/User.kt @@ -5,16 +5,15 @@ import androidx.compose.runtime.Stable import androidx.lifecycle.LiveData import androidx.lifecycle.MediatorLiveData import androidx.lifecycle.distinctUntilChanged -import androidx.lifecycle.map import com.vitorpamplona.amethyst.service.NostrSingleUserDataSource import com.vitorpamplona.amethyst.service.checkNotInMainThread import com.vitorpamplona.amethyst.service.relays.EOSETime import com.vitorpamplona.amethyst.service.relays.Relay import com.vitorpamplona.amethyst.ui.components.BundledUpdate import com.vitorpamplona.amethyst.ui.note.toShortenHex -import com.vitorpamplona.quartz.encoders.Bech32 import com.vitorpamplona.quartz.encoders.Hex import com.vitorpamplona.quartz.encoders.HexKey +import com.vitorpamplona.quartz.encoders.Lud06 import com.vitorpamplona.quartz.encoders.toNpub import com.vitorpamplona.quartz.events.BookmarkListEvent import com.vitorpamplona.quartz.events.ChatroomKey @@ -27,9 +26,6 @@ import com.vitorpamplona.quartz.events.toImmutableListOfLists import kotlinx.collections.immutable.persistentSetOf import kotlinx.coroutines.Dispatchers import java.math.BigDecimal -import java.util.regex.Pattern - -val lnurlpPattern = Pattern.compile("(?i:http|https):\\/\\/((.+)\\/)*\\.well-known\\/lnurlp\\/(.*)") @Stable class User(val pubkeyHex: String) { @@ -268,19 +264,11 @@ class User(val pubkeyHex: String) { info?.updatedMetadataAt = latestMetadata.createdAt info?.tags = latestMetadata.tags.toImmutableListOfLists() - if (newUserInfo.lud16.isNullOrBlank() && newUserInfo.lud06?.lowercase()?.startsWith("lnurl") == true) { - try { - val url = String(Bech32.decodeBytes(newUserInfo.lud06!!, false).second) - - val matcher = lnurlpPattern.matcher(url) - while (matcher.find()) { - val domain = matcher.group(2) - val username = matcher.group(3) - - info?.lud16 = "$username@$domain" + if (newUserInfo.lud16.isNullOrBlank()) { + info?.lud06?.let { + if (it.lowercase().startsWith("lnurl")) { + info?.lud16 = Lud06().toLud16(it) } - } catch (t: Throwable) { - // Doesn't create errors. } } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/lnurl/LightningAddressResolver.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/lnurl/LightningAddressResolver.kt index eded63d1d..00032ac22 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/lnurl/LightningAddressResolver.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/lnurl/LightningAddressResolver.kt @@ -4,8 +4,8 @@ import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper import com.vitorpamplona.amethyst.BuildConfig import com.vitorpamplona.amethyst.service.HttpClient import com.vitorpamplona.amethyst.service.checkNotInMainThread -import com.vitorpamplona.quartz.encoders.Bech32 import com.vitorpamplona.quartz.encoders.LnInvoiceUtil +import com.vitorpamplona.quartz.encoders.Lud06 import com.vitorpamplona.quartz.encoders.toLnUrl import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext @@ -27,11 +27,7 @@ class LightningAddressResolver() { } if (lnaddress.lowercase().startsWith("lnurl")) { - return try { - String(Bech32.decodeBytes(lnaddress, false).second) - } catch (e: Exception) { - null - } + return Lud06().toLnUrlp(lnaddress) } return null diff --git a/app/src/main/res/values-bn-rBD/strings.xml b/app/src/main/res/values-bn-rBD/strings.xml index 9ea048828..e25e22795 100644 --- a/app/src/main/res/values-bn-rBD/strings.xml +++ b/app/src/main/res/values-bn-rBD/strings.xml @@ -162,6 +162,48 @@ পেশকৃত আধেয় গৃহীত হয়েছে সরিয়ে ফেলুন স্বয়ংক্রিয় + এই মূলপাঠ থেকে অনূদিত হয়েছে + থেকে + প্রথমে %1$s ভাষায় দেখান + সর্বদা %1$s ভাষায় অনুবাদ করুন + কখনোই %1$s ভাষা থেকে অনুবাদ করবেন না + নস্টার ঠিকানা + কখনো না + এখন + h + m + d + নগ্নতা + অশ্লীলতা / বিদ্বেষপূর্ণ বক্তব্য + বিদ্বেষপূর্ণ বক্তব্য হিসেবে অভিযোগ জানান + নগ্নতা / পর্ন হিসেবে অভিযোগ জানান + অন্যান্য + পরিচিত সবগুলোকে পঠিত হিসেবে চিহ্নিত করুন + নতুন সবগুলোকে পঠিত হিসেবে চিহ্নিত করুন + সবগুলোকে পঠিত হিসেবে চিহ্নিত করুন + ব্যাকআপ চাবিগুলি + ## চাবির ব্যাকআপ এবং নিরাপত্তা বিষয়ক টিপস + \n\nআপনার অ্যাকাউন্ট একটি ব্যক্তিগত চাবি দ্বারা সুরক্ষিত। চাবি হলো এলোমেলো অক্ষর ও সংখ্যার একটি দীর্ঘ তন্তু যা **nsec** দ্বারা শুরু হয়। আপনার ব্যক্তিগত চাবিটি পেলে যে কেউ আপনার পরিচয় ব্যবহার করে যেকোনো আধেয় প্রকাশ করতে পারবে। + \n\n- আপনি বিশ্বাস করেন না এমন কোনো ওয়েবসাইট কিংবা সফটওয়্যারে আপনার ব্যক্তিগত চাবিটি রাখবেন **না**। + \n- অ্যামেথিস্টের ডেভেলপাররা **কখনোই** আপনার কাছে আপনার ব্যক্তিগত চাবিটি জানতে চাইবে না। + \n- আপনার ব্যক্তিগত চাবির একটি নিরাপদ ব্যাকআপ **অবশ্যই** সংরক্ষণ করবেন কারণ এটি আপনার অ্যাকাউন্ট পুনরুদ্ধারে কাজে আসবে। আমরা একটি পাসওয়ার্ড ম্যানেজার ব্যবহারের পরামর্শ দিই। + + ব্যক্তিগত চাবি (nsec) ক্লিপবোর্ডে কপি করা হয়েছে + আমার ব্যক্তিগত চাবিটি কপি করুন + প্রমাণীকরণ ব্যর্থ হয়েছে। + ত্রুটি + "%1$s দ্বারা নির্মিত" + "%1$s -এর জন্য ব্যাজ পুরষ্কারের ছবি" + আপনি একটি নতুন ব্যাজ পুরষ্কার পেয়েছেন + ব্যাজ পুরস্কারটি পাচ্ছে + নোটের রচনাটি ক্লিপবোর্ডে কপি করা হয়েছে + রচয়িতার @npub ক্লিপবোর্ডে কপি করুন + নোট আইডিটি (@note1) ক্লিপবোর্ডে কপি করা হয়েছে + রচনাটি নির্বাচন করুন + "<Unable to decrypt private message>\n\nআপনাকে %1$s এবং %2$s এর মধ্যে একটি ব্যক্তিগত/এনক্রিপ্টেড কথোপকথনে উদ্ধৃত করা হয়েছে৷" + নতুন অ্যাকাউন্ট যুক্ত করুন + অ্যাকাউন্টগুলি + অ্যাকাউন্ট নির্বাচন করুন ব্রাউজারের লিংক শেয়ার করুন শেয়ার লেখকের আইডি diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index 0ab767de5..18551bc0d 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -468,10 +468,20 @@ A bejegyzésazonosító vágólapra másolása Létrehozva Szabályok - Állapotod változtatása + Állapotod megjelenítése Hiba a hibaüzenet elemzésekor A szavazatokat a Zap-ek összegével súlyozzuk. Beállíthatsz egy minimális összeget, hogy a kéretlen leveleket elkerüld, és egy maximális összeget annak elkerülésére, hogy a szavazás feletti irányítást a nagy Zapperek vegyék át. Mindkét mezőben ugyanazt az összeget használd, hogy minden szavazat azonos értéket kapjon. Bármilyen összeg elfogadásához, hagyjd üresen. Zap küldése nem sikerült Üzenet a Felhasználónak Ok + Nem sikerült elérni %1$s: %2$s + Nem sikerült elérni %1$s: %2$s + Nem sikerült az eredmény elemzése a %1$s: %2$s + %1$s hiba a következő kóddal %2$s + Aktív: + Főoldal + PÜk + Chat + Globális + Keresés diff --git a/app/src/main/res/values-sv-rSE/strings.xml b/app/src/main/res/values-sv-rSE/strings.xml index f5a27eea5..c56a9e75b 100644 --- a/app/src/main/res/values-sv-rSE/strings.xml +++ b/app/src/main/res/values-sv-rSE/strings.xml @@ -1,6 +1,6 @@ - Peka på QR-koden + Peka mot QR-koden Visa QR Profilbild Scanna QR diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/encoders/Bech32Util.kt b/quartz/src/main/java/com/vitorpamplona/quartz/encoders/Bech32Util.kt index 6398225dc..f8fc487ba 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/encoders/Bech32Util.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/encoders/Bech32Util.kt @@ -69,14 +69,14 @@ object Bech32 { values.forEach { v -> val b = chk shr 25 chk = ((chk and 0x1ffffff) shl 5) xor v.toInt() - for (i in 0..5) { + for (i in 0..4) { if (((b shr i) and 1) != 0) chk = chk xor GEN[i] } } values1.forEach { v -> val b = chk shr 25 chk = ((chk and 0x1ffffff) shl 5) xor v.toInt() - for (i in 0..5) { + for (i in 0..4) { if (((b shr i) and 1) != 0) chk = chk xor GEN[i] } } @@ -129,7 +129,7 @@ object Bech32 { } } - val hrp = bech32.take(pos) + val hrp = bech32.take(pos).lowercase() // strings must be lower case require(hrp.length in 1..83) { "hrp must contain 1 to 83 characters" } val data = Array(bech32.length - pos - 1) { diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/encoders/Lud06.kt b/quartz/src/main/java/com/vitorpamplona/quartz/encoders/Lud06.kt new file mode 100644 index 000000000..0cbb8d876 --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/encoders/Lud06.kt @@ -0,0 +1,35 @@ +package com.vitorpamplona.quartz.encoders + +import android.util.Log +import java.util.regex.Pattern + +val lnurlpPattern = Pattern.compile("(?i:http|https):\\/\\/((.+)\\/)*\\.well-known\\/lnurlp\\/(.*)") + +class Lud06 { + fun toLud16(str: String): String? { + return try { + val url = toLnUrlp(str) + + val matcher = lnurlpPattern.matcher(url) + matcher.find() + val domain = matcher.group(2) + val username = matcher.group(3) + + "$username@$domain" + } catch (t: Throwable) { + t.printStackTrace() + Log.w("Lud06ToLud16","Fail to convert LUD06 to LUD16",t) + null + } + } + + fun toLnUrlp(str: String): String? { + return try { + String(Bech32.decodeBytes(str, false).second) + } catch (t: Throwable) { + t.printStackTrace() + Log.w("Lud06ToLud16","Fail to convert LUD06 to LUD16",t) + null + } + } +} \ No newline at end of file diff --git a/quartz/src/test/java/com/vitorpamplona/quartz/encoders/Lud06Test.kt b/quartz/src/test/java/com/vitorpamplona/quartz/encoders/Lud06Test.kt new file mode 100644 index 000000000..99db42c1d --- /dev/null +++ b/quartz/src/test/java/com/vitorpamplona/quartz/encoders/Lud06Test.kt @@ -0,0 +1,13 @@ +package com.vitorpamplona.quartz.encoders + +import org.junit.Assert.assertEquals +import org.junit.Test + +class Lud06Test { + val lnTips = "LNURL1DP68GURN8GHJ7MRW9E6XJURN9UH8WETVDSKKKMN0WAHZ7MRWW4EXCUP0XPURXEFEX9SKGCT9V5ER2V33X4NRGP2NE42" + @Test() + fun parseLnUrlp() { + assertEquals("https://ln.tips/.well-known/lnurlp/0x3e91adaee25215f4", Lud06().toLnUrlp(lnTips)) + assertEquals("0x3e91adaee25215f4@ln.tips", Lud06().toLud16(lnTips)) + } +} \ No newline at end of file