fix(@desktop/sections): make ctrl+k display chats from communities
Closes: #4059
This commit is contained in:
parent
16328823a9
commit
914c7b2839
|
@ -0,0 +1,35 @@
|
||||||
|
type
|
||||||
|
Item* = ref object
|
||||||
|
chatId: string
|
||||||
|
name: string
|
||||||
|
color: string
|
||||||
|
icon: string
|
||||||
|
sectionId: string
|
||||||
|
sectionName: string
|
||||||
|
|
||||||
|
proc initItem*(chatId, name, color, icon, sectionId, sectionName: string): Item =
|
||||||
|
result = Item()
|
||||||
|
result.chatId = chatId
|
||||||
|
result.name = name
|
||||||
|
result.color = color
|
||||||
|
result.icon = icon
|
||||||
|
result.sectionId = sectionId
|
||||||
|
result.sectionName = sectionName
|
||||||
|
|
||||||
|
proc chatId*(self: Item): string =
|
||||||
|
self.chatId
|
||||||
|
|
||||||
|
proc name*(self: Item): string =
|
||||||
|
self.name
|
||||||
|
|
||||||
|
proc color*(self: Item): string =
|
||||||
|
self.color
|
||||||
|
|
||||||
|
proc icon*(self: Item): string =
|
||||||
|
self.icon
|
||||||
|
|
||||||
|
proc sectionId*(self: Item): string =
|
||||||
|
self.sectionId
|
||||||
|
|
||||||
|
proc sectionName*(self: Item): string =
|
||||||
|
self.sectionName
|
|
@ -0,0 +1,66 @@
|
||||||
|
import NimQml, Tables
|
||||||
|
import chat_search_item
|
||||||
|
|
||||||
|
type
|
||||||
|
ModelRole {.pure.} = enum
|
||||||
|
ChatId = UserRole + 1
|
||||||
|
Name
|
||||||
|
Color
|
||||||
|
Icon
|
||||||
|
SectionId
|
||||||
|
SectionName
|
||||||
|
|
||||||
|
QtObject:
|
||||||
|
type Model* = ref object of QAbstractListModel
|
||||||
|
items: seq[Item]
|
||||||
|
|
||||||
|
proc setup(self: Model) =
|
||||||
|
self.QAbstractListModel.setup
|
||||||
|
|
||||||
|
proc delete(self: Model) =
|
||||||
|
self.items = @[]
|
||||||
|
self.QAbstractListModel.delete
|
||||||
|
|
||||||
|
proc newModel*(): Model =
|
||||||
|
new(result, delete)
|
||||||
|
result.setup
|
||||||
|
|
||||||
|
proc setItems*(self: Model, items: seq[Item]) =
|
||||||
|
self.beginResetModel()
|
||||||
|
self.items = items
|
||||||
|
self.endResetModel()
|
||||||
|
|
||||||
|
method rowCount(self: Model, index: QModelIndex = nil): int =
|
||||||
|
return self.items.len
|
||||||
|
|
||||||
|
method roleNames(self: Model): Table[int, string] =
|
||||||
|
{
|
||||||
|
ModelRole.ChatId.int:"chatId",
|
||||||
|
ModelRole.Name.int:"name",
|
||||||
|
ModelRole.Color.int:"color",
|
||||||
|
ModelRole.Icon.int:"icon",
|
||||||
|
ModelRole.SectionId.int:"sectionId",
|
||||||
|
ModelRole.SectionName.int:"sectionName",
|
||||||
|
}.toTable
|
||||||
|
|
||||||
|
method data(self: Model, index: QModelIndex, role: int): QVariant =
|
||||||
|
if not index.isValid:
|
||||||
|
return
|
||||||
|
if index.row < 0 or index.row >= self.items.len:
|
||||||
|
return
|
||||||
|
let item = self.items[index.row]
|
||||||
|
let enumRole = role.ModelRole
|
||||||
|
|
||||||
|
case enumRole:
|
||||||
|
of ModelRole.ChatId:
|
||||||
|
result = newQVariant(item.chatId)
|
||||||
|
of ModelRole.Name:
|
||||||
|
result = newQVariant(item.name)
|
||||||
|
of ModelRole.Color:
|
||||||
|
result = newQVariant(item.color)
|
||||||
|
of ModelRole.Icon:
|
||||||
|
result = newQVariant(item.icon)
|
||||||
|
of ModelRole.SectionId:
|
||||||
|
result = newQVariant(item.sectionId)
|
||||||
|
of ModelRole.SectionName:
|
||||||
|
result = newQVariant(item.sectionName)
|
|
@ -64,6 +64,9 @@ QtObject:
|
||||||
method rowCount(self: Model, index: QModelIndex = nil): int =
|
method rowCount(self: Model, index: QModelIndex = nil): int =
|
||||||
return self.items.len
|
return self.items.len
|
||||||
|
|
||||||
|
proc items*(self: Model): seq[Item] =
|
||||||
|
return self.items
|
||||||
|
|
||||||
method roleNames(self: Model): Table[int, string] =
|
method roleNames(self: Model): Table[int, string] =
|
||||||
{
|
{
|
||||||
ModelRole.Id.int:"itemId",
|
ModelRole.Id.int:"itemId",
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import NimQml, Tables, chronicles, json, sequtils
|
import NimQml, Tables, chronicles, json, sequtils
|
||||||
import io_interface
|
import io_interface
|
||||||
import ../io_interface as delegate_interface
|
import ../io_interface as delegate_interface
|
||||||
import view, controller, item, sub_item, model, sub_model, base_item
|
import view, controller, item, sub_item, sub_model, base_item
|
||||||
|
import model as chats_model
|
||||||
import ../../shared_models/contacts_item as contacts_item
|
import ../../shared_models/contacts_item as contacts_item
|
||||||
import ../../shared_models/contacts_model as contacts_model
|
import ../../shared_models/contacts_model as contacts_model
|
||||||
|
|
||||||
|
@ -355,6 +356,9 @@ method onActiveSectionChange*(self: Module, sectionId: string) =
|
||||||
self.updateNotifications(self.controller.getActiveChatId(), unviewedMessagesCount=0, unviewedMentionsCount=0)
|
self.updateNotifications(self.controller.getActiveChatId(), unviewedMessagesCount=0, unviewedMentionsCount=0)
|
||||||
self.delegate.onActiveChatChange(self.controller.getMySectionId(), self.controller.getActiveChatId())
|
self.delegate.onActiveChatChange(self.controller.getMySectionId(), self.controller.getActiveChatId())
|
||||||
|
|
||||||
|
method chatsModel*(self: Module): chats_model.Model =
|
||||||
|
return self.view.chatsModel()
|
||||||
|
|
||||||
method createPublicChat*(self: Module, chatId: string) =
|
method createPublicChat*(self: Module, chatId: string) =
|
||||||
if(self.controller.isCommunity()):
|
if(self.controller.isCommunity()):
|
||||||
debug "creating public chat is not allowed for community, most likely it's an error in qml", methodName="createPublicChat"
|
debug "creating public chat is not allowed for community, most likely it's an error in qml", methodName="createPublicChat"
|
||||||
|
|
|
@ -8,6 +8,8 @@ import ../../../../../app_service/service/message/service as message_service
|
||||||
import ../../../../../app_service/service/gif/service as gif_service
|
import ../../../../../app_service/service/gif/service as gif_service
|
||||||
import ../../../../../app_service/service/mailservers/service as mailservers_service
|
import ../../../../../app_service/service/mailservers/service as mailservers_service
|
||||||
|
|
||||||
|
import ../model as chats_model
|
||||||
|
|
||||||
import ../../../../core/eventemitter
|
import ../../../../core/eventemitter
|
||||||
|
|
||||||
method delete*(self: AccessInterface) {.base.} =
|
method delete*(self: AccessInterface) {.base.} =
|
||||||
|
@ -30,4 +32,7 @@ method getModuleAsVariant*(self: AccessInterface): QVariant {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
method onActiveSectionChange*(self: AccessInterface, sectionId: string) {.base.} =
|
method onActiveSectionChange*(self: AccessInterface, sectionId: string) {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method chatsModel*(self: AccessInterface): chats_model.Model {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
|
@ -57,6 +57,9 @@ QtObject:
|
||||||
method rowCount(self: SubModel, index: QModelIndex = nil): int =
|
method rowCount(self: SubModel, index: QModelIndex = nil): int =
|
||||||
return self.items.len
|
return self.items.len
|
||||||
|
|
||||||
|
proc items*(self: SubModel): seq[SubItem] =
|
||||||
|
return self.items
|
||||||
|
|
||||||
method roleNames(self: SubModel): Table[int, string] =
|
method roleNames(self: SubModel): Table[int, string] =
|
||||||
{
|
{
|
||||||
ModelRole.Id.int:"itemId",
|
ModelRole.Id.int:"itemId",
|
||||||
|
|
|
@ -251,4 +251,7 @@ method resolveENS*(self: Controller, ensName: string, uuid: string = "") =
|
||||||
self.contactsService.resolveENS(ensName, uuid)
|
self.contactsService.resolveENS(ensName, uuid)
|
||||||
|
|
||||||
method isMnemonicBackedUp*(self: Controller): bool =
|
method isMnemonicBackedUp*(self: Controller): bool =
|
||||||
result = self.privacyService.isMnemonicBackedUp()
|
result = self.privacyService.isMnemonicBackedUp()
|
||||||
|
|
||||||
|
method switchTo*(self: Controller, sectionId, chatId: string) =
|
||||||
|
self.messageService.switchTo(sectionId, chatId, "")
|
||||||
|
|
|
@ -48,4 +48,7 @@ method resolveENS*(self: AccessInterface, ensName: string, uuid: string = "") {.
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
method isMnemonicBackedUp*(self: AccessInterface): bool {.base.} =
|
method isMnemonicBackedUp*(self: AccessInterface): bool {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method switchTo*(self: AccessInterface, sectionId, chatId: string) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
import NimQml, tables, json, sugar, sequtils
|
import NimQml, tables, json, sugar, sequtils
|
||||||
|
|
||||||
import io_interface, view, controller
|
import io_interface, view, controller, chat_search_item, chat_search_model
|
||||||
import ./communities/models/[pending_request_item, pending_request_model]
|
import ./communities/models/[pending_request_item, pending_request_model]
|
||||||
import ../shared_models/[user_item, user_model, section_item, section_model, active_section]
|
import ../shared_models/[user_item, user_model, section_item, section_model, active_section]
|
||||||
import ../../global/app_sections_config as conf
|
import ../../global/app_sections_config as conf
|
||||||
import ../../global/app_signals
|
import ../../global/app_signals
|
||||||
import ../../global/global_singleton
|
import ../../global/global_singleton
|
||||||
|
|
||||||
|
import chat_section/[model, sub_item, sub_model]
|
||||||
|
import chat_section/base_item as chat_section_base_item
|
||||||
|
import chat_section/item as chat_section_item
|
||||||
import chat_section/module as chat_section_module
|
import chat_section/module as chat_section_module
|
||||||
import wallet_section/module as wallet_section_module
|
import wallet_section/module as wallet_section_module
|
||||||
import browser_section/module as browser_section_module
|
import browser_section/module as browser_section_module
|
||||||
|
@ -508,6 +511,27 @@ method getCommunitySectionModule*[T](self: Module[T], communityId: string): QVar
|
||||||
|
|
||||||
return self.communitySectionsModule[communityId].getModuleAsVariant()
|
return self.communitySectionsModule[communityId].getModuleAsVariant()
|
||||||
|
|
||||||
|
method rebuildChatSearchModel*[T](self: Module[T]) =
|
||||||
|
let transformItem = proc(item: chat_section_base_item.BaseItem, sectionId, sectionName: string): chat_search_item.Item =
|
||||||
|
result = chat_search_item.initItem(item.id(), item.name(), item.color(), item.icon(), sectionId, sectionName)
|
||||||
|
|
||||||
|
let transform = proc(items: seq[chat_section_item.Item], sectionId, sectionName: string): seq[chat_search_item.Item] =
|
||||||
|
for item in items:
|
||||||
|
if item.type() != ChatType.Unknown.int:
|
||||||
|
result.add(transformItem(item, sectionId, sectionName))
|
||||||
|
else:
|
||||||
|
for subItem in item.subItems().items():
|
||||||
|
result.add(transformItem(subItem, sectionId, sectionName))
|
||||||
|
|
||||||
|
var items = transform(self.chatSectionModule.chatsModel().items(), conf.CHAT_SECTION_ID, conf.CHAT_SECTION_NAME)
|
||||||
|
for cId in self.communitySectionsModule.keys:
|
||||||
|
items.add(transform(self.communitySectionsModule[cId].chatsModel().items(), cId, self.view.model().getItemById(cId).name()))
|
||||||
|
|
||||||
|
self.view.chatSearchModel().setItems(items)
|
||||||
|
|
||||||
|
method switchTo*[T](self: Module[T], sectionId, chatId: string) =
|
||||||
|
self.controller.switchTo(sectionId, chatId)
|
||||||
|
|
||||||
method onActiveChatChange*[T](self: Module[T], sectionId: string, chatId: string) =
|
method onActiveChatChange*[T](self: Module[T], sectionId: string, chatId: string) =
|
||||||
self.appSearchModule.onActiveChatChange(sectionId, chatId)
|
self.appSearchModule.onActiveChatChange(sectionId, chatId)
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import NimQml
|
import NimQml
|
||||||
import ../../shared_models/section_item
|
import ../../shared_models/section_item
|
||||||
|
import ../chat_search_item
|
||||||
|
|
||||||
method viewDidLoad*(self: AccessInterface) {.base.} =
|
method viewDidLoad*(self: AccessInterface) {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
@ -26,4 +27,10 @@ method getContactDetailsAsJson*(self: AccessInterface, publicKey: string): strin
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
method resolveENS*(self: AccessInterface, ensName: string, uuid: string) {.base.} =
|
method resolveENS*(self: AccessInterface, ensName: string, uuid: string) {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method rebuildChatSearchModel*(self: AccessInterface) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method switchTo*(self: AccessInterface, sectionId, chatId: string) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
|
@ -3,15 +3,18 @@ import ../shared_models/section_model
|
||||||
import ../shared_models/section_item
|
import ../shared_models/section_item
|
||||||
import ../shared_models/active_section
|
import ../shared_models/active_section
|
||||||
import io_interface
|
import io_interface
|
||||||
|
import chat_search_model
|
||||||
|
|
||||||
QtObject:
|
QtObject:
|
||||||
type
|
type
|
||||||
View* = ref object of QObject
|
View* = ref object of QObject
|
||||||
delegate: io_interface.AccessInterface
|
delegate: io_interface.AccessInterface
|
||||||
model: SectionModel
|
model: section_model.SectionModel
|
||||||
modelVariant: QVariant
|
modelVariant: QVariant
|
||||||
activeSection: ActiveSection
|
activeSection: ActiveSection
|
||||||
activeSectionVariant: QVariant
|
activeSectionVariant: QVariant
|
||||||
|
chatSearchModel: chat_search_model.Model
|
||||||
|
chatSearchModelVariant: QVariant
|
||||||
tmpCommunityId: string # shouldn't be used anywhere except in prepareCommunitySectionModuleForCommunityId/getCommunitySectionModule procs
|
tmpCommunityId: string # shouldn't be used anywhere except in prepareCommunitySectionModuleForCommunityId/getCommunitySectionModule procs
|
||||||
|
|
||||||
proc activeSectionChanged*(self:View) {.signal.}
|
proc activeSectionChanged*(self:View) {.signal.}
|
||||||
|
@ -21,16 +24,20 @@ QtObject:
|
||||||
self.modelVariant.delete
|
self.modelVariant.delete
|
||||||
self.activeSection.delete
|
self.activeSection.delete
|
||||||
self.activeSectionVariant.delete
|
self.activeSectionVariant.delete
|
||||||
|
self.chatSearchModel.delete
|
||||||
|
self.chatSearchModelVariant.delete
|
||||||
self.QObject.delete
|
self.QObject.delete
|
||||||
|
|
||||||
proc newView*(delegate: io_interface.AccessInterface): View =
|
proc newView*(delegate: io_interface.AccessInterface): View =
|
||||||
new(result, delete)
|
new(result, delete)
|
||||||
result.QObject.setup
|
result.QObject.setup
|
||||||
result.delegate = delegate
|
result.delegate = delegate
|
||||||
result.model = newModel()
|
result.model = section_model.newModel()
|
||||||
result.modelVariant = newQVariant(result.model)
|
result.modelVariant = newQVariant(result.model)
|
||||||
result.activeSection = newActiveSection()
|
result.activeSection = newActiveSection()
|
||||||
result.activeSectionVariant = newQVariant(result.activeSection)
|
result.activeSectionVariant = newQVariant(result.activeSection)
|
||||||
|
result.chatSearchModel = chat_search_model.newModel()
|
||||||
|
result.chatSearchModelVariant = newQVariant(result.chatSearchModel)
|
||||||
|
|
||||||
proc load*(self: View) =
|
proc load*(self: View) =
|
||||||
# In some point, here, we will setup some exposed main module related things.
|
# In some point, here, we will setup some exposed main module related things.
|
||||||
|
@ -54,6 +61,21 @@ QtObject:
|
||||||
read = getModel
|
read = getModel
|
||||||
notify = modelChanged
|
notify = modelChanged
|
||||||
|
|
||||||
|
proc chatSearchModel*(self: View): chat_search_model.Model =
|
||||||
|
return self.chatSearchModel
|
||||||
|
|
||||||
|
proc chatSearchModelChanged*(self: View) {.signal.}
|
||||||
|
|
||||||
|
proc getChatSearchModel(self: View): QVariant {.slot.} =
|
||||||
|
return self.chatSearchModelVariant
|
||||||
|
|
||||||
|
proc rebuildChatSearchModel*(self: View) {.slot.} =
|
||||||
|
self.delegate.rebuildChatSearchModel()
|
||||||
|
|
||||||
|
QtProperty[QVariant] chatSearchModel:
|
||||||
|
read = getChatSearchModel
|
||||||
|
notify = chatSearchModelChanged
|
||||||
|
|
||||||
proc openStoreToKeychainPopup*(self: View) {.signal.}
|
proc openStoreToKeychainPopup*(self: View) {.signal.}
|
||||||
|
|
||||||
proc offerToStorePassword*(self: View) =
|
proc offerToStorePassword*(self: View) =
|
||||||
|
@ -96,6 +118,9 @@ QtObject:
|
||||||
let item = self.model.getItemBySectionType(sectionType.SectionType)
|
let item = self.model.getItemBySectionType(sectionType.SectionType)
|
||||||
self.delegate.setActiveSection(item)
|
self.delegate.setActiveSection(item)
|
||||||
|
|
||||||
|
proc switchTo*(self: View, sectionId: string, chatId: string) {.slot.} =
|
||||||
|
self.delegate.switchTo(sectionId, chatId)
|
||||||
|
|
||||||
proc setUserStatus*(self: View, status: bool) {.slot.} =
|
proc setUserStatus*(self: View, status: bool) {.slot.} =
|
||||||
self.delegate.setUserStatus(status)
|
self.delegate.setUserStatus(status)
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit d85ed4c3ed95fa1f32d8e50b2746691e5d9e5e4e
|
Subproject commit 5780f183c7b3cf63c3abbc584daa72078241e917
|
|
@ -19,6 +19,16 @@ QtObject {
|
||||||
property EmojiReactions emojiReactionsModel: EmojiReactions {
|
property EmojiReactions emojiReactionsModel: EmojiReactions {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
property var chatSearchModel: mainModuleInst.chatSearchModel
|
||||||
|
|
||||||
|
function rebuildChatSearchModel() {
|
||||||
|
mainModuleInst.rebuildChatSearchModel()
|
||||||
|
}
|
||||||
|
|
||||||
|
function setActiveSectionChat(sectionId, chatId) {
|
||||||
|
mainModuleInst.switchTo(sectionId, chatId)
|
||||||
|
}
|
||||||
|
|
||||||
// Not Refactored Yet
|
// Not Refactored Yet
|
||||||
// property var chatsModelInst: chatsModel
|
// property var chatsModelInst: chatsModel
|
||||||
// Not Refactored Yet
|
// Not Refactored Yet
|
||||||
|
|
|
@ -286,7 +286,7 @@ Item {
|
||||||
// // that's why we're using it this way
|
// // that's why we're using it this way
|
||||||
mainModule.prepareCommunitySectionModuleForCommunityId(model.id)
|
mainModule.prepareCommunitySectionModuleForCommunityId(model.id)
|
||||||
communityContextMenu.chatCommunitySectionModule = mainModule.getCommunitySectionModule()
|
communityContextMenu.chatCommunitySectionModule = mainModule.getCommunitySectionModule()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StatusMenuItem {
|
StatusMenuItem {
|
||||||
|
@ -723,12 +723,12 @@ Item {
|
||||||
Global.toastMessage = this;
|
Global.toastMessage = this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add SendModal here as it is used by the Wallet as well as the Browser
|
// Add SendModal here as it is used by the Wallet as well as the Browser
|
||||||
Loader {
|
Loader {
|
||||||
id: sendModal
|
id: sendModal
|
||||||
active: false
|
active: false
|
||||||
|
|
||||||
function open() {
|
function open() {
|
||||||
this.active = true
|
this.active = true
|
||||||
this.item.open()
|
this.item.open()
|
||||||
|
@ -783,52 +783,44 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Component {
|
StatusSearchListPopup {
|
||||||
id: statusSmartIdenticonComponent
|
|
||||||
StatusSmartIdenticon {
|
|
||||||
property string imageSource: ""
|
|
||||||
image: StatusImageSettings {
|
|
||||||
width: channelPicker.imageWidth
|
|
||||||
height: channelPicker.imageHeight
|
|
||||||
source: imageSource
|
|
||||||
isIdenticon: true
|
|
||||||
}
|
|
||||||
icon: StatusIconSettings {
|
|
||||||
width: channelPicker.imageWidth
|
|
||||||
height: channelPicker.imageHeight
|
|
||||||
letterSize: 15
|
|
||||||
color: Theme.palette.miscColor5
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StatusInputListPopup {
|
|
||||||
id: channelPicker
|
id: channelPicker
|
||||||
//% "Where do you want to go?"
|
|
||||||
title: qsTrId("where-do-you-want-to-go-")
|
|
||||||
showSearchBox: true
|
|
||||||
width: 350
|
|
||||||
x: parent.width / 2 - width / 2
|
x: parent.width / 2 - width / 2
|
||||||
y: parent.height / 2 - height / 2
|
y: parent.height / 2 - height / 2
|
||||||
// TODO improve this to work with community Chats as well
|
|
||||||
modelList: mainModule.getChatSectionModule().model
|
searchBoxPlaceholder: qsTr("Where do you want to go?")
|
||||||
getText: function (modelData) {
|
model: rootStore.chatSearchModel
|
||||||
return modelData.name
|
delegate: StatusListItem {
|
||||||
}
|
property var modelData
|
||||||
getId: function (modelData) {
|
property bool isCurrentItem: true
|
||||||
return modelData.itemId
|
function filterAccepts(searchText) {
|
||||||
}
|
return title.includes(searchText)
|
||||||
getImageComponent: function (parent, modelData) {
|
}
|
||||||
return statusSmartIdenticonComponent.createObject(parent, {
|
|
||||||
imageSource: modelData.identicon,
|
title: modelData ? modelData.name : ""
|
||||||
name: modelData.name
|
label: modelData? modelData.sectionName : ""
|
||||||
});
|
highlighted: isCurrentItem
|
||||||
|
sensor.hoverEnabled: false
|
||||||
|
statusListItemIcon {
|
||||||
|
name: modelData ? modelData.name : ""
|
||||||
|
active: true
|
||||||
|
}
|
||||||
|
icon {
|
||||||
|
width: image.width
|
||||||
|
height: image.height
|
||||||
|
color: modelData ? modelData.color : ""
|
||||||
|
}
|
||||||
|
image {
|
||||||
|
source: modelData ? modelData.icon : ""
|
||||||
|
isIdenticon: true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onClicked: function (index, id) {
|
onAboutToShow: rootStore.rebuildChatSearchModel()
|
||||||
Global.changeAppSectionBySectionType(Constants.appSection.chat)
|
onSelected: {
|
||||||
mainModule.getChatSectionModule().setActiveItem(id, "")
|
rootStore.setActiveSectionChat(modelData.sectionId, modelData.chatId)
|
||||||
channelPicker.close()
|
close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,166 @@
|
||||||
|
import QtQuick 2.14
|
||||||
|
import QtQuick.Controls 2.14
|
||||||
|
import QtQuick.Layouts 1.14
|
||||||
|
import QtGraphicalEffects 1.0
|
||||||
|
|
||||||
|
import StatusQ.Components 0.1
|
||||||
|
import StatusQ.Controls 0.1
|
||||||
|
import StatusQ.Core 0.1
|
||||||
|
import StatusQ.Core.Theme 0.1
|
||||||
|
|
||||||
|
import utils 1.0
|
||||||
|
|
||||||
|
Popup {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
width: 400
|
||||||
|
height: 300
|
||||||
|
|
||||||
|
property alias model: listView.model
|
||||||
|
|
||||||
|
// delegate interface has to be fulfilled
|
||||||
|
property Component delegate: Item {
|
||||||
|
property var modelData
|
||||||
|
property bool isCurrentItem
|
||||||
|
function filterAccepts(searchText) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
property string searchBoxPlaceholder: qsTr("Search...")
|
||||||
|
|
||||||
|
signal selected(int index, var modelData)
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
radius: Style.current.radius
|
||||||
|
color: Style.current.background
|
||||||
|
border.color: Style.current.border
|
||||||
|
layer.enabled: true
|
||||||
|
layer.effect: DropShadow {
|
||||||
|
verticalOffset: 3
|
||||||
|
radius: 8
|
||||||
|
samples: 15
|
||||||
|
fast: true
|
||||||
|
cached: true
|
||||||
|
color: "#22000000"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
StatusInput {
|
||||||
|
id: searchBox
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
leftPadding: 0
|
||||||
|
rightPadding: 0
|
||||||
|
input.placeholderText: root.searchBoxPlaceholder
|
||||||
|
input.icon: StatusIconSettings {
|
||||||
|
width: 24
|
||||||
|
height: 24
|
||||||
|
name: "search"
|
||||||
|
color: Theme.palette.baseColor1
|
||||||
|
}
|
||||||
|
|
||||||
|
function goToNextAvailableIndex(up) {
|
||||||
|
var currentIndex = listView.currentIndex
|
||||||
|
for (var i = 0; i < listView.count; i++) {
|
||||||
|
currentIndex = up ? (currentIndex === 0 ? listView.count - 1 : currentIndex - 1)
|
||||||
|
: (currentIndex === listView.count - 1 ? 0 : currentIndex + 1)
|
||||||
|
listView.currentIndex = currentIndex
|
||||||
|
if (listView.currentItem.visible) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
listView.currentIndex = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
Keys.onReleased: {
|
||||||
|
listView.selectByHover = false
|
||||||
|
|
||||||
|
if (event.key === Qt.Key_Down) {
|
||||||
|
searchBox.goToNextAvailableIndex(false)
|
||||||
|
}
|
||||||
|
if (event.key === Qt.Key_Up) {
|
||||||
|
searchBox.goToNextAvailableIndex(true)
|
||||||
|
}
|
||||||
|
if (event.key === Qt.Key_Escape) {
|
||||||
|
return root.close()
|
||||||
|
}
|
||||||
|
if (event.key === Qt.Key_Enter || event.key === Qt.Key_Return) {
|
||||||
|
return root.selected(listView.currentIndex,
|
||||||
|
listView.currentItem.myData)
|
||||||
|
}
|
||||||
|
if (!listView.currentItem.visible) {
|
||||||
|
goToNextAvailableIndex(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onTextChanged: if (text === "") listView.currentIndex = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
ListView {
|
||||||
|
id: listView
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
|
||||||
|
property bool selectByHover: false
|
||||||
|
|
||||||
|
clip: true
|
||||||
|
highlightMoveDuration: 200
|
||||||
|
|
||||||
|
delegate: Item {
|
||||||
|
id: delegateItem
|
||||||
|
|
||||||
|
property var myData: typeof modelData === "undefined" ? model : modelData
|
||||||
|
|
||||||
|
width: listView.width
|
||||||
|
height: visible ? delegateLoader.height : 0
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: delegateLoader
|
||||||
|
|
||||||
|
width: parent.width
|
||||||
|
sourceComponent: root.delegate
|
||||||
|
|
||||||
|
onLoaded: {
|
||||||
|
item.modelData = delegateItem.myData
|
||||||
|
item.isCurrentItem = Qt.binding(() => delegateItem.ListView.isCurrentItem)
|
||||||
|
delegateItem.visible = Qt.binding(() => item.filterAccepts(searchBox.text))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
hoverEnabled: true
|
||||||
|
onClicked: (mouse) => {
|
||||||
|
listView.currentIndex = index
|
||||||
|
root.selected(index, delegateItem.myData)
|
||||||
|
mouse.accepted = false
|
||||||
|
}
|
||||||
|
onContainsMouseChanged: if (containsMouse) listView.currentIndex = index
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
anchors.fill: parent
|
||||||
|
active: !listView.selectByHover
|
||||||
|
|
||||||
|
sourceComponent: MouseArea {
|
||||||
|
hoverEnabled: true
|
||||||
|
onPositionChanged: listView.selectByHover = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onAboutToShow: {
|
||||||
|
listView.currentIndex = 0
|
||||||
|
listView.selectByHover = false
|
||||||
|
searchBox.text = ""
|
||||||
|
searchBox.input.edit.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
|
@ -21,6 +21,7 @@ StatusImageModal 1.0 StatusImageModal.qml
|
||||||
StatusImageRadioButton 1.0 StatusImageRadioButton.qml
|
StatusImageRadioButton 1.0 StatusImageRadioButton.qml
|
||||||
StatusInputListPopup 1.0 StatusInputListPopup.qml
|
StatusInputListPopup 1.0 StatusInputListPopup.qml
|
||||||
StatusNotification 1.0 StatusNotification.qml
|
StatusNotification 1.0 StatusNotification.qml
|
||||||
|
StatusSearchListPopup 1.0 StatusSearchListPopup.qml
|
||||||
StatusSectionDescItem 1.0 StatusSectionDescItem.qml
|
StatusSectionDescItem 1.0 StatusSectionDescItem.qml
|
||||||
StatusSectionHeadline 1.0 StatusSectionHeadline.qml
|
StatusSectionHeadline 1.0 StatusSectionHeadline.qml
|
||||||
StatusSettingsLineButton 1.0 StatusSettingsLineButton.qml
|
StatusSettingsLineButton 1.0 StatusSettingsLineButton.qml
|
||||||
|
|
Loading…
Reference in New Issue