Adds communities, hashtags and geohashes to the lists on the top navigation bar.
This commit is contained in:
@@ -2478,13 +2478,7 @@ class Account(
|
|||||||
val privKey = keyPair.privKey
|
val privKey = keyPair.privKey
|
||||||
|
|
||||||
return if (listName != null) {
|
return if (listName != null) {
|
||||||
val aTag = ATag(
|
val list = LocalCache.addressables[listName]
|
||||||
PeopleListEvent.kind,
|
|
||||||
userProfile().pubkeyHex,
|
|
||||||
listName,
|
|
||||||
null
|
|
||||||
).toTag()
|
|
||||||
val list = LocalCache.addressables[aTag]
|
|
||||||
if (list != null) {
|
if (list != null) {
|
||||||
val publicHexList = (list.event as? PeopleListEvent)?.bookmarkedPeople() ?: emptySet()
|
val publicHexList = (list.event as? PeopleListEvent)?.bookmarkedPeople() ?: emptySet()
|
||||||
val privateHexList = privKey?.let {
|
val privateHexList = privKey?.let {
|
||||||
@@ -2507,13 +2501,7 @@ class Account(
|
|||||||
val privKey = keyPair.privKey
|
val privKey = keyPair.privKey
|
||||||
|
|
||||||
return if (listName != null) {
|
return if (listName != null) {
|
||||||
val aTag = ATag(
|
val list = LocalCache.addressables[listName]
|
||||||
PeopleListEvent.kind,
|
|
||||||
userProfile().pubkeyHex,
|
|
||||||
listName,
|
|
||||||
null
|
|
||||||
).toTag()
|
|
||||||
val list = LocalCache.addressables[aTag]
|
|
||||||
if (list != null) {
|
if (list != null) {
|
||||||
val publicAddresses = list.event?.hashtags() ?: emptySet()
|
val publicAddresses = list.event?.hashtags() ?: emptySet()
|
||||||
val privateAddresses = privKey?.let {
|
val privateAddresses = privKey?.let {
|
||||||
@@ -2536,13 +2524,7 @@ class Account(
|
|||||||
val privKey = keyPair.privKey
|
val privKey = keyPair.privKey
|
||||||
|
|
||||||
return if (listName != null) {
|
return if (listName != null) {
|
||||||
val aTag = ATag(
|
val list = LocalCache.addressables[listName]
|
||||||
PeopleListEvent.kind,
|
|
||||||
userProfile().pubkeyHex,
|
|
||||||
listName,
|
|
||||||
null
|
|
||||||
).toTag()
|
|
||||||
val list = LocalCache.addressables[aTag]
|
|
||||||
if (list != null) {
|
if (list != null) {
|
||||||
val publicAddresses = list.event?.geohashes() ?: emptySet()
|
val publicAddresses = list.event?.geohashes() ?: emptySet()
|
||||||
val privateAddresses = privKey?.let {
|
val privateAddresses = privKey?.let {
|
||||||
@@ -2565,13 +2547,7 @@ class Account(
|
|||||||
val privKey = keyPair.privKey
|
val privKey = keyPair.privKey
|
||||||
|
|
||||||
return if (listName != null) {
|
return if (listName != null) {
|
||||||
val aTag = ATag(
|
val list = LocalCache.addressables[listName]
|
||||||
PeopleListEvent.kind,
|
|
||||||
userProfile().pubkeyHex,
|
|
||||||
listName,
|
|
||||||
null
|
|
||||||
).toTag()
|
|
||||||
val list = LocalCache.addressables[aTag]
|
|
||||||
if (list != null) {
|
if (list != null) {
|
||||||
val publicAddresses = list.event?.taggedAddresses()?.map { it.toTag() } ?: emptySet()
|
val publicAddresses = list.event?.taggedAddresses()?.map { it.toTag() } ?: emptySet()
|
||||||
val privateAddresses = privKey?.let {
|
val privateAddresses = privKey?.let {
|
||||||
|
|||||||
@@ -43,6 +43,10 @@ class AddressableNote(val address: ATag) : Note(address.toTag()) {
|
|||||||
|
|
||||||
return minOf(publishedAt, lastCreatedAt)
|
return minOf(publishedAt, lastCreatedAt)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun dTag(): String? {
|
||||||
|
return (event as? AddressableEvent)?.dTag()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Stable
|
@Stable
|
||||||
|
|||||||
@@ -319,7 +319,7 @@ class User(val pubkeyHex: String) {
|
|||||||
return latestContactList?.verifiedFollowKeySet ?: emptySet()
|
return latestContactList?.verifiedFollowKeySet ?: emptySet()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun cachedFollowingTagSet(): Set<HexKey> {
|
fun cachedFollowingTagSet(): Set<String> {
|
||||||
return latestContactList?.verifiedFollowTagSet ?: emptySet()
|
return latestContactList?.verifiedFollowTagSet ?: emptySet()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ import com.vitorpamplona.amethyst.model.ServersAvailable
|
|||||||
import com.vitorpamplona.amethyst.ui.components.VideoView
|
import com.vitorpamplona.amethyst.ui.components.VideoView
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.TextSpinner
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.TextSpinner
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.TitleExplainer
|
||||||
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
||||||
import kotlinx.collections.immutable.toImmutableList
|
import kotlinx.collections.immutable.toImmutableList
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@@ -186,8 +187,7 @@ fun ImageVideoPost(postViewModel: NewMediaModel, accountViewModel: AccountViewMo
|
|||||||
Triple(ServersAvailable.NIP95, stringResource(id = R.string.upload_server_relays_nip95), stringResource(id = R.string.upload_server_relays_nip95_explainer))
|
Triple(ServersAvailable.NIP95, stringResource(id = R.string.upload_server_relays_nip95), stringResource(id = R.string.upload_server_relays_nip95_explainer))
|
||||||
)
|
)
|
||||||
|
|
||||||
val fileServerOptions = remember { fileServers.map { it.second }.toImmutableList() }
|
val fileServerOptions = remember { fileServers.map { TitleExplainer(it.second, it.third) }.toImmutableList() }
|
||||||
val fileServerExplainers = remember { fileServers.map { it.third }.toImmutableList() }
|
|
||||||
val resolver = LocalContext.current.contentResolver
|
val resolver = LocalContext.current.contentResolver
|
||||||
|
|
||||||
Row(
|
Row(
|
||||||
@@ -252,7 +252,6 @@ fun ImageVideoPost(postViewModel: NewMediaModel, accountViewModel: AccountViewMo
|
|||||||
label = stringResource(id = R.string.file_server),
|
label = stringResource(id = R.string.file_server),
|
||||||
placeholder = fileServers.firstOrNull { it.first == accountViewModel.account.defaultFileServer }?.second ?: fileServers[0].second,
|
placeholder = fileServers.firstOrNull { it.first == accountViewModel.account.defaultFileServer }?.second ?: fileServers[0].second,
|
||||||
options = fileServerOptions,
|
options = fileServerOptions,
|
||||||
explainers = fileServerExplainers,
|
|
||||||
onSelect = {
|
onSelect = {
|
||||||
postViewModel.selectedServer = fileServers[it].first
|
postViewModel.selectedServer = fileServers[it].first
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -93,6 +93,7 @@ import com.vitorpamplona.amethyst.ui.note.UsernameDisplay
|
|||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.MyTextField
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.MyTextField
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.TextSpinner
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.TextSpinner
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.TitleExplainer
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.UserLine
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.UserLine
|
||||||
import com.vitorpamplona.amethyst.ui.theme.BitcoinOrange
|
import com.vitorpamplona.amethyst.ui.theme.BitcoinOrange
|
||||||
import com.vitorpamplona.amethyst.ui.theme.ButtonBorder
|
import com.vitorpamplona.amethyst.ui.theme.ButtonBorder
|
||||||
@@ -1318,8 +1319,7 @@ fun ImageVideoDescription(
|
|||||||
Triple(ServersAvailable.NIP95, stringResource(id = R.string.upload_server_relays_nip95), stringResource(id = R.string.upload_server_relays_nip95_explainer))
|
Triple(ServersAvailable.NIP95, stringResource(id = R.string.upload_server_relays_nip95), stringResource(id = R.string.upload_server_relays_nip95_explainer))
|
||||||
)
|
)
|
||||||
|
|
||||||
val fileServerOptions = remember { fileServers.map { it.second }.toImmutableList() }
|
val fileServerOptions = remember { fileServers.map { TitleExplainer(it.second, it.third) }.toImmutableList() }
|
||||||
val fileServerExplainers = remember { fileServers.map { it.third }.toImmutableList() }
|
|
||||||
|
|
||||||
var selectedServer by remember { mutableStateOf(defaultServer) }
|
var selectedServer by remember { mutableStateOf(defaultServer) }
|
||||||
var message by remember { mutableStateOf("") }
|
var message by remember { mutableStateOf("") }
|
||||||
@@ -1433,7 +1433,6 @@ fun ImageVideoDescription(
|
|||||||
label = stringResource(id = R.string.file_server),
|
label = stringResource(id = R.string.file_server),
|
||||||
placeholder = fileServers.filter { it.first == defaultServer }.firstOrNull()?.second ?: fileServers[0].second,
|
placeholder = fileServers.filter { it.first == defaultServer }.firstOrNull()?.second ?: fileServers[0].second,
|
||||||
options = fileServerOptions,
|
options = fileServerOptions,
|
||||||
explainers = fileServerExplainers,
|
|
||||||
onSelect = {
|
onSelect = {
|
||||||
selectedServer = fileServers[it].first
|
selectedServer = fileServers[it].first
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import androidx.compose.material.OutlinedTextField
|
|||||||
import androidx.compose.material.Surface
|
import androidx.compose.material.Surface
|
||||||
import androidx.compose.material.Text
|
import androidx.compose.material.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.Immutable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
@@ -37,8 +38,7 @@ import kotlinx.collections.immutable.ImmutableList
|
|||||||
fun TextSpinner(
|
fun TextSpinner(
|
||||||
label: String?,
|
label: String?,
|
||||||
placeholder: String,
|
placeholder: String,
|
||||||
options: ImmutableList<String>,
|
options: ImmutableList<TitleExplainer>,
|
||||||
explainers: ImmutableList<String>? = null,
|
|
||||||
onSelect: (Int) -> Unit,
|
onSelect: (Int) -> Unit,
|
||||||
modifier: Modifier = Modifier
|
modifier: Modifier = Modifier
|
||||||
) {
|
) {
|
||||||
@@ -74,8 +74,8 @@ fun TextSpinner(
|
|||||||
|
|
||||||
if (optionsShowing) {
|
if (optionsShowing) {
|
||||||
options.isNotEmpty().also {
|
options.isNotEmpty().also {
|
||||||
SpinnerSelectionDialog(options = options, explainers = explainers, onDismiss = { optionsShowing = false }) {
|
SpinnerSelectionDialog(options = options, onDismiss = { optionsShowing = false }) {
|
||||||
currentText = options[it]
|
currentText = options[it].title
|
||||||
optionsShowing = false
|
optionsShowing = false
|
||||||
onSelect(it)
|
onSelect(it)
|
||||||
}
|
}
|
||||||
@@ -85,10 +85,40 @@ fun TextSpinner(
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun SpinnerSelectionDialog(
|
fun SpinnerSelectionDialog(
|
||||||
options: ImmutableList<String>,
|
options: ImmutableList<TitleExplainer>,
|
||||||
explainers: ImmutableList<String>?,
|
|
||||||
onDismiss: () -> Unit,
|
onDismiss: () -> Unit,
|
||||||
onSelect: (Int) -> Unit
|
onSelect: (Int) -> Unit
|
||||||
|
) {
|
||||||
|
SpinnerSelectionDialog(
|
||||||
|
options = options,
|
||||||
|
onSelect = onSelect,
|
||||||
|
onDismiss = onDismiss
|
||||||
|
) { item ->
|
||||||
|
Row(
|
||||||
|
horizontalArrangement = Arrangement.Center,
|
||||||
|
modifier = Modifier.fillMaxWidth()
|
||||||
|
) {
|
||||||
|
Text(text = item.title, color = MaterialTheme.colors.onSurface)
|
||||||
|
}
|
||||||
|
item.explainer?.let {
|
||||||
|
Spacer(modifier = Modifier.height(5.dp))
|
||||||
|
Row(
|
||||||
|
horizontalArrangement = Arrangement.Start,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
) {
|
||||||
|
Text(text = it, color = Color.Gray, fontSize = Font14SP)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun <T> SpinnerSelectionDialog(
|
||||||
|
options: ImmutableList<T>,
|
||||||
|
onSelect: (Int) -> Unit,
|
||||||
|
onDismiss: () -> Unit,
|
||||||
|
onRenderItem: @Composable (T) -> Unit
|
||||||
) {
|
) {
|
||||||
Dialog(onDismissRequest = onDismiss) {
|
Dialog(onDismissRequest = onDismiss) {
|
||||||
Surface(
|
Surface(
|
||||||
@@ -106,23 +136,7 @@ fun SpinnerSelectionDialog(
|
|||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
Column() {
|
Column() {
|
||||||
Row(
|
onRenderItem(item)
|
||||||
horizontalArrangement = Arrangement.Center,
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
) {
|
|
||||||
Text(text = item, color = MaterialTheme.colors.onSurface)
|
|
||||||
}
|
|
||||||
explainers?.getOrNull(index)?.let {
|
|
||||||
Spacer(modifier = Modifier.height(5.dp))
|
|
||||||
Row(
|
|
||||||
horizontalArrangement = Arrangement.Start,
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
) {
|
|
||||||
Text(text = it, color = Color.Gray, fontSize = Font14SP)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (index < options.lastIndex) {
|
if (index < options.lastIndex) {
|
||||||
@@ -133,3 +147,6 @@ fun SpinnerSelectionDialog(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Immutable
|
||||||
|
data class TitleExplainer(val title: String, val explainer: String? = null)
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import androidx.compose.material.icons.Icons
|
|||||||
import androidx.compose.material.icons.filled.ExpandMore
|
import androidx.compose.material.icons.filled.ExpandMore
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.CompositionLocalProvider
|
import androidx.compose.runtime.CompositionLocalProvider
|
||||||
|
import androidx.compose.runtime.Immutable
|
||||||
import androidx.compose.runtime.Stable
|
import androidx.compose.runtime.Stable
|
||||||
import androidx.compose.runtime.State
|
import androidx.compose.runtime.State
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
@@ -54,11 +55,13 @@ import androidx.compose.ui.unit.Dp
|
|||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
|
import androidx.lifecycle.map
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import androidx.navigation.NavBackStackEntry
|
import androidx.navigation.NavBackStackEntry
|
||||||
import coil.Coil
|
import coil.Coil
|
||||||
import com.vitorpamplona.amethyst.R
|
import com.vitorpamplona.amethyst.R
|
||||||
import com.vitorpamplona.amethyst.model.Account
|
import com.vitorpamplona.amethyst.model.Account
|
||||||
|
import com.vitorpamplona.amethyst.model.AddressableNote
|
||||||
import com.vitorpamplona.amethyst.model.GLOBAL_FOLLOWS
|
import com.vitorpamplona.amethyst.model.GLOBAL_FOLLOWS
|
||||||
import com.vitorpamplona.amethyst.model.KIND3_FOLLOWS
|
import com.vitorpamplona.amethyst.model.KIND3_FOLLOWS
|
||||||
import com.vitorpamplona.amethyst.model.LiveActivitiesChannel
|
import com.vitorpamplona.amethyst.model.LiveActivitiesChannel
|
||||||
@@ -88,6 +91,7 @@ import com.vitorpamplona.amethyst.ui.note.ArrowBackIcon
|
|||||||
import com.vitorpamplona.amethyst.ui.note.ClickableUserPicture
|
import com.vitorpamplona.amethyst.ui.note.ClickableUserPicture
|
||||||
import com.vitorpamplona.amethyst.ui.note.LoadAddressableNote
|
import com.vitorpamplona.amethyst.ui.note.LoadAddressableNote
|
||||||
import com.vitorpamplona.amethyst.ui.note.LoadChannel
|
import com.vitorpamplona.amethyst.ui.note.LoadChannel
|
||||||
|
import com.vitorpamplona.amethyst.ui.note.LoadCityName
|
||||||
import com.vitorpamplona.amethyst.ui.note.LoadUser
|
import com.vitorpamplona.amethyst.ui.note.LoadUser
|
||||||
import com.vitorpamplona.amethyst.ui.note.LongCommunityHeader
|
import com.vitorpamplona.amethyst.ui.note.LongCommunityHeader
|
||||||
import com.vitorpamplona.amethyst.ui.note.NonClickableUserPictures
|
import com.vitorpamplona.amethyst.ui.note.NonClickableUserPictures
|
||||||
@@ -117,6 +121,7 @@ import com.vitorpamplona.amethyst.ui.theme.Size34dp
|
|||||||
import com.vitorpamplona.amethyst.ui.theme.Size40dp
|
import com.vitorpamplona.amethyst.ui.theme.Size40dp
|
||||||
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
||||||
import com.vitorpamplona.quartz.events.ChatroomKey
|
import com.vitorpamplona.quartz.events.ChatroomKey
|
||||||
|
import com.vitorpamplona.quartz.events.ContactListEvent
|
||||||
import com.vitorpamplona.quartz.events.PeopleListEvent
|
import com.vitorpamplona.quartz.events.PeopleListEvent
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
import kotlinx.collections.immutable.toImmutableList
|
import kotlinx.collections.immutable.toImmutableList
|
||||||
@@ -382,11 +387,12 @@ fun StoriesTopBar(followLists: FollowListViewModel, scaffoldState: ScaffoldState
|
|||||||
val list by accountViewModel.storiesListLiveData.observeAsState(GLOBAL_FOLLOWS)
|
val list by accountViewModel.storiesListLiveData.observeAsState(GLOBAL_FOLLOWS)
|
||||||
|
|
||||||
FollowList(
|
FollowList(
|
||||||
followLists,
|
followListsModel = followLists,
|
||||||
list,
|
listName = list,
|
||||||
true
|
withGlobal = true,
|
||||||
|
withRoutes = false
|
||||||
) { listName ->
|
) { listName ->
|
||||||
accountViewModel.account.changeDefaultStoriesFollowList(listName)
|
accountViewModel.account.changeDefaultStoriesFollowList(listName.code)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -397,11 +403,16 @@ fun HomeTopBar(followLists: FollowListViewModel, scaffoldState: ScaffoldState, a
|
|||||||
val list by accountViewModel.homeListLiveData.observeAsState(KIND3_FOLLOWS)
|
val list by accountViewModel.homeListLiveData.observeAsState(KIND3_FOLLOWS)
|
||||||
|
|
||||||
FollowList(
|
FollowList(
|
||||||
followLists,
|
followListsModel = followLists,
|
||||||
list,
|
listName = list,
|
||||||
true
|
withGlobal = true,
|
||||||
|
withRoutes = true
|
||||||
) { listName ->
|
) { listName ->
|
||||||
accountViewModel.account.changeDefaultHomeFollowList(listName)
|
if (listName.type == CodeNameType.ROUTE) {
|
||||||
|
nav(listName.code)
|
||||||
|
} else {
|
||||||
|
accountViewModel.account.changeDefaultHomeFollowList(listName.code)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -412,11 +423,12 @@ fun NotificationTopBar(followLists: FollowListViewModel, scaffoldState: Scaffold
|
|||||||
val list by accountViewModel.notificationListLiveData.observeAsState(GLOBAL_FOLLOWS)
|
val list by accountViewModel.notificationListLiveData.observeAsState(GLOBAL_FOLLOWS)
|
||||||
|
|
||||||
FollowList(
|
FollowList(
|
||||||
followLists,
|
followListsModel = followLists,
|
||||||
list,
|
listName = list,
|
||||||
true
|
withGlobal = true,
|
||||||
|
withRoutes = false
|
||||||
) { listName ->
|
) { listName ->
|
||||||
accountViewModel.account.changeDefaultNotificationFollowList(listName)
|
accountViewModel.account.changeDefaultNotificationFollowList(listName.code)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -427,11 +439,12 @@ fun DiscoveryTopBar(followLists: FollowListViewModel, scaffoldState: ScaffoldSta
|
|||||||
val list by accountViewModel.discoveryListLiveData.observeAsState(GLOBAL_FOLLOWS)
|
val list by accountViewModel.discoveryListLiveData.observeAsState(GLOBAL_FOLLOWS)
|
||||||
|
|
||||||
FollowList(
|
FollowList(
|
||||||
followLists,
|
followListsModel = followLists,
|
||||||
list,
|
listName = list,
|
||||||
true
|
withGlobal = true,
|
||||||
|
withRoutes = false
|
||||||
) { listName ->
|
) { listName ->
|
||||||
accountViewModel.account.changeDefaultDiscoveryFollowList(listName)
|
accountViewModel.account.changeDefaultDiscoveryFollowList(listName.code)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -523,37 +536,81 @@ private fun LoggedInUserPictureDrawer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun FollowList(followListsModel: FollowListViewModel, listName: String, withGlobal: Boolean, onChange: (String) -> Unit) {
|
fun FollowList(
|
||||||
val kind3Follow = Pair(KIND3_FOLLOWS, stringResource(id = R.string.follow_list_kind3follows))
|
followListsModel: FollowListViewModel,
|
||||||
val globalFollow = Pair(GLOBAL_FOLLOWS, stringResource(id = R.string.follow_list_global))
|
listName: String,
|
||||||
|
withGlobal: Boolean,
|
||||||
|
withRoutes: Boolean,
|
||||||
|
onChange: (CodeName) -> Unit
|
||||||
|
) {
|
||||||
|
val context = LocalContext.current
|
||||||
|
|
||||||
|
val kind3Follow = CodeName(KIND3_FOLLOWS, ResourceName(R.string.follow_list_kind3follows, context), CodeNameType.HARDCODED)
|
||||||
|
val globalFollow = CodeName(GLOBAL_FOLLOWS, ResourceName(R.string.follow_list_global, context), CodeNameType.HARDCODED)
|
||||||
|
|
||||||
val defaultOptions = if (withGlobal) listOf(kind3Follow, globalFollow) else listOf(kind3Follow)
|
val defaultOptions = if (withGlobal) listOf(kind3Follow, globalFollow) else listOf(kind3Follow)
|
||||||
|
|
||||||
val followLists by followListsModel.followLists.collectAsState()
|
val followLists by followListsModel.peopleLists.collectAsState()
|
||||||
|
val routeList by followListsModel.routes.collectAsState()
|
||||||
|
|
||||||
val allLists = remember(followLists) {
|
val allLists = remember(followLists) {
|
||||||
(defaultOptions + followLists)
|
if (withRoutes) {
|
||||||
|
(defaultOptions + followLists + routeList)
|
||||||
|
} else {
|
||||||
|
(defaultOptions + followLists)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val followNames by remember(followLists) {
|
val followNames by remember(followLists) {
|
||||||
derivedStateOf {
|
derivedStateOf {
|
||||||
allLists.map { it.second }.toImmutableList()
|
allLists.map { it.name }.toImmutableList()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SimpleTextSpinner(
|
SimpleTextSpinner(
|
||||||
placeholder = allLists.firstOrNull { it.first == listName }?.second ?: "Select an Option",
|
placeholder = allLists.firstOrNull { it.code == listName }?.name?.name() ?: "Select an Option",
|
||||||
options = followNames,
|
options = followNames,
|
||||||
onSelect = {
|
onSelect = {
|
||||||
onChange(allLists.getOrNull(it)?.first ?: KIND3_FOLLOWS)
|
onChange(allLists.getOrNull(it) ?: kind3Follow)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum class CodeNameType {
|
||||||
|
HARDCODED, PEOPLE_LIST, ROUTE
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class Name {
|
||||||
|
abstract fun name(): String
|
||||||
|
}
|
||||||
|
|
||||||
|
class GeoHashName(val geoHashTag: String) : Name() {
|
||||||
|
override fun name() = "/g/$geoHashTag"
|
||||||
|
}
|
||||||
|
class HashtagName(val hashTag: String) : Name() {
|
||||||
|
override fun name() = "#$hashTag"
|
||||||
|
}
|
||||||
|
class ResourceName(val resourceId: Int, val context: Context) : Name() {
|
||||||
|
override fun name() = context.getString(resourceId)
|
||||||
|
}
|
||||||
|
|
||||||
|
class PeopleListName(val note: AddressableNote) : Name() {
|
||||||
|
override fun name() = note.dTag() ?: ""
|
||||||
|
}
|
||||||
|
class CommunityName(val note: AddressableNote) : Name() {
|
||||||
|
override fun name() = "/n/${(note.dTag() ?: "")}"
|
||||||
|
}
|
||||||
|
|
||||||
|
@Immutable
|
||||||
|
data class CodeName(val code: String, val name: Name, val type: CodeNameType)
|
||||||
|
|
||||||
@Stable
|
@Stable
|
||||||
class FollowListViewModel(val account: Account) : ViewModel() {
|
class FollowListViewModel(val account: Account) : ViewModel() {
|
||||||
private var _followLists = MutableStateFlow<ImmutableList<Pair<String, String>>>(emptyList<Pair<String, String>>().toPersistentList())
|
private var _peopleLists = MutableStateFlow<ImmutableList<CodeName>>(emptyList<CodeName>().toPersistentList())
|
||||||
val followLists = _followLists.asStateFlow()
|
val peopleLists = _peopleLists.asStateFlow()
|
||||||
|
|
||||||
|
private var _routes = MutableStateFlow<ImmutableList<CodeName>>(emptyList<CodeName>().toPersistentList())
|
||||||
|
val routes = _routes.asStateFlow()
|
||||||
|
|
||||||
fun refresh() {
|
fun refresh() {
|
||||||
viewModelScope.launch(Dispatchers.Default) {
|
viewModelScope.launch(Dispatchers.Default) {
|
||||||
@@ -571,14 +628,34 @@ class FollowListViewModel(val account: Account) : ViewModel() {
|
|||||||
event.pubKey == account.userProfile().pubkeyHex &&
|
event.pubKey == account.userProfile().pubkeyHex &&
|
||||||
(event.tags.size > 1 || event.content.length > 50)
|
(event.tags.size > 1 || event.content.length > 50)
|
||||||
) {
|
) {
|
||||||
Pair(event.dTag(), event.dTag())
|
CodeName(event.address().toTag(), PeopleListName(it.value), CodeNameType.PEOPLE_LIST)
|
||||||
} else {
|
} else {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
}.sortedBy { it.second }.toImmutableList()
|
}.sortedBy { it.name.name() }.toImmutableList()
|
||||||
|
|
||||||
if (!equalImmutableLists(_followLists.value, newFollowLists)) {
|
if (!equalImmutableLists(_peopleLists.value, newFollowLists)) {
|
||||||
_followLists.emit(newFollowLists)
|
_peopleLists.emit(newFollowLists)
|
||||||
|
}
|
||||||
|
|
||||||
|
val communities = account.userProfile().cachedFollowingCommunitiesSet().mapNotNull {
|
||||||
|
LocalCache.checkGetOrCreateAddressableNote(it)?.let { communityNote ->
|
||||||
|
CodeName("Community/${communityNote.idHex}", CommunityName(communityNote), CodeNameType.ROUTE)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val hashtags = account.userProfile().cachedFollowingTagSet().map {
|
||||||
|
CodeName("Hashtag/$it", HashtagName(it), CodeNameType.ROUTE)
|
||||||
|
}
|
||||||
|
|
||||||
|
val geotags = account.userProfile().cachedFollowingGeohashSet().map {
|
||||||
|
CodeName("Geohash/$it", GeoHashName(it), CodeNameType.ROUTE)
|
||||||
|
}
|
||||||
|
|
||||||
|
val routeList = (communities + hashtags + geotags).sortedBy { it.name.name() }.toImmutableList()
|
||||||
|
|
||||||
|
if (!equalImmutableLists(_routes.value, routeList)) {
|
||||||
|
_routes.emit(routeList)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -590,7 +667,10 @@ class FollowListViewModel(val account: Account) : ViewModel() {
|
|||||||
collectorJob = viewModelScope.launch(Dispatchers.IO) {
|
collectorJob = viewModelScope.launch(Dispatchers.IO) {
|
||||||
LocalCache.live.newEventBundles.collect { newNotes ->
|
LocalCache.live.newEventBundles.collect { newNotes ->
|
||||||
checkNotInMainThread()
|
checkNotInMainThread()
|
||||||
if (newNotes.any { it.event is PeopleListEvent }) {
|
if (newNotes.any {
|
||||||
|
it.event?.pubKey() == account.userProfile().pubkeyHex && (it.event is PeopleListEvent || it.event is ContactListEvent)
|
||||||
|
}
|
||||||
|
) {
|
||||||
refresh()
|
refresh()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -612,8 +692,7 @@ class FollowListViewModel(val account: Account) : ViewModel() {
|
|||||||
@Composable
|
@Composable
|
||||||
fun SimpleTextSpinner(
|
fun SimpleTextSpinner(
|
||||||
placeholder: String,
|
placeholder: String,
|
||||||
options: ImmutableList<String>,
|
options: ImmutableList<Name>,
|
||||||
explainers: ImmutableList<String>? = null,
|
|
||||||
onSelect: (Int) -> Unit,
|
onSelect: (Int) -> Unit,
|
||||||
modifier: Modifier = Modifier
|
modifier: Modifier = Modifier
|
||||||
) {
|
) {
|
||||||
@@ -649,10 +728,68 @@ fun SimpleTextSpinner(
|
|||||||
|
|
||||||
if (optionsShowing) {
|
if (optionsShowing) {
|
||||||
options.isNotEmpty().also {
|
options.isNotEmpty().also {
|
||||||
SpinnerSelectionDialog(options = options, explainers = explainers, onDismiss = { optionsShowing = false }) {
|
SpinnerSelectionDialog(
|
||||||
currentText = options[it]
|
options = options,
|
||||||
optionsShowing = false
|
onDismiss = { optionsShowing = false },
|
||||||
onSelect(it)
|
onSelect = {
|
||||||
|
currentText = options[it].name()
|
||||||
|
optionsShowing = false
|
||||||
|
onSelect(it)
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
RenderOption(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun RenderOption(it: Name) {
|
||||||
|
when (it) {
|
||||||
|
is GeoHashName -> {
|
||||||
|
LoadCityName(it.geoHashTag) {
|
||||||
|
Row(
|
||||||
|
horizontalArrangement = Arrangement.Center,
|
||||||
|
modifier = Modifier.fillMaxWidth()
|
||||||
|
) {
|
||||||
|
Text(text = "/g/$it", color = MaterialTheme.colors.onSurface)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is HashtagName -> {
|
||||||
|
Row(
|
||||||
|
horizontalArrangement = Arrangement.Center,
|
||||||
|
modifier = Modifier.fillMaxWidth()
|
||||||
|
) {
|
||||||
|
Text(text = it.name(), color = MaterialTheme.colors.onSurface)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is ResourceName -> {
|
||||||
|
Row(
|
||||||
|
horizontalArrangement = Arrangement.Center,
|
||||||
|
modifier = Modifier.fillMaxWidth()
|
||||||
|
) {
|
||||||
|
Text(text = stringResource(id = it.resourceId), color = MaterialTheme.colors.onSurface)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is PeopleListName -> {
|
||||||
|
Row(
|
||||||
|
horizontalArrangement = Arrangement.Center,
|
||||||
|
modifier = Modifier.fillMaxWidth()
|
||||||
|
) {
|
||||||
|
Text(text = it.name(), color = MaterialTheme.colors.onSurface)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is CommunityName -> {
|
||||||
|
Row(
|
||||||
|
horizontalArrangement = Arrangement.Center,
|
||||||
|
modifier = Modifier.fillMaxWidth()
|
||||||
|
) {
|
||||||
|
val name by it.note.live().metadata.map {
|
||||||
|
"/n/" + (it.note as? AddressableNote)?.dTag()
|
||||||
|
}.observeAsState()
|
||||||
|
|
||||||
|
Text(text = name ?: "", color = MaterialTheme.colors.onSurface)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2579,7 +2579,7 @@ fun LoadStatuses(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun DisplayLocation(geohash: String, nav: (String) -> Unit) {
|
fun LoadCityName(geohash: String, content: @Composable (String) -> Unit) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
var cityName by remember(geohash) {
|
var cityName by remember(geohash) {
|
||||||
mutableStateOf<String>(geohash)
|
mutableStateOf<String>(geohash)
|
||||||
@@ -2594,18 +2594,25 @@ fun DisplayLocation(geohash: String, nav: (String) -> Unit) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ClickableText(
|
content(cityName)
|
||||||
text = AnnotatedString(cityName),
|
}
|
||||||
onClick = { nav("Geohash/$geohash") },
|
|
||||||
style = LocalTextStyle.current.copy(
|
@Composable
|
||||||
color = MaterialTheme.colors.primary.copy(
|
fun DisplayLocation(geohash: String, nav: (String) -> Unit) {
|
||||||
alpha = 0.52f
|
LoadCityName(geohash) { cityName ->
|
||||||
|
ClickableText(
|
||||||
|
text = AnnotatedString(cityName),
|
||||||
|
onClick = { nav("Geohash/$geohash") },
|
||||||
|
style = LocalTextStyle.current.copy(
|
||||||
|
color = MaterialTheme.colors.primary.copy(
|
||||||
|
alpha = 0.52f
|
||||||
|
),
|
||||||
|
fontSize = Font14SP,
|
||||||
|
fontWeight = FontWeight.Bold
|
||||||
),
|
),
|
||||||
fontSize = Font14SP,
|
maxLines = 1
|
||||||
fontWeight = FontWeight.Bold
|
)
|
||||||
),
|
}
|
||||||
maxLines = 1
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
|||||||
@@ -89,7 +89,6 @@ import com.vitorpamplona.amethyst.ui.theme.DarkerGreen
|
|||||||
import com.vitorpamplona.amethyst.ui.theme.Font14SP
|
import com.vitorpamplona.amethyst.ui.theme.Font14SP
|
||||||
import com.vitorpamplona.amethyst.ui.theme.HalfDoubleVertSpacer
|
import com.vitorpamplona.amethyst.ui.theme.HalfDoubleVertSpacer
|
||||||
import com.vitorpamplona.amethyst.ui.theme.HalfStartPadding
|
import com.vitorpamplona.amethyst.ui.theme.HalfStartPadding
|
||||||
import com.vitorpamplona.amethyst.ui.theme.Height4dpModifier
|
|
||||||
import com.vitorpamplona.amethyst.ui.theme.ModifierWidth3dp
|
import com.vitorpamplona.amethyst.ui.theme.ModifierWidth3dp
|
||||||
import com.vitorpamplona.amethyst.ui.theme.NoSoTinyBorders
|
import com.vitorpamplona.amethyst.ui.theme.NoSoTinyBorders
|
||||||
import com.vitorpamplona.amethyst.ui.theme.ReactionRowExpandButton
|
import com.vitorpamplona.amethyst.ui.theme.ReactionRowExpandButton
|
||||||
@@ -135,13 +134,14 @@ fun ReactionsRow(
|
|||||||
|
|
||||||
InnerReactionRow(baseNote, showReactionDetail, wantsToSeeReactions, accountViewModel, nav)
|
InnerReactionRow(baseNote, showReactionDetail, wantsToSeeReactions, accountViewModel, nav)
|
||||||
|
|
||||||
|
Spacer(modifier = HalfDoubleVertSpacer)
|
||||||
|
|
||||||
LoadAndDisplayZapraiser(baseNote, showReactionDetail, wantsToSeeReactions, accountViewModel)
|
LoadAndDisplayZapraiser(baseNote, showReactionDetail, wantsToSeeReactions, accountViewModel)
|
||||||
|
|
||||||
if (showReactionDetail && wantsToSeeReactions.value) {
|
if (showReactionDetail && wantsToSeeReactions.value) {
|
||||||
ReactionDetailGallery(baseNote, nav, accountViewModel)
|
ReactionDetailGallery(baseNote, nav, accountViewModel)
|
||||||
|
Spacer(modifier = HalfDoubleVertSpacer)
|
||||||
}
|
}
|
||||||
|
|
||||||
Spacer(modifier = HalfDoubleVertSpacer)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@@ -251,7 +251,6 @@ private fun LoadAndDisplayZapraiser(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (zapraiserAmount > 0) {
|
if (zapraiserAmount > 0) {
|
||||||
Spacer(modifier = Height4dpModifier)
|
|
||||||
Box(
|
Box(
|
||||||
modifier = remember {
|
modifier = remember {
|
||||||
ReactionRowZapraiserSize
|
ReactionRowZapraiserSize
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ import com.vitorpamplona.amethyst.ui.actions.SaveButton
|
|||||||
import com.vitorpamplona.amethyst.ui.qrcode.SimpleQrCodeScanner
|
import com.vitorpamplona.amethyst.ui.qrcode.SimpleQrCodeScanner
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.TextSpinner
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.TextSpinner
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.TitleExplainer
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.getFragmentActivity
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.getFragmentActivity
|
||||||
import com.vitorpamplona.amethyst.ui.theme.ButtonBorder
|
import com.vitorpamplona.amethyst.ui.theme.ButtonBorder
|
||||||
import com.vitorpamplona.amethyst.ui.theme.Font14SP
|
import com.vitorpamplona.amethyst.ui.theme.Font14SP
|
||||||
@@ -219,8 +220,7 @@ fun UpdateZapAmountDialog(
|
|||||||
Triple(LnZapEvent.ZapType.NONZAP, stringResource(id = R.string.zap_type_nonzap), stringResource(id = R.string.zap_type_nonzap_explainer))
|
Triple(LnZapEvent.ZapType.NONZAP, stringResource(id = R.string.zap_type_nonzap), stringResource(id = R.string.zap_type_nonzap_explainer))
|
||||||
)
|
)
|
||||||
|
|
||||||
val zapOptions = remember { zapTypes.map { it.second }.toImmutableList() }
|
val zapOptions = remember { zapTypes.map { TitleExplainer(it.second, it.third) }.toImmutableList() }
|
||||||
val zapOptionExplainers = remember { zapTypes.map { it.third }.toImmutableList() }
|
|
||||||
|
|
||||||
LaunchedEffect(accountViewModel, nip47uri) {
|
LaunchedEffect(accountViewModel, nip47uri) {
|
||||||
postViewModel.load()
|
postViewModel.load()
|
||||||
@@ -361,7 +361,6 @@ fun UpdateZapAmountDialog(
|
|||||||
placeholder = zapTypes.filter { it.first == accountViewModel.defaultZapType() }
|
placeholder = zapTypes.filter { it.first == accountViewModel.defaultZapType() }
|
||||||
.first().second,
|
.first().second,
|
||||||
options = zapOptions,
|
options = zapOptions,
|
||||||
explainers = zapOptionExplainers,
|
|
||||||
onSelect = {
|
onSelect = {
|
||||||
postViewModel.selectedZapType = zapTypes[it].first
|
postViewModel.selectedZapType = zapTypes[it].first
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ import com.vitorpamplona.amethyst.service.ZapPaymentHandler
|
|||||||
import com.vitorpamplona.amethyst.ui.actions.CloseButton
|
import com.vitorpamplona.amethyst.ui.actions.CloseButton
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.TextSpinner
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.TextSpinner
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.TitleExplainer
|
||||||
import com.vitorpamplona.amethyst.ui.theme.ButtonBorder
|
import com.vitorpamplona.amethyst.ui.theme.ButtonBorder
|
||||||
import com.vitorpamplona.amethyst.ui.theme.DoubleHorzSpacer
|
import com.vitorpamplona.amethyst.ui.theme.DoubleHorzSpacer
|
||||||
import com.vitorpamplona.amethyst.ui.theme.DoubleVertSpacer
|
import com.vitorpamplona.amethyst.ui.theme.DoubleVertSpacer
|
||||||
@@ -107,8 +108,7 @@ fun ZapCustomDialog(
|
|||||||
Triple(LnZapEvent.ZapType.NONZAP, stringResource(id = R.string.zap_type_nonzap), stringResource(id = R.string.zap_type_nonzap_explainer))
|
Triple(LnZapEvent.ZapType.NONZAP, stringResource(id = R.string.zap_type_nonzap), stringResource(id = R.string.zap_type_nonzap_explainer))
|
||||||
)
|
)
|
||||||
|
|
||||||
val zapOptions = remember { zapTypes.map { it.second }.toImmutableList() }
|
val zapOptions = remember { zapTypes.map { TitleExplainer(it.second, it.third) }.toImmutableList() }
|
||||||
val zapOptionExplainers = remember { zapTypes.map { it.third }.toImmutableList() }
|
|
||||||
var selectedZapType by remember(accountViewModel) { mutableStateOf(accountViewModel.account.defaultZapType) }
|
var selectedZapType by remember(accountViewModel) { mutableStateOf(accountViewModel.account.defaultZapType) }
|
||||||
|
|
||||||
Dialog(
|
Dialog(
|
||||||
@@ -181,7 +181,6 @@ fun ZapCustomDialog(
|
|||||||
label = stringResource(id = R.string.zap_type),
|
label = stringResource(id = R.string.zap_type),
|
||||||
placeholder = zapTypes.filter { it.first == accountViewModel.account.defaultZapType }.first().second,
|
placeholder = zapTypes.filter { it.first == accountViewModel.account.defaultZapType }.first().second,
|
||||||
options = zapOptions,
|
options = zapOptions,
|
||||||
explainers = zapOptionExplainers,
|
|
||||||
onSelect = {
|
onSelect = {
|
||||||
selectedZapType = zapTypes[it].first
|
selectedZapType = zapTypes[it].first
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ fun ReportNoteDialog(note: Note, accountViewModel: AccountViewModel, onDismiss:
|
|||||||
Pair(ReportEvent.ReportType.ILLEGAL, stringResource(R.string.report_dialog_illegal))
|
Pair(ReportEvent.ReportType.ILLEGAL, stringResource(R.string.report_dialog_illegal))
|
||||||
)
|
)
|
||||||
|
|
||||||
val reasonOptions = remember { reportTypes.map { it.second }.toImmutableList() }
|
val reasonOptions = remember { reportTypes.map { TitleExplainer(it.second) }.toImmutableList() }
|
||||||
var additionalReason by remember { mutableStateOf("") }
|
var additionalReason by remember { mutableStateOf("") }
|
||||||
var selectedReason by remember { mutableStateOf(-1) }
|
var selectedReason by remember { mutableStateOf(-1) }
|
||||||
|
|
||||||
|
|||||||
@@ -111,15 +111,15 @@ fun SettingsScreen(
|
|||||||
) {
|
) {
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
val selectedItens = persistentListOf(
|
val selectedItens = persistentListOf(
|
||||||
stringResource(ConnectivityType.ALWAYS.reourceId),
|
TitleExplainer(stringResource(ConnectivityType.ALWAYS.reourceId)),
|
||||||
stringResource(ConnectivityType.WIFI_ONLY.reourceId),
|
TitleExplainer(stringResource(ConnectivityType.WIFI_ONLY.reourceId)),
|
||||||
stringResource(ConnectivityType.NEVER.reourceId)
|
TitleExplainer(stringResource(ConnectivityType.NEVER.reourceId))
|
||||||
)
|
)
|
||||||
|
|
||||||
val themeItens = persistentListOf(
|
val themeItens = persistentListOf(
|
||||||
stringResource(R.string.system),
|
TitleExplainer(stringResource(R.string.system)),
|
||||||
stringResource(R.string.light),
|
TitleExplainer(stringResource(R.string.light)),
|
||||||
stringResource(R.string.dark)
|
TitleExplainer(stringResource(R.string.dark))
|
||||||
)
|
)
|
||||||
|
|
||||||
val settings = accountViewModel.account.settings
|
val settings = accountViewModel.account.settings
|
||||||
@@ -132,7 +132,7 @@ fun SettingsScreen(
|
|||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
|
|
||||||
val languageEntries = context.getLangPreferenceDropdownEntries()
|
val languageEntries = context.getLangPreferenceDropdownEntries()
|
||||||
val languageList = languageEntries.keys.toImmutableList()
|
val languageList = languageEntries.keys.map { TitleExplainer(it) }.toImmutableList()
|
||||||
val languageIndex = getLanguageIndex(languageEntries)
|
val languageIndex = getLanguageIndex(languageEntries)
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
@@ -149,12 +149,12 @@ fun SettingsScreen(
|
|||||||
) {
|
) {
|
||||||
GlobalScope.launch(Dispatchers.Main) {
|
GlobalScope.launch(Dispatchers.Main) {
|
||||||
val job = scope.launch(Dispatchers.IO) {
|
val job = scope.launch(Dispatchers.IO) {
|
||||||
val locale = languageEntries[languageList[it]]
|
val locale = languageEntries[languageList[it].title]
|
||||||
accountViewModel.account.settings.preferredLanguage = locale
|
accountViewModel.account.settings.preferredLanguage = locale
|
||||||
LocalPreferences.saveToEncryptedStorage(accountViewModel.account)
|
LocalPreferences.saveToEncryptedStorage(accountViewModel.account)
|
||||||
}
|
}
|
||||||
job.join()
|
job.join()
|
||||||
val appLocale: LocaleListCompat = LocaleListCompat.forLanguageTags(languageEntries[languageList[it]])
|
val appLocale: LocaleListCompat = LocaleListCompat.forLanguageTags(languageEntries[languageList[it].title])
|
||||||
AppCompatDelegate.setApplicationLocales(appLocale)
|
AppCompatDelegate.setApplicationLocales(appLocale)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -227,7 +227,7 @@ fun SettingsScreen(
|
|||||||
fun SettingsRow(
|
fun SettingsRow(
|
||||||
name: Int,
|
name: Int,
|
||||||
description: Int,
|
description: Int,
|
||||||
selectedItens: ImmutableList<String>,
|
selectedItens: ImmutableList<TitleExplainer>,
|
||||||
selectedIndex: Int,
|
selectedIndex: Int,
|
||||||
onSelect: (Int) -> Unit
|
onSelect: (Int) -> Unit
|
||||||
) {
|
) {
|
||||||
@@ -255,7 +255,7 @@ fun SettingsRow(
|
|||||||
|
|
||||||
TextSpinner(
|
TextSpinner(
|
||||||
label = "",
|
label = "",
|
||||||
placeholder = selectedItens[selectedIndex],
|
placeholder = selectedItens[selectedIndex].title,
|
||||||
options = selectedItens,
|
options = selectedItens,
|
||||||
onSelect = onSelect,
|
onSelect = onSelect,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
|||||||
Reference in New Issue
Block a user