add proxy to all http clients

This commit is contained in:
greenart7c3
2023-04-26 08:42:49 -03:00
parent ad420da6de
commit 9f3d6a75e6
20 changed files with 88 additions and 54 deletions
@@ -12,9 +12,10 @@ import okhttp3.Callback
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
import java.net.Proxy
class Nip05Verifier { class Nip05Verifier(proxy: Proxy?) {
val client = OkHttpClient.Builder().build() val client = OkHttpClient.Builder().proxy(proxy).build()
fun assembleUrl(nip05address: String): String? { fun assembleUrl(nip05address: String): String? {
val parts = nip05address.trim().split("@") val parts = nip05address.trim().split("@")
@@ -14,10 +14,11 @@ import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
import java.math.BigDecimal import java.math.BigDecimal
import java.net.Proxy
import java.net.URLEncoder import java.net.URLEncoder
class LightningAddressResolver { class LightningAddressResolver(proxy: Proxy?) {
val client = OkHttpClient.Builder().build() val client = OkHttpClient.Builder().proxy(proxy).build()
fun assembleUrl(lnaddress: String): String? { fun assembleUrl(lnaddress: String): String? {
val parts = lnaddress.split("@") val parts = lnaddress.split("@")
@@ -14,6 +14,7 @@ import okio.BufferedSource
import okio.IOException import okio.IOException
import okio.sink import okio.sink
import java.io.File import java.io.File
import java.net.Proxy
object ImageSaver { object ImageSaver {
/** /**
@@ -26,9 +27,10 @@ object ImageSaver {
url: String, url: String,
context: Context, context: Context,
onSuccess: () -> Any?, onSuccess: () -> Any?,
onError: (Throwable) -> Any? onError: (Throwable) -> Any?,
proxy: Proxy?
) { ) {
val client = OkHttpClient.Builder().build() val client = OkHttpClient.Builder().proxy(proxy).build()
val request = Request.Builder() val request = Request.Builder()
.header("User-Agent", "Amethyst/${BuildConfig.VERSION_NAME}") .header("User-Agent", "Amethyst/${BuildConfig.VERSION_NAME}")
@@ -9,6 +9,7 @@ import okhttp3.MediaType.Companion.toMediaType
import okio.BufferedSink import okio.BufferedSink
import okio.source import okio.source
import java.io.IOException import java.io.IOException
import java.net.Proxy
import java.util.* import java.util.*
object ImageUploader { object ImageUploader {
@@ -16,14 +17,15 @@ object ImageUploader {
uri: Uri, uri: Uri,
contentResolver: ContentResolver, contentResolver: ContentResolver,
onSuccess: (String) -> Unit, onSuccess: (String) -> Unit,
onError: (Throwable) -> Unit onError: (Throwable) -> Unit,
proxy: Proxy?
) { ) {
val contentType = contentResolver.getType(uri) val contentType = contentResolver.getType(uri)
val category = contentType?.toMediaType()?.toString()?.split("/")?.get(0) ?: "image" val category = contentType?.toMediaType()?.toString()?.split("/")?.get(0) ?: "image"
val url = if (category == "image") "https://api.imgur.com/3/image" else "https://api.imgur.com/3/upload" val url = if (category == "image") "https://api.imgur.com/3/image" else "https://api.imgur.com/3/upload"
val client = OkHttpClient.Builder().build() val client = OkHttpClient.Builder().proxy(proxy).build()
val requestBody: RequestBody = MultipartBody.Builder() val requestBody: RequestBody = MultipartBody.Builder()
.setType(MultipartBody.FORM) .setType(MultipartBody.FORM)
@@ -124,7 +124,8 @@ open class NewPostViewModel : ViewModel() {
viewModelScope.launch { viewModelScope.launch {
imageUploadingError.emit("Failed to upload the image / video") imageUploadingError.emit("Failed to upload the image / video")
} }
} },
account!!.proxy
) )
} }
@@ -180,7 +180,8 @@ class NewUserMetadataViewModel : ViewModel() {
viewModelScope.launch { viewModelScope.launch {
imageUploadingError.emit("Failed to upload the image / video") imageUploadingError.emit("Failed to upload the image / video")
} }
} },
account.proxy
) )
} }
} }
@@ -18,6 +18,7 @@ import com.google.accompanist.permissions.isGranted
import com.google.accompanist.permissions.rememberPermissionState import com.google.accompanist.permissions.rememberPermissionState
import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.R
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import java.net.Proxy
/** /**
* A button to save the remote image to the gallery. * A button to save the remote image to the gallery.
@@ -27,7 +28,7 @@ import kotlinx.coroutines.launch
*/ */
@OptIn(ExperimentalPermissionsApi::class) @OptIn(ExperimentalPermissionsApi::class)
@Composable @Composable
fun SaveToGallery(url: String) { fun SaveToGallery(url: String, proxy: Proxy?) {
val localContext = LocalContext.current val localContext = LocalContext.current
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
@@ -54,7 +55,8 @@ fun SaveToGallery(url: String) {
) )
.show() .show()
} }
} },
proxy = proxy
) )
} }
@@ -27,6 +27,7 @@ import androidx.compose.ui.unit.dp
import androidx.navigation.NavController import androidx.navigation.NavController
import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import java.net.Proxy
const val SHORT_TEXT_LENGTH = 350 const val SHORT_TEXT_LENGTH = 350
@@ -38,7 +39,8 @@ fun ExpandableRichTextViewer(
tags: List<List<String>>?, tags: List<List<String>>?,
backgroundColor: Color, backgroundColor: Color,
accountViewModel: AccountViewModel, accountViewModel: AccountViewModel,
navController: NavController navController: NavController,
proxy: Proxy?
) { ) {
var showFullText by remember { mutableStateOf(false) } var showFullText by remember { mutableStateOf(false) }
@@ -62,7 +64,8 @@ fun ExpandableRichTextViewer(
tags, tags,
backgroundColor, backgroundColor,
accountViewModel, accountViewModel,
navController navController,
proxy
) )
if (content.length > whereToCut && !showFullText) { if (content.length > whereToCut && !showFullText) {
@@ -138,7 +138,7 @@ fun InvoiceRequest(
onClick = { onClick = {
val zapRequest = account.createZapRequestFor(toUserPubKeyHex, message, LnZapEvent.ZapType.PUBLIC) val zapRequest = account.createZapRequestFor(toUserPubKeyHex, message, LnZapEvent.ZapType.PUBLIC)
LightningAddressResolver().lnAddressInvoice( LightningAddressResolver(account.proxy).lnAddressInvoice(
lud16, lud16,
amount * 1000, amount * 1000,
message, message,
@@ -43,6 +43,7 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import java.net.MalformedURLException import java.net.MalformedURLException
import java.net.Proxy
import java.net.URISyntaxException import java.net.URISyntaxException
import java.net.URL import java.net.URL
import java.util.regex.Pattern import java.util.regex.Pattern
@@ -80,7 +81,8 @@ fun RichTextViewer(
tags: List<List<String>>?, tags: List<List<String>>?,
backgroundColor: Color, backgroundColor: Color,
accountViewModel: AccountViewModel, accountViewModel: AccountViewModel,
navController: NavController navController: NavController,
proxy: Proxy?
) { ) {
Column(modifier = modifier) { Column(modifier = modifier) {
if (content.startsWith("# ") || if (content.startsWith("# ") ||
@@ -159,9 +161,9 @@ fun RichTextViewer(
if (isValidURL(word)) { if (isValidURL(word)) {
val removedParamsFromUrl = word.split("?")[0].lowercase() val removedParamsFromUrl = word.split("?")[0].lowercase()
if (imageExtensions.any { removedParamsFromUrl.endsWith(it) }) { if (imageExtensions.any { removedParamsFromUrl.endsWith(it) }) {
ZoomableImageView(word, imagesForPager) ZoomableImageView(word, imagesForPager, proxy)
} else if (videoExtensions.any { removedParamsFromUrl.endsWith(it) }) { } else if (videoExtensions.any { removedParamsFromUrl.endsWith(it) }) {
ZoomableImageView(word, imagesForPager) ZoomableImageView(word, imagesForPager, proxy)
} else { } else {
UrlPreview(word, "$word ") UrlPreview(word, "$word ")
} }
@@ -46,10 +46,11 @@ import com.vitorpamplona.amethyst.ui.actions.LoadingAnimation
import com.vitorpamplona.amethyst.ui.actions.SaveToGallery import com.vitorpamplona.amethyst.ui.actions.SaveToGallery
import net.engawapg.lib.zoomable.rememberZoomState import net.engawapg.lib.zoomable.rememberZoomState
import net.engawapg.lib.zoomable.zoomable import net.engawapg.lib.zoomable.zoomable
import java.net.Proxy
@Composable @Composable
@OptIn(ExperimentalFoundationApi::class) @OptIn(ExperimentalFoundationApi::class)
fun ZoomableImageView(word: String, images: List<String> = listOf(word)) { fun ZoomableImageView(word: String, images: List<String> = listOf(word), proxy: Proxy?) {
val clipboardManager = LocalClipboardManager.current val clipboardManager = LocalClipboardManager.current
// store the dialog open or close state // store the dialog open or close state
@@ -126,13 +127,13 @@ fun ZoomableImageView(word: String, images: List<String> = listOf(word)) {
} }
if (dialogOpen) { if (dialogOpen) {
ZoomableImageDialog(word, images, onDismiss = { dialogOpen = false }) ZoomableImageDialog(word, images, onDismiss = { dialogOpen = false }, proxy)
} }
} }
@OptIn(ExperimentalPagerApi::class) @OptIn(ExperimentalPagerApi::class)
@Composable @Composable
fun ZoomableImageDialog(imageUrl: String, allImages: List<String> = listOf(imageUrl), onDismiss: () -> Unit) { fun ZoomableImageDialog(imageUrl: String, allImages: List<String> = listOf(imageUrl), onDismiss: () -> Unit, proxy: Proxy?) {
Dialog( Dialog(
onDismissRequest = onDismiss, onDismissRequest = onDismiss,
properties = DialogProperties(usePlatformDefaultWidth = false) properties = DialogProperties(usePlatformDefaultWidth = false)
@@ -150,7 +151,7 @@ fun ZoomableImageDialog(imageUrl: String, allImages: List<String> = listOf(image
) { ) {
CloseButton(onCancel = onDismiss) CloseButton(onCancel = onDismiss)
SaveToGallery(url = allImages[pagerState.currentPage]) SaveToGallery(url = allImages[pagerState.currentPage], proxy)
} }
if (allImages.size > 1) { if (allImages.size > 1) {
@@ -290,7 +290,8 @@ fun ChatroomMessageCompose(
note.event?.tags(), note.event?.tags(),
backgroundBubbleColor, backgroundBubbleColor,
accountViewModel, accountViewModel,
navController navController,
account.proxy
) )
} else { } else {
TranslatableRichTextViewer( TranslatableRichTextViewer(
@@ -300,7 +301,8 @@ fun ChatroomMessageCompose(
note.event?.tags(), note.event?.tags(),
backgroundBubbleColor, backgroundBubbleColor,
accountViewModel, accountViewModel,
navController navController,
account.proxy
) )
} }
} }
@@ -35,10 +35,11 @@ import com.vitorpamplona.amethyst.service.Nip05Verifier
import com.vitorpamplona.amethyst.ui.theme.Nip05 import com.vitorpamplona.amethyst.ui.theme.Nip05
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import java.net.Proxy
import java.util.Date import java.util.Date
@Composable @Composable
fun nip05VerificationAsAState(user: UserMetadata, pubkeyHex: String): State<Boolean?> { fun nip05VerificationAsAState(user: UserMetadata, pubkeyHex: String, proxy: Proxy?): State<Boolean?> {
var nip05Verified = remember { mutableStateOf<Boolean?>(null) } var nip05Verified = remember { mutableStateOf<Boolean?>(null) }
LaunchedEffect(key1 = user) { LaunchedEffect(key1 = user) {
@@ -48,7 +49,7 @@ fun nip05VerificationAsAState(user: UserMetadata, pubkeyHex: String): State<Bool
if ((user.nip05LastVerificationTime ?: 0) > (now - 60 * 60)) { // 1hour if ((user.nip05LastVerificationTime ?: 0) > (now - 60 * 60)) { // 1hour
nip05Verified.value = user.nip05Verified nip05Verified.value = user.nip05Verified
} else { } else {
Nip05Verifier().verifyNip05( Nip05Verifier(proxy).verifyNip05(
nip05, nip05,
onSuccess = { onSuccess = {
// Marks user as verified // Marks user as verified
@@ -77,18 +78,18 @@ fun nip05VerificationAsAState(user: UserMetadata, pubkeyHex: String): State<Bool
} }
@Composable @Composable
fun ObserveDisplayNip05Status(baseNote: Note, columnModifier: Modifier = Modifier) { fun ObserveDisplayNip05Status(baseNote: Note, columnModifier: Modifier = Modifier, proxy: Proxy?) {
val noteState by baseNote.live().metadata.observeAsState() val noteState by baseNote.live().metadata.observeAsState()
val note = noteState?.note ?: return val note = noteState?.note ?: return
val author = note.author val author = note.author
if (author != null) { if (author != null) {
ObserveDisplayNip05Status(author, columnModifier) ObserveDisplayNip05Status(author, columnModifier, proxy)
} }
} }
@Composable @Composable
fun ObserveDisplayNip05Status(baseUser: User, columnModifier: Modifier = Modifier) { fun ObserveDisplayNip05Status(baseUser: User, columnModifier: Modifier = Modifier, proxy: Proxy?) {
val userState by baseUser.live().metadata.observeAsState() val userState by baseUser.live().metadata.observeAsState()
val user = userState?.user ?: return val user = userState?.user ?: return
@@ -107,7 +108,7 @@ fun ObserveDisplayNip05Status(baseUser: User, columnModifier: Modifier = Modifie
) )
} }
val nip05Verified by nip05VerificationAsAState(user.info!!, user.pubkeyHex) val nip05Verified by nip05VerificationAsAState(user.info!!, user.pubkeyHex, proxy)
if (nip05Verified == null) { if (nip05Verified == null) {
Icon( Icon(
tint = Color.Yellow, tint = Color.Yellow,
@@ -151,12 +152,12 @@ fun ObserveDisplayNip05Status(baseUser: User, columnModifier: Modifier = Modifie
} }
@Composable @Composable
fun DisplayNip05ProfileStatus(user: User) { fun DisplayNip05ProfileStatus(user: User, proxy: Proxy?) {
val uri = LocalUriHandler.current val uri = LocalUriHandler.current
user.nip05()?.let { nip05 -> user.nip05()?.let { nip05 ->
if (nip05.split("@").size == 2) { if (nip05.split("@").size == 2) {
val nip05Verified by nip05VerificationAsAState(user.info!!, user.pubkeyHex) val nip05Verified by nip05VerificationAsAState(user.info!!, user.pubkeyHex, proxy)
Row(verticalAlignment = Alignment.CenterVertically) { Row(verticalAlignment = Alignment.CenterVertically) {
if (nip05Verified == null) { if (nip05Verified == null) {
Icon( Icon(
@@ -353,7 +353,7 @@ fun NoteComposeInner(
if (note.author != null && !makeItShort && !isQuotedNote) { if (note.author != null && !makeItShort && !isQuotedNote) {
Row(verticalAlignment = Alignment.CenterVertically) { Row(verticalAlignment = Alignment.CenterVertically) {
ObserveDisplayNip05Status(note.author!!, Modifier.weight(1f)) ObserveDisplayNip05Status(note.author!!, Modifier.weight(1f), account.proxy)
val baseReward = noteEvent.getReward() val baseReward = noteEvent.getReward()
if (baseReward != null) { if (baseReward != null) {
@@ -509,7 +509,8 @@ fun NoteComposeInner(
noteEvent.tags(), noteEvent.tags(),
backgroundColor, backgroundColor,
accountViewModel, accountViewModel,
navController navController,
account.proxy
) )
if (!makeItShort) { if (!makeItShort) {
@@ -539,7 +540,8 @@ fun NoteComposeInner(
noteEvent.tags(), noteEvent.tags(),
backgroundColor, backgroundColor,
accountViewModel, accountViewModel,
navController navController,
account.proxy
) )
DisplayUncitedHashtags(noteEvent.hashtags(), eventContent, navController) DisplayUncitedHashtags(noteEvent.hashtags(), eventContent, navController)
@@ -551,7 +553,8 @@ fun NoteComposeInner(
canPreview = canPreview && !makeItShort, canPreview = canPreview && !makeItShort,
backgroundColor, backgroundColor,
accountViewModel, accountViewModel,
navController navController,
account.proxy
) )
} }
} }
@@ -37,6 +37,7 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.theme.BitcoinOrange import com.vitorpamplona.amethyst.ui.theme.BitcoinOrange
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import java.net.Proxy
import java.util.* import java.util.*
import kotlin.math.roundToInt import kotlin.math.roundToInt
@@ -46,7 +47,8 @@ fun PollNote(
canPreview: Boolean, canPreview: Boolean,
backgroundColor: Color, backgroundColor: Color,
accountViewModel: AccountViewModel, accountViewModel: AccountViewModel,
navController: NavController navController: NavController,
proxy: Proxy?
) { ) {
val zapsState by baseNote.live().zaps.observeAsState() val zapsState by baseNote.live().zaps.observeAsState()
val zappedNote = zapsState?.note ?: return val zappedNote = zapsState?.note ?: return
@@ -111,7 +113,8 @@ fun PollNote(
pollViewModel.pollEvent?.tags(), pollViewModel.pollEvent?.tags(),
backgroundColor, backgroundColor,
accountViewModel, accountViewModel,
navController navController,
proxy
) )
} }
} }
@@ -144,7 +147,8 @@ fun PollNote(
pollViewModel.pollEvent?.tags(), pollViewModel.pollEvent?.tags(),
backgroundColor, backgroundColor,
accountViewModel, accountViewModel,
navController navController,
proxy
) )
} }
} }
@@ -282,7 +282,7 @@ fun NoteMaster(
} }
Row(verticalAlignment = Alignment.CenterVertically) { Row(verticalAlignment = Alignment.CenterVertically) {
ObserveDisplayNip05Status(baseNote, Modifier.weight(1f)) ObserveDisplayNip05Status(baseNote, Modifier.weight(1f), account.proxy)
val baseReward = noteEvent.getReward() val baseReward = noteEvent.getReward()
if (baseReward != null) { if (baseReward != null) {
@@ -362,7 +362,8 @@ fun NoteMaster(
note.event?.tags(), note.event?.tags(),
MaterialTheme.colors.background, MaterialTheme.colors.background,
accountViewModel, accountViewModel,
navController navController,
account.proxy
) )
DisplayUncitedHashtags(noteEvent.hashtags(), eventContent, navController) DisplayUncitedHashtags(noteEvent.hashtags(), eventContent, navController)
@@ -373,7 +374,8 @@ fun NoteMaster(
canPreview, canPreview,
backgroundColor, backgroundColor,
accountViewModel, accountViewModel,
navController navController,
account.proxy
) )
} }
} }
@@ -72,7 +72,7 @@ class AccountViewModel(private val account: Account) : ViewModel() {
onProgress(0.10f) onProgress(0.10f)
LightningAddressResolver().lnAddressInvoice( LightningAddressResolver(account.proxy).lnAddressInvoice(
lud16, lud16,
amount, amount,
message, message,
@@ -59,6 +59,7 @@ import com.vitorpamplona.amethyst.ui.note.UserPicture
import com.vitorpamplona.amethyst.ui.note.UsernameDisplay import com.vitorpamplona.amethyst.ui.note.UsernameDisplay
import com.vitorpamplona.amethyst.ui.screen.ChatroomFeedView import com.vitorpamplona.amethyst.ui.screen.ChatroomFeedView
import com.vitorpamplona.amethyst.ui.screen.NostrChatRoomFeedViewModel import com.vitorpamplona.amethyst.ui.screen.NostrChatRoomFeedViewModel
import java.net.Proxy
@Composable @Composable
fun ChatroomScreen(userId: String?, accountViewModel: AccountViewModel, navController: NavController) { fun ChatroomScreen(userId: String?, accountViewModel: AccountViewModel, navController: NavController) {
@@ -104,7 +105,7 @@ fun ChatroomScreen(userId: String?, accountViewModel: AccountViewModel, navContr
Column(Modifier.fillMaxHeight()) { Column(Modifier.fillMaxHeight()) {
NostrChatroomDataSource.withUser?.let { NostrChatroomDataSource.withUser?.let {
ChatroomHeader(it, account.userProfile(), navController = navController) ChatroomHeader(it, account.userProfile(), navController = navController, account.proxy)
} }
Column( Column(
@@ -206,7 +207,7 @@ fun ChatroomScreen(userId: String?, accountViewModel: AccountViewModel, navContr
} }
@Composable @Composable
fun ChatroomHeader(baseUser: User, accountUser: User, navController: NavController) { fun ChatroomHeader(baseUser: User, accountUser: User, navController: NavController, proxy: Proxy?) {
Column( Column(
modifier = Modifier.clickable( modifier = Modifier.clickable(
onClick = { navController.navigate("User/${baseUser.pubkeyHex}") } onClick = { navController.navigate("User/${baseUser.pubkeyHex}") }
@@ -226,7 +227,7 @@ fun ChatroomHeader(baseUser: User, accountUser: User, navController: NavControll
} }
Row(verticalAlignment = Alignment.CenterVertically) { Row(verticalAlignment = Alignment.CenterVertically) {
ObserveDisplayNip05Status(baseUser) ObserveDisplayNip05Status(baseUser, proxy = proxy)
} }
} }
} }
@@ -1,6 +1,7 @@
package com.vitorpamplona.amethyst.ui.screen.loggedIn package com.vitorpamplona.amethyst.ui.screen.loggedIn
import android.content.Intent import android.content.Intent
import java.net.Proxy
import android.net.Uri import android.net.Uri
import androidx.compose.foundation.* import androidx.compose.foundation.*
import androidx.compose.foundation.gestures.scrollBy import androidx.compose.foundation.gestures.scrollBy
@@ -308,7 +309,7 @@ private fun ProfileHeader(
val clipboardManager = LocalClipboardManager.current val clipboardManager = LocalClipboardManager.current
Box { Box {
DrawBanner(baseUser) DrawBanner(baseUser, account.proxy)
Box( Box(
modifier = Modifier modifier = Modifier
@@ -410,7 +411,7 @@ private fun ProfileHeader(
} }
if (zoomImageDialogOpen) { if (zoomImageDialogOpen) {
ZoomableImageDialog(baseUser.profilePicture()!!, onDismiss = { zoomImageDialogOpen = false }) ZoomableImageDialog(baseUser.profilePicture()!!, onDismiss = { zoomImageDialogOpen = false }, proxy = account.proxy)
} }
} }
@@ -514,7 +515,7 @@ private fun DrawAdditionalInfo(baseUser: User, account: Account, accountViewMode
} }
} }
DisplayNip05ProfileStatus(user) DisplayNip05ProfileStatus(user, account.proxy)
val website = user.info?.website val website = user.info?.website
if (!website.isNullOrEmpty()) { if (!website.isNullOrEmpty()) {
@@ -616,7 +617,8 @@ private fun DrawAdditionalInfo(baseUser: User, account: Account, accountViewMode
tags = null, tags = null,
backgroundColor = MaterialTheme.colors.background, backgroundColor = MaterialTheme.colors.background,
accountViewModel = accountViewModel, accountViewModel = accountViewModel,
navController = navController navController = navController,
proxy = account.proxy
) )
} }
} }
@@ -686,7 +688,7 @@ fun BadgeThumb(
@OptIn(ExperimentalFoundationApi::class) @OptIn(ExperimentalFoundationApi::class)
@Composable @Composable
private fun DrawBanner(baseUser: User) { private fun DrawBanner(baseUser: User, proxy: Proxy?) {
val userState by baseUser.live().metadata.observeAsState() val userState by baseUser.live().metadata.observeAsState()
val user = userState?.user ?: return val user = userState?.user ?: return
@@ -712,7 +714,7 @@ private fun DrawBanner(baseUser: User) {
) )
if (zoomImageDialogOpen) { if (zoomImageDialogOpen) {
ZoomableImageDialog(imageUrl = banner, onDismiss = { zoomImageDialogOpen = false }) ZoomableImageDialog(imageUrl = banner, onDismiss = { zoomImageDialogOpen = false }, proxy = proxy)
} }
} else { } else {
Image( Image(
@@ -35,6 +35,7 @@ import com.vitorpamplona.amethyst.service.lang.ResultOrError
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import java.net.Proxy
import java.util.Locale import java.util.Locale
@Composable @Composable
@@ -45,7 +46,8 @@ fun TranslatableRichTextViewer(
tags: List<List<String>>?, tags: List<List<String>>?,
backgroundColor: Color, backgroundColor: Color,
accountViewModel: AccountViewModel, accountViewModel: AccountViewModel,
navController: NavController navController: NavController,
proxy: Proxy?
) { ) {
val translatedTextState = remember { val translatedTextState = remember {
mutableStateOf(ResultOrError(content, null, null, null)) mutableStateOf(ResultOrError(content, null, null, null))
@@ -87,7 +89,8 @@ fun TranslatableRichTextViewer(
tags, tags,
backgroundColor, backgroundColor,
accountViewModel, accountViewModel,
navController navController,
proxy
) )
val target = translatedTextState.value.targetLang val target = translatedTextState.value.targetLang