Merge remote-tracking branch 'origin/HEAD' into local-database

local-database
Vitor Pamplona 2023-09-27 14:35:34 -04:00
commit 7871236ce7
23 zmienionych plików z 302 dodań i 41 usunięć

Wyświetl plik

@ -80,6 +80,7 @@ private object PrefKeys {
const val AUTOMATICALLY_LOAD_URL_PREVIEW = "automatically_load_url_preview"
const val AUTOMATICALLY_HIDE_NAV_BARS = "automatically_hide_nav_bars"
const val LOGIN_WITH_EXTERNAL_SIGNER = "login_with_external_signer"
const val AUTOMATICALLY_SHOW_PROFILE_PICTURE = "automatically_show_profile_picture"
}
object LocalPreferences {
@ -280,6 +281,12 @@ object LocalPreferences {
} else {
putBoolean(PrefKeys.AUTOMATICALLY_HIDE_NAV_BARS, account.settings.automaticallyHideNavigationBars.prefCode!!)
}
if (account.settings.automaticallyShowProfilePictures.prefCode == null) {
remove(PrefKeys.AUTOMATICALLY_SHOW_PROFILE_PICTURE)
} else {
putBoolean(PrefKeys.AUTOMATICALLY_SHOW_PROFILE_PICTURE, account.settings.automaticallyShowProfilePictures.prefCode!!)
}
putString(PrefKeys.PREFERRED_LANGUAGE, account.settings.preferredLanguage ?: "")
}.apply()
}
@ -431,6 +438,12 @@ object LocalPreferences {
BooleanType.ALWAYS
}
settings.automaticallyShowProfilePictures = if (contains(PrefKeys.AUTOMATICALLY_SHOW_PROFILE_PICTURE)) {
parseConnectivityType(getBoolean(PrefKeys.AUTOMATICALLY_SHOW_PROFILE_PICTURE, false))
} else {
ConnectivityType.ALWAYS
}
settings.preferredLanguage = getString(PrefKeys.PREFERRED_LANGUAGE, "")
}

Wyświetl plik

