diff --git a/storybook/pages/StatusChatInputPage.qml b/storybook/pages/StatusChatInputPage.qml index 3f4cc6fddf..35ad802490 100644 --- a/storybook/pages/StatusChatInputPage.qml +++ b/storybook/pages/StatusChatInputPage.qml @@ -7,7 +7,7 @@ import Models 1.0 import utils 1.0 import shared.status 1.0 -import shared.stores 1.0 +import shared.stores 1.0 as SharedStores import StatusQ.Core.Utils 0.1 @@ -37,21 +37,6 @@ SplitView { } } - QtObject { - id: rootStoreMock - - property bool ready: false - - readonly property ListModel gifColumnA: ListModel {} - - Component.onCompleted: { - RootStore.isWalletEnabled = true - RootStore.gifUnfurlingEnabled = true - RootStore.gifColumnA = rootStoreMock.gifColumnA - rootStoreMock.ready = true - } - } - UsersModel { id: fakeUsersModel } @@ -71,7 +56,7 @@ SplitView { Loader { id: chatInputLoader - active: rootStoreMock.ready && globalUtilsMock.ready + active: globalUtilsMock.ready sourceComponent: StatusChatInput { id: chatInput property var globalUtils: globalUtilsMock.globalUtils @@ -112,6 +97,16 @@ SplitView { usersStore: ChatStores.UsersStore { readonly property var usersModel: fakeUsersModel } + + sharedStore: SharedStores.RootStore { + isWalletEnabled: true + gifUnfurlingEnabled: true + + property var gifStore: SharedStores.GifStore { + property var gifColumnA: ListModel {} + } + } + onSendMessage: { logs.logEvent("StatusChatInput::sendMessage", ["MessageWithPk"], [chatInput.getTextWithPublicKeys()]) logs.logEvent("StatusChatInput::sendMessage", ["PlainText"], [globalUtilsMock.globalUtils.plainText(chatInput.getTextWithPublicKeys())]) diff --git a/storybook/qmlTests/tests/tst_StatusChatInput.qml b/storybook/qmlTests/tests/tst_StatusChatInput.qml index 47fdbd3bd4..fbbc707634 100644 --- a/storybook/qmlTests/tests/tst_StatusChatInput.qml +++ b/storybook/qmlTests/tests/tst_StatusChatInput.qml @@ -7,7 +7,7 @@ import StatusQ 0.1 // https://github.com/status-im/status-desktop/issues/10218 import utils 1.0 import shared.status 1.0 -import shared.stores 1.0 +import shared.stores 1.0 as SharedStores import AppLayouts.Chat.stores 1.0 as ChatStores @@ -29,6 +29,15 @@ Item { usersStore: ChatStores.UsersStore { property var usersModel: ListModel {} } + + sharedStore: SharedStores.RootStore { + isWalletEnabled: true + gifUnfurlingEnabled: true + + property var gifStore: SharedStores.GifStore { + property var gifColumnA: ListModel {} + } + } } } @@ -696,20 +705,8 @@ Item { function isCompressedPubKey(publicKey) { return false } - } - - QtObject { - id: rootStoreMock - - property ListModel gifColumnA: ListModel {} - - property bool gifUnfurlingEnabled: true Component.onCompleted: { - RootStore.isWalletEnabled = true - RootStore.gifUnfurlingEnabled = rootStoreMock.gifUnfurlingEnabled - RootStore.gifColumnA = rootStoreMock.gifColumnA - Global.dragArea = root } } diff --git a/storybook/stubs/shared/stores/GifStore.qml b/storybook/stubs/shared/stores/GifStore.qml new file mode 100644 index 0000000000..2587cd419c --- /dev/null +++ b/storybook/stubs/shared/stores/GifStore.qml @@ -0,0 +1,3 @@ +import QtQml 2.15 + +QtObject {} diff --git a/storybook/stubs/shared/stores/RootStore.qml b/storybook/stubs/shared/stores/RootStore.qml index 84f235c642..cc3844f2cf 100644 --- a/storybook/stubs/shared/stores/RootStore.qml +++ b/storybook/stubs/shared/stores/RootStore.qml @@ -4,7 +4,6 @@ QtObject { property var userProfileInst property bool gifUnfurlingEnabled property bool isWalletEnabled - property var gifColumnA property var currentCurrency property bool neverAskAboutUnfurlingAgain: false diff --git a/storybook/stubs/shared/stores/qmldir b/storybook/stubs/shared/stores/qmldir index 682f93f57a..8ae4a68091 100644 --- a/storybook/stubs/shared/stores/qmldir +++ b/storybook/stubs/shared/stores/qmldir @@ -1,10 +1,11 @@ +BIP39_en 1.0 BIP39_en.qml CommunityTokensStore 1.0 CommunityTokensStore.qml CurrenciesStore 1.0 CurrenciesStore.qml +DAppsStore 1.0 DAppsStore.qml +GifStore 1.0 GifStore.qml NetworkConnectionStore 1.0 NetworkConnectionStore.qml +PermissionsStore 1.0 PermissionsStore.qml +ProfileStore 1.0 ProfileStore.qml RootStore 1.0 RootStore.qml TokenBalanceHistoryStore 1.0 TokenBalanceHistoryStore.qml -BIP39_en 1.0 BIP39_en.qml -DAppsStore 1.0 DAppsStore.qml -ProfileStore 1.0 ProfileStore.qml -PermissionsStore 1.0 PermissionsStore.qml TokenMarketValuesStore 1.0 TokenMarketValuesStore.qml diff --git a/ui/app/AppLayouts/Chat/views/ChatColumnView.qml b/ui/app/AppLayouts/Chat/views/ChatColumnView.qml index 0431b6f9f0..a6b7d1ad31 100644 --- a/ui/app/AppLayouts/Chat/views/ChatColumnView.qml +++ b/ui/app/AppLayouts/Chat/views/ChatColumnView.qml @@ -10,13 +10,15 @@ import StatusQ.Core.Backpressure 0.1 import StatusQ.Core.Theme 0.1 import StatusQ.Core.Utils 0.1 -import utils 1.0 import shared 1.0 -import shared.popups 1.0 -import shared.status 1.0 import shared.controls 1.0 -import shared.views.chat 1.0 +import shared.popups 1.0 import shared.popups.send 1.0 +import shared.status 1.0 +import shared.stores 1.0 as SharedStores +import shared.views.chat 1.0 +import utils 1.0 + import SortFilterProxyModel 0.2 import AppLayouts.Communities.popups 1.0 @@ -270,7 +272,7 @@ Item { id: chatInput width: parent.width visible: !!d.activeChatContentModule - + // When `enabled` is switched true->false, `textInput.text` is cleared before d.activeChatContentModule updates. // We delay the binding so that the `inputAreaModule.preservedProperties.text` doesn't get overriden with empty value. Binding on enabled { @@ -285,6 +287,9 @@ Item { store: root.rootStore usersStore: d.activeUsersStore + + sharedStore: SharedStores.RootStore + linkPreviewModel: !!d.activeChatContentModule ? d.activeChatContentModule.inputAreaModule.linkPreviewModel : null urlsList: d.urlsList askToEnableLinkPreview: { @@ -365,7 +370,7 @@ Item { onKeyUpPress: { d.activeMessagesStore.setEditModeOnLastMessage(root.rootStore.userProfileInst.pubKey) } - + onLinkPreviewReloaded: (link) => d.activeChatContentModule.inputAreaModule.reloadLinkPreview(link) onEnableLinkPreview: () => { d.activeChatContentModule.inputAreaModule.enableLinkPreview() diff --git a/ui/app/AppLayouts/Chat/views/CreateChatView.qml b/ui/app/AppLayouts/Chat/views/CreateChatView.qml index 9619fa2667..16e8aad047 100644 --- a/ui/app/AppLayouts/Chat/views/CreateChatView.qml +++ b/ui/app/AppLayouts/Chat/views/CreateChatView.qml @@ -9,9 +9,10 @@ import StatusQ.Components 0.1 import StatusQ.Core 0.1 import StatusQ.Core.Theme 0.1 -import utils 1.0 -import shared.status 1.0 import shared.controls.delegates 1.0 +import shared.status 1.0 +import shared.stores 1.0 as SharedStores +import utils 1.0 import AppLayouts.Chat.stores 1.0 as ChatStores @@ -163,6 +164,7 @@ Page { usersStore: ({ usersModel: membersSelector.model }) + sharedStore: SharedStores.RootStore onStickerSelected: { root.createChatPropertiesStore.createChatStickerHashId = hashId; root.createChatPropertiesStore.createChatStickerPackId = packId; diff --git a/ui/imports/shared/status/StatusChatInput.qml b/ui/imports/shared/status/StatusChatInput.qml index 8319d90d6b..3a215acd9c 100644 --- a/ui/imports/shared/status/StatusChatInput.qml +++ b/ui/imports/shared/status/StatusChatInput.qml @@ -9,7 +9,7 @@ import shared 1.0 import shared.controls.chat 1.0 import shared.panels 1.0 import shared.popups 1.0 -import shared.stores 1.0 +import shared.stores 1.0 as SharedStores //TODO remove this dependency import AppLayouts.Chat.panels 1.0 @@ -38,6 +38,7 @@ Rectangle { property ChatStores.UsersStore usersStore property ChatStores.RootStore store + property SharedStores.RootStore sharedStore property var emojiPopup: null property var stickersPopup: null @@ -1036,6 +1037,9 @@ Rectangle { StatusGifPopup { readonly property point relativePosition: d.getCommonPopupRelativePosition(this, parent) + gifStore: control.sharedStore.gifStore + gifUnfurlingEnabled: control.sharedStore.gifUnfurlingEnabled + width: 360 height: 440 x: relativePosition.x diff --git a/ui/imports/shared/status/StatusGifPopup.qml b/ui/imports/shared/status/StatusGifPopup.qml index 7665913e79..fab7e7203f 100644 --- a/ui/imports/shared/status/StatusGifPopup.qml +++ b/ui/imports/shared/status/StatusGifPopup.qml @@ -18,29 +18,32 @@ import "./StatusGifPopup" Popup { id: root + property GifStore gifStore + property bool gifUnfurlingEnabled + property var gifSelected: function () {} property var searchGif: Backpressure.debounce(searchBox, 500, function (query) { - RootStore.searchGifs(query) + root.gifStore.searchGifs(query) }) property var toggleCategory: function(newCategory) { previousCategory = currentCategory currentCategory = newCategory searchBox.text = "" if (currentCategory === GifPopupDefinitions.Category.Trending) { - RootStore.getTrendingsGifs() + root.gifStore.getTrendingsGifs() } else if(currentCategory === GifPopupDefinitions.Category.Favorite) { - RootStore.getFavoritesGifs() + root.gifStore.getFavoritesGifs() } else if(currentCategory === GifPopupDefinitions.Category.Recent) { - RootStore.getRecentsGifs() + root.gifStore.getRecentsGifs() } } property var toggleFavorite: function(item) { - RootStore.toggleFavoriteGif(item.id, currentCategory === GifPopupDefinitions.Category.Favorite) + root.gifStore.toggleFavoriteGif(item.id, currentCategory === GifPopupDefinitions.Category.Favorite) } property alias searchString: searchBox.text property int currentCategory: GifPopupDefinitions.Category.Trending property int previousCategory: GifPopupDefinitions.Category.Trending - property bool loading: RootStore.gifLoading + property bool loading: root.gifStore.gifLoading modal: false width: 360 @@ -62,8 +65,8 @@ Popup { onAboutToShow: { searchBox.text = "" searchBox.input.edit.forceActiveFocus() - if (RootStore.gifUnfurlingEnabled) { - RootStore.getTrendingsGifs() + if (root.gifUnfurlingEnabled) { + root.gifStore.getTrendingsGifs() } } @@ -95,7 +98,7 @@ Popup { SearchBox { id: searchBox placeholderText: qsTr("Search") - enabled: RootStore.gifUnfurlingEnabled + enabled: root.gifUnfurlingEnabled anchors.right: parent.right anchors.rightMargin: gifHeader.headerMargin anchors.top: parent.top @@ -137,14 +140,14 @@ Popup { Loader { id: gifsLoader - active: root.opened && RootStore.gifUnfurlingEnabled + active: root.opened && root.gifUnfurlingEnabled Layout.fillWidth: true Layout.alignment: Qt.AlignTop | Qt.AlignLeft Layout.preferredHeight: { const headerTextHeight = searchBox.text === "" ? headerText.height : 0 return 400 - gifHeader.height - headerTextHeight } - sourceComponent: RootStore.gifColumnA.rowCount() === 0 ? emptyPlaceholderComponent : gifItemsComponent + sourceComponent: root.gifStore.gifColumnA.rowCount() === 0 ? emptyPlaceholderComponent : gifItemsComponent } Row { @@ -161,7 +164,7 @@ Popup { onClicked: { toggleCategory(GifPopupDefinitions.Category.Trending) } - enabled: RootStore.gifUnfurlingEnabled + enabled: root.gifUnfurlingEnabled } StatusTabBarIconButton { @@ -170,7 +173,7 @@ Popup { onClicked: { toggleCategory(GifPopupDefinitions.Category.Recent) } - enabled: RootStore.gifUnfurlingEnabled + enabled: root.gifUnfurlingEnabled } StatusTabBarIconButton { @@ -179,7 +182,7 @@ Popup { onClicked: { toggleCategory(GifPopupDefinitions.Category.Favorite) } - enabled: RootStore.gifUnfurlingEnabled + enabled: root.gifUnfurlingEnabled } } } @@ -200,8 +203,13 @@ Popup { sourceComponent: ConfirmationPopup { visible: true + + onEnableGifsRequested: { + RootStore.setGifUnfurlingEnabled(true) + root.gifStore.getTrendingsGifs() + } } - active: !RootStore.gifUnfurlingEnabled + active: !root.gifUnfurlingEnabled } Component { @@ -219,36 +227,42 @@ Popup { property string lastHoveredId StatusGifColumn { - gifList.model: RootStore.gifColumnA + gifStore: root.gifStore + + gifList.model: root.gifStore.gifColumnA gifWidth: (root.width / 3) - Style.current.padding gifSelected: root.gifSelected toggleFavorite: root.toggleFavorite lastHoveredId: gifs.lastHoveredId - store: RootStore + onGifHovered: { gifs.lastHoveredId = id } } StatusGifColumn { - gifList.model: RootStore.gifColumnB + gifStore: root.gifStore + + gifList.model: root.gifStore.gifColumnB gifWidth: (root.width / 3) - Style.current.padding gifSelected: root.gifSelected toggleFavorite: root.toggleFavorite lastHoveredId: gifs.lastHoveredId - store: RootStore + onGifHovered: { gifs.lastHoveredId = id } } StatusGifColumn { - gifList.model: RootStore.gifColumnC + gifStore: root.gifStore + + gifList.model: root.gifStore.gifColumnC gifWidth: (root.width / 3) - Style.current.padding gifSelected: root.gifSelected toggleFavorite: root.toggleFavorite lastHoveredId: gifs.lastHoveredId - store: RootStore + onGifHovered: { gifs.lastHoveredId = id } @@ -265,7 +279,7 @@ Popup { currentCategory: root.currentCategory loading: root.loading onDoRetry: searchBox.text === "" - ? RootStore.getTrendingsGifs() + ? root.gifStore.getTrendingsGifs() : searchGif(searchBox.text) } } diff --git a/ui/imports/shared/status/StatusGifPopup/ConfirmationPopup.qml b/ui/imports/shared/status/StatusGifPopup/ConfirmationPopup.qml index f26c136547..7ccaa85921 100644 --- a/ui/imports/shared/status/StatusGifPopup/ConfirmationPopup.qml +++ b/ui/imports/shared/status/StatusGifPopup/ConfirmationPopup.qml @@ -13,6 +13,8 @@ import shared.controls 1.0 Popup { id: root + signal enableGifsRequested + anchors.centerIn: parent height: 278 width: 291 @@ -79,8 +81,7 @@ Popup { size: StatusBaseButton.Size.Small onClicked: { - RootStore.setGifUnfurlingEnabled(true) - RootStore.getTrendingsGifs() + root.enableGifsRequested() root.close() } } diff --git a/ui/imports/shared/status/StatusGifPopup/StatusGifColumn.qml b/ui/imports/shared/status/StatusGifPopup/StatusGifColumn.qml index 0746cc30e4..5009f4db3b 100644 --- a/ui/imports/shared/status/StatusGifPopup/StatusGifColumn.qml +++ b/ui/imports/shared/status/StatusGifPopup/StatusGifColumn.qml @@ -13,9 +13,11 @@ import shared.stores 1.0 Column { id: root spacing: 8 + + property GifStore gifStore + property alias gifList: repeater property int gifWidth: 0 - property RootStore store property var gifSelected: function () {} property var toggleFavorite: function () {} property string lastHoveredId @@ -52,7 +54,7 @@ Column { StatusBaseButton { id: starButton - property bool favorite: RootStore.isFavorite(model.id) + property bool favorite: root.gifStore.isFavorite(model.id) type: StatusFlatRoundButton.Type.Secondary textColor: hovered || favorite ? Style.current.yellow : Style.current.secondaryText @@ -111,7 +113,7 @@ Column { anchors.fill: parent hoverEnabled: true onClicked: function (event) { - root.store.addToRecentsGif(model.id) + root.gifStore.addToRecentsGif(model.id) root.gifSelected(event, model.url) } } diff --git a/ui/imports/shared/stores/GifStore.qml b/ui/imports/shared/stores/GifStore.qml new file mode 100644 index 0000000000..983cb3cbd3 --- /dev/null +++ b/ui/imports/shared/stores/GifStore.qml @@ -0,0 +1,48 @@ +import QtQuick 2.15 + +QtObject { + readonly property QtObject _d: QtObject { + id: d + + readonly property var gifsModuleInst: typeof gifsModule !== "undefined" + ? gifsModule : null + } + + property var gifColumnA: d.gifsModuleInst ? d.gifsModuleInst.gifColumnA : null + property var gifColumnB: d.gifsModuleInst ? d.gifsModuleInst.gifColumnB : null + property var gifColumnC: d.gifsModuleInst ? d.gifsModuleInst.gifColumnC : null + property bool gifLoading: d.gifsModuleInst ? d.gifsModuleInst.gifLoading : false + + function searchGifs(query) { + if (d.gifsModuleInst) + d.gifsModuleInst.searchGifs(query) + } + + function getTrendingsGifs() { + if (d.gifsModuleInst) + d.gifsModuleInst.getTrendingsGifs() + } + + function getRecentsGifs() { + if (d.gifsModuleInst) + d.gifsModuleInst.getRecentsGifs() + } + + function getFavoritesGifs() { + return d.gifsModuleInst ? d.gifsModuleInst.getFavoritesGifs() : null + } + + function isFavorite(id) { + return d.gifsModuleInst ? d.gifsModuleInst.isFavorite(id) : null + } + + function toggleFavoriteGif(id, reload) { + if (d.gifsModuleInst) + d.gifsModuleInst.toggleFavoriteGif(id, reload) + } + + function addToRecentsGif(id) { + if (d.gifsModuleInst) + d.gifsModuleInst.addToRecentsGif(id) + } +} diff --git a/ui/imports/shared/stores/RootStore.qml b/ui/imports/shared/stores/RootStore.qml index 9e897e5db3..76b9d3166f 100644 --- a/ui/imports/shared/stores/RootStore.qml +++ b/ui/imports/shared/stores/RootStore.qml @@ -1,11 +1,13 @@ pragma Singleton -import QtQuick 2.12 +import QtQuick 2.15 import utils 1.0 QtObject { id: root + readonly property GifStore gifStore: GifStore {} + property var profileSectionModuleInst: profileSectionModule property var privacyModule: profileSectionModuleInst.privacyModule property var userProfileInst: !!Global.userProfile? Global.userProfile : null @@ -45,51 +47,6 @@ QtObject { localAccountSensitiveSettings.gifUnfurlingEnabled = value } - property var gifsModuleInst: typeof gifsModule !== "undefined" ? gifsModule : null - property var gifColumnA: gifsModuleInst ? gifsModuleInst.gifColumnA - : null - property var gifColumnB: gifsModuleInst ? gifsModuleInst.gifColumnB - : null - property var gifColumnC: gifsModuleInst ? gifsModuleInst.gifColumnC - : null - property bool gifLoading: gifsModuleInst ? gifsModuleInst.gifLoading - : false - - function searchGifs(query) { - if (gifsModuleInst) - gifsModuleInst.searchGifs(query) - } - - function getTrendingsGifs() { - if (gifsModuleInst) - gifsModuleInst.getTrendingsGifs() - } - - function getRecentsGifs() { - if (gifsModuleInst) - gifsModuleInst.getRecentsGifs() - } - - function getFavoritesGifs() { - return gifsModuleInst ? gifsModuleInst.getFavoritesGifs() - : null - } - - function isFavorite(id) { - return gifsModuleInst ? gifsModuleInst.isFavorite(id) - : null - } - - function toggleFavoriteGif(id, reload) { - if (gifsModuleInst) - gifsModuleInst.toggleFavoriteGif(id, reload) - } - - function addToRecentsGif(id) { - if (gifsModuleInst) - gifsModuleInst.addToRecentsGif(id) - } - function getPasswordStrengthScore(password) { return root.privacyModule.getPasswordStrengthScore(password); } diff --git a/ui/imports/shared/stores/qmldir b/ui/imports/shared/stores/qmldir index 4e8b5ada5b..25db99462a 100644 --- a/ui/imports/shared/stores/qmldir +++ b/ui/imports/shared/stores/qmldir @@ -1,11 +1,12 @@ -singleton RootStore 1.0 RootStore.qml -CurrenciesStore 1.0 CurrenciesStore.qml -CommunityTokensStore 1.0 CommunityTokensStore.qml BIP39_en 1.0 BIP39_en.qml ChartStoreBase 1.0 ChartStoreBase.qml +CommunityTokensStore 1.0 CommunityTokensStore.qml +CurrenciesStore 1.0 CurrenciesStore.qml +DAppsStore 1.0 DAppsStore.qml +GifStore 1.0 GifStore.qml +MetricsStore 1.0 MetricsStore.qml +NetworkConnectionStore 1.0 NetworkConnectionStore.qml PermissionsStore 1.0 PermissionsStore.qml TokenBalanceHistoryStore 1.0 TokenBalanceHistoryStore.qml TokenMarketValuesStore 1.0 TokenMarketValuesStore.qml -MetricsStore 1.0 MetricsStore.qml -NetworkConnectionStore 1.0 NetworkConnectionStore.qml -DAppsStore 1.0 DAppsStore.qml +singleton RootStore 1.0 RootStore.qml diff --git a/ui/imports/shared/views/chat/MessageView.qml b/ui/imports/shared/views/chat/MessageView.qml index b1e9b5f86a..29f8a77622 100644 --- a/ui/imports/shared/views/chat/MessageView.qml +++ b/ui/imports/shared/views/chat/MessageView.qml @@ -8,7 +8,7 @@ import shared.controls 1.0 import shared.popups 1.0 import shared.views.chat 1.0 import shared.controls.chat 1.0 -import shared.stores 1.0 +import shared.stores 1.0 as SharedStores import StatusQ.Core 0.1 import StatusQ.Core.Theme 0.1 @@ -916,6 +916,7 @@ Loader { store: root.rootStore usersStore: root.usersStore + sharedStore: SharedStores.RootStore emojiPopup: root.emojiPopup stickersPopup: root.stickersPopup