fix(sync): handle syncronization of user status

This fixes a bug where the new user status set by the logged in user
would not be broadcast because the corresponding setting would prevent
status-go from doing so.

The fix is done by always enabling broadcasting the user status, then
disabling it again right after setting, in case it was set to "offline".

This commit also ensures that, when current user status updates are
broadcast, the updates are handled across paired devices in real-time.

Partially addresses #5201
This commit is contained in:
Pascal Precht 2022-06-14 13:27:23 +02:00 committed by r4bbit.eth
parent 9a926e110c
commit 56f7c52e81
4 changed files with 44 additions and 8 deletions

View File

@ -114,7 +114,7 @@ proc newAppController*(statusFoundation: StatusFoundation): AppController =
result.statusFoundation = statusFoundation result.statusFoundation = statusFoundation
# Preparing settings service to be exposed later as global QObject # Preparing settings service to be exposed later as global QObject
result.settingsService = settings_service.newService() result.settingsService = settings_service.newService(statusFoundation.events)
result.appSettingsVariant = newQVariant(result.settingsService) result.appSettingsVariant = newQVariant(result.settingsService)
result.notificationsManager = newNotificationsManager(statusFoundation.events, result.settingsService) result.notificationsManager = newNotificationsManager(statusFoundation.events, result.settingsService)

View File

@ -22,6 +22,7 @@ type MessageSignal* = ref object of Signal
activityCenterNotifications*: seq[ActivityCenterNotificationDto] activityCenterNotifications*: seq[ActivityCenterNotificationDto]
statusUpdates*: seq[StatusUpdateDto] statusUpdates*: seq[StatusUpdateDto]
deletedMessages*: seq[RemovedMessageDto] deletedMessages*: seq[RemovedMessageDto]
currentStatus*: seq[StatusUpdateDto]
proc fromEvent*(T: type MessageSignal, event: JsonNode): MessageSignal = proc fromEvent*(T: type MessageSignal, event: JsonNode): MessageSignal =
var signal:MessageSignal = MessageSignal() var signal:MessageSignal = MessageSignal()
@ -47,6 +48,10 @@ proc fromEvent*(T: type MessageSignal, event: JsonNode): MessageSignal =
var statusUpdate = jsonStatusUpdate.toStatusUpdateDto() var statusUpdate = jsonStatusUpdate.toStatusUpdateDto()
signal.statusUpdates.add(statusUpdate) signal.statusUpdates.add(statusUpdate)
if event["event"]{"currentStatus"} != nil:
var currentStatus = event["event"]["currentStatus"].toStatusUpdateDto()
signal.currentStatus.add(currentStatus)
if event["event"]{"installations"} != nil: if event["event"]{"installations"} != nil:
for jsonDevice in event["event"]["installations"]: for jsonDevice in event["event"]["installations"]:
signal.devices.add(jsonDevice.toDeviceDto()) signal.devices.add(jsonDevice.toDeviceDto())

View File

@ -203,6 +203,13 @@ proc init*(self: Controller) =
self.events.on(SIGNAL_NETWORK_DISCONNECTED) do(e: Args): self.events.on(SIGNAL_NETWORK_DISCONNECTED) do(e: Args):
self.delegate.onNetworkDisconnected() self.delegate.onNetworkDisconnected()
self.events.on(SIGNAL_CURRENT_USER_STATUS_UPDATED) do (e: Args):
var args = CurrentUserStatusArgs(e)
var status = true
if args.statusType == StatusType.Invisible:
status = false
singletonInstance.userProfile.setUserStatus(status)
proc isConnected*(self: Controller): bool = proc isConnected*(self: Controller): bool =
return self.nodeService.isConnected() return self.nodeService.isConnected()

View File

