fix(@desktop/general): Fix community deep links
Cleanups in deep links - removing not needed links handlers Improve `open community` and `open channel` deep links - spectate community if not a member Fix #7892
This commit is contained in:
parent
6c90034b6b
commit
6ac091d094
|
@ -6,29 +6,15 @@ import ../../global/app_signals
|
|||
logScope:
|
||||
topics = "urls-manager"
|
||||
|
||||
const UriFormatBrowserShort = "status-im://b/"
|
||||
const UriFormatBrowserLong = "status-im://browser/"
|
||||
const UriFormatUserProfile = "status-im://u/"
|
||||
|
||||
const UriFormatUserProfileShort = "status-im://u/"
|
||||
const UriFormatUserProfileLong = "status-im://user/"
|
||||
const UriFormatCommunity = "status-im://c/"
|
||||
|
||||
const UriFormatPrivateChatShort = "status-im://pm/"
|
||||
const UriFormatPrivateChatLong = "status-im://private-message/"
|
||||
const UriFormatCommunityChannel = "status-im://cc/"
|
||||
|
||||
const UriFormatPublicChatShort = "status-im://p/"
|
||||
const UriFormatPublicChatLong = "status-im://public/"
|
||||
const UriFormatGroupChat = "status-im://g/"
|
||||
|
||||
const UriFormatGroupChatShort = "status-im://g/"
|
||||
const UriFormatGroupChatLong = "status-im://group/"
|
||||
|
||||
const UriFormatCommunityRequestsShort = "status-im://cr/"
|
||||
const UriFormatCommunityRequestsLong = "status-im://community-requests/"
|
||||
|
||||
const UriFormatCommunityShort = "status-im://c/"
|
||||
const UriFormatCommunityLong = "status-im://community/"
|
||||
|
||||
const UriFormatCommunityChannelShort = "status-im://cc/"
|
||||
const UriFormatCommunityChannelLong = "status-im://community-channel/"
|
||||
const UriFormatBrowser = "status-im://b/"
|
||||
|
||||
QtObject:
|
||||
type UrlsManager* = ref object of QObject
|
||||
|
@ -55,16 +41,6 @@ QtObject:
|
|||
result.protocolUriOnStart = protocolUriOnStart
|
||||
result.loggedIn = false
|
||||
|
||||
proc prepareGroupChatDetails(self: UrlsManager, urlQuery: string,
|
||||
data: var StatusUrlArgs) =
|
||||
var urlParams = rsplit(urlQuery, "/u/")
|
||||
if(urlParams.len > 0):
|
||||
data.groupName = urlParams[0]
|
||||
urlParams.delete(0)
|
||||
data.listOfUserIds = urlParams
|
||||
else:
|
||||
info "wrong url format for group chat"
|
||||
|
||||
proc onUrlActivated*(self: UrlsManager, urlRaw: string) {.slot.} =
|
||||
if not self.loggedIn:
|
||||
self.protocolUriOnStart = urlRaw
|
||||
|
@ -75,72 +51,26 @@ QtObject:
|
|||
.multiReplace(("\r\n", ""))
|
||||
.multiReplace(("\n", ""))
|
||||
|
||||
# Open `url` in the app's browser
|
||||
if url.startsWith(UriFormatBrowserShort):
|
||||
data.action = StatusUrlAction.OpenLinkInBrowser
|
||||
data.url = url[UriFormatBrowserShort.len .. url.len-1]
|
||||
elif url.startsWith(UriFormatBrowserLong):
|
||||
data.action = StatusUrlAction.OpenLinkInBrowser
|
||||
data.url = url[UriFormatBrowserLong.len .. url.len-1]
|
||||
|
||||
# Display user profile popup for user with `user_pk` or `ens_name`
|
||||
elif url.startsWith(UriFormatUserProfileShort):
|
||||
if url.startsWith(UriFormatUserProfile):
|
||||
data.action = StatusUrlAction.DisplayUserProfile
|
||||
data.userId = url[UriFormatUserProfileShort.len .. url.len-1]
|
||||
elif url.startsWith(UriFormatUserProfileLong):
|
||||
data.action = StatusUrlAction.DisplayUserProfile
|
||||
data.userId = url[UriFormatUserProfileLong.len .. url.len-1]
|
||||
|
||||
# Open or create 1:1 chat with user with `user_pk` or `ens_name`
|
||||
elif url.startsWith(UriFormatPrivateChatShort):
|
||||
data.action = StatusUrlAction.OpenOrCreatePrivateChat
|
||||
data.chatId = url[UriFormatPrivateChatShort.len .. url.len-1]
|
||||
elif url.startsWith(UriFormatPrivateChatLong):
|
||||
data.action = StatusUrlAction.OpenOrCreatePrivateChat
|
||||
data.chatId = url[UriFormatPrivateChatLong.len .. url.len-1]
|
||||
|
||||
# Open public chat with `chat_key`
|
||||
elif url.startsWith(UriFormatPublicChatShort):
|
||||
data.action = StatusUrlAction.OpenOrJoinPublicChat
|
||||
data.chatId = url[UriFormatPublicChatShort.len .. url.len-1]
|
||||
elif url.startsWith(UriFormatPublicChatLong):
|
||||
data.action = StatusUrlAction.OpenOrJoinPublicChat
|
||||
data.chatId = url[UriFormatPublicChatLong.len .. url.len-1]
|
||||
|
||||
# Open a group chat with named `group_name`, adding up to 19 participants with their `user_pk` or `ens_name`.
|
||||
# Group chat may have up to 20 participants including the admin of a group
|
||||
elif url.startsWith(UriFormatGroupChatShort):
|
||||
data.action = StatusUrlAction.OpenOrCreateGroupChat
|
||||
let urlQuery = url[UriFormatGroupChatShort.len .. url.len-1]
|
||||
self.prepareGroupChatDetails(urlQuery, data)
|
||||
elif url.startsWith(UriFormatGroupChatLong):
|
||||
data.action = StatusUrlAction.OpenOrCreateGroupChat
|
||||
let urlQuery = url[UriFormatGroupChatLong.len .. url.len-1]
|
||||
self.prepareGroupChatDetails(urlQuery, data)
|
||||
|
||||
# Send a join community request to a community with `community_key`
|
||||
elif url.startsWith(UriFormatCommunityRequestsShort):
|
||||
data.action = StatusUrlAction.RequestToJoinCommunity
|
||||
data.communityId = url[UriFormatCommunityRequestsShort.len .. url.len-1]
|
||||
elif url.startsWith(UriFormatCommunityRequestsLong):
|
||||
data.action = StatusUrlAction.RequestToJoinCommunity
|
||||
data.communityId = url[UriFormatCommunityRequestsLong.len .. url.len-1]
|
||||
data.userId = url[UriFormatUserProfile.len .. url.len-1]
|
||||
|
||||
# Open community with `community_key`
|
||||
elif url.startsWith(UriFormatCommunityShort):
|
||||
elif url.startsWith(UriFormatCommunity):
|
||||
data.action = StatusUrlAction.OpenCommunity
|
||||
data.communityId = url[UriFormatCommunityShort.len .. url.len-1]
|
||||
elif url.startsWith(UriFormatCommunityLong):
|
||||
data.action = StatusUrlAction.OpenCommunity
|
||||
data.communityId = url[UriFormatCommunityLong.len .. url.len-1]
|
||||
data.communityId = url[UriFormatCommunity.len .. url.len-1]
|
||||
|
||||
# Open community which has a channel with `channel_key` and makes that channel active
|
||||
elif url.startsWith(UriFormatCommunityChannelShort):
|
||||
elif url.startsWith(UriFormatCommunityChannel):
|
||||
data.action = StatusUrlAction.OpenCommunityChannel
|
||||
data.chatId = url[UriFormatCommunityChannelShort.len .. url.len-1]
|
||||
elif url.startsWith(UriFormatCommunityChannelLong):
|
||||
data.action = StatusUrlAction.OpenCommunityChannel
|
||||
data.chatId = url[UriFormatCommunityChannelLong.len .. url.len-1]
|
||||
data.chatId = url[UriFormatCommunityChannel.len .. url.len-1]
|
||||
|
||||
# Open `url` in the app's browser
|
||||
# Enable after MVP
|
||||
#elif url.startsWith(UriFormatBrowser):
|
||||
# data.action = StatusUrlAction.OpenLinkInBrowser
|
||||
# data.url = url[UriFormatBrowser.len .. url.len-1]
|
||||
|
||||
else:
|
||||
info "Unsupported deep link structure: ", url
|
||||
|
|
|
@ -28,10 +28,6 @@ type
|
|||
StatusUrlAction* {.pure.} = enum
|
||||
OpenLinkInBrowser = 0
|
||||
DisplayUserProfile,
|
||||
OpenOrCreatePrivateChat,
|
||||
OpenOrJoinPublicChat,
|
||||
OpenOrCreateGroupChat,
|
||||
RequestToJoinCommunity,
|
||||
OpenCommunity,
|
||||
OpenCommunityChannel
|
||||
|
||||
|
@ -42,7 +38,5 @@ type
|
|||
chatId*: string
|
||||
url*: string
|
||||
userId*: string # can be public key or ens name
|
||||
groupName*: string
|
||||
listOfUserIds*: seq[string] # used for creating group chat
|
||||
|
||||
const SIGNAL_STATUS_URL_REQUESTED* = "statusUrlRequested"
|
|
@ -170,6 +170,10 @@ proc init*(self: Controller) =
|
|||
setActive = false
|
||||
)
|
||||
|
||||
self.events.on(SIGNAL_COMMUNITY_DATA_IMPORTED) do(e:Args):
|
||||
let args = CommunityArgs(e)
|
||||
self.delegate.communityDataImported(args.community)
|
||||
|
||||
self.events.on(SIGNAL_COMMUNITY_LEFT) do(e:Args):
|
||||
let args = CommunityIdArgs(e)
|
||||
self.delegate.communityLeft(args.communityId)
|
||||
|
@ -220,8 +224,7 @@ proc init*(self: Controller) =
|
|||
|
||||
self.events.on(SIGNAL_STATUS_URL_REQUESTED) do(e: Args):
|
||||
var args = StatusUrlArgs(e)
|
||||
self.delegate.onStatusUrlRequested(args.action, args.communityId, args.chatId, args.url, args.userId,
|
||||
args.groupName, args.listOfUserIds)
|
||||
self.delegate.onStatusUrlRequested(args.action, args.communityId, args.chatId, args.url, args.userId)
|
||||
|
||||
self.events.on(SIGNAL_OS_NOTIFICATION_CLICKED) do(e: Args):
|
||||
var args = ClickedNotificationArgs(e)
|
||||
|
|
|
@ -189,6 +189,9 @@ method getAppSearchModule*(self: AccessInterface): QVariant {.base.} =
|
|||
method getContactDetailsAsJson*(self: AccessInterface, publicKey: string, getVerificationRequest: bool): string {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method communityDataImported*(self: AccessInterface, community: CommunityDto) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method resolveENS*(self: AccessInterface, ensName: string, uuid: string, reason: string = "") {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
|
@ -202,7 +205,7 @@ 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, groupName: string, listOfUserIds: seq[string]) {.base.} =
|
||||
url: string, userId: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getVerificationRequestFrom*(self: AccessInterface, publicKey: string): VerificationRequest {.base.} =
|
||||
|
|
|
@ -92,9 +92,7 @@ type
|
|||
networksModule: networks_module.AccessInterface
|
||||
keycardSharedModule: keycard_shared_module.AccessInterface
|
||||
moduleLoaded: bool
|
||||
statusUrlGroupName: string
|
||||
statusUrlGroupMembers: seq[string] # used only for creating group chat from the status url
|
||||
statusUrlGroupMembersCount: int
|
||||
statusUrlCommunityToSpectate: string
|
||||
|
||||
# Forward declaration
|
||||
method calculateProfileSectionHasNotification*[T](self: Module[T]): bool
|
||||
|
@ -791,6 +789,11 @@ method getContactDetailsAsJson*[T](self: Module[T], publicKey: string, getVerifi
|
|||
}
|
||||
return $jsonObj
|
||||
|
||||
method communityDataImported*[T](self: Module[T], community: CommunityDto) =
|
||||
if community.id == self.statusUrlCommunityToSpectate:
|
||||
self.statusUrlCommunityToSpectate = ""
|
||||
discard self.communitiesModule.spectateCommunity(community.id)
|
||||
|
||||
method resolveENS*[T](self: Module[T], ensName: string, uuid: string, reason: string = "") =
|
||||
if ensName.len == 0:
|
||||
echo "error: cannot do a lookup for empty ens name"
|
||||
|
@ -806,19 +809,6 @@ method resolvedENS*[T](self: Module[T], publicKey: string, address: string, uuid
|
|||
let item = self.view.model().getItemById(singletonInstance.userProfile.getPubKey())
|
||||
self.setActiveSection(item)
|
||||
self.view.emitDisplayUserProfileSignal(publicKey)
|
||||
elif(reason == STATUS_URL_ENS_RESOLVE_REASON & $StatusUrlAction.OpenOrCreatePrivateChat):
|
||||
let item = self.view.model().getItemById(singletonInstance.userProfile.getPubKey())
|
||||
self.setActiveSection(item)
|
||||
self.getChatSectionModule().switchToOrCreateOneToOneChat(publicKey)
|
||||
elif(reason == STATUS_URL_ENS_RESOLVE_REASON & $StatusUrlAction.OpenOrCreateGroupChat):
|
||||
self.statusUrlGroupMembers.add(publicKey)
|
||||
if(self.statusUrlGroupMembers.len == self.statusUrlGroupMembersCount):
|
||||
let item = self.view.model().getItemById(singletonInstance.userProfile.getPubKey())
|
||||
self.setActiveSection(item)
|
||||
self.getChatSectionModule().createGroupChat(self.statusUrlGroupName, self.statusUrlGroupMembers)
|
||||
self.statusUrlGroupName = ""
|
||||
self.statusUrlGroupMembers = @[]
|
||||
self.statusUrlGroupMembersCount = 0
|
||||
else:
|
||||
self.view.emitResolvedENSSignal(publicKey, address, uuid)
|
||||
|
||||
|
@ -912,56 +902,47 @@ method ephemeralNotificationClicked*[T](self: Module[T], id: int64) =
|
|||
method onMyRequestAdded*[T](self: Module[T]) =
|
||||
self.displayEphemeralNotification("Your Request has been submitted", "" , "checkmark-circle", false, EphemeralNotificationType.Success.int, "")
|
||||
|
||||
proc getCommunityIdFromFullChatId(fullChatId: string): string =
|
||||
const communityIdLength = 68
|
||||
return fullChatId.substr(0, communityIdLength-1)
|
||||
|
||||
method onStatusUrlRequested*[T](self: Module[T], action: StatusUrlAction, communityId: string, chatId: string,
|
||||
url: string, userId: string, groupName: string, listOfUserIds: seq[string]) =
|
||||
url: string, userId: string) =
|
||||
|
||||
if(action == StatusUrlAction.OpenLinkInBrowser and singletonInstance.localAccountSensitiveSettings.getIsBrowserEnabled()):
|
||||
let item = self.view.model().getItemById(conf.BROWSER_SECTION_ICON)
|
||||
self.setActiveSection(item)
|
||||
self.browserSectionModule.openUrl(url)
|
||||
|
||||
elif(action == StatusUrlAction.DisplayUserProfile):
|
||||
if(action == StatusUrlAction.DisplayUserProfile):
|
||||
self.resolveENS(userId, "", STATUS_URL_ENS_RESOLVE_REASON & $StatusUrlAction.DisplayUserProfile)
|
||||
|
||||
elif(action == StatusUrlAction.OpenOrCreatePrivateChat):
|
||||
self.resolveENS(chatId, "", STATUS_URL_ENS_RESOLVE_REASON & $StatusUrlAction.OpenOrCreatePrivateChat)
|
||||
|
||||
elif(action == StatusUrlAction.OpenOrJoinPublicChat):
|
||||
let item = self.view.model().getItemById(singletonInstance.userProfile.getPubKey())
|
||||
self.setActiveSection(item)
|
||||
self.getChatSectionModule().createPublicChat(chatId)
|
||||
|
||||
elif(action == StatusUrlAction.OpenOrCreateGroupChat):
|
||||
self.statusUrlGroupName = groupName
|
||||
# if there are more than 20 members added to the url, we add only first 19
|
||||
self.statusUrlGroupMembersCount = if listOfUserIds.len <= MAX_MEMBERS_IN_GROUP_CHAT_WITHOUT_ADMIN: listOfUserIds.len else: MAX_MEMBERS_IN_GROUP_CHAT_WITHOUT_ADMIN
|
||||
var i = 0
|
||||
for id in listOfUserIds:
|
||||
if(i >= MAX_MEMBERS_IN_GROUP_CHAT_WITHOUT_ADMIN):
|
||||
break
|
||||
i.inc
|
||||
self.resolveENS(id, "", STATUS_URL_ENS_RESOLVE_REASON & $StatusUrlAction.OpenOrCreateGroupChat)
|
||||
|
||||
elif(action == StatusUrlAction.RequestToJoinCommunity):
|
||||
let item = self.view.model().getItemById(singletonInstance.userProfile.getPubKey())
|
||||
self.setActiveSection(item)
|
||||
self.communitiesModule.requestToJoinCommunity(communityId, singletonInstance.userProfile.getName())
|
||||
|
||||
elif(action == StatusUrlAction.OpenCommunity):
|
||||
let item = self.view.model().getItemById(communityId)
|
||||
self.setActiveSection(item)
|
||||
if item.isEmpty():
|
||||
# request community info and then spectate
|
||||
self.statusUrlCommunityToSpectate = communityId
|
||||
self.communitiesModule.requestCommunityInfo(communityId)
|
||||
else:
|
||||
self.setActiveSection(item)
|
||||
|
||||
elif(action == StatusUrlAction.OpenCommunityChannel):
|
||||
var found = false
|
||||
for cId, cModule in self.channelGroupModules.pairs:
|
||||
if(cId == singletonInstance.userProfile.getPubKey()):
|
||||
continue
|
||||
if(cModule.doesCatOrChatExist(chatId)):
|
||||
let item = self.view.model().getItemById(cId)
|
||||
self.setActiveSection(item)
|
||||
|
||||
cModule.makeChatWithIdActive(chatId)
|
||||
found = true
|
||||
break
|
||||
if not found:
|
||||
let communityIdToSpectate = getCommunityIdFromFullChatId(chatId)
|
||||
# request community info and then spectate
|
||||
self.statusUrlCommunityToSpectate = communityIdToSpectate
|
||||
self.communitiesModule.requestCommunityInfo(communityIdToSpectate)
|
||||
|
||||
# enable after MVP
|
||||
#else(action == StatusUrlAction.OpenLinkInBrowser and singletonInstance.localAccountSensitiveSettings.getIsBrowserEnabled()):
|
||||
# let item = self.view.model().getItemById(conf.BROWSER_SECTION_ICON)
|
||||
# self.setActiveSection(item)
|
||||
# self.browserSectionModule.openUrl(url)
|
||||
|
||||
method getKeycardSharedModule*[T](self: Module[T]): QVariant =
|
||||
return self.keycardSharedModule.getModuleAsVariant()
|
||||
|
|
Loading…
Reference in New Issue