mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2025-04-03 09:28:18 +02:00
Merge branch 'main' into amber
This commit is contained in:
commit
87dbf86129
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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),
|
||||
|
||||
|
@ -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.
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -162,6 +162,48 @@
|
||||
<string name="posts_received">পেশকৃত আধেয় গৃহীত হয়েছে</string>
|
||||
<string name="remove">সরিয়ে ফেলুন</string>
|
||||
<string name="translations_auto">স্বয়ংক্রিয়</string>
|
||||
<string name="translations_translated_from">এই মূলপাঠ থেকে অনূদিত হয়েছে</string>
|
||||
<string name="translations_to">থেকে</string>
|
||||
<string name="translations_show_in_lang_first">প্রথমে %1$s ভাষায় দেখান</string>
|
||||
<string name="translations_always_translate_to_lang">সর্বদা %1$s ভাষায় অনুবাদ করুন</string>
|
||||
<string name="translations_never_translate_from_lang">কখনোই %1$s ভাষা থেকে অনুবাদ করবেন না</string>
|
||||
<string name="nip_05">নস্টার ঠিকানা</string>
|
||||
<string name="never">কখনো না</string>
|
||||
<string name="now">এখন</string>
|
||||
<string name="h">h</string>
|
||||
<string name="m">m</string>
|
||||
<string name="d">d</string>
|
||||
<string name="nudity">নগ্নতা</string>
|
||||
<string name="profanity_hateful_speech">অশ্লীলতা / বিদ্বেষপূর্ণ বক্তব্য</string>
|
||||
<string name="report_hateful_speech">বিদ্বেষপূর্ণ বক্তব্য হিসেবে অভিযোগ জানান</string>
|
||||
<string name="report_nudity_porn">নগ্নতা / পর্ন হিসেবে অভিযোগ জানান</string>
|
||||
<string name="others">অন্যান্য</string>
|
||||
<string name="mark_all_known_as_read">পরিচিত সবগুলোকে পঠিত হিসেবে চিহ্নিত করুন</string>
|
||||
<string name="mark_all_new_as_read">নতুন সবগুলোকে পঠিত হিসেবে চিহ্নিত করুন</string>
|
||||
<string name="mark_all_as_read">সবগুলোকে পঠিত হিসেবে চিহ্নিত করুন</string>
|
||||
<string name="backup_keys">ব্যাকআপ চাবিগুলি</string>
|
||||
<string name="account_backup_tips_md" tools:ignore="Typos"> ## চাবির ব্যাকআপ এবং নিরাপত্তা বিষয়ক টিপস
|
||||
\n\nআপনার অ্যাকাউন্ট একটি ব্যক্তিগত চাবি দ্বারা সুরক্ষিত। চাবি হলো এলোমেলো অক্ষর ও সংখ্যার একটি দীর্ঘ তন্তু যা **nsec** দ্বারা শুরু হয়। আপনার ব্যক্তিগত চাবিটি পেলে যে কেউ আপনার পরিচয় ব্যবহার করে যেকোনো আধেয় প্রকাশ করতে পারবে।
|
||||
\n\n- আপনি বিশ্বাস করেন না এমন কোনো ওয়েবসাইট কিংবা সফটওয়্যারে আপনার ব্যক্তিগত চাবিটি রাখবেন **না**।
|
||||
\n- অ্যামেথিস্টের ডেভেলপাররা **কখনোই** আপনার কাছে আপনার ব্যক্তিগত চাবিটি জানতে চাইবে না।
|
||||
\n- আপনার ব্যক্তিগত চাবির একটি নিরাপদ ব্যাকআপ **অবশ্যই** সংরক্ষণ করবেন কারণ এটি আপনার অ্যাকাউন্ট পুনরুদ্ধারে কাজে আসবে। আমরা একটি পাসওয়ার্ড ম্যানেজার ব্যবহারের পরামর্শ দিই।
|
||||
</string>
|
||||
<string name="secret_key_copied_to_clipboard">ব্যক্তিগত চাবি (nsec) ক্লিপবোর্ডে কপি করা হয়েছে</string>
|
||||
<string name="copy_my_secret_key">আমার ব্যক্তিগত চাবিটি কপি করুন</string>
|
||||
<string name="biometric_authentication_failed">প্রমাণীকরণ ব্যর্থ হয়েছে।</string>
|
||||
<string name="biometric_error">ত্রুটি</string>
|
||||
<string name="badge_created_by">"%1$s দ্বারা নির্মিত"</string>
|
||||
<string name="badge_award_image_for">"%1$s -এর জন্য ব্যাজ পুরষ্কারের ছবি"</string>
|
||||
<string name="new_badge_award_notif">আপনি একটি নতুন ব্যাজ পুরষ্কার পেয়েছেন</string>
|
||||
<string name="award_granted_to">ব্যাজ পুরস্কারটি পাচ্ছে</string>
|
||||
<string name="copied_note_text_to_clipboard">নোটের রচনাটি ক্লিপবোর্ডে কপি করা হয়েছে</string>
|
||||
<string name="copied_user_id_to_clipboard" tools:ignore="Typos">রচয়িতার @npub ক্লিপবোর্ডে কপি করুন</string>
|
||||
<string name="copied_note_id_to_clipboard" tools:ignore="Typos">নোট আইডিটি (@note1) ক্লিপবোর্ডে কপি করা হয়েছে</string>
|
||||
<string name="select_text_dialog_top">রচনাটি নির্বাচন করুন</string>
|
||||
<string name="private_conversation_notification">"<Unable to decrypt private message>\n\nআপনাকে %1$s এবং %2$s এর মধ্যে একটি ব্যক্তিগত/এনক্রিপ্টেড কথোপকথনে উদ্ধৃত করা হয়েছে৷"</string>
|
||||
<string name="account_switch_add_account_dialog_title">নতুন অ্যাকাউন্ট যুক্ত করুন</string>
|
||||
<string name="drawer_accounts">অ্যাকাউন্টগুলি</string>
|
||||
<string name="account_switch_select_account">অ্যাকাউন্ট নির্বাচন করুন</string>
|
||||
<string name="quick_action_share_browser_link">ব্রাউজারের লিংক শেয়ার করুন</string>
|
||||
<string name="quick_action_share">শেয়ার</string>
|
||||
<string name="quick_action_copy_user_id">লেখকের আইডি</string>
|
||||
|
@ -468,10 +468,20 @@
|
||||
<string name="copy_the_note_id_to_the_clipboard">A bejegyzésazonosító vágólapra másolása</string>
|
||||
<string name="created_at">Létrehozva</string>
|
||||
<string name="rules">Szabályok</string>
|
||||
<string name="status_update">Állapotod változtatása</string>
|
||||
<string name="status_update">Állapotod megjelenítése</string>
|
||||
<string name="lightning_wallets_not_found">Hiba a hibaüzenet elemzésekor</string>
|
||||
<string name="poll_zap_value_min_max_explainer">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.</string>
|
||||
<string name="error_dialog_zap_error">Zap küldése nem sikerült</string>
|
||||
<string name="error_dialog_talk_to_user">Üzenet a Felhasználónak</string>
|
||||
<string name="error_dialog_button_ok">Ok</string>
|
||||
<string name="relay_information_document_error_assemble_url">Nem sikerült elérni %1$s: %2$s</string>
|
||||
<string name="relay_information_document_error_reach_server">Nem sikerült elérni %1$s: %2$s</string>
|
||||
<string name="relay_information_document_error_parse_result">Nem sikerült az eredmény elemzése a %1$s: %2$s</string>
|
||||
<string name="relay_information_document_error_http_status">%1$s hiba a következő kóddal %2$s</string>
|
||||
<string name="active_for">Aktív: </string>
|
||||
<string name="active_for_home">Főoldal</string>
|
||||
<string name="active_for_msg">PÜk</string>
|
||||
<string name="active_for_chats">Chat</string>
|
||||
<string name="active_for_global">Globális</string>
|
||||
<string name="active_for_search">Keresés</string>
|
||||
</resources>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<string name="point_to_the_qr_code">Peka på QR-koden</string>
|
||||
<string name="point_to_the_qr_code">Peka mot QR-koden</string>
|
||||
<string name="show_qr">Visa QR</string>
|
||||
<string name="profile_image">Profilbild</string>
|
||||
<string name="scan_qr">Scanna QR</string>
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
@ -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))
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user