Files
status-app/src/app/modules/main/io_interface.nim
T
Alex Jbanca 4483d7eb2d fix(ios): pause/resume services with the app lifecycle and re-point media URLs on rebind (#21687)
* fix(media): re-point cached media URLs when the media server restarts (#47)

iOS suspends the app and kills status-go's local media server; on resume
it rebinds on a NEW ephemeral port and emits mediaserver.started, which
the Nim side never handled — every cached https://localhost:<oldport>/
image URL (chat images, avatars, stickers, link previews, community
icons) went permanently stale.

Key decisions:
- New MediaServerStartedSignal decoded in signals_manager (the enum
  member already existed, so the cheap-triage scan needs no change);
  null-event envelopes decode to port 0 and every rewrite helper treats
  port <= 0 as a no-op.
- One shared helper, withMediaServerPort (app_service/common/
  media_server_url.nim): rewrites the port ONLY for http(s)://
  localhost|127.0.0.1|0.0.0.0:<port> URLs, splicing around the authority
  so path/query stay byte-identical; everything else (remote URLs, data
  URIs, qrc/file paths, port-less URLs) passes through untouched, so
  callers apply it blindly. Desktop stays a no-op: the signal never
  fires there, and an unchanged port rewrites nothing.
- Subscribers rewrite in place + notify: message models (chat + pinned)
  re-emit image-carrying roles via dataChanged; link-preview thumbnails
  are QObjects and emit urlChanged directly; section model refreshes
  community image/banner/icon; contacts service rewrites its
  ContactDetails cache and re-emits SIGNAL_CONTACT_UPDATED per changed
  contact, plus the user-profile singleton's own avatar (its setters
  already no-op on equal values).
- Dropped the contacts service's imageServerUrl field: it was write-only
  dead code (fetched once, never read).

Files: src/app/core/signals/{signals_manager,types}.nim,
src/app/core/signals/remote_signals/mediaserver.nim (new),
src/app_service/common/media_server_url.nim (new),
src/app_service/service/contacts/service.nim,
src/app_service/service/message/dto/{link_preview,link_preview_thumbnail}.nim,
src/app/modules/shared_models/{message_item,message_model,link_preview_model,section_model}.nim,
chat_section chat_content + messages + main module/controller/io_interface
wiring, test/nim/{media_server_url_test (new),message_model_test,
signals_manager_test}.nim

Verified: media_server_url_test 9/9 OK, signals_manager_test 6/6 OK
(incl. 2 new mediaserver.started tests) via make nim-test-run USE_SYSTEM_NIM=1.
message_model_test does NOT link in this arm64 container — pre-existing
nimqml/LTO link failure, reproduced identically on clean HEAD with a
fresh nimcache; the 3 new model tests compile but need CI/another host
to run. Device repro (background 10+ min, resume, images reload) remains
for the human pass.

* fix(build): normalize two 'import Nimqml' casings to the module's real name

discord_message_item and message_transaction_parameters_item imported
Nimqml (capital N) while the vendored module file is nimqml.nim. On a
case-insensitive checkout (Docker-on-Mac bind mount) Nim treats the two
spellings as distinct modules whose nimcache artifacts collide on one
file, so any test pulling in these items (e.g. message_model_test) fails
to link with undefined nimqml symbols. Found while verifying #47.

* refactor(media): deduplicate the media-URL refresh template and drop dead code

Review follow-up to ca5e5c92c, no behavior change:
- Extract the thrice-duplicated compare-rewrite-flag template into
  refreshMediaServerUrl in media_server_url.nim; message_item,
  section_model and contacts/service now share one definition.
- Drop the why-comment copy-pasted verbatim into three controllers;
  the explanation lives on MediaServerStartedSignal and the helper module.
- Remove backend getImageServerURL, dead since its only caller
  (setImageServerUrl) was deleted on this branch.
- Whitespace: trailing newline in signals/types.nim, blank line before
  the appended suite in message_model_test.nim.

Verified: media_server_url_test, message_model_test and
signals_manager_test all pass (nim-test-run recipe); app wiring
compile-checked via app/modules/main/module + contacts service +
section_model with --compileOnly.

* fix(ios): drive PauseServices/ResumeServices from the app lifecycle (#51)

On iOS status-go runs in-process and nothing drove the pausable-services
lifecycle: services never paused on backgrounding (battery cost) and never
resumed on foregrounding, so the media server's listening socket iOS kills
during suspension stayed dead and every cached localhost media URL failed
until app restart (device-confirmed: post-resume image loads get Connection
refused while in-process RPC still works). Resuming now re-runs the full
recovery chain: ResumeServices -> ServiceRegistry -> mediaserver
ToForeground() rebind -> mediaserver.started -> #47/#49's URL refresh.

Key decisions:
- Lifecycle source is StatusQ's UrlSchemeEvent applicationStateChanged
  watcher (already the iOS foreground seam): new appBackgrounded signal
  emitted ONLY on Qt::ApplicationSuspended — Inactive dips from share
  sheets/system alerts never pause; appForegrounded fires on every return
  to Active, so ServicesPauseBridge latches (`paused`) and resumes only
  when it actually paused. Connections are synchronous (AutoConnection,
  same thread): iOS freezes the process right after the state change, a
  queued pause slot might never run.
- Bridge wired only under `when defined(ios)`: Android's service process
  already drives pause/resume from binder visibility (UI process must not
  double-drive), desktop is never suspended.
- Same contract as StatusGoService.java: fetch the service list from
  PausableServices() at each transition (late-registered services picked
  up; empty list — node not running, e.g. login screen — drives nothing),
  then PauseServices/ResumeServices with the JSON name array. The three
  libstatus C exports are bound in new backend/pausable_services.nim
  (vendor/nim-status-go doesn't cover them); errors logged, not fatal.
- Backend calls injected into the bridge as a seam
  (PausableServicesCalls), so the Nim test drives the real StatusQ
  signal emitters against recorders.

Files: src/app/core/services_pause_bridge.nim (new),
src/backend/pausable_services.nim (new), src/nim_status_client.nim,
src/statusq_bridge.nim, ui/StatusQ/{include/StatusQ/urlschemeevent.h,
src/{urlschemeevent,externc}.cpp}, Makefile (test target),
test/nim/services_pause_bridge_test.nim (new)

Verified: services_pause_bridge_test 15/15 OK; full tests-nim-linux 464
OK / 0 failed (chat_section_model_test fails to compile identically on
the clean base — pre-existing, unrelated); nim_status_client Linux path
compile-checked (--compileOnly, exit 0); StatusQ recompiles clean;
libstatus.so exports PausableServices/PauseServices/ResumeServices
(linked by the test). Device criteria (iPhone: photo -> background 10+
min -> resume -> images recover; Android S21: exactly one service-driven
pause/resume, no duplicates) remain for the human pass — iOS paths can't
run in this container.

* fix(tests): reset the fetch counter per case in services_pause_bridge

unittest setup vars are module-scope globals; the int's constant
initializer runs once, so fetches leaked across cases and the two
absolute-count assertions saw the running total.

* fix: Potential fix for pull request finding

* fix(statusq): handle the full application-state enum in watchApplicationState

Inactive is an expected transient dip and stays a no-op; anything else
unhandled now logs a qWarning.

* fix(tests): empty pausable set no longer latches paused, so foregrounding skips the fetch
2026-08-05 14:18:26 +03:00

473 lines
23 KiB
Nim

import nimqml, stint, json
import app_service/service/settings/service as settings_service
import app_service/service/node_configuration/service as node_configuration_service
import app_service/service/contacts/service as contacts_service
import app_service/service/chat/service as chat_service
import app_service/service/community/service as community_service
import app_service/service/message/service as message_service
import app_service/service/mailservers/service as mailservers_service
import app_service/service/community_tokens/service as community_token_service
import app_service/service/wallet_account/service as wallet_account_service
import app_service/service/token/service as token_service
import app_service/service/community_tokens/service as community_tokens_service
import app_service/service/community_tokens/community_collectible_owner
import app_service/service/shared_urls/service as urls_service
import app_service/service/network/service as network_service
import app_service/service/network/network_item
from app_service/common/types import StatusType, ContractTransactionStatus, MembershipRequestState, RequestToJoinState
import app/global/app_signals
import app/core/eventemitter
import app/core/notifications/details
import app/modules/shared_models/section_item
type
AccessInterface* {.pure inheritable.} = ref object of RootObj
method delete*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method load*(
self: AccessInterface,
events: EventEmitter,
settingsService: settings_service.Service,
nodeConfigurationService: node_configuration_service.Service,
contactsService: contacts_service.Service,
chatService: chat_service.Service,
communityService: community_service.Service,
messageService: message_service.Service,
mailserversService: mailservers_service.Service)
{.base.} =
raise newException(ValueError, "No implementation available")
method getAppNetwork*(self: AccessInterface): NetworkItem {.base.} =
raise newException(ValueError, "No implementation available")
method onAppNetworkChanged*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method calculateProfileSectionHasNotification*(self: AccessInterface): bool {.base.} =
raise newException(ValueError, "No implementation available")
method appSearchDidLoad*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method stickersDidLoad*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method gifsDidLoad*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method activityCenterDidLoad*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method profileSectionDidLoad*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method walletSectionDidLoad*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method browserSectionDidLoad*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method networkConnectionModuleDidLoad*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method chatSectionDidLoad*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method communitySectionDidLoad*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method onChatsLoaded*(
self: AccessInterface,
events: EventEmitter,
settingsService: settings_service.Service,
nodeConfigurationService: node_configuration_service.Service,
contactsService: contacts_service.Service,
chatService: chat_service.Service,
communityService: community_service.Service,
messageService: message_service.Service,
mailserversService: mailservers_service.Service,
walletAccountService: wallet_account_service.Service,
tokenService: token_service.Service,
communityTokensService: community_tokens_service.Service,
sharedUrlsService: urls_service.Service,
networkService: network_service.Service,
) {.base.} =
raise newException(ValueError, "No implementation available")
method onMediaServerStarted*(self: AccessInterface, port: int) {.base.} =
raise newException(ValueError, "No implementation available")
method onCommunityDataLoaded*(
self: AccessInterface,
events: EventEmitter,
settingsService: settings_service.Service,
nodeConfigurationService: node_configuration_service.Service,
contactsService: contacts_service.Service,
chatService: chat_service.Service,
communityService: community_service.Service,
messageService: message_service.Service,
mailserversService: mailservers_service.Service,
walletAccountService: wallet_account_service.Service,
tokenService: token_service.Service,
communityTokensService: community_tokens_service.Service,
sharedUrlsService: urls_service.Service,
networkService: network_service.Service,
){.base.} =
raise newException(ValueError, "No implementation available")
method onContactsLoaded*(
self: AccessInterface,
events: EventEmitter,
settingsService: settings_service.Service,
nodeConfigurationService: node_configuration_service.Service,
contactsService: contacts_service.Service,
chatService: chat_service.Service,
communityService: community_service.Service,
messageService: message_service.Service,
mailserversService: mailservers_service.Service,
walletAccountService: wallet_account_service.Service,
tokenService: token_service.Service,
communityTokensService: community_tokens_service.Service,
sharedUrlsService: urls_service.Service,
networkService: network_service.Service,
){.base.} =
raise newException(ValueError, "No implementation available")
method onActiveChatChange*(self: AccessInterface, sectionId: string, chatId: string) {.base.} =
raise newException(ValueError, "No implementation available")
method onActivityNotificationsUpdated*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method onNotificationsUpdated*(self: AccessInterface, sectionId: string, sectionHasUnreadMessages: bool,
sectionNotificationCount: int) {.base.} =
raise newException(ValueError, "No implementation available")
method onNotificationsIncreased*(self: AccessInterface, sectionId: string, addedSectionNotificationCount: bool,
sectionNotificationCount: int) {.base.} =
raise newException(ValueError, "No implementation available")
method getActiveSectionId*(self: AccessInterface): string {.base.} =
raise newException(ValueError, "No implementation available")
method communitiesModuleDidLoad*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method emitMailserverWorking*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method emitMailserverNotWorking*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method emitMessagingNetworkConnected*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method emitMessagingNetworkDisconnected*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method isMessagingNetworkConnected*(self: AccessInterface): bool {.base.} =
raise newException(ValueError, "No implementation available")
method activeSectionSet*(self: AccessInterface, sectionId: string, skipSavingInSettings: bool = false) {.base.} =
raise newException(ValueError, "No implementation available")
method toggleSection*(self: AccessInterface, sectionType: SectionType) {.base.} =
raise newException(ValueError, "No implementation available")
method communitySpectated*(self: AccessInterface, communityId: string) {.base.} =
raise newException(ValueError, "No implementation available")
method communityJoined*(self: AccessInterface, community: CommunityDto, events: EventEmitter,
settingsService: settings_service.Service,
nodeConfigurationService: node_configuration_service.Service,
contactsService: contacts_service.Service,
chatService: chat_service.Service,
communityService: community_service.Service,
messageService: message_service.Service,
mailserversService: mailservers_service.Service,
walletAccountService: wallet_account_service.Service,
tokenService: token_service.Service,
communityTokensService: community_tokens_service.Service,
sharedUrlsService: urls_service.Service,
networkService: network_service.Service,
setActive: bool = false,
) {.base.} =
raise newException(ValueError, "No implementation available")
method communityEdited*(self: AccessInterface, community: CommunityDto) {.base.} =
raise newException(ValueError, "No implementation available")
method onCommunityMuted*(self: AccessInterface, communityId: string, muted: bool) {.base.} =
raise newException(ValueError, "No implementation available")
method communityLeft*(self: AccessInterface, communityId: string) {.base.} =
raise newException(ValueError, "No implementation available")
method resolvedENS*(self: AccessInterface, publicKey: string, address: string, uuid: string, reason: string) {.base.} =
raise newException(ValueError, "No implementation available")
method osNotificationClicked*(self: AccessInterface, details: NotificationDetails) {.base.} =
raise newException(ValueError, "No implementation available")
method displayWindowsOsNotification*(self: AccessInterface, title: string, message: string) {.base.} =
raise newException(ValueError, "No implementation available")
method displayEphemeralNotification*(self: AccessInterface, title: string, subTitle: string, details: NotificationDetails)
{.base.} =
raise newException(ValueError, "No implementation available")
method displayEphemeralNotification*(
self: AccessInterface,
title: string,
subTitle: string,
image: string,
icon: string,
iconColor: string,
loading: bool,
ephNotifType: int,
actionType: int,
actionData: string,
url: string,
details = NotificationDetails(),
) {.base.} =
raise newException(ValueError, "No implementation available")
method removeEphemeralNotification*(self: AccessInterface, id: int64) {.base.} =
raise newException(ValueError, "No implementation available")
method ephemeralNotificationClicked*(self: AccessInterface, id: int64) {.base.} =
raise newException(ValueError, "No implementation available")
method newCommunityMembershipRequestReceived*(self: AccessInterface, membershipRequest: CommunityMembershipRequestDto)
{.base.} =
raise newException(ValueError, "No implementation available")
method communityMembershipRequestCanceled*(self: AccessInterface, communityId: string, requestId: string, pubKey: string) {.base.} =
raise newException(ValueError, "No implementation available")
method onPlayNotificationSound*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method viewDidLoad*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method setActiveSection*(self: AccessInterface, item: SectionItem, skipSavingInSettings: bool = false) {.base.} =
raise newException(ValueError, "No implementation available")
method setActiveSectionById*(self: AccessInterface, id: string) {.base.} =
raise newException(ValueError, "No implementation available")
method onChatLeft*(self: AccessInterface, chatId: string) {.base.} =
raise newException(ValueError, "No implementation available")
method setCurrentUserStatus*(self: AccessInterface, status: StatusType) {.base.} =
raise newException(ValueError, "No implementation available")
method getChatSectionModuleAsVariant*(self: AccessInterface): QVariant {.base.} =
raise newException(ValueError, "No implementation available")
method getCommunitySectionModule*(self: AccessInterface, communityId: string): QVariant {.base.} =
raise newException(ValueError, "No implementation available")
method getAppSearchModule*(self: AccessInterface): QVariant {.base.} =
raise newException(ValueError, "No implementation available")
method getOwnerTokenAsJson*(self: AccessInterface, communityId: string): string {.base.} =
raise newException(ValueError, "No implementation available")
method isEnsVerified*(self: AccessInterface, publicKey: string): bool {.base.} =
raise newException(ValueError, "No implementation available")
method communityDataImported*(self: AccessInterface, community: CommunityDto) {.base.} =
raise newException(ValueError, "No implementation available")
method communityInfoRequestFailed*(self: AccessInterface, communityId: string, errorMsg: string) {.base.} =
raise newException(ValueError, "No implementation available")
method resolveENS*(self: AccessInterface, ensName: string, uuid: string, reason: string = "") {.base.} =
raise newException(ValueError, "No implementation available")
method switchTo*(self: AccessInterface, sectionId, chatId: string) {.base.} =
raise newException(ValueError, "No implementation available")
method isConnected*(self: AccessInterface): bool {.base.} =
raise newException(ValueError, "No implementation available")
method onStatusUrlRequested*(self: AccessInterface, action: StatusUrlAction, communityId: string, chatId: string,
url: string, userId: string) {.base.} =
raise newException(ValueError, "No implementation available")
method prepareAuthenticationModule*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method destroyAuthenticationModule*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method getAuthenticationModule*(self: AccessInterface): QVariant {.base.} =
raise newException(ValueError, "No implementation available")
method prepareSigningModule*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method destroySigningModule*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method getSigningModule*(self: AccessInterface): QVariant {.base.} =
raise newException(ValueError, "No implementation available")
method prepareKeycardManagementModule*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method destroyKeycardManagementModule*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method getKeycardManagementModule*(self: AccessInterface): QVariant {.base.} =
raise newException(ValueError, "No implementation available")
method checkAndPerformProfileMigrationIfNeeded*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method onProfileMigrationFlowOpened*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method onProfileMigrationFlowClosed*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method onMyRequestAdded*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method activateStatusDeepLink*(self: AccessInterface, statusDeepLink: string) {.base.} =
raise newException(ValueError, "No implementation available")
method setCommunityIdToSpectate*(self: AccessInterface, commnityId: string, channelUuid: string = "") {.base.} =
raise newException(ValueError, "No implementation available")
method onCommunityTokenDeploymentStored*(self: AccessInterface, communityToken: CommunityTokenDto, error: string) {.base.} =
raise newException(ValueError, "No implementation available")
method onOwnerTokensDeploymentStored*(self: AccessInterface, ownerToken: CommunityTokenDto, masterToken: CommunityTokenDto, error: string) {.base.} =
raise newException(ValueError, "No implementation available")
method onCommunityTokenOwnersFetched*(self: AccessInterface, communityId: string, chainId: int, contractAddress: string, owners: seq[CommunityCollectibleOwner]) {.base.} =
raise newException(ValueError, "No implementation available")
method errorLoadingTokenHolders*(self: AccessInterface, communityId: string, chainId: int, contractAddress: string, error: string) {.base.} =
raise newException(ValueError, "No implementation available")
method onCommunityTokenDeployStateChanged*(self: AccessInterface, communityId: string, chainId: int, contractAddress: string, deployState: DeployState) {.base.} =
raise newException(ValueError, "No implementation available")
method onOwnerTokenDeployStateChanged*(self: AccessInterface, communityId: string, chainId: int, ownerContractAddress: string, masterContractAddress: string, deployState: DeployState, transactionHash: string) {.base.} =
raise newException(ValueError, "No implementation available")
method onCommunityTokenSupplyChanged*(self: AccessInterface, communityId: string, chainId: int, contractAddress: string, supply: Uint256, remainingSupply: Uint256, destructedAmount: Uint256) {.base.} =
raise newException(ValueError, "No implementation available")
method onCommunityTokenRemoved*(self: AccessInterface, communityId: string, chainId: int, contractAddress: string) {.base.} =
raise newException(ValueError, "No implementation available")
method onBurnStateChanged*(self: AccessInterface, communityId: string, chainId: int, contractAddress: string, burnState: ContractTransactionStatus) {.base.} =
raise newException(ValueError, "No implementation available")
method onFinaliseOwnershipStatusChanged*(self: AccessInterface, isPending: bool, communityId: string) {.base.} =
raise newException(ValueError, "No implementation available")
method onRemoteDestructed*(self: AccessInterface, communityId: string, chainId: int, contractAddress: string, addresses: seq[string]) {.base.} =
raise newException(ValueError, "No implementation available")
method onRequestReevaluateMembersPermissionsIfRequired*(self: AccessInterface, communityId: string, chainId: int, contractAddress: string) {.base.} =
raise newException(ValueError, "No implementation available")
method onAcceptRequestToJoinFailed*(self: AccessInterface, communityId: string, memberKey: string, requestId: string) {.base.} =
raise newException(ValueError, "No implementation available")
method onDeclineRequestToJoinFailed*(self: AccessInterface, communityId: string, memberKey: string, requestId: string) {.base.} =
raise newException(ValueError, "No implementation available")
method onAcceptRequestToJoinFailedNoPermission*(self: AccessInterface, communityId: string, memberKey: string, requestId: string) {.base.} =
raise newException(ValueError, "No implementation available")
method onAcceptRequestToJoinLoading*(self: AccessInterface, communityId: string, memberKey: string) {.base.} =
raise newException(ValueError, "No implementation available")
method onDeclineRequestToJoinLoading*(self: AccessInterface, communityId: string, memberKey: string) {.base.} =
raise newException(ValueError, "No implementation available")
method onAcceptRequestToJoinSuccess*(self: AccessInterface, communityId: string, memberKey: string, requestId: string) {.base.} =
raise newException(ValueError, "No implementation available")
method onDeclineRequestToJoinSuccess*(self: AccessInterface, communityId: string, memberKey: string, requestId: string) {.base.} =
raise newException(ValueError, "No implementation available")
method onMembershipStateUpdated*(self: AccessInterface, communityId: string, memberPubkey: string, state: MembershipRequestState) {.base.} =
raise newException(ValueError, "No implementation available")
method onDeactivateChatLoader*(self: AccessInterface, sectionId: string, chatId: string) {.base.} =
raise newException(ValueError, "No implementation available")
method windowActivated*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method windowDeactivated*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method connectionChange*(self: AccessInterface, connectionType: string, isExpensive: bool, isOnline: bool) {.base.} =
raise newException(ValueError, "No implementation available")
method communityMembersRevealedAccountsLoaded*(self: AccessInterface, communityId: string, membersRevealedAccounts: MembersRevealedAccounts) {.base.} =
raise newException(ValueError, "No implementation available")
method communityMemberRevealedAccountsAdded*(self: AccessInterface, request: CommunityMembershipRequestDto) {.base.} =
raise newException(ValueError, "No implementation available")
method onCommunityTokensDetailsLoaded*(self: AccessInterface, communityId: string,
communityTokens: seq[CommunityTokenDto], communityTokenJsonItems: JsonNode) {.base.} =
raise newException(ValueError, "No implementation available")
method addressWasShown*(self: AccessInterface, address: string) {.base.} =
raise newException(ValueError, "No implementation available")
method openSectionChatAndMessage*(self: AccessInterface, sectionId: string, chatId: string, messageId: string): bool {.base.} =
raise newException(ValueError, "No implementation available")
method updateRequestToJoinState*(self: AccessInterface, sectionId: string, requestToJoinState: RequestToJoinState) {.base.} =
raise newException(ValueError, "No implementation available")
method startTokenHoldersManagement*(self: AccessInterface, communityId: string, chainId: int, contractAddress: string) {.base.} =
raise newException(ValueError, "No implementation available")
method stopTokenHoldersManagement*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method contactUpdated*(self: AccessInterface, contactId: string) {.base.} =
raise newException(ValueError, "No implementation available")
method loadMembersForSectionId*(self: AccessInterface, sectionId: string) {.base.} =
raise newException(ValueError, "No implementation available")
method getSectionId*(self: AccessInterface, sectionType: SectionType): string {.base.} =
raise newException(ValueError, "No implementation available")
method getSectionName*(self: AccessInterface, sectionId: string): string {.base.} =
raise newException(ValueError, "No implementation available")
method requestGetCredentialFromKeychainResult*(self: AccessInterface, success: bool, secret: string) {.base.} =
raise newException(ValueError, "No implementation available")
method credentialStoredToKeychainResult*(self: AccessInterface, success: bool) {.base.} =
raise newException(ValueError, "No implementation available")
method signOutAndQuit*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
# This way (using concepts) is used only for the modules managed by AppController
type
DelegateInterface* = concept c
c.mainDidLoad()