Skip to content

Commit 45e8f8b

Browse files
committed
feat(Adaptive navigation) Primary nav sidebar POC
- introduce `PrimaryNavSidebar{Button}` components - update the main sections SVG icons - added a basic QML test suite - add a SB page for the sidebar POC Fixes #19593
1 parent e66ad7d commit 45e8f8b

File tree

22 files changed

+1270
-46
lines changed

22 files changed

+1270
-46
lines changed
Lines changed: 314 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,314 @@
1+
import QtQuick
2+
import QtQuick.Controls
3+
import QtQuick.Layouts
4+
import QtWebView
5+
6+
import StatusQ
7+
import StatusQ.Core
8+
import StatusQ.Core.Theme
9+
import StatusQ.Controls
10+
import StatusQ.Components
11+
import StatusQ.Popups
12+
13+
import Models
14+
import Storybook
15+
16+
import shared.controls.chat.menuItems
17+
18+
import utils
19+
20+
import AppLayouts.Profile.stores as ProfileStores
21+
22+
import mainui
23+
24+
SplitView {
25+
id: root
26+
27+
orientation: Qt.Vertical
28+
29+
Logs { id: logs }
30+
31+
QtObject {
32+
id: d
33+
34+
readonly property var sectionsModel: SectionsModel {}
35+
36+
property bool acVisible
37+
38+
property int activeSectionType: Constants.appSection.wallet
39+
property string activeSectionId: "id2"
40+
}
41+
42+
Item {
43+
SplitView.fillWidth: true
44+
SplitView.fillHeight: true
45+
46+
Label {
47+
anchors.centerIn: parent
48+
visible: secondaryWindow.visible
49+
text: "Interact with the sidebar in the secondary window"
50+
}
51+
Button {
52+
anchors.centerIn: parent
53+
text: "Reopen"
54+
visible: !secondaryWindow.visible
55+
onClicked: secondaryWindow.visible = true
56+
}
57+
}
58+
59+
Window {
60+
id: secondaryWindow
61+
visible: true
62+
width: 800
63+
height: 640
64+
title: "PrimaryNavSidebar"
65+
color: Theme.palette.baseColor4 // doesn't get the proper StatusQ palette w/o Theme.xxx
66+
67+
ColumnLayout {
68+
anchors.fill: parent
69+
anchors.margins: 2
70+
anchors.leftMargin: sidebar.alwaysVisible ? sidebar.width : 2
71+
Behavior on anchors.leftMargin {PropertyAnimation {duration: ThemeUtils.AnimationDuration.Fast}}
72+
73+
WebView {
74+
Layout.fillWidth: true
75+
Layout.fillHeight: true
76+
url: "https://status.app"
77+
}
78+
79+
StatusButton {
80+
icon.name: "more"
81+
enabled: !sidebar.alwaysVisible
82+
onClicked: sidebar.open()
83+
84+
tooltip.text: "Open sidebar"
85+
tooltip.orientation: StatusToolTip.Orientation.Bottom
86+
}
87+
StatusBaseText {
88+
Layout.fillWidth: true
89+
wrapMode: Text.Wrap
90+
text: "Active section type/id: %1/\"%2\"".arg(d.activeSectionType).arg(d.activeSectionId)
91+
}
92+
StatusBaseText {
93+
Layout.fillWidth: true
94+
wrapMode: Text.Wrap
95+
text: "Window size: %1x%2".arg(secondaryWindow.width).arg(secondaryWindow.height)
96+
}
97+
StatusBaseText {
98+
Layout.fillWidth: true
99+
wrapMode: Text.Wrap
100+
text: sidebar.alwaysVisible ? "alwaysVisible: <b>true</b> (%1)".arg("pushes the content; background not dimmed")
101+
: "alwaysVisible: <b>false</b> (%1)".arg("open the sidebar by dragging on the left edge, or click the above button; background dimmed")
102+
}
103+
StatusBaseText {
104+
Layout.fillWidth: true
105+
wrapMode: Text.Wrap
106+
text: "Sidebar position: %1".arg(sidebar.position)
107+
}
108+
}
109+
110+
PrimaryNavSidebar {
111+
id: sidebar
112+
height: parent.height
113+
114+
sectionsModel: d.sectionsModel
115+
116+
acVisible: d.acVisible
117+
acHasUnseenNotifications: ctrlAcHasUnseenNotifications.checked // <- ActivityCenterStore.hasUnseenNotifications
118+
acUnreadNotificationsCount: ctrlAcUnreadNotificationsCount.value // <- ActivityCenterStore.unreadNotificationsCount
119+
120+
profileStore: ProfileStores.ProfileStore {
121+
id: profileStore
122+
readonly property string pubKey: "0xdeadbeef"
123+
readonly property string compressedPubKey: "zxDeadBeef"
124+
readonly property string name: "John Doe"
125+
readonly property string icon: ModelsData.icons.rarible
126+
readonly property int colorId: 7
127+
readonly property bool usesDefaultName: false
128+
property int currentUserStatus: Constants.currentUserStatus.automatic
129+
}
130+
131+
getEmojiHashFn: function(pubKey) { // <- root.utilsStore.getEmojiHash(pubKey)
132+
if (pubKey === "")
133+
return ""
134+
135+
return["👨🏻‍🍼", "🏃🏿‍♂️", "🌇", "🤶🏿", "🏮","🤷🏻‍♂️", "🤦🏻", "📣", "🤎", "👷🏽", "😺", "🥞", "🔃", "🧝🏽‍♂️"]
136+
}
137+
getLinkToProfileFn: function(pubKey) { // <- root.rootStore.contactsStore.getLinkToProfile(pubKey)
138+
return Constants.userLinkPrefix + pubKey
139+
}
140+
141+
communityPopupMenu: Component {
142+
StatusMenu {
143+
id: communityContextMenu
144+
145+
required property var model
146+
required property int index
147+
148+
readonly property bool isSpectator: model.spectated && !model.joined
149+
150+
onClosed: destroy()
151+
152+
StatusAction {
153+
text: qsTr("Invite People")
154+
icon.name: "share-ios"
155+
objectName: "invitePeople"
156+
}
157+
158+
StatusAction {
159+
text: qsTr("Community Info")
160+
icon.name: "info"
161+
}
162+
163+
StatusAction {
164+
text: qsTr("Community Rules")
165+
icon.name: "text"
166+
}
167+
168+
StatusMenuSeparator {}
169+
170+
MuteChatMenuItem {
171+
enabled: !model.muted
172+
title: qsTr("Mute Community")
173+
}
174+
175+
StatusAction {
176+
enabled: model.muted
177+
text: qsTr("Unmute Community")
178+
icon.name: "notification"
179+
}
180+
181+
StatusAction {
182+
text: qsTr("Mark as read")
183+
icon.name: "check-circle"
184+
}
185+
186+
StatusAction {
187+
text: qsTr("Edit Shared Addresses")
188+
icon.name: "wallet"
189+
enabled: {
190+
if (model.memberRole === Constants.memberRole.owner || communityContextMenu.isSpectator)
191+
return false
192+
return true
193+
}
194+
}
195+
196+
StatusMenuSeparator { visible: leaveCommunityMenuItem.enabled }
197+
198+
StatusAction {
199+
id: leaveCommunityMenuItem
200+
objectName: "leaveCommunityMenuItem"
201+
// allow to leave community for the owner in non-production builds
202+
enabled: model.memberRole !== Constants.memberRole.owner || !production
203+
text: {
204+
if (communityContextMenu.isSpectator)
205+
return qsTr("Close Community")
206+
return qsTr("Leave Community")
207+
}
208+
icon.name: communityContextMenu.isSpectator ? "close-circle" : "arrow-left"
209+
type: StatusAction.Type.Danger
210+
}
211+
}
212+
}
213+
214+
showEnabledSectionsOnly: ctrlShowEnabledSectionsOnly.checked
215+
marketEnabled: ctrlMarketEnabled.checked
216+
browserEnabled: ctrlBrowserEnabled.checked
217+
nodeEnabled: ctrlNodeEnabled.checked
218+
thirdpartyServicesEnabled: ctrlThirdPartyServices.checked
219+
showCreateCommunityBadge: ctrlShowCreateCommunityBadge.checked
220+
profileSectionHasNotification: ctrlSettingsHasNotification.checked
221+
222+
onItemActivated: function (sectionType, id) {
223+
logs.logEvent("onItemActivated", ["sectionType", "sectionId"], arguments)
224+
sectionsModel.setActiveSection(id)
225+
d.activeSectionType = sectionType
226+
d.activeSectionId = id
227+
}
228+
onActivityCenterRequested: function (shouldShow) {
229+
logs.logEvent("onActivityCenterRequested", ["shouldShow"], arguments)
230+
d.acVisible = shouldShow
231+
}
232+
onSetCurrentUserStatusRequested: function (status) {
233+
profileStore.currentUserStatus = status
234+
logs.logEvent("onSetCurrentUserStatusRequested", ["status"], arguments) // <- root.rootStore.setCurrentUserStatus(status)
235+
}
236+
onViewProfileRequested: logs.logEvent("onViewProfileRequested", ["pubKey"], arguments) // <- Global.openProfilePopup(pubKey)
237+
}
238+
}
239+
240+
LogsAndControlsPanel {
241+
SplitView.minimumHeight: 330
242+
SplitView.preferredHeight: 330
243+
SplitView.fillWidth: true
244+
245+
logsView.logText: logs.logText
246+
247+
RowLayout {
248+
anchors.fill: parent
249+
250+
ColumnLayout {
251+
Label { text: "Sections config:" }
252+
Switch {
253+
id: ctrlShowEnabledSectionsOnly
254+
text: "Show enabled sections only"
255+
checked: true
256+
}
257+
Switch {
258+
id: ctrlMarketEnabled
259+
text: "Market enabled"
260+
checked: true
261+
}
262+
Switch {
263+
id: ctrlBrowserEnabled
264+
text: "Browser enabled"
265+
checked: true
266+
}
267+
Switch {
268+
id: ctrlNodeEnabled
269+
text: "Node mgmt enabled"
270+
checked: false
271+
}
272+
Switch {
273+
id: ctrlThirdPartyServices
274+
text: "Third party services enabled"
275+
checked: true
276+
}
277+
Switch {
278+
id: ctrlSettingsHasNotification
279+
text: "Settings has notification"
280+
}
281+
Switch {
282+
id: ctrlShowCreateCommunityBadge
283+
text: "Show create community badge"
284+
}
285+
}
286+
287+
ColumnLayout {
288+
Layout.fillWidth: true
289+
Label { text: "Activity Center:" }
290+
Switch {
291+
id: ctrlAcHasUnseenNotifications
292+
text: "Has unseen notifications"
293+
checked: true
294+
}
295+
RowLayout {
296+
Label { text: "Notifications count:" }
297+
SpinBox {
298+
id: ctrlAcUnreadNotificationsCount
299+
from: 0
300+
to: 101
301+
value: 4
302+
editable: true
303+
}
304+
}
305+
Item { Layout.fillHeight: true }
306+
}
307+
}
308+
}
309+
}
310+
311+
// category: Panels
312+
// status: good
313+
// https://www.figma.com/design/pJgiysu3rw8XvL4wS2Us7W/DS?node-id=4185-86833&t=lNokXnXl5AHjxHan-0
314+
// https://www.figma.com/design/pJgiysu3rw8XvL4wS2Us7W/DS?node-id=4185-86833&t=hN6bacud6gPREDcH-0

storybook/qmlTests/tests/tst_HomePage.qml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ Item {
136136
key: "1;0x7F47C2e98a4BBf5487E6fb082eC2D9Ab0E6d8884", searchStr: "Fab"}, // Fab
137137
{tag: "chat", sectionType: Constants.appSection.chat, key: "2;id1", searchStr: "Punx"}, // 1-1 chat
138138
{tag: "group chat", sectionType: Constants.appSection.chat, key: "2;id5", searchStr: "Channel Y_3"}, // group chat
139-
{tag: "community", sectionType: Constants.appSection.community, key: "3;id15", searchStr: "Dribb"}, // Dribble
139+
{tag: "community", sectionType: Constants.appSection.community, key: "3;id106", searchStr: "Dribb"}, // Dribble
140140
{tag: "dApp", sectionType: Constants.appSection.dApp, key: "999;https://dapp.test/2", searchStr: "dapp 2"}, // Test dApp 2
141141
{tag: "settings", sectionType: Constants.appSection.profile, key: "4;1", searchStr: "passw"}, // Settings/Password
142142
]

0 commit comments

Comments
 (0)