@ -1,14 +1,15 @@
import NimQml, chronicles, json, strutils, sequtils, tables, sugar import NimQml, chronicles, json, strutils, sequtils, tables, sugar
import ../../common/[network_constants] import ../../common/[network_constants]
import ../../../app/core/eventemitter
import ../../../app/core/fleets/fleet_configuration import ../../../app/core/fleets/fleet_configuration
import ../../../app/core/signals/types
import ../../../backend/settings as status_settings import ../../../backend/settings as status_settings
import ../../../backend/status_update as status_update import ../../../backend/status_update as status_update
import ./dto/settings as settings_dto import ./dto/settings as settings_dto
import ../contacts/dto/status_update as status_update_dto import ../contacts/dto/status_update as status_update_dto
import ../stickers/dto/stickers as stickers_dto import ../stickers/dto/stickers as stickers_dto
import ../../../app/core/fleets/fleet_configuration
export settings_dto export settings_dto
export stickers_dto export stickers_dto
@ -19,18 +20,27 @@ const DEFAULT_CURRENCY* = "usd"
const DEFAULT_TELEMETRY_SERVER_URL* = "https://telemetry.status.im" const DEFAULT_TELEMETRY_SERVER_URL* = "https://telemetry.status.im"
const DEFAULT_FLEET* = $Fleet.Prod const DEFAULT_FLEET* = $Fleet.Prod
const SIGNAL_CURRENT_USER_STATUS_UPDATED* = "currentUserStatusUpdated"
logScope: logScope:
topics = "settings-service" topics = "settings-service"
type
CurrentUserStatusArgs* = ref object of Args
statusType*: StatusType
text*: string
QtObject: QtObject:
type Service* = ref object of QObject type Service* = ref object of QObject
events: EventEmitter
settings: SettingsDto settings: SettingsDto
proc delete*(self: Service) = proc delete*(self: Service) =
self.QObject.delete self.QObject.delete
proc newService*(): Service = proc newService*(events: EventEmitter): Service =
new(result, delete) new(result, delete)
result.events = events
result.QObject.setup result.QObject.setup
proc init*(self: Service) = proc init*(self: Service) =
@ -41,6 +51,13 @@ QtObject:
let errDesription = e.msg let errDesription = e.msg
error "error: ", errDesription error "error: ", errDesription
self.events.on(SignalType.Message.event) do(e: Args):
var receivedData = MessageSignal(e)
if receivedData.currentStatus.len > 0:
var statusUpdate = receivedData.currentStatus[0]
self.events.emit(SIGNAL_CURRENT_USER_STATUS_UPDATED, CurrentUserStatusArgs(statusType: statusUpdate.statusType, text: statusUpdate.text))
proc saveSetting(self: Service, attribute: string, value: string | JsonNode | bool | int): bool = proc saveSetting(self: Service, attribute: string, value: string | JsonNode | bool | int): bool =
try: try:
let response = status_settings.saveSettings(attribute, value) let response = status_settings.saveSettings(attribute, value)
@ -312,9 +329,16 @@ QtObject:
proc saveSendStatusUpdates*(self: Service, value: bool): bool = proc saveSendStatusUpdates*(self: Service, value: bool): bool =
var newStatus = StatusType.Online var newStatus = StatusType.Online
if not value: if not value:
newStatus = StatusType.Offline # This looks unintuitive, but `StatusType.Offline` is interpreted
# as `StatusUpdate.UNKNOWN_STATUS_TYPE` in status-go, which causes an error.
# Hence `Invisible` (= 4 [which is `INACTIVE` in status-go]) is considerd offline.
newStatus = StatusType.Invisible
try: try:
# The new user status needs to always be broadcast, so we need to update
# the settings accordingly and might turn it off afterwards (if user has
# set status to "offline"
if (self.saveSetting(KEY_SEND_STATUS_UPDATES, true)):
let r = status_update.setUserStatus(int(newStatus)) let r = status_update.setUserStatus(int(newStatus))
if(self.saveSetting(KEY_SEND_STATUS_UPDATES, value)): if(self.saveSetting(KEY_SEND_STATUS_UPDATES, value)):
self.settings.sendStatusUpdates = value self.settings.sendStatusUpdates = value