diff --git a/src/app/global/local_account_sensitive_settings.nim b/src/app/global/local_account_sensitive_settings.nim index 88fa819c2ab..eb066f9ee91 100644 --- a/src/app/global/local_account_sensitive_settings.nim +++ b/src/app/global/local_account_sensitive_settings.nim @@ -16,8 +16,6 @@ const LSS_KEY_ENS_COMMUNITY_PERMISSIONS_ENABLED* = "ensCommunityPermissionsEnabl const DEFAULT_COMMUNITY_PERMISSIONS_ENABLED = false const LSS_KEY_IS_BROWSER_ENABLED* = "isExperimentalBrowserEnabled" let DEFAULT_IS_BROWSER_ENABLED = not TEST_MODE_ENABLED -const LSS_KEY_SHOW_ONLINE_USERS* = "showOnlineUsers" -const DEFAULT_SHOW_ONLINE_USERS = true const LSS_KEY_EXPAND_USERS_LIST* = "expandUsersList" const DEFAULT_EXPAND_USERS_LIST = true const DEFAULT_IS_MULTI_NETWORK_ENABLED = false @@ -242,19 +240,6 @@ QtObject: write = setEnsCommunityPermissionsEnabled notify = ensCommunityPermissionsEnabledChanged - proc showOnlineUsersChanged*(self: LocalAccountSensitiveSettings) {.signal.} - proc getShowOnlineUsers*(self: LocalAccountSensitiveSettings): bool {.slot.} = - getSettingsProp[bool](self, LSS_KEY_SHOW_ONLINE_USERS, newQVariant(DEFAULT_SHOW_ONLINE_USERS)) - proc setShowOnlineUsers*(self: LocalAccountSensitiveSettings, value: bool) {.slot.} = - setSettingsProp(self, LSS_KEY_SHOW_ONLINE_USERS, newQVariant(value)): - self.showOnlineUsersChanged() - - QtProperty[bool] showOnlineUsers: - read = getShowOnlineUsers - write = setShowOnlineUsers - notify = showOnlineUsersChanged - - proc expandUsersListChanged*(self: LocalAccountSensitiveSettings) {.signal.} proc getExpandUsersList*(self: LocalAccountSensitiveSettings): bool {.slot.} = getSettingsProp[bool](self, LSS_KEY_EXPAND_USERS_LIST, newQVariant(DEFAULT_EXPAND_USERS_LIST)) @@ -615,7 +600,6 @@ QtObject: of LSS_KEY_NODE_MANAGEMENT_ENABLED: self.nodeManagementEnabledChanged() of LSS_KEY_ENS_COMMUNITY_PERMISSIONS_ENABLED: self.ensCommunityPermissionsEnabledChanged() of LSS_KEY_IS_BROWSER_ENABLED: self.isBrowserEnabledChanged() - of LSS_KEY_SHOW_ONLINE_USERS: self.showOnlineUsersChanged() of LSS_KEY_EXPAND_USERS_LIST: self.expandUsersListChanged() of LSS_KEY_NEVER_ASK_ABOUT_UNFURLING_AGAIN: self.neverAskAboutUnfurlingAgainChanged() of LSS_KEY_HIDE_CHANNEL_SUGGESTIONS: self.hideChannelSuggestionsChanged() diff --git a/ui/StatusQ/src/StatusQ/Layout/StatusSectionLayout.qml b/ui/StatusQ/src/StatusQ/Layout/StatusSectionLayout.qml index 637fc7f5441..19b3bbc33c5 100644 --- a/ui/StatusQ/src/StatusQ/Layout/StatusSectionLayout.qml +++ b/ui/StatusQ/src/StatusQ/Layout/StatusSectionLayout.qml @@ -46,6 +46,12 @@ LayoutChooser { implicitWidth: Theme.portraitBreakpoint.width implicitHeight: Theme.portraitBreakpoint.height + enum Panels { + LeftPanel, + CentralPanel, + RightPanel + } + property Component handle: Item { } /*! @@ -120,18 +126,20 @@ LayoutChooser { signal backButtonClicked() + signal swiped(int previousIndex, int currentIndex) + /*! \qmlmethod StatusSectionLayout::goToNextPanel() This method is used to focus the panel that needs to be active. */ function goToNextPanel() { if (portraitView.visible) - portraitView.currentIndex = portraitView.currentIndex + 1; + portraitView.incrementCurrentIndex() } function goToPreviousPanel() { if (portraitView.visible) - portraitView.currentIndex = portraitView.currentIndex - 1; + portraitView.decrementCurrentIndex() } criteria: [ @@ -178,6 +186,15 @@ LayoutChooser { backButtonName: root.backButtonName headerContent: root.headerContent + property int currentIndexCache + + onCurrentIndexChanged: { + root.swiped(currentIndexCache, currentIndex) + currentIndexCache = currentIndex + } + onBackButtonClicked: root.backButtonClicked() + + Component.onCompleted: currentIndexCache = currentIndex } } diff --git a/ui/app/AppLayouts/Chat/ChatLayout.qml b/ui/app/AppLayouts/Chat/ChatLayout.qml index 8faad0d2231..b09eb887685 100644 --- a/ui/app/AppLayouts/Chat/ChatLayout.qml +++ b/ui/app/AppLayouts/Chat/ChatLayout.qml @@ -67,6 +67,7 @@ StackLayout { readonly property int isInvitationPending: root.rootStore.chatCommunitySectionModule.requestToJoinState !== Constants.RequestToJoinState.None property bool communitySettingsDisabled + property bool showUsersList property bool sendViaPersonalChatEnabled property string disabledTooltipText @@ -106,9 +107,11 @@ StackLayout { signal removeTrustStatusRequest(string pubKey) signal dismissContactRequest(string chatId, string contactRequestId) signal acceptContactRequest(string chatId, string contactRequestId) - onIsPrivilegedUserChanged: if (root.currentIndex === 1) root.currentIndex = 0 + // Navigation + signal showUsersListRequested(bool show) + onCurrentIndexChanged: { Global.closeCreateChatView() } @@ -217,6 +220,7 @@ StackLayout { sendViaPersonalChatEnabled: root.sendViaPersonalChatEnabled disabledTooltipText: root.disabledTooltipText paymentRequestFeatureEnabled: root.paymentRequestFeatureEnabled + showUsersList: root.showUsersList hasUnrestrictedViewOnlyPermission: { viewOnlyUnrestrictedPermissionHelper.revision @@ -342,6 +346,8 @@ StackLayout { onSpectateCommunityRequested: (communityId) => { root.communityAccessStore.spectateCommunity(communityId) } + + onShowUsersListRequested: show => root.showUsersListRequested(show) } } diff --git a/ui/app/AppLayouts/Chat/views/ChatHeaderContentView.qml b/ui/app/AppLayouts/Chat/views/ChatHeaderContentView.qml index b556de1ab39..53d46c031dd 100644 --- a/ui/app/AppLayouts/Chat/views/ChatHeaderContentView.qml +++ b/ui/app/AppLayouts/Chat/views/ChatHeaderContentView.qml @@ -32,6 +32,8 @@ RowLayout { property var usersModel property var amIChatAdmin + property bool showMembersButtonHighlighted + signal groupMembersUpdateRequested(string membersPubKeysList) signal searchButtonClicked() @@ -45,6 +47,8 @@ RowLayout { var deleteDialog, bool hideIfPermissionsNotMet) + signal toggleShowMembersRequested + function addRemoveGroupMember() { root.state = d.stateMembersSelectorContent } @@ -98,15 +102,15 @@ RowLayout { if(!chatContentModule) return false - return localAccountSensitiveSettings.showOnlineUsers && - chatContentModule.chatDetails.isUsersListAvailable + return chatContentModule.chatDetails.isUsersListAvailable } - highlighted: localAccountSensitiveSettings.expandUsersList + + highlighted: root.showMembersButtonHighlighted + icon.name: "group-chat" type: StatusFlatRoundButton.Type.Secondary - onClicked: { - localAccountSensitiveSettings.expandUsersList = !localAccountSensitiveSettings.expandUsersList; - } + onClicked: root.toggleShowMembersRequested() + // initializing the tooltip tooltip.text: qsTr("Members") tooltip.orientation: StatusToolTip.Orientation.Bottom diff --git a/ui/app/AppLayouts/Chat/views/ChatView.qml b/ui/app/AppLayouts/Chat/views/ChatView.qml index f8acdad4a61..a2b439d4972 100644 --- a/ui/app/AppLayouts/Chat/views/ChatView.qml +++ b/ui/app/AppLayouts/Chat/views/ChatView.qml @@ -15,6 +15,7 @@ import SortFilterProxyModel import StatusQ import StatusQ.Controls import StatusQ.Core +import StatusQ.Core.Backpressure import StatusQ.Core.Theme import StatusQ.Core.Utils import StatusQ.Layout @@ -67,6 +68,7 @@ StatusSectionLayout { property bool amIMember: false property bool amISectionAdmin: false property bool allChannelsAreHiddenBecauseNotPermitted: false + property bool showUsersList: false property int requestToJoinState: Constants.RequestToJoinState.None @@ -162,6 +164,9 @@ StatusSectionLayout { // Community access related requests: signal spectateCommunityRequested(string communityId) + // Navigation + signal showUsersListRequested(bool show) + Connections { target: root.rootStore.stickersStore.stickersModule @@ -199,19 +204,10 @@ StatusSectionLayout { } showRightPanel: { - if (root.contentLocked) { - return false - } - - if (root.rootStore.openCreateChat || - !localAccountSensitiveSettings.showOnlineUsers || - !localAccountSensitiveSettings.expandUsersList) { + if (root.contentLocked || root.rootStore.openCreateChat || + !root.showUsersList || !root.chatContentModule) return false - } - if (!root.chatContentModule) { - return false - } // Check if user list is available as an option for particular chat content module return root.chatContentModule.chatDetails.isUsersListAvailable } @@ -264,6 +260,7 @@ StatusSectionLayout { usersModel: root.usersModel amIChatAdmin: root.amIChatAdmin + showMembersButtonHighlighted: root.showUsersList onSearchButtonClicked: root.openAppSearch() onDisplayEditChannelPopup: { @@ -282,6 +279,7 @@ StatusSectionLayout { } onGroupMembersUpdateRequested: root.groupMembersUpdateRequested(membersPubKeysList) + onToggleShowMembersRequested: root.showUsersListRequested(!root.showUsersList) } } @@ -422,6 +420,25 @@ StatusSectionLayout { } } + onSwiped: (previous, current) => { + if (previous !== StatusSectionLayout.RightPanel) + return + + // Setting timeout to let the swipe animation to complete. The workaround + // is needed because SwipeView doesn't expose any API to detect completed + // swipe action + Backpressure.setTimeout(this, 300, () => { + root.showUsersList = false + }) + } + + onShowUsersListChanged: { + Qt.callLater(() => { + if (root.showUsersList) + goToNextPanel() + }) + } + Component { id: statusStickerPackClickPopup StatusStickerPackClickPopup{ diff --git a/ui/app/AppLayouts/Profile/stores/AdvancedStore.qml b/ui/app/AppLayouts/Profile/stores/AdvancedStore.qml index fb3189aca15..27db74cb093 100644 --- a/ui/app/AppLayouts/Profile/stores/AdvancedStore.qml +++ b/ui/app/AppLayouts/Profile/stores/AdvancedStore.qml @@ -28,7 +28,6 @@ QtObject { readonly property string communities: "communities" readonly property string activityCenter: "activityCenter" readonly property string nodeManagement: "nodeManagement" - readonly property string onlineUsers: "onlineUsers" readonly property string communitiesPortal: "communitiesPortal" readonly property string communityPermissions: "communityPermissions" readonly property string discordImportTool: "discordImportTool" @@ -123,9 +122,6 @@ QtObject { else if (feature === experimentalFeatures.nodeManagement) { advancedModule.toggleNodeManagementSection() } - else if (feature === experimentalFeatures.onlineUsers) { - localAccountSensitiveSettings.showOnlineUsers = !localAccountSensitiveSettings.showOnlineUsers - } } function toggleArchiveProtocolEnabled() { diff --git a/ui/app/AppLayouts/stores/AccountSettingsStore.qml b/ui/app/AppLayouts/stores/AccountSettingsStore.qml new file mode 100644 index 00000000000..f1ab351fb9c --- /dev/null +++ b/ui/app/AppLayouts/stores/AccountSettingsStore.qml @@ -0,0 +1,19 @@ +import QtQml + +import StatusQ.Core.Utils + +QObject { + id: root + + readonly property bool showUsersList: d.settings.expandUsersList + + function setShowUsersList(expanded: bool) { + d.settings.expandUsersList = expanded + } + + QtObject { + id: d + + readonly property var settings: localAccountSensitiveSettings + } +} diff --git a/ui/app/AppLayouts/stores/RootStore.qml b/ui/app/AppLayouts/stores/RootStore.qml index ba7314cead6..3b2bee35d37 100644 --- a/ui/app/AppLayouts/stores/RootStore.qml +++ b/ui/app/AppLayouts/stores/RootStore.qml @@ -41,6 +41,8 @@ QtObject { readonly property ProfileStores.ProfileSectionStore profileSectionStore: ProfileStores.ProfileSectionStore { localBackupEnabled: root.localBackupEnabled } + + readonly property AccountSettingsStore accountSettingsStore: AccountSettingsStore {} readonly property ContactsStore contactsStore: ContactsStore {} readonly property ActivityCenterStore activityCenterStore: ActivityCenterStore {} diff --git a/ui/app/AppLayouts/stores/qmldir b/ui/app/AppLayouts/stores/qmldir index 1a219ab8b48..e3703f40c13 100644 --- a/ui/app/AppLayouts/stores/qmldir +++ b/ui/app/AppLayouts/stores/qmldir @@ -1,3 +1,4 @@ +AccountSettingsStore 1.0 AccountSettingsStore.qml ActivityCenterStore 1.0 ActivityCenterStore.qml AppSearchStore 1.0 AppSearchStore.qml ContactsStore 1.0 ContactsStore.qml diff --git a/ui/app/mainui/AppMain.qml b/ui/app/mainui/AppMain.qml index 0364acc5eb3..f560c255767 100644 --- a/ui/app/mainui/AppMain.qml +++ b/ui/app/mainui/AppMain.qml @@ -72,6 +72,7 @@ Item { } // Global cross-domain stores (just references from `rootStore`) + readonly property AppStores.AccountSettingsStore accountSettingsStore: rootStore.accountSettingsStore readonly property AppStores.ContactsStore contactsStore: rootStore.contactsStore readonly property AppStores.ActivityCenterStore activityCenterStore: rootStore.activityCenterStore @@ -822,9 +823,8 @@ Item { id: d readonly property int activeSectionType: appMain.rootStore.activeSectionType - readonly property bool isBrowserEnabled: featureFlagsStore.browserEnabled && localAccountSensitiveSettings.isBrowserEnabled - + function openHomePage() { appMain.rootStore.setActiveSectionBySectionType(Constants.appSection.homePage) homePageLoader.item.focusSearch() @@ -1895,6 +1895,10 @@ Item { ChatLayout { id: chatLayoutContainer + showUsersList: appMain.accountSettingsStore.showUsersList + onShowUsersListRequested: + show => appMain.accountSettingsStore.setShowUsersList(show) + isChatView: true navBar: appMain.navBar rootStore: ChatStores.RootStore { @@ -2285,6 +2289,10 @@ Item { } } + showUsersList: appMain.accountSettingsStore.showUsersList + onShowUsersListRequested: + show => appMain.accountSettingsStore.setShowUsersList(show) + isChatView: false // This will be a community view navBar: appMain.navBar emojiPopup: statusEmojiPopup.item