Code reviews:
fix(broadcast): observe tracked-broadcasts toggle reactively fix(settings): preserve prior broadcast-tracker behavior on upgrade refactor(broadcast): rename setting to match what the toggle does
This commit is contained in:
@@ -42,7 +42,7 @@ data class UiSettings(
|
|||||||
val featureSet: FeatureSetType = FeatureSetType.SIMPLIFIED,
|
val featureSet: FeatureSetType = FeatureSetType.SIMPLIFIED,
|
||||||
val gallerySet: ProfileGalleryType = ProfileGalleryType.CLASSIC,
|
val gallerySet: ProfileGalleryType = ProfileGalleryType.CLASSIC,
|
||||||
val automaticallyProposeAiImprovements: BooleanType = BooleanType.ALWAYS,
|
val automaticallyProposeAiImprovements: BooleanType = BooleanType.ALWAYS,
|
||||||
val showBroadcaster: BooleanType = BooleanType.ALWAYS,
|
val useTrackedBroadcasts: BooleanType = BooleanType.ALWAYS,
|
||||||
val bottomBarItems: List<NavBarItem> = DefaultBottomBarItems,
|
val bottomBarItems: List<NavBarItem> = DefaultBottomBarItems,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ class UiSettingsFlow(
|
|||||||
val featureSet: MutableStateFlow<FeatureSetType> = MutableStateFlow(FeatureSetType.SIMPLIFIED),
|
val featureSet: MutableStateFlow<FeatureSetType> = MutableStateFlow(FeatureSetType.SIMPLIFIED),
|
||||||
val gallerySet: MutableStateFlow<ProfileGalleryType> = MutableStateFlow(ProfileGalleryType.CLASSIC),
|
val gallerySet: MutableStateFlow<ProfileGalleryType> = MutableStateFlow(ProfileGalleryType.CLASSIC),
|
||||||
val automaticallyProposeAiImprovements: MutableStateFlow<BooleanType> = MutableStateFlow(BooleanType.ALWAYS),
|
val automaticallyProposeAiImprovements: MutableStateFlow<BooleanType> = MutableStateFlow(BooleanType.ALWAYS),
|
||||||
val showBroadcaster: MutableStateFlow<BooleanType> = MutableStateFlow(BooleanType.ALWAYS),
|
val useTrackedBroadcasts: MutableStateFlow<BooleanType> = MutableStateFlow(BooleanType.ALWAYS),
|
||||||
val bottomBarItems: MutableStateFlow<List<NavBarItem>> = MutableStateFlow(DefaultBottomBarItems),
|
val bottomBarItems: MutableStateFlow<List<NavBarItem>> = MutableStateFlow(DefaultBottomBarItems),
|
||||||
) {
|
) {
|
||||||
val listOfFlows: List<Flow<Any?>> =
|
val listOfFlows: List<Flow<Any?>> =
|
||||||
@@ -60,7 +60,7 @@ class UiSettingsFlow(
|
|||||||
featureSet,
|
featureSet,
|
||||||
gallerySet,
|
gallerySet,
|
||||||
automaticallyProposeAiImprovements,
|
automaticallyProposeAiImprovements,
|
||||||
showBroadcaster,
|
useTrackedBroadcasts,
|
||||||
bottomBarItems,
|
bottomBarItems,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -102,7 +102,7 @@ class UiSettingsFlow(
|
|||||||
featureSet.value,
|
featureSet.value,
|
||||||
gallerySet.value,
|
gallerySet.value,
|
||||||
automaticallyProposeAiImprovements.value,
|
automaticallyProposeAiImprovements.value,
|
||||||
showBroadcaster.value,
|
useTrackedBroadcasts.value,
|
||||||
bottomBarItems.value,
|
bottomBarItems.value,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -161,8 +161,8 @@ class UiSettingsFlow(
|
|||||||
automaticallyProposeAiImprovements.tryEmit(torSettings.automaticallyProposeAiImprovements)
|
automaticallyProposeAiImprovements.tryEmit(torSettings.automaticallyProposeAiImprovements)
|
||||||
any = true
|
any = true
|
||||||
}
|
}
|
||||||
if (showBroadcaster.value != torSettings.showBroadcaster) {
|
if (useTrackedBroadcasts.value != torSettings.useTrackedBroadcasts) {
|
||||||
showBroadcaster.tryEmit(torSettings.showBroadcaster)
|
useTrackedBroadcasts.tryEmit(torSettings.useTrackedBroadcasts)
|
||||||
any = true
|
any = true
|
||||||
}
|
}
|
||||||
if (bottomBarItems.value != torSettings.bottomBarItems) {
|
if (bottomBarItems.value != torSettings.bottomBarItems) {
|
||||||
@@ -201,7 +201,7 @@ class UiSettingsFlow(
|
|||||||
MutableStateFlow(uiSettings.featureSet),
|
MutableStateFlow(uiSettings.featureSet),
|
||||||
MutableStateFlow(uiSettings.gallerySet),
|
MutableStateFlow(uiSettings.gallerySet),
|
||||||
MutableStateFlow(uiSettings.automaticallyProposeAiImprovements),
|
MutableStateFlow(uiSettings.automaticallyProposeAiImprovements),
|
||||||
MutableStateFlow(uiSettings.showBroadcaster),
|
MutableStateFlow(uiSettings.useTrackedBroadcasts),
|
||||||
MutableStateFlow(uiSettings.bottomBarItems),
|
MutableStateFlow(uiSettings.bottomBarItems),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-4
@@ -106,7 +106,7 @@ class UiSharedPreferences(
|
|||||||
val UI_FEATURE_SET = stringPreferencesKey("ui.feature_set")
|
val UI_FEATURE_SET = stringPreferencesKey("ui.feature_set")
|
||||||
val UI_GALLERY_SET = stringPreferencesKey("ui.gallery_set")
|
val UI_GALLERY_SET = stringPreferencesKey("ui.gallery_set")
|
||||||
val UI_PROPOSE_AI_IMPROVEMENTS = stringPreferencesKey("ui.propose_ai_improvements")
|
val UI_PROPOSE_AI_IMPROVEMENTS = stringPreferencesKey("ui.propose_ai_improvements")
|
||||||
val UI_SHOW_BROADCASTER = stringPreferencesKey("ui.show_broadcaster")
|
val UI_USE_TRACKED_BROADCASTS = stringPreferencesKey("ui.use_tracked_broadcasts")
|
||||||
val UI_BOTTOM_BAR_ITEMS = stringPreferencesKey("ui.bottom_bar_items")
|
val UI_BOTTOM_BAR_ITEMS = stringPreferencesKey("ui.bottom_bar_items")
|
||||||
|
|
||||||
suspend fun uiPreferences(context: Context): UiSettings? =
|
suspend fun uiPreferences(context: Context): UiSettings? =
|
||||||
@@ -114,6 +114,8 @@ class UiSharedPreferences(
|
|||||||
// Get the preference flow and take the first value.
|
// Get the preference flow and take the first value.
|
||||||
val preferences = context.sharedPreferencesDataStore.data.first()
|
val preferences = context.sharedPreferencesDataStore.data.first()
|
||||||
|
|
||||||
|
val featureSet = preferences[UI_FEATURE_SET]?.let { FeatureSetType.valueOf(it) } ?: FeatureSetType.SIMPLIFIED
|
||||||
|
|
||||||
UiSettings(
|
UiSettings(
|
||||||
theme = preferences[UI_THEME]?.let { ThemeType.valueOf(it) } ?: ThemeType.SYSTEM,
|
theme = preferences[UI_THEME]?.let { ThemeType.valueOf(it) } ?: ThemeType.SYSTEM,
|
||||||
preferredLanguage = preferences[UI_LANGUAGE]?.ifBlank { null },
|
preferredLanguage = preferences[UI_LANGUAGE]?.ifBlank { null },
|
||||||
@@ -125,10 +127,12 @@ class UiSharedPreferences(
|
|||||||
automaticallyShowProfilePictures = preferences[UI_SHOW_PROFILE_PICTURES]?.let { ConnectivityType.valueOf(it) } ?: ConnectivityType.ALWAYS,
|
automaticallyShowProfilePictures = preferences[UI_SHOW_PROFILE_PICTURES]?.let { ConnectivityType.valueOf(it) } ?: ConnectivityType.ALWAYS,
|
||||||
dontShowPushNotificationSelector = preferences[UI_DONT_SHOW_PUSH_NOTIFICATION_SELECTOR] ?: false,
|
dontShowPushNotificationSelector = preferences[UI_DONT_SHOW_PUSH_NOTIFICATION_SELECTOR] ?: false,
|
||||||
dontAskForNotificationPermissions = preferences[UI_DONT_ASK_FOR_NOTIFICATION_PERMISSIONS] ?: false,
|
dontAskForNotificationPermissions = preferences[UI_DONT_ASK_FOR_NOTIFICATION_PERMISSIONS] ?: false,
|
||||||
featureSet = preferences[UI_FEATURE_SET]?.let { FeatureSetType.valueOf(it) } ?: FeatureSetType.SIMPLIFIED,
|
featureSet = featureSet,
|
||||||
gallerySet = preferences[UI_GALLERY_SET]?.let { ProfileGalleryType.valueOf(it) } ?: ProfileGalleryType.CLASSIC,
|
gallerySet = preferences[UI_GALLERY_SET]?.let { ProfileGalleryType.valueOf(it) } ?: ProfileGalleryType.CLASSIC,
|
||||||
automaticallyProposeAiImprovements = preferences[UI_PROPOSE_AI_IMPROVEMENTS]?.let { BooleanType.valueOf(it) } ?: BooleanType.ALWAYS,
|
automaticallyProposeAiImprovements = preferences[UI_PROPOSE_AI_IMPROVEMENTS]?.let { BooleanType.valueOf(it) } ?: BooleanType.ALWAYS,
|
||||||
showBroadcaster = preferences[UI_SHOW_BROADCASTER]?.let { BooleanType.valueOf(it) } ?: BooleanType.ALWAYS,
|
useTrackedBroadcasts =
|
||||||
|
preferences[UI_USE_TRACKED_BROADCASTS]?.let { BooleanType.valueOf(it) }
|
||||||
|
?: if (featureSet == FeatureSetType.COMPLETE) BooleanType.ALWAYS else BooleanType.NEVER,
|
||||||
bottomBarItems = preferences[UI_BOTTOM_BAR_ITEMS]?.let { decodeBottomBarItems(it) } ?: DefaultBottomBarItems,
|
bottomBarItems = preferences[UI_BOTTOM_BAR_ITEMS]?.let { decodeBottomBarItems(it) } ?: DefaultBottomBarItems,
|
||||||
)
|
)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
@@ -167,7 +171,7 @@ class UiSharedPreferences(
|
|||||||
preferences[UI_FEATURE_SET] = sharedSettings.featureSet.name
|
preferences[UI_FEATURE_SET] = sharedSettings.featureSet.name
|
||||||
preferences[UI_GALLERY_SET] = sharedSettings.gallerySet.name
|
preferences[UI_GALLERY_SET] = sharedSettings.gallerySet.name
|
||||||
preferences[UI_PROPOSE_AI_IMPROVEMENTS] = sharedSettings.automaticallyProposeAiImprovements.name
|
preferences[UI_PROPOSE_AI_IMPROVEMENTS] = sharedSettings.automaticallyProposeAiImprovements.name
|
||||||
preferences[UI_SHOW_BROADCASTER] = sharedSettings.showBroadcaster.name
|
preferences[UI_USE_TRACKED_BROADCASTS] = sharedSettings.useTrackedBroadcasts.name
|
||||||
preferences[UI_BOTTOM_BAR_ITEMS] = sharedSettings.bottomBarItems.joinToString(",") { it.name }
|
preferences[UI_BOTTOM_BAR_ITEMS] = sharedSettings.bottomBarItems.joinToString(",") { it.name }
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
|||||||
+5
-2
@@ -37,6 +37,7 @@ import androidx.compose.ui.Alignment
|
|||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
|
import com.vitorpamplona.amethyst.model.BooleanType
|
||||||
import com.vitorpamplona.amethyst.service.broadcast.BroadcastEvent
|
import com.vitorpamplona.amethyst.service.broadcast.BroadcastEvent
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
||||||
@@ -49,12 +50,14 @@ import kotlinx.coroutines.delay
|
|||||||
* - CompletedBroadcastIndicator: Shows completed broadcast for tap-to-view (auto-dismisses after 10s)
|
* - CompletedBroadcastIndicator: Shows completed broadcast for tap-to-view (auto-dismisses after 10s)
|
||||||
* - BroadcastDetailsSheet: Shows detailed relay status on tap
|
* - BroadcastDetailsSheet: Shows detailed relay status on tap
|
||||||
*
|
*
|
||||||
* Visibility is controlled by the dedicated "Show Broadcaster" UI setting.
|
* Hidden when the "Tracked broadcasts" UI setting is off.
|
||||||
*/
|
*/
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun DisplayBroadcastProgress(accountViewModel: AccountViewModel) {
|
fun DisplayBroadcastProgress(accountViewModel: AccountViewModel) {
|
||||||
if (!accountViewModel.settings.showBroadcaster()) return
|
val useTrackedBroadcasts by accountViewModel.settings.uiSettingsFlow.useTrackedBroadcasts
|
||||||
|
.collectAsStateWithLifecycle()
|
||||||
|
if (useTrackedBroadcasts != BooleanType.ALWAYS) return
|
||||||
|
|
||||||
val activeBroadcasts by accountViewModel.broadcastTracker.activeBroadcasts.collectAsStateWithLifecycle()
|
val activeBroadcasts by accountViewModel.broadcastTracker.activeBroadcasts.collectAsStateWithLifecycle()
|
||||||
|
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ class UiSettingsState(
|
|||||||
|
|
||||||
fun isCompleteUIMode() = uiSettingsFlow.featureSet.value == FeatureSetType.COMPLETE
|
fun isCompleteUIMode() = uiSettingsFlow.featureSet.value == FeatureSetType.COMPLETE
|
||||||
|
|
||||||
fun showBroadcaster() = uiSettingsFlow.showBroadcaster.value == BooleanType.ALWAYS
|
fun useTrackedBroadcasts() = uiSettingsFlow.useTrackedBroadcasts.value == BooleanType.ALWAYS
|
||||||
|
|
||||||
fun isImmersiveScrollingActive() = uiSettingsFlow.automaticallyHideNavigationBars.value == BooleanType.ALWAYS
|
fun isImmersiveScrollingActive() = uiSettingsFlow.automaticallyHideNavigationBars.value == BooleanType.ALWAYS
|
||||||
|
|
||||||
|
|||||||
+66
-116
@@ -413,7 +413,7 @@ class AccountViewModel(
|
|||||||
if (currentReactions.isNotEmpty()) {
|
if (currentReactions.isNotEmpty()) {
|
||||||
account.delete(currentReactions)
|
account.delete(currentReactions)
|
||||||
} else {
|
} else {
|
||||||
if (settings.showBroadcaster() && note.event !is NIP17Group) {
|
if (settings.useTrackedBroadcasts() && note.event !is NIP17Group) {
|
||||||
// Tracked broadcasting with progress feedback
|
// Tracked broadcasting with progress feedback
|
||||||
account.createReactionEvent(note, reaction)?.let { (event, relays) ->
|
account.createReactionEvent(note, reaction)?.let { (event, relays) ->
|
||||||
broadcastTracker.trackBroadcast(
|
broadcastTracker.trackBroadcast(
|
||||||
@@ -841,24 +841,12 @@ class AccountViewModel(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun boost(note: Note) {
|
fun boost(note: Note) =
|
||||||
if (settings.showBroadcaster()) {
|
launchTrackedOrDirect(
|
||||||
// Tracked broadcasting with progress feedback
|
createTracked = { account.createBoostEvent(note) },
|
||||||
launchSigner {
|
consumeTracked = account::consumeBoostEvent,
|
||||||
account.createBoostEvent(note)?.let { (event, relays) ->
|
direct = { account.boost(note) },
|
||||||
broadcastTracker.trackBroadcast(
|
)
|
||||||
event = event,
|
|
||||||
relays = relays,
|
|
||||||
client = account.client,
|
|
||||||
)
|
|
||||||
account.consumeBoostEvent(event)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Fire-and-forget (original behavior)
|
|
||||||
launchSigner { account.boost(note) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun removeEmojiPack(emojiPack: Note) = launchSigner { account.removeEmojiPack(emojiPack) }
|
fun removeEmojiPack(emojiPack: Note) = launchSigner { account.removeEmojiPack(emojiPack) }
|
||||||
|
|
||||||
@@ -886,112 +874,51 @@ class AccountViewModel(
|
|||||||
|
|
||||||
fun pinnedNotes(user: User): Note = LocalCache.getOrCreateAddressableNote(PinListEvent.createPinAddress(user.pubkeyHex))
|
fun pinnedNotes(user: User): Note = LocalCache.getOrCreateAddressableNote(PinListEvent.createPinAddress(user.pubkeyHex))
|
||||||
|
|
||||||
fun addPin(note: Note) {
|
fun addPin(note: Note) =
|
||||||
if (settings.showBroadcaster()) {
|
launchTrackedOrDirect(
|
||||||
launchSigner {
|
createTracked = { account.createAddPinEvent(note) },
|
||||||
account.createAddPinEvent(note)?.let { (event, relays) ->
|
consumeTracked = account::consumePinEvent,
|
||||||
broadcastTracker.trackBroadcast(
|
direct = { account.addPin(note) },
|
||||||
event = event,
|
)
|
||||||
relays = relays,
|
|
||||||
client = account.client,
|
|
||||||
)
|
|
||||||
account.consumePinEvent(event)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
launchSigner { account.addPin(note) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun removePin(note: Note) {
|
fun removePin(note: Note) =
|
||||||
if (settings.showBroadcaster()) {
|
launchTrackedOrDirect(
|
||||||
launchSigner {
|
createTracked = { account.createRemovePinEvent(note) },
|
||||||
account.createRemovePinEvent(note)?.let { (event, relays) ->
|
consumeTracked = account::consumePinEvent,
|
||||||
broadcastTracker.trackBroadcast(
|
direct = { account.removePin(note) },
|
||||||
event = event,
|
)
|
||||||
relays = relays,
|
|
||||||
client = account.client,
|
|
||||||
)
|
|
||||||
account.consumePinEvent(event)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
launchSigner { account.removePin(note) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun removeDeletedPins(deletedNotes: Set<Note>) {
|
fun removeDeletedPins(deletedNotes: Set<Note>) {
|
||||||
launchSigner { account.removeDeletedPins(deletedNotes) }
|
launchSigner { account.removeDeletedPins(deletedNotes) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addPrivateBookmark(note: Note) {
|
fun addPrivateBookmark(note: Note) =
|
||||||
if (settings.showBroadcaster()) {
|
launchTrackedOrDirect(
|
||||||
launchSigner {
|
createTracked = { account.createAddBookmarkEvent(note, true) },
|
||||||
account.createAddBookmarkEvent(note, true)?.let { (event, relays) ->
|
consumeTracked = account::consumeBookmarkEvent,
|
||||||
broadcastTracker.trackBroadcast(
|
direct = { account.addBookmark(note, true) },
|
||||||
event = event,
|
)
|
||||||
relays = relays,
|
|
||||||
client = account.client,
|
|
||||||
)
|
|
||||||
account.consumeBookmarkEvent(event)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
launchSigner { account.addBookmark(note, true) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun addPublicBookmark(note: Note) {
|
fun addPublicBookmark(note: Note) =
|
||||||
if (settings.showBroadcaster()) {
|
launchTrackedOrDirect(
|
||||||
launchSigner {
|
createTracked = { account.createAddBookmarkEvent(note, false) },
|
||||||
account.createAddBookmarkEvent(note, false)?.let { (event, relays) ->
|
consumeTracked = account::consumeBookmarkEvent,
|
||||||
broadcastTracker.trackBroadcast(
|
direct = { account.addBookmark(note, false) },
|
||||||
event = event,
|
)
|
||||||
relays = relays,
|
|
||||||
client = account.client,
|
|
||||||
)
|
|
||||||
account.consumeBookmarkEvent(event)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
launchSigner { account.addBookmark(note, false) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun removePrivateBookmark(note: Note) {
|
fun removePrivateBookmark(note: Note) =
|
||||||
if (settings.showBroadcaster()) {
|
launchTrackedOrDirect(
|
||||||
launchSigner {
|
createTracked = { account.createRemoveBookmarkEvent(note, true) },
|
||||||
account.createRemoveBookmarkEvent(note, true)?.let { (event, relays) ->
|
consumeTracked = account::consumeBookmarkEvent,
|
||||||
broadcastTracker.trackBroadcast(
|
direct = { account.removeBookmark(note, true) },
|
||||||
event = event,
|
)
|
||||||
relays = relays,
|
|
||||||
client = account.client,
|
|
||||||
)
|
|
||||||
|
|
||||||
account.consumeBookmarkEvent(event)
|
fun removePublicBookmark(note: Note) =
|
||||||
}
|
launchTrackedOrDirect(
|
||||||
}
|
createTracked = { account.createRemoveBookmarkEvent(note, false) },
|
||||||
} else {
|
consumeTracked = account::consumeBookmarkEvent,
|
||||||
launchSigner { account.removeBookmark(note, true) }
|
direct = { account.removeBookmark(note, false) },
|
||||||
}
|
)
|
||||||
}
|
|
||||||
|
|
||||||
fun removePublicBookmark(note: Note) {
|
|
||||||
if (settings.showBroadcaster()) {
|
|
||||||
launchSigner {
|
|
||||||
account.createRemoveBookmarkEvent(note, false)?.let { (event, relays) ->
|
|
||||||
broadcastTracker.trackBroadcast(
|
|
||||||
event = event,
|
|
||||||
relays = relays,
|
|
||||||
client = account.client,
|
|
||||||
)
|
|
||||||
account.consumeBookmarkEvent(event)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
launchSigner { account.removeBookmark(note, false) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun removeDeletedBookmarks(
|
fun removeDeletedBookmarks(
|
||||||
deletedEventIds: Set<String>,
|
deletedEventIds: Set<String>,
|
||||||
@@ -1035,6 +962,29 @@ class AccountViewModel(
|
|||||||
account.decryptContent(note)?.let { onReady(it) }
|
account.decryptContent(note)?.let { onReady(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs an action that has both a tracked and a direct broadcast variant,
|
||||||
|
* picking the path the user selected via the "Tracked broadcasts" setting.
|
||||||
|
*/
|
||||||
|
inline fun launchTrackedOrDirect(
|
||||||
|
crossinline createTracked: suspend () -> Pair<Event, Set<NormalizedRelayUrl>>?,
|
||||||
|
crossinline consumeTracked: (Event) -> Unit,
|
||||||
|
crossinline direct: suspend () -> Unit,
|
||||||
|
) = launchSigner {
|
||||||
|
if (settings.useTrackedBroadcasts()) {
|
||||||
|
createTracked()?.let { (event, relays) ->
|
||||||
|
broadcastTracker.trackBroadcast(
|
||||||
|
event = event,
|
||||||
|
relays = relays,
|
||||||
|
client = account.client,
|
||||||
|
)
|
||||||
|
consumeTracked(event)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
direct()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
inline fun launchSigner(crossinline action: suspend () -> Unit) {
|
inline fun launchSigner(crossinline action: suspend () -> Unit) {
|
||||||
viewModelScope.launch(Dispatchers.IO) {
|
viewModelScope.launch(Dispatchers.IO) {
|
||||||
try {
|
try {
|
||||||
|
|||||||
+1
-1
@@ -326,7 +326,7 @@ class LongFormPostViewModel :
|
|||||||
val version = draftTag.current
|
val version = draftTag.current
|
||||||
cancel()
|
cancel()
|
||||||
|
|
||||||
if (accountViewModel.settings.showBroadcaster()) {
|
if (accountViewModel.settings.useTrackedBroadcasts()) {
|
||||||
val (event, relays, extras) = accountViewModel.account.createPostEvent(template, emptyList())
|
val (event, relays, extras) = accountViewModel.account.createPostEvent(template, emptyList())
|
||||||
accountViewModel.viewModelScope.launch(Dispatchers.IO) {
|
accountViewModel.viewModelScope.launch(Dispatchers.IO) {
|
||||||
accountViewModel.broadcastTracker.trackBroadcast(
|
accountViewModel.broadcastTracker.trackBroadcast(
|
||||||
|
|||||||
+1
-1
@@ -833,7 +833,7 @@ open class ShortNotePostViewModel :
|
|||||||
|
|
||||||
if (anonymous) {
|
if (anonymous) {
|
||||||
accountViewModel.account.signAnonymouslyAndBroadcast(template, extraNotesToBroadcast)
|
accountViewModel.account.signAnonymouslyAndBroadcast(template, extraNotesToBroadcast)
|
||||||
} else if (accountViewModel.settings.showBroadcaster()) {
|
} else if (accountViewModel.settings.useTrackedBroadcasts()) {
|
||||||
// Tracked broadcasting with progress feedback (non-blocking)
|
// Tracked broadcasting with progress feedback (non-blocking)
|
||||||
val (event, relays, extras) = accountViewModel.account.createPostEvent(template, extraNotesToBroadcast)
|
val (event, relays, extras) = accountViewModel.account.createPostEvent(template, extraNotesToBroadcast)
|
||||||
|
|
||||||
|
|||||||
+10
-9
@@ -54,6 +54,7 @@ import androidx.compose.ui.unit.dp
|
|||||||
import androidx.core.os.LocaleListCompat
|
import androidx.core.os.LocaleListCompat
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import com.vitorpamplona.amethyst.R
|
import com.vitorpamplona.amethyst.R
|
||||||
|
import com.vitorpamplona.amethyst.model.BooleanType
|
||||||
import com.vitorpamplona.amethyst.model.ConnectivityType
|
import com.vitorpamplona.amethyst.model.ConnectivityType
|
||||||
import com.vitorpamplona.amethyst.model.FeatureSetType
|
import com.vitorpamplona.amethyst.model.FeatureSetType
|
||||||
import com.vitorpamplona.amethyst.model.ProfileGalleryType
|
import com.vitorpamplona.amethyst.model.ProfileGalleryType
|
||||||
@@ -133,7 +134,7 @@ fun SettingsScreen(
|
|||||||
FeatureSetChoice(sharedPrefs)
|
FeatureSetChoice(sharedPrefs)
|
||||||
GalleryChoice(sharedPrefs)
|
GalleryChoice(sharedPrefs)
|
||||||
AiWritingHelpChoice(sharedPrefs)
|
AiWritingHelpChoice(sharedPrefs)
|
||||||
ShowBroadcasterChoice(sharedPrefs)
|
TrackedBroadcastsChoice(sharedPrefs)
|
||||||
PushNotificationSettingsRow(sharedPrefs)
|
PushNotificationSettingsRow(sharedPrefs)
|
||||||
if (accountViewModel != null) {
|
if (accountViewModel != null) {
|
||||||
AlwaysOnNotificationServiceChoice(accountViewModel)
|
AlwaysOnNotificationServiceChoice(accountViewModel)
|
||||||
@@ -423,22 +424,22 @@ fun AiWritingHelpChoice(sharedPrefs: UiSettingsFlow) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ShowBroadcasterChoice(sharedPrefs: UiSettingsFlow) {
|
fun TrackedBroadcastsChoice(sharedPrefs: UiSettingsFlow) {
|
||||||
val showBroadcasterIndex by sharedPrefs.showBroadcaster.collectAsState()
|
val useTrackedBroadcastsIndex by sharedPrefs.useTrackedBroadcasts.collectAsState()
|
||||||
|
|
||||||
val booleanItems =
|
val booleanItems =
|
||||||
persistentListOf(
|
persistentListOf(
|
||||||
TitleExplainer(stringRes(ConnectivityType.ALWAYS.resourceId)),
|
TitleExplainer(stringRes(BooleanType.ALWAYS.reourceId)),
|
||||||
TitleExplainer(stringRes(ConnectivityType.NEVER.resourceId)),
|
TitleExplainer(stringRes(BooleanType.NEVER.reourceId)),
|
||||||
)
|
)
|
||||||
|
|
||||||
SettingsRow(
|
SettingsRow(
|
||||||
R.string.show_broadcaster_setting_title,
|
R.string.tracked_broadcasts_setting_title,
|
||||||
R.string.show_broadcaster_setting_description,
|
R.string.tracked_broadcasts_setting_description,
|
||||||
booleanItems,
|
booleanItems,
|
||||||
showBroadcasterIndex.screenCode,
|
useTrackedBroadcastsIndex.screenCode,
|
||||||
) {
|
) {
|
||||||
sharedPrefs.showBroadcaster.tryEmit(parseBooleanType(it))
|
sharedPrefs.useTrackedBroadcasts.tryEmit(parseBooleanType(it))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2469,8 +2469,8 @@
|
|||||||
<string name="ai_writing_help">AI Writing Help</string>
|
<string name="ai_writing_help">AI Writing Help</string>
|
||||||
<string name="ai_writing_setting_title">Propose text improvements</string>
|
<string name="ai_writing_setting_title">Propose text improvements</string>
|
||||||
<string name="ai_writing_setting_description">Uses an on-device AI model to propose text corrections and tone changes.</string>
|
<string name="ai_writing_setting_description">Uses an on-device AI model to propose text corrections and tone changes.</string>
|
||||||
<string name="show_broadcaster_setting_title">Show broadcast tracker</string>
|
<string name="tracked_broadcasts_setting_title">Tracked broadcasts</string>
|
||||||
<string name="show_broadcaster_setting_description">Show progress and per-relay status while events are being broadcast.</string>
|
<string name="tracked_broadcasts_setting_description">Use the tracked broadcaster when sending events. Shows live progress and per-relay status while broadcasting.</string>
|
||||||
<string name="ai_writing_use_this">Use This</string>
|
<string name="ai_writing_use_this">Use This</string>
|
||||||
<string name="ai_writing_dismiss">Dismiss</string>
|
<string name="ai_writing_dismiss">Dismiss</string>
|
||||||
<string name="ai_tone_correct">Correct</string>
|
<string name="ai_tone_correct">Correct</string>
|
||||||
|
|||||||
Reference in New Issue
Block a user