@ -185,6 +185,14 @@ class Account(
saveable.invalidateData()
}
fun updateAutomaticallyShowProfilePicture(
automaticallyShowProfilePicture: ConnectivityType
) {
settings.automaticallyShowProfilePictures = automaticallyShowProfilePicture
live.invalidateData()
saveable.invalidateData()
}
fun updateAutomaticallyHideHavBars(
automaticallyHideHavBars: BooleanType
) {

Wyświetl plik

@ -9,7 +9,8 @@ class Settings(
var automaticallyShowImages: ConnectivityType = ConnectivityType.ALWAYS,
var automaticallyStartPlayback: ConnectivityType = ConnectivityType.ALWAYS,
var automaticallyShowUrlPreview: ConnectivityType = ConnectivityType.ALWAYS,
var automaticallyHideNavigationBars: BooleanType = BooleanType.ALWAYS
var automaticallyHideNavigationBars: BooleanType = BooleanType.ALWAYS,
var automaticallyShowProfilePictures: ConnectivityType = ConnectivityType.ALWAYS
)
enum class ConnectivityType(val prefCode: Boolean?, val screenCode: Int, val reourceId: Int) {

Wyświetl plik

@ -54,10 +54,12 @@ import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.viewmodel.compose.viewModel
import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.model.ConnectivityType
import com.vitorpamplona.amethyst.model.LocalCache
import com.vitorpamplona.amethyst.model.User
import com.vitorpamplona.amethyst.service.NostrSearchEventOrUserDataSource
import com.vitorpamplona.amethyst.service.checkNotInMainThread
import com.vitorpamplona.amethyst.service.connectivitystatus.ConnectivityStatus
import com.vitorpamplona.amethyst.ui.note.ChannelName
import com.vitorpamplona.amethyst.ui.note.ClickableUserPicture
import com.vitorpamplona.amethyst.ui.note.SearchIcon
@ -303,6 +305,13 @@ private fun RenderSearchResults(
val users by searchBarViewModel.searchResultsUsers.collectAsState()
val channels by searchBarViewModel.searchResultsChannels.collectAsState()
val scope = rememberCoroutineScope()
val automaticallyShowProfilePicture = remember {
when (accountViewModel.account.settings.automaticallyShowProfilePictures) {
ConnectivityType.WIFI_ONLY -> !ConnectivityStatus.isOnMobileData.value
ConnectivityType.NEVER -> false
ConnectivityType.ALWAYS -> true
}
}
Row(
modifier = Modifier
@ -337,7 +346,7 @@ private fun RenderSearchResults(
channels,
key = { _, item -> "c" + item.idHex }
) { _, item ->
RenderChannel(item) {
RenderChannel(item, automaticallyShowProfilePicture) {
nav("Channel/${item.idHex}")
searchBarViewModel.clear()
}
@ -350,6 +359,7 @@ private fun RenderSearchResults(
@Composable
private fun RenderChannel(
item: com.vitorpamplona.amethyst.model.Channel,
loadProfilePicture: Boolean,
onClick: () -> Unit
) {
val hasNewMessages = remember {
@ -368,7 +378,8 @@ private fun RenderChannel(
channelLastTime = null,
channelLastContent = item.summary(),
hasNewMessages,
onClick = onClick
onClick = onClick,
loadProfilePicture = loadProfilePicture
)
}

Wyświetl plik

@ -56,9 +56,11 @@ import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
import androidx.lifecycle.viewmodel.compose.viewModel
import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.model.ConnectivityType
import com.vitorpamplona.amethyst.model.RelayBriefInfo
import com.vitorpamplona.amethyst.model.RelaySetupInfo
import com.vitorpamplona.amethyst.service.Nip11Retriever
import com.vitorpamplona.amethyst.service.connectivitystatus.ConnectivityStatus
import com.vitorpamplona.amethyst.service.relays.Constants
import com.vitorpamplona.amethyst.service.relays.Constants.defaultRelays
import com.vitorpamplona.amethyst.service.relays.FeedType
@ -258,6 +260,7 @@ fun ServerConfigHeader() {
@Composable
fun ServerConfigPreview() {
ServerConfigClickableLine(
loadProfilePicture = true,
item = RelaySetupInfo(
url = "nostr.mom",
read = true,
@ -310,7 +313,16 @@ fun ServerConfig(
)
}
val automaticallyShowProfilePicture = remember {
when (accountViewModel.account.settings.automaticallyShowProfilePictures) {
ConnectivityType.WIFI_ONLY -> !ConnectivityStatus.isOnMobileData.value
ConnectivityType.NEVER -> false
ConnectivityType.ALWAYS -> true
}
}
ServerConfigClickableLine(
loadProfilePicture = automaticallyShowProfilePicture,
item = item,
onToggleDownload = onToggleDownload,
onToggleUpload = onToggleUpload,
@ -351,6 +363,7 @@ fun ServerConfig(
@Composable
fun ServerConfigClickableLine(
loadProfilePicture: Boolean,
item: RelaySetupInfo,
onToggleDownload: (RelaySetupInfo) -> Unit,
onToggleUpload: (RelaySetupInfo) -> Unit,
@ -368,7 +381,7 @@ fun ServerConfigClickableLine(
modifier = Modifier.padding(vertical = 5.dp)
) {
Column(Modifier.clickable(onClick = onClick)) {
RenderRelayIcon(iconUrl = item.briefInfo.favIcon, Size55dp)
RenderRelayIcon(iconUrl = item.briefInfo.favIcon, loadProfilePicture, Size55dp)
}
Spacer(modifier = HalfHorzPadding)

Wyświetl plik

@ -16,6 +16,7 @@ import androidx.compose.foundation.verticalScroll
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
@ -25,8 +26,10 @@ import androidx.compose.ui.unit.sp
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.model.ConnectivityType
import com.vitorpamplona.amethyst.model.RelayBriefInfo
import com.vitorpamplona.amethyst.model.RelayInformation
import com.vitorpamplona.amethyst.service.connectivitystatus.ConnectivityStatus
import com.vitorpamplona.amethyst.ui.components.ClickableEmail
import com.vitorpamplona.amethyst.ui.components.ClickableUrl
import com.vitorpamplona.amethyst.ui.note.LoadUser
@ -47,6 +50,14 @@ fun RelayInformationDialog(
accountViewModel: AccountViewModel,
nav: (String) -> Unit
) {
val automaticallyShowProfilePicture = remember {
when (accountViewModel.account.settings.automaticallyShowProfilePictures) {
ConnectivityType.WIFI_ONLY -> !ConnectivityStatus.isOnMobileData.value
ConnectivityType.NEVER -> false
ConnectivityType.ALWAYS -> true
}
}
Dialog(
onDismissRequest = { onClose() },
properties = DialogProperties(
@ -77,6 +88,7 @@ fun RelayInformationDialog(
Column() {
RenderRelayIcon(
relayBriefInfo.favIcon,
automaticallyShowProfilePicture,
Size55dp
)
}

Wyświetl plik

@ -58,14 +58,15 @@ fun RobohashFallbackAsyncImage(
contentScale: ContentScale = ContentScale.Fit,
alpha: Float = DefaultAlpha,
colorFilter: ColorFilter? = null,
filterQuality: FilterQuality = DrawScope.DefaultFilterQuality
filterQuality: FilterQuality = DrawScope.DefaultFilterQuality,
loadProfilePicture: Boolean
) {
val context = LocalContext.current
val painter = rememberAsyncImagePainter(
model = Robohash.imageRequest(context, robot)
)
if (model != null) {
if (model != null && loadProfilePicture) {
AsyncImage(
model = model,
contentDescription = contentDescription,
@ -101,7 +102,8 @@ fun RobohashAsyncImageProxy(
contentScale: ContentScale = ContentScale.Fit,
alpha: Float = DefaultAlpha,
colorFilter: ColorFilter? = null,
filterQuality: FilterQuality = DrawScope.DefaultFilterQuality
filterQuality: FilterQuality = DrawScope.DefaultFilterQuality,
loadProfilePicture: Boolean
) {
RobohashFallbackAsyncImage(
robot = robot,
@ -112,6 +114,7 @@ fun RobohashAsyncImageProxy(
contentScale = contentScale,
alpha = alpha,
colorFilter = colorFilter,
filterQuality = filterQuality
filterQuality = filterQuality,
loadProfilePicture = loadProfilePicture
)
}

Wyświetl plik

@ -44,8 +44,10 @@ import androidx.lifecycle.map
import com.vitorpamplona.amethyst.AccountInfo
import com.vitorpamplona.amethyst.LocalPreferences
import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.model.ConnectivityType
import com.vitorpamplona.amethyst.model.LocalCache
import com.vitorpamplona.amethyst.model.User
import com.vitorpamplona.amethyst.service.connectivitystatus.ConnectivityStatus
import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji
import com.vitorpamplona.amethyst.ui.components.RobohashAsyncImageProxy
import com.vitorpamplona.amethyst.ui.note.ArrowBackIcon
@ -136,6 +138,14 @@ fun DisplayAccount(
)
}
val automaticallyShowProfilePicture = remember {
when (accountViewModel.account.settings.automaticallyShowProfilePictures) {
ConnectivityType.WIFI_ONLY -> !ConnectivityStatus.isOnMobileData.value
ConnectivityType.NEVER -> false
ConnectivityType.ALWAYS -> true
}
}
if (baseUser == null) {
LaunchedEffect(key1 = acc.npub) {
launch(Dispatchers.IO) {
@ -173,7 +183,7 @@ fun DisplayAccount(
.width(55.dp)
.padding(0.dp)
) {
AccountPicture(it)
AccountPicture(it, automaticallyShowProfilePicture)
}
Spacer(modifier = Modifier.width(16.dp))
Column(modifier = Modifier.weight(1f)) {
@ -208,7 +218,7 @@ private fun ActiveMarker(acc: AccountInfo, accountViewModel: AccountViewModel) {
}
@Composable
private fun AccountPicture(user: User) {
private fun AccountPicture(user: User, loadProfilePicture: Boolean) {
val profilePicture by user.live().metadata.map {
it.user.profilePicture()
}.observeAsState()
@ -217,7 +227,8 @@ private fun AccountPicture(user: User) {
robot = remember(user) { user.pubkeyHex },
model = profilePicture,
contentDescription = stringResource(R.string.profile_image),
modifier = AccountPictureModifier
modifier = AccountPictureModifier,
loadProfilePicture = loadProfilePicture
)
}

Wyświetl plik

@ -62,6 +62,7 @@ import coil.Coil
import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.model.Account
import com.vitorpamplona.amethyst.model.AddressableNote
import com.vitorpamplona.amethyst.model.ConnectivityType
import com.vitorpamplona.amethyst.model.GLOBAL_FOLLOWS
import com.vitorpamplona.amethyst.model.KIND3_FOLLOWS
import com.vitorpamplona.amethyst.model.LocalCache
@ -82,6 +83,7 @@ import com.vitorpamplona.amethyst.service.NostrThreadDataSource
import com.vitorpamplona.amethyst.service.NostrUserProfileDataSource
import com.vitorpamplona.amethyst.service.NostrVideoDataSource
import com.vitorpamplona.amethyst.service.checkNotInMainThread
import com.vitorpamplona.amethyst.service.connectivitystatus.ConnectivityStatus
import com.vitorpamplona.amethyst.service.relays.Client
import com.vitorpamplona.amethyst.service.relays.RelayPool
import com.vitorpamplona.amethyst.ui.components.RobohashAsyncImageProxy
@ -515,6 +517,14 @@ private fun LoggedInUserPictureDrawer(
val pubkeyHex = remember { accountViewModel.userProfile().pubkeyHex }
val automaticallyShowProfilePicture = remember {
when (accountViewModel.account.settings.automaticallyShowProfilePictures) {
ConnectivityType.WIFI_ONLY -> !ConnectivityStatus.isOnMobileData.value
ConnectivityType.NEVER -> false
ConnectivityType.ALWAYS -> true
}
}
IconButton(
onClick = onClick
) {
@ -523,7 +533,8 @@ private fun LoggedInUserPictureDrawer(
model = profilePicture,
contentDescription = stringResource(id = R.string.profile_image),
modifier = HeaderPictureModifier,
contentScale = ContentScale.Crop
contentScale = ContentScale.Crop,
loadProfilePicture = automaticallyShowProfilePicture
)
}
}

Wyświetl plik

@ -70,8 +70,10 @@ import com.vitorpamplona.amethyst.LocalPreferences
import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.ServiceManager
import com.vitorpamplona.amethyst.model.Account
import com.vitorpamplona.amethyst.model.ConnectivityType
import com.vitorpamplona.amethyst.model.User
import com.vitorpamplona.amethyst.service.HttpClient
import com.vitorpamplona.amethyst.service.connectivitystatus.ConnectivityStatus
import com.vitorpamplona.amethyst.service.relays.RelayPool
import com.vitorpamplona.amethyst.service.relays.RelayPoolStatus
import com.vitorpamplona.amethyst.ui.actions.NewRelayListView
@ -100,6 +102,14 @@ fun DrawerContent(
sheetState: ModalBottomSheetState,
accountViewModel: AccountViewModel
) {
val automaticallyShowProfilePicture = remember {
when (accountViewModel.account.settings.automaticallyShowProfilePictures) {
ConnectivityType.WIFI_ONLY -> !ConnectivityStatus.isOnMobileData.value
ConnectivityType.NEVER -> false
ConnectivityType.ALWAYS -> true
}
}
Surface(
modifier = Modifier.fillMaxWidth(),
color = MaterialTheme.colors.background
@ -129,7 +139,7 @@ fun DrawerContent(
accountViewModel
)
BottomContent(accountViewModel.account.userProfile(), scaffoldState, nav)
BottomContent(accountViewModel.account.userProfile(), scaffoldState, automaticallyShowProfilePicture, nav)
}
}
}
@ -155,6 +165,14 @@ fun ProfileContent(
val tags = remember(accountUserState) { accountUserState?.user?.info?.latestMetadata?.tags?.toImmutableListOfLists() }
val route = remember(accountUserState) { "User/${accountUserState?.user?.pubkeyHex}" }
val automaticallyShowProfilePicture = remember {
when (accountViewModel.account.settings.automaticallyShowProfilePictures) {
ConnectivityType.WIFI_ONLY -> !ConnectivityStatus.isOnMobileData.value
ConnectivityType.NEVER -> false
ConnectivityType.ALWAYS -> true
}
}
Box {
if (profileBanner != null) {
AsyncImage(
@ -192,7 +210,8 @@ fun ProfileContent(
coroutineScope.launch {
scaffoldState.drawerState.close()
}
})
}),
loadProfilePicture = automaticallyShowProfilePicture
)
if (bestDisplayName != null) {
@ -754,7 +773,7 @@ fun IconRowRelays(accountViewModel: AccountViewModel, onClick: () -> Unit) {
}
@Composable
fun BottomContent(user: User, scaffoldState: ScaffoldState, nav: (String) -> Unit) {
fun BottomContent(user: User, scaffoldState: ScaffoldState, loadProfilePicture: Boolean, nav: (String) -> Unit) {
val coroutineScope = rememberCoroutineScope()
// store the dialog open or close state
@ -816,6 +835,7 @@ fun BottomContent(user: User, scaffoldState: ScaffoldState, nav: (String) -> Uni
if (dialogOpen) {
ShowQRDialog(
user,
loadProfilePicture = loadProfilePicture,
onScan = {
dialogOpen = false
coroutineScope.launch {

Wyświetl plik

@ -47,8 +47,10 @@ import androidx.lifecycle.map
import com.patrykandpatrick.vico.core.extension.forEachIndexedExtended
import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.model.Channel
import com.vitorpamplona.amethyst.model.ConnectivityType
import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.model.User
import com.vitorpamplona.amethyst.service.connectivitystatus.ConnectivityStatus
import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji
import com.vitorpamplona.amethyst.ui.components.RobohashAsyncImageProxy
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
@ -185,6 +187,14 @@ private fun ChannelRoomCompose(
val hasNewMessages = remember { mutableStateOf<Boolean>(false) }
val automaticallyShowProfilePicture = remember {
when (accountViewModel.account.settings.automaticallyShowProfilePictures) {
ConnectivityType.WIFI_ONLY -> !ConnectivityStatus.isOnMobileData.value
ConnectivityType.NEVER -> false
ConnectivityType.ALWAYS -> true
}
}
WatchNotificationChanges(note, route, accountViewModel) { newHasNewMessages ->
if (hasNewMessages.value != newHasNewMessages) {
hasNewMessages.value = newHasNewMessages
@ -200,6 +210,7 @@ private fun ChannelRoomCompose(
channelLastTime = remember(note) { note.createdAt() },
channelLastContent = remember(note) { "$authorName: $description" },
hasNewMessages = hasNewMessages,
loadProfilePicture = automaticallyShowProfilePicture,
onClick = { nav(route) }
)
}
@ -443,6 +454,7 @@ fun ChannelName(
channelLastTime: Long?,
channelLastContent: String?,
hasNewMessages: MutableState<Boolean>,
loadProfilePicture: Boolean,
onClick: () -> Unit
) {
ChannelName(
@ -456,7 +468,8 @@ fun ChannelName(
.width(Size55dp)
.height(Size55dp)
.clip(shape = CircleShape)
}
},
loadProfilePicture = loadProfilePicture
)
},
channelTitle,

Wyświetl plik

@ -43,8 +43,10 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.lifecycle.map
import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.model.ConnectivityType
import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.model.User
import com.vitorpamplona.amethyst.service.connectivitystatus.ConnectivityStatus
import com.vitorpamplona.amethyst.ui.components.CreateClickableTextWithEmoji
import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji
import com.vitorpamplona.amethyst.ui.components.RobohashAsyncImageProxy
@ -400,10 +402,19 @@ private fun MessageBubbleLines(
bubbleSize: MutableState<Int>,
availableBubbleSize: MutableState<Int>
) {
val automaticallyShowProfilePicture = remember {
when (accountViewModel.account.settings.automaticallyShowProfilePictures) {
ConnectivityType.WIFI_ONLY -> !ConnectivityStatus.isOnMobileData.value
ConnectivityType.NEVER -> false
ConnectivityType.ALWAYS -> true
}
}
if (drawAuthorInfo) {
DrawAuthorInfo(
baseNote,
alignment,
automaticallyShowProfilePicture,
nav
)
} else {
@ -712,6 +723,7 @@ private fun RenderCreateChannelNote(note: Note) {
private fun DrawAuthorInfo(
baseNote: Note,
alignment: Arrangement.Horizontal,
loadProfilePicture: Boolean,
nav: (String) -> Unit
) {
Row(
@ -719,26 +731,28 @@ private fun DrawAuthorInfo(
horizontalArrangement = alignment,
modifier = Modifier.padding(top = 5.dp)
) {
DisplayAndWatchNoteAuthor(baseNote, nav)
DisplayAndWatchNoteAuthor(baseNote, loadProfilePicture, nav)
}
}
@Composable
private fun DisplayAndWatchNoteAuthor(
baseNote: Note,
loadProfilePicture: Boolean,
nav: (String) -> Unit
) {
val author = remember {
baseNote.author
}
author?.let {
WatchAndDisplayUser(it, nav)
WatchAndDisplayUser(it, loadProfilePicture, nav)
}
}
@Composable
private fun WatchAndDisplayUser(
author: User,
loadProfilePicture: Boolean,
nav: (String) -> Unit
) {
val pubkeyHex = remember { author.pubkeyHex }
@ -764,7 +778,7 @@ private fun WatchAndDisplayUser(
}
}
UserIcon(pubkeyHex, userProfilePicture, nav, route)
UserIcon(pubkeyHex, userProfilePicture, loadProfilePicture, nav, route)
userDisplayName?.let {
DisplayMessageUsername(it, userTags, route, nav)
@ -775,6 +789,7 @@ private fun WatchAndDisplayUser(
private fun UserIcon(
pubkeyHex: String,
userProfilePicture: String?,
loadProfilePicture: Boolean,
nav: (String) -> Unit,
route: String
) {
@ -782,6 +797,7 @@ private fun UserIcon(
robot = pubkeyHex,
model = userProfilePicture,
contentDescription = stringResource(id = R.string.profile_image),
loadProfilePicture = loadProfilePicture,
modifier = remember {
Modifier
.width(Size25dp)

Wyświetl plik

@ -43,8 +43,10 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.model.ConnectivityType
import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.model.User
import com.vitorpamplona.amethyst.service.connectivitystatus.ConnectivityStatus
import com.vitorpamplona.amethyst.ui.components.ImageUrlType
import com.vitorpamplona.amethyst.ui.components.InLineIconRenderer
import com.vitorpamplona.amethyst.ui.components.RobohashAsyncImageProxy
@ -525,6 +527,14 @@ fun WatchUserMetadataAndFollowsAndRenderUserProfilePicture(
author: User,
accountViewModel: AccountViewModel
) {
val automaticallyShowProfilePicture = remember {
when (accountViewModel.account.settings.automaticallyShowProfilePictures) {
ConnectivityType.WIFI_ONLY -> !ConnectivityStatus.isOnMobileData.value
ConnectivityType.NEVER -> false
ConnectivityType.ALWAYS -> true
}
}
WatchUserMetadata(author) { baseUserPicture ->
// Crossfade(targetState = baseUserPicture) { userPicture ->
RobohashAsyncImageProxy(
@ -532,7 +542,8 @@ fun WatchUserMetadataAndFollowsAndRenderUserProfilePicture(
model = baseUserPicture,
contentDescription = stringResource(id = R.string.profile_image),
modifier = MaterialTheme.colors.profile35dpModifier,
contentScale = ContentScale.Crop
contentScale = ContentScale.Crop,
loadProfilePicture = automaticallyShowProfilePicture
)
// }
}

Wyświetl plik

@ -728,6 +728,14 @@ fun ShortCommunityHeader(baseNote: AddressableNote, fontWeight: FontWeight = Fon
val noteState by baseNote.live().metadata.observeAsState()
val noteEvent = remember(noteState) { noteState?.note?.event as? CommunityDefinitionEvent } ?: return
val automaticallyShowProfilePicture = remember {
when (accountViewModel.account.settings.automaticallyShowProfilePictures) {
ConnectivityType.WIFI_ONLY -> !ConnectivityStatus.isOnMobileData.value
ConnectivityType.NEVER -> false
ConnectivityType.ALWAYS -> true
}
}
Row(verticalAlignment = Alignment.CenterVertically) {
noteEvent.image()?.let {
RobohashAsyncImageProxy(
@ -735,7 +743,8 @@ fun ShortCommunityHeader(baseNote: AddressableNote, fontWeight: FontWeight = Fon
model = it,
contentDescription = stringResource(R.string.profile_image),
contentScale = ContentScale.Crop,
modifier = HeaderPictureModifier
modifier = HeaderPictureModifier,
loadProfilePicture = automaticallyShowProfilePicture
)
}
@ -2770,11 +2779,19 @@ private fun RenderAuthorImages(
val isChannel = baseNote.event is ChannelMessageEvent && baseNote.channelHex() != null
val automaticallyShowProfilePicture = remember {
when (accountViewModel.account.settings.automaticallyShowProfilePictures) {
ConnectivityType.WIFI_ONLY -> !ConnectivityStatus.isOnMobileData.value
ConnectivityType.NEVER -> false
ConnectivityType.ALWAYS -> true
}
}
if (isChannel) {
val baseChannelHex = remember { baseNote.channelHex() }
if (baseChannelHex != null) {
LoadChannel(baseChannelHex, accountViewModel) { channel ->
ChannelNotePicture(channel)
ChannelNotePicture(channel, loadProfilePicture = automaticallyShowProfilePicture)
}
}
}
@ -2802,7 +2819,7 @@ fun LoadChannel(baseChannelHex: String, accountViewModel: AccountViewModel, cont
}
@Composable
private fun ChannelNotePicture(baseChannel: Channel) {
private fun ChannelNotePicture(baseChannel: Channel, loadProfilePicture: Boolean) {
val model by baseChannel.live.map {
it.channel.profilePicture()
}.distinctUntilChanged().observeAsState()
@ -2827,7 +2844,8 @@ private fun ChannelNotePicture(baseChannel: Channel) {
robot = baseChannel.idHex,
model = model,
contentDescription = stringResource(R.string.group_picture),
modifier = modifier
modifier = modifier,
loadProfilePicture = loadProfilePicture
)
}
}

Wyświetl plik

@ -33,10 +33,12 @@ import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.lifecycle.map
import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.model.ConnectivityType
import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.model.RelayBriefInfo
import com.vitorpamplona.amethyst.model.RelayInformation
import com.vitorpamplona.amethyst.service.Nip11Retriever
import com.vitorpamplona.amethyst.service.connectivitystatus.ConnectivityStatus
import com.vitorpamplona.amethyst.ui.actions.RelayInformationDialog
import com.vitorpamplona.amethyst.ui.components.RobohashFallbackAsyncImage
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
@ -126,6 +128,14 @@ fun RenderRelay(relay: RelayBriefInfo, accountViewModel: AccountViewModel, nav:
val interactionSource = remember { MutableInteractionSource() }
val ripple = rememberRipple(bounded = false, radius = Size15dp)
val automaticallyShowProfilePicture = remember {
when (accountViewModel.account.settings.automaticallyShowProfilePictures) {
ConnectivityType.WIFI_ONLY -> !ConnectivityStatus.isOnMobileData.value
ConnectivityType.NEVER -> false
ConnectivityType.ALWAYS -> true
}
}
val clickableModifier = remember(relay) {
Modifier
.padding(1.dp)
@ -166,12 +176,12 @@ fun RenderRelay(relay: RelayBriefInfo, accountViewModel: AccountViewModel, nav:
Box(
modifier = clickableModifier
) {
RenderRelayIcon(relay.favIcon)
RenderRelayIcon(relay.favIcon, automaticallyShowProfilePicture)
}
}
@Composable
fun RenderRelayIcon(iconUrl: String, size: Dp = Size13dp) {
fun RenderRelayIcon(iconUrl: String, loadProfilePicture: Boolean, size: Dp = Size13dp) {
val backgroundColor = MaterialTheme.colors.background
val iconModifier = remember {
@ -186,6 +196,7 @@ fun RenderRelayIcon(iconUrl: String, size: Dp = Size13dp) {
model = iconUrl,
contentDescription = stringResource(id = R.string.relay_icon),
colorFilter = RelayIconFilter,
modifier = iconModifier
modifier = iconModifier,
loadProfilePicture = loadProfilePicture
)
}

Wyświetl plik

@ -41,9 +41,11 @@ import androidx.core.content.ContextCompat
import androidx.lifecycle.distinctUntilChanged
import androidx.lifecycle.map
import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.model.ConnectivityType
import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.model.User
import com.vitorpamplona.amethyst.service.ExternalSignerUtils
import com.vitorpamplona.amethyst.service.connectivitystatus.ConnectivityStatus
import com.vitorpamplona.amethyst.ui.components.RobohashAsyncImage
import com.vitorpamplona.amethyst.ui.components.RobohashAsyncImageProxy
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
@ -76,6 +78,13 @@ fun NoteAuthorPicture(
onClick: ((User) -> Unit)? = null
) {
val author by baseNote.live().authorChanges.observeAsState(baseNote.author)
val automaticallyShowProfilePicture = remember {
when (accountViewModel.account.settings.automaticallyShowProfilePictures) {
ConnectivityType.WIFI_ONLY -> !ConnectivityStatus.isOnMobileData.value
ConnectivityType.NEVER -> false
ConnectivityType.ALWAYS -> true
}
}
Crossfade(targetState = author) {
if (it == null) {
@ -323,12 +332,21 @@ fun PictureAndFollowingMark(
.background(backgroundColor)
}
val automaticallyShowProfilePicture = remember {
when (accountViewModel.account.settings.automaticallyShowProfilePictures) {
ConnectivityType.WIFI_ONLY -> !ConnectivityStatus.isOnMobileData.value
ConnectivityType.NEVER -> false
ConnectivityType.ALWAYS -> true
}
}
RobohashAsyncImageProxy(
robot = userHex,
model = userPicture,
contentDescription = stringResource(id = R.string.profile_image),
modifier = myImageModifier,
contentScale = ContentScale.Crop
contentScale = ContentScale.Crop,
loadProfilePicture = automaticallyShowProfilePicture
)
val myIconSize by remember(size) {

Wyświetl plik

@ -41,7 +41,7 @@ import com.vitorpamplona.amethyst.ui.theme.Size35dp
import com.vitorpamplona.quartz.events.toImmutableListOfLists
@Composable
fun ShowQRDialog(user: User, onScan: (String) -> Unit, onClose: () -> Unit) {
fun ShowQRDialog(user: User, loadProfilePicture: Boolean, onScan: (String) -> Unit, onClose: () -> Unit) {
var presenting by remember { mutableStateOf(true) }
Dialog(
@ -82,7 +82,8 @@ fun ShowQRDialog(user: User, onScan: (String) -> Unit, onClose: () -> Unit) {
.height(100.dp)
.clip(shape = CircleShape)
.border(3.dp, MaterialTheme.colors.background, CircleShape)
.background(MaterialTheme.colors.background)
.background(MaterialTheme.colors.background),
loadProfilePicture = loadProfilePicture
)
}
Row(horizontalArrangement = Arrangement.Center, modifier = Modifier.fillMaxWidth().padding(top = 5.dp)) {

Wyświetl plik

@ -98,6 +98,12 @@ class AccountViewModel(val account: Account) : ViewModel(), Dao {
account.updateAutomaticallyShowUrlPreview(automaticallyShowUrlPreview)
}
fun updateAutomaticallyShowProfilePicture(
automaticallyShowProfilePicture: ConnectivityType
) {
account.updateAutomaticallyShowProfilePicture(automaticallyShowProfilePicture)
}
fun updateAutomaticallyHideNavBars(
automaticallyHideHavBars: BooleanType
) {

Wyświetl plik

@ -79,6 +79,7 @@ import androidx.lifecycle.viewmodel.compose.viewModel
import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.model.AddressableNote
import com.vitorpamplona.amethyst.model.Channel
import com.vitorpamplona.amethyst.model.ConnectivityType
import com.vitorpamplona.amethyst.model.LiveActivitiesChannel
import com.vitorpamplona.amethyst.model.LocalCache
import com.vitorpamplona.amethyst.model.Note
@ -86,6 +87,7 @@ import com.vitorpamplona.amethyst.model.PublicChatChannel
import com.vitorpamplona.amethyst.model.ServersAvailable
import com.vitorpamplona.amethyst.model.User
import com.vitorpamplona.amethyst.service.NostrChannelDataSource
import com.vitorpamplona.amethyst.service.connectivitystatus.ConnectivityStatus
import com.vitorpamplona.amethyst.ui.actions.NewChannelView
import com.vitorpamplona.amethyst.ui.actions.NewMessageTagger
import com.vitorpamplona.amethyst.ui.actions.NewPostViewModel
@ -677,6 +679,14 @@ fun ShortChannelHeader(
channelState.value?.channel
} ?: return
val automaticallyShowProfilePicture = remember {
when (accountViewModel.account.settings.automaticallyShowProfilePictures) {
ConnectivityType.WIFI_ONLY -> !ConnectivityStatus.isOnMobileData.value
ConnectivityType.NEVER -> false
ConnectivityType.ALWAYS -> true
}
}
Row(verticalAlignment = Alignment.CenterVertically) {
if (channel is LiveActivitiesChannel) {
channel.creator?.let {
@ -694,7 +704,8 @@ fun ShortChannelHeader(
model = it,
contentDescription = stringResource(R.string.profile_image),
contentScale = ContentScale.Crop,
modifier = HeaderPictureModifier
modifier = HeaderPictureModifier,
loadProfilePicture = automaticallyShowProfilePicture
)
}
}

Wyświetl plik

@ -55,10 +55,12 @@ import coil.compose.AsyncImage
import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.model.Account
import com.vitorpamplona.amethyst.model.AddressableNote
import com.vitorpamplona.amethyst.model.ConnectivityType
import com.vitorpamplona.amethyst.model.LocalCache
import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.model.User
import com.vitorpamplona.amethyst.service.NostrUserProfileDataSource
import com.vitorpamplona.amethyst.service.connectivitystatus.ConnectivityStatus
import com.vitorpamplona.amethyst.ui.actions.NewUserMetadataView
import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji
import com.vitorpamplona.amethyst.ui.components.DisplayNip05ProfileStatus
@ -864,6 +866,14 @@ private fun DrawAdditionalInfo(
val uri = LocalUriHandler.current
val clipboardManager = LocalClipboardManager.current
val automaticallyShowProfilePicture = remember {
when (accountViewModel.account.settings.automaticallyShowProfilePictures) {
ConnectivityType.WIFI_ONLY -> !ConnectivityStatus.isOnMobileData.value
ConnectivityType.NEVER -> false
ConnectivityType.ALWAYS -> true
}
}
(user.bestDisplayName() ?: user.bestUsername())?.let {
Row(verticalAlignment = Alignment.Bottom, modifier = Modifier.padding(top = 7.dp)) {
CreateTextWithEmoji(
@ -918,6 +928,7 @@ private fun DrawAdditionalInfo(
if (dialogOpen) {
ShowQRDialog(
user,
automaticallyShowProfilePicture,
onScan = {
dialogOpen = false
nav(it)
@ -1186,6 +1197,14 @@ private fun DisplayBadges(
accountViewModel: AccountViewModel,
nav: (String) -> Unit
) {
val automaticallyShowProfilePicture = remember {
when (accountViewModel.account.settings.automaticallyShowProfilePictures) {
ConnectivityType.WIFI_ONLY -> !ConnectivityStatus.isOnMobileData.value
ConnectivityType.NEVER -> false
ConnectivityType.ALWAYS -> true
}
}
LoadAddressableNote(
aTag = ATag(
BadgeProfilesEvent.kind,
@ -1196,7 +1215,7 @@ private fun DisplayBadges(
accountViewModel
) { note ->
if (note != null) {
WatchAndRenderBadgeList(note, nav)
WatchAndRenderBadgeList(note, automaticallyShowProfilePicture, nav)
}
}
}
@ -1204,6 +1223,7 @@ private fun DisplayBadges(
@Composable
private fun WatchAndRenderBadgeList(
note: AddressableNote,
loadProfilePicture: Boolean,
nav: (String) -> Unit
) {
val badgeList by note.live().metadata.map {
@ -1211,7 +1231,7 @@ private fun WatchAndRenderBadgeList(
}.distinctUntilChanged().observeAsState()
badgeList?.let { list ->
RenderBadgeList(list, nav)
RenderBadgeList(list, loadProfilePicture, nav)
}
}
@ -1219,6 +1239,7 @@ private fun WatchAndRenderBadgeList(
@OptIn(ExperimentalLayoutApi::class)
private fun RenderBadgeList(
list: ImmutableList<String>,
loadProfilePicture: Boolean,
nav: (String) -> Unit
) {
FlowRow(
@ -1226,13 +1247,13 @@ private fun RenderBadgeList(
modifier = Modifier.padding(vertical = 5.dp)
) {
list.forEach { badgeAwardEvent ->
LoadAndRenderBadge(badgeAwardEvent, nav)
LoadAndRenderBadge(badgeAwardEvent, loadProfilePicture, nav)
}
}
}
@Composable
private fun LoadAndRenderBadge(badgeAwardEventHex: String, nav: (String) -> Unit) {
private fun LoadAndRenderBadge(badgeAwardEventHex: String, loadProfilePicture: Boolean, nav: (String) -> Unit) {
var baseNote by remember {
mutableStateOf(LocalCache.getNoteIfExists(badgeAwardEventHex))
}
@ -1246,13 +1267,14 @@ private fun LoadAndRenderBadge(badgeAwardEventHex: String, nav: (String) -> Unit
}
baseNote?.let {
ObserveAndRenderBadge(it, nav)
ObserveAndRenderBadge(it, loadProfilePicture, nav)
}
}
@Composable
private fun ObserveAndRenderBadge(
it: Note,
loadProfilePicture: Boolean,
nav: (String) -> Unit
) {
val badgeAwardState by it.live().metadata.observeAsState()
@ -1263,18 +1285,19 @@ private fun ObserveAndRenderBadge(
}
baseBadgeDefinition?.let {
BadgeThumb(it, nav, Size35dp)
BadgeThumb(it, loadProfilePicture, nav, Size35dp)
}
}
@Composable
fun BadgeThumb(
note: Note,
loadProfilePicture: Boolean,
nav: (String) -> Unit,
size: Dp,
pictureModifier: Modifier = Modifier
) {
BadgeThumb(note, size, pictureModifier) {
BadgeThumb(note, loadProfilePicture, size, pictureModifier) {
nav("Note/${note.idHex}")
}
}
@ -1282,6 +1305,7 @@ fun BadgeThumb(
@Composable
fun BadgeThumb(
baseNote: Note,
loadProfilePicture: Boolean,
size: Dp,
pictureModifier: Modifier = Modifier,
onClick: ((String) -> Unit)? = null
@ -1293,13 +1317,14 @@ fun BadgeThumb(
.height(size)
}
) {
WatchAndRenderBadgeImage(baseNote, size, pictureModifier, onClick)
WatchAndRenderBadgeImage(baseNote, loadProfilePicture, size, pictureModifier, onClick)
}
}
@Composable
private fun WatchAndRenderBadgeImage(
baseNote: Note,
loadProfilePicture: Boolean,
size: Dp,
pictureModifier: Modifier,
onClick: ((String) -> Unit)?
@ -1344,8 +1369,8 @@ private fun WatchAndRenderBadgeImage(
this
}
}
}
},
loadProfilePicture = loadProfilePicture
)
}
}

Wyświetl plik

@ -49,11 +49,13 @@ import androidx.lifecycle.viewmodel.compose.viewModel
import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.model.Account
import com.vitorpamplona.amethyst.model.Channel
import com.vitorpamplona.amethyst.model.ConnectivityType
import com.vitorpamplona.amethyst.model.LocalCache
import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.model.User
import com.vitorpamplona.amethyst.service.NostrSearchEventOrUserDataSource
import com.vitorpamplona.amethyst.service.checkNotInMainThread
import com.vitorpamplona.amethyst.service.connectivitystatus.ConnectivityStatus
import com.vitorpamplona.amethyst.ui.components.BundledUpdate
import com.vitorpamplona.amethyst.ui.note.AboutDisplay
import com.vitorpamplona.amethyst.ui.note.ChannelName
@ -343,6 +345,14 @@ private fun DisplaySearchResults(
mutableStateOf(false)
}
val automaticallyShowProfilePicture = remember {
when (accountViewModel.account.settings.automaticallyShowProfilePictures) {
ConnectivityType.WIFI_ONLY -> !ConnectivityStatus.isOnMobileData.value
ConnectivityType.NEVER -> false
ConnectivityType.ALWAYS -> true
}
}
LazyColumn(
modifier = Modifier.fillMaxHeight(),
contentPadding = PaddingValues(
@ -383,6 +393,7 @@ private fun DisplaySearchResults(
channelLastTime = null,
channelLastContent = item.summary(),
hasNewMessages = hasNewMessages,
loadProfilePicture = automaticallyShowProfilePicture,
onClick = { nav("Channel/${item.idHex}") }
)
}

Wyświetl plik

@ -133,6 +133,7 @@ fun SettingsScreen(
val videoIndex = settings.automaticallyStartPlayback.screenCode
val linkIndex = settings.automaticallyShowUrlPreview.screenCode
val hideNavBarsIndex = settings.automaticallyHideNavigationBars.screenCode
val profilePictureIndex = settings.automaticallyShowProfilePictures.screenCode
val themeIndex = themeViewModel.theme.value ?: 0
@ -228,6 +229,20 @@ fun SettingsScreen(
}
}
SettingsRow(
R.string.automatically_show_profile_picture,
R.string.automatically_show_profile_picture_description,
selectedItens,
profilePictureIndex
) {
val automaticallyShowProfilePicture = parseConnectivityType(it)
scope.launch(Dispatchers.IO) {
accountViewModel.updateAutomaticallyShowProfilePicture(automaticallyShowProfilePicture)
LocalPreferences.saveToEncryptedStorage(accountViewModel.account)
}
}
Spacer(modifier = HalfVertSpacer)
SettingsRow(

Wyświetl plik

@ -598,4 +598,6 @@
<string name="hidden_words">Hidden Words</string>
<string name="hide_new_word_label">Hide new word or sentence</string>
<string name="automatically_show_profile_picture">Profile Picture</string>
<string name="automatically_show_profile_picture_description">Show Profile pictures</string>
</resources>