parent
00f10f600a
commit
1e39cf4821
|
@ -1,4 +1,4 @@
|
||||||
import NimQml, Tables, json, sequtils, chronicles, times, strutils
|
import NimQml, Tables, json, sequtils, chronicles, times, re, sugar, strutils
|
||||||
|
|
||||||
import ../../status/status
|
import ../../status/status
|
||||||
import ../../status/accounts as status_accounts
|
import ../../status/accounts as status_accounts
|
||||||
|
@ -11,7 +11,7 @@ import ../../status/profile/profile
|
||||||
|
|
||||||
import ../../status/threads
|
import ../../status/threads
|
||||||
|
|
||||||
import views/channels_list, views/message_list, views/chat_item, views/sticker_pack_list, views/sticker_list
|
import views/channels_list, views/message_list, views/chat_item, views/sticker_pack_list, views/sticker_list, views/suggestions_list
|
||||||
|
|
||||||
logScope:
|
logScope:
|
||||||
topics = "chats-view"
|
topics = "chats-view"
|
||||||
|
@ -21,6 +21,7 @@ QtObject:
|
||||||
ChatsView* = ref object of QAbstractListModel
|
ChatsView* = ref object of QAbstractListModel
|
||||||
status: Status
|
status: Status
|
||||||
chats*: ChannelsList
|
chats*: ChannelsList
|
||||||
|
currentSuggestions*: SuggestionsList
|
||||||
callResult: string
|
callResult: string
|
||||||
messageList: Table[string, ChatMessageList]
|
messageList: Table[string, ChatMessageList]
|
||||||
activeChannel*: ChatItemView
|
activeChannel*: ChatItemView
|
||||||
|
@ -35,6 +36,7 @@ QtObject:
|
||||||
proc delete(self: ChatsView) =
|
proc delete(self: ChatsView) =
|
||||||
self.chats.delete
|
self.chats.delete
|
||||||
self.activeChannel.delete
|
self.activeChannel.delete
|
||||||
|
self.currentSuggestions.delete
|
||||||
for msg in self.messageList.values:
|
for msg in self.messageList.values:
|
||||||
msg.delete
|
msg.delete
|
||||||
self.messageList = initTable[string, ChatMessageList]()
|
self.messageList = initTable[string, ChatMessageList]()
|
||||||
|
@ -47,6 +49,7 @@ QtObject:
|
||||||
result.connected = false
|
result.connected = false
|
||||||
result.chats = newChannelsList(status)
|
result.chats = newChannelsList(status)
|
||||||
result.activeChannel = newChatItemView(status)
|
result.activeChannel = newChatItemView(status)
|
||||||
|
result.currentSuggestions = newSuggestionsList()
|
||||||
result.messageList = initTable[string, ChatMessageList]()
|
result.messageList = initTable[string, ChatMessageList]()
|
||||||
result.stickerPacks = newStickerPackList()
|
result.stickerPacks = newStickerPackList()
|
||||||
result.recentStickers = newStickerList()
|
result.recentStickers = newStickerList()
|
||||||
|
@ -70,8 +73,30 @@ QtObject:
|
||||||
proc getChannelColor*(self: ChatsView, channel: string): string {.slot.} =
|
proc getChannelColor*(self: ChatsView, channel: string): string {.slot.} =
|
||||||
self.chats.getChannelColor(channel)
|
self.chats.getChannelColor(channel)
|
||||||
|
|
||||||
|
proc replaceMentionsWithPubKeys(self: ChatsView, mentions: seq[string], contacts: seq[Profile], message: string, predicate: proc (contact: Profile): string): string =
|
||||||
|
result = message
|
||||||
|
for mention in mentions:
|
||||||
|
let matches = contacts.filter(c => "@" & predicate(c) == mention).map(c => c.address)
|
||||||
|
if matches.len > 0:
|
||||||
|
let pubKey = matches[0]
|
||||||
|
result = message.replace(mention, "@" & pubKey)
|
||||||
|
|
||||||
proc sendMessage*(self: ChatsView, message: string, replyTo: string) {.slot.} =
|
proc sendMessage*(self: ChatsView, message: string, replyTo: string) {.slot.} =
|
||||||
self.status.chat.sendMessage(self.activeChannel.id, message, replyTo)
|
let aliasPattern = re(r"(@[A-z][a-z]* [A-z][a-z]* [A-z][a-z]*)", flags = {reStudy, reIgnoreCase})
|
||||||
|
let ensPattern = re(r"(@\w*(?=\.stateofus\.eth))", flags = {reStudy, reIgnoreCase})
|
||||||
|
let namePattern = re(r"(@\w*)", flags = {reStudy, reIgnoreCase})
|
||||||
|
|
||||||
|
let contacts = self.status.contacts.getContacts()
|
||||||
|
|
||||||
|
let aliasMentions = findAll(message, aliasPattern)
|
||||||
|
let ensMentions = findAll(message, ensPattern)
|
||||||
|
let nameMentions = findAll(message, namePattern)
|
||||||
|
|
||||||
|
var m = self.replaceMentionsWithPubKeys(aliasMentions, contacts, message, (c => c.alias))
|
||||||
|
m = self.replaceMentionsWithPubKeys(ensMentions, contacts, m, (c => c.ensName))
|
||||||
|
m = self.replaceMentionsWithPubKeys(nameMentions, contacts, m, (c => c.ensName.split(".")[0]))
|
||||||
|
|
||||||
|
self.status.chat.sendMessage(self.activeChannel.id, m, replyTo)
|
||||||
|
|
||||||
proc activeChannelChanged*(self: ChatsView) {.signal.}
|
proc activeChannelChanged*(self: ChatsView) {.signal.}
|
||||||
|
|
||||||
|
@ -93,6 +118,7 @@ QtObject:
|
||||||
|
|
||||||
self.activeChannel.setChatItem(selectedChannel)
|
self.activeChannel.setChatItem(selectedChannel)
|
||||||
self.status.chat.setActiveChannel(selectedChannel.id)
|
self.status.chat.setActiveChannel(selectedChannel.id)
|
||||||
|
self.currentSuggestions.setNewData(self.status.contacts.getContacts())
|
||||||
self.activeChannelChanged()
|
self.activeChannelChanged()
|
||||||
|
|
||||||
proc getActiveChannelIdx(self: ChatsView): QVariant {.slot.} =
|
proc getActiveChannelIdx(self: ChatsView): QVariant {.slot.} =
|
||||||
|
@ -122,6 +148,7 @@ QtObject:
|
||||||
proc setActiveChannel*(self: ChatsView, channel: string) {.slot.} =
|
proc setActiveChannel*(self: ChatsView, channel: string) {.slot.} =
|
||||||
if(channel == ""): return
|
if(channel == ""): return
|
||||||
self.activeChannel.setChatItem(self.chats.getChannel(self.chats.chats.findIndexById(channel)))
|
self.activeChannel.setChatItem(self.chats.getChannel(self.chats.chats.findIndexById(channel)))
|
||||||
|
self.currentSuggestions.setNewData(self.status.contacts.getContacts())
|
||||||
self.activeChannelChanged()
|
self.activeChannelChanged()
|
||||||
|
|
||||||
proc getActiveChannel*(self: ChatsView): QVariant {.slot.} =
|
proc getActiveChannel*(self: ChatsView): QVariant {.slot.} =
|
||||||
|
@ -132,6 +159,13 @@ QtObject:
|
||||||
write = setActiveChannel
|
write = setActiveChannel
|
||||||
notify = activeChannelChanged
|
notify = activeChannelChanged
|
||||||
|
|
||||||
|
|
||||||
|
proc getCurrentSuggestions(self: ChatsView): QVariant {.slot.} =
|
||||||
|
return newQVariant(self.currentSuggestions)
|
||||||
|
|
||||||
|
QtProperty[QVariant] suggestionList:
|
||||||
|
read = getCurrentSuggestions
|
||||||
|
|
||||||
proc upsertChannel(self: ChatsView, channel: string) =
|
proc upsertChannel(self: ChatsView, channel: string) =
|
||||||
if not self.messageList.hasKey(channel):
|
if not self.messageList.hasKey(channel):
|
||||||
self.messageList[channel] = newChatMessageList(channel, self.status)
|
self.messageList[channel] = newChatMessageList(channel, self.status)
|
||||||
|
@ -222,6 +256,7 @@ QtObject:
|
||||||
self.chats.updateChat(chat)
|
self.chats.updateChat(chat)
|
||||||
if(self.activeChannel.id == chat.id):
|
if(self.activeChannel.id == chat.id):
|
||||||
self.activeChannel.setChatItem(chat)
|
self.activeChannel.setChatItem(chat)
|
||||||
|
self.currentSuggestions.setNewData(self.status.contacts.getContacts())
|
||||||
self.activeChannelChanged()
|
self.activeChannelChanged()
|
||||||
|
|
||||||
proc renameGroup*(self: ChatsView, newName: string) {.slot.} =
|
proc renameGroup*(self: ChatsView, newName: string) {.slot.} =
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
import NimQml, tables
|
||||||
|
import ../../../status/profile/profile
|
||||||
|
|
||||||
|
type
|
||||||
|
SuggestionRoles {.pure.} = enum
|
||||||
|
Alias = UserRole + 1,
|
||||||
|
Identicon = UserRole + 2,
|
||||||
|
Address = UserRole + 3,
|
||||||
|
EnsName = UserRole + 4,
|
||||||
|
EnsVerified = UserRole + 5
|
||||||
|
|
||||||
|
QtObject:
|
||||||
|
type SuggestionsList* = ref object of QAbstractListModel
|
||||||
|
suggestions*: seq[Profile]
|
||||||
|
|
||||||
|
proc setup(self: SuggestionsList) = self.QAbstractListModel.setup
|
||||||
|
|
||||||
|
proc delete(self: SuggestionsList) =
|
||||||
|
self.suggestions = @[]
|
||||||
|
self.QAbstractListModel.delete
|
||||||
|
|
||||||
|
proc newSuggestionsList*(): SuggestionsList =
|
||||||
|
new(result, delete)
|
||||||
|
result.suggestions = @[]
|
||||||
|
result.setup
|
||||||
|
|
||||||
|
proc rowData(self: SuggestionsList, index: int, column: string): string {.slot.} =
|
||||||
|
if (index >= self.suggestions.len - 1):
|
||||||
|
return
|
||||||
|
let suggestion = self.suggestions[index]
|
||||||
|
case column:
|
||||||
|
of "alias": result = suggestion.alias
|
||||||
|
of "ensName": result = suggestion.ensName
|
||||||
|
of "address": result = suggestion.address
|
||||||
|
of "identicon": result = suggestion.identicon
|
||||||
|
|
||||||
|
method rowCount(self: SuggestionsList, index: QModelIndex = nil): int =
|
||||||
|
return self.suggestions.len
|
||||||
|
|
||||||
|
method data(self: SuggestionsList, index: QModelIndex, role: int): QVariant =
|
||||||
|
if not index.isValid:
|
||||||
|
return
|
||||||
|
if index.row < 0 or index.row >= self.suggestions.len:
|
||||||
|
return
|
||||||
|
let suggestion = self.suggestions[index.row]
|
||||||
|
let suggestionRole = role.SuggestionRoles
|
||||||
|
case suggestionRole:
|
||||||
|
of SuggestionRoles.Alias: result = newQVariant(suggestion.alias)
|
||||||
|
of SuggestionRoles.Identicon: result = newQVariant(suggestion.identicon)
|
||||||
|
of SuggestionRoles.Address: result = newQVariant(suggestion.address)
|
||||||
|
of SuggestionRoles.EnsName: result = newQVariant(suggestion.ensName)
|
||||||
|
of SuggestionRoles.EnsVerified: result = newQVariant(suggestion.ensVerified)
|
||||||
|
|
||||||
|
method roleNames(self: SuggestionsList): Table[int, string] =
|
||||||
|
{ SuggestionRoles.Alias.int:"alias",
|
||||||
|
SuggestionRoles.Identicon.int:"identicon",
|
||||||
|
SuggestionRoles.Address.int:"address",
|
||||||
|
SuggestionRoles.EnsName.int:"ensName",
|
||||||
|
SuggestionRoles.EnsVerified.int:"ensVerified" }.toTable
|
||||||
|
|
||||||
|
proc addSuggestionToList*(self: SuggestionsList, profile: Profile) =
|
||||||
|
self.beginInsertRows(newQModelIndex(), self.suggestions.len, self.suggestions.len)
|
||||||
|
self.suggestions.add(profile)
|
||||||
|
self.endInsertRows()
|
||||||
|
|
||||||
|
proc setNewData*(self: SuggestionsList, suggestionsList: seq[Profile]) =
|
||||||
|
self.beginResetModel()
|
||||||
|
self.suggestions = suggestionsList
|
||||||
|
self.endResetModel()
|
||||||
|
|
||||||
|
proc forceUpdate*(self: SuggestionsList) =
|
||||||
|
self.beginResetModel()
|
||||||
|
self.endResetModel()
|
|
@ -108,6 +108,57 @@ StackLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ListModel {
|
||||||
|
id: suggestions
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: chatsModel
|
||||||
|
onActiveChannelChanged: {
|
||||||
|
suggestions.clear()
|
||||||
|
for (let i = 0; i < chatsModel.suggestionList.rowCount(); i++) {
|
||||||
|
suggestions.append({
|
||||||
|
alias: chatsModel.suggestionList.rowData(i, "alias"),
|
||||||
|
ensName: chatsModel.suggestionList.rowData(i, "ensName"),
|
||||||
|
address: chatsModel.suggestionList.rowData(i, "address"),
|
||||||
|
identicon: chatsModel.suggestionList.rowData(i, "identicon"),
|
||||||
|
ensVerified: chatsModel.suggestionList.rowData(i, "ensVerified")
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SuggestionBox {
|
||||||
|
id: suggestionsBox
|
||||||
|
model: suggestions
|
||||||
|
width: chatContainer.width
|
||||||
|
anchors.bottom: inputArea.top
|
||||||
|
anchors.left: inputArea.left
|
||||||
|
filter: chatInput.textInput.text
|
||||||
|
property: "ensName, alias"
|
||||||
|
onItemSelected: function (item) {
|
||||||
|
let currentText = chatInput.textInput.text
|
||||||
|
let lastAt = currentText.lastIndexOf("@")
|
||||||
|
let aliasName = item[suggestionsBox.property.split(",").map(p => p.trim()).find(p => !!item[p])]
|
||||||
|
let nameLen = aliasName.length + 2 // We're doing a +2 here because of the `@` and the trailing whitespace
|
||||||
|
let position = 0;
|
||||||
|
let text = ""
|
||||||
|
|
||||||
|
if (currentText.length == 1) {
|
||||||
|
position = nameLen
|
||||||
|
text = "@" + aliasName + " "
|
||||||
|
} else {
|
||||||
|
let left = currentText.slice(0, lastAt)
|
||||||
|
position = left.length + nameLen
|
||||||
|
text = left + "@" + aliasName + " "
|
||||||
|
}
|
||||||
|
|
||||||
|
chatInput.textInput.text = text
|
||||||
|
chatInput.textInput.cursorPosition = position
|
||||||
|
suggestionsBox.suggestionsModel.clear()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: inputArea
|
id: inputArea
|
||||||
color: Style.current.background
|
color: Style.current.background
|
||||||
|
@ -126,6 +177,7 @@ StackLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
ChatInput {
|
ChatInput {
|
||||||
|
id: chatInput
|
||||||
height: 40
|
height: 40
|
||||||
anchors.top: !isReply ? inputArea.top : replyAreaContainer.bottom
|
anchors.top: !isReply ? inputArea.top : replyAreaContainer.bottom
|
||||||
anchors.topMargin: 4
|
anchors.topMargin: 4
|
||||||
|
|
|
@ -8,6 +8,7 @@ import "../../../../imports"
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: rectangle
|
id: rectangle
|
||||||
|
property alias textInput: txtData
|
||||||
border.width: 0
|
border.width: 0
|
||||||
height: 52
|
height: 52
|
||||||
color: Style.current.transparent
|
color: Style.current.transparent
|
||||||
|
@ -31,12 +32,14 @@ Rectangle {
|
||||||
}
|
}
|
||||||
|
|
||||||
function onEnter(event){
|
function onEnter(event){
|
||||||
|
|
||||||
if (event.modifiers === Qt.NoModifier && (event.key === Qt.Key_Enter || event.key === Qt.Key_Return)) {
|
if (event.modifiers === Qt.NoModifier && (event.key === Qt.Key_Enter || event.key === Qt.Key_Return)) {
|
||||||
|
|
||||||
if(txtData.text.trim().length > 0){
|
if(txtData.text.trim().length > 0){
|
||||||
let msg = interpretMessage(txtData.text.trim())
|
let msg = interpretMessage(txtData.text.trim())
|
||||||
chatsModel.sendMessage(msg, chatColumn.isReply ? SelectedMessage.messageId : "");
|
chatsModel.sendMessage(msg, chatColumn.isReply ? SelectedMessage.messageId : "");
|
||||||
txtData.text = "";
|
txtData.text = "";
|
||||||
event.accepted = true;
|
event.accepted = true
|
||||||
sendMessageSound.stop()
|
sendMessageSound.stop()
|
||||||
Qt.callLater(sendMessageSound.play);
|
Qt.callLater(sendMessageSound.play);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,137 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2011 Jocelyn Turcotte <turcotte.j@gmail.com>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Library General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Library General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Library General Public License
|
||||||
|
along with this program; see the file COPYING.LIB. If not, write to
|
||||||
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||||
|
Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import QtQuick 2.13
|
||||||
|
import QtQuick.Controls 2.13
|
||||||
|
import QtGraphicalEffects 1.13
|
||||||
|
import "../../../../imports"
|
||||||
|
import "../../../../shared"
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: container
|
||||||
|
|
||||||
|
property QtObject model: undefined
|
||||||
|
property Item delegate
|
||||||
|
property alias suggestionsModel: filterItem.model
|
||||||
|
property alias filter: filterItem.filter
|
||||||
|
property alias property: filterItem.property
|
||||||
|
signal itemSelected(var item)
|
||||||
|
|
||||||
|
|
||||||
|
z: parent.z + 100
|
||||||
|
visible: filter.length > 0 && suggestionsModel.count > 0
|
||||||
|
height: visible ? childrenRect.height + (Style.current.padding * 2) : 0
|
||||||
|
opacity: visible ? 1.0 : 0
|
||||||
|
Behavior on opacity {
|
||||||
|
NumberAnimation { }
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- defaults
|
||||||
|
color: Style.current.white2
|
||||||
|
radius: 16
|
||||||
|
layer.enabled: true
|
||||||
|
layer.effect: DropShadow{
|
||||||
|
width: container.width
|
||||||
|
height: container.height
|
||||||
|
x: container.x
|
||||||
|
y: container.y + 10
|
||||||
|
visible: container.visible
|
||||||
|
source: container
|
||||||
|
horizontalOffset: 0
|
||||||
|
verticalOffset: 2
|
||||||
|
radius: 10
|
||||||
|
samples: 15
|
||||||
|
color: "#22000000"
|
||||||
|
}
|
||||||
|
|
||||||
|
SuggestionFilter {
|
||||||
|
id: filterItem
|
||||||
|
sourceModel: container.model
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ScrollView {
|
||||||
|
id: popup
|
||||||
|
height: items.height >= 400 ? 400 : items.height
|
||||||
|
width: parent.width
|
||||||
|
anchors.centerIn: parent
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
property int selectedIndex
|
||||||
|
property var selectedItem: selectedIndex == -1 ? null : model[selectedIndex]
|
||||||
|
signal suggestionClicked(var item)
|
||||||
|
ScrollBar.vertical.policy: items.contentHeight > items.height ? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff
|
||||||
|
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: items
|
||||||
|
clip: true
|
||||||
|
height: childrenRect.height
|
||||||
|
width: parent.width
|
||||||
|
Repeater {
|
||||||
|
id: repeater
|
||||||
|
model: container.suggestionsModel
|
||||||
|
delegate: Rectangle {
|
||||||
|
id: delegateItem
|
||||||
|
property var suggestion: model
|
||||||
|
property bool hovered
|
||||||
|
|
||||||
|
height: 50
|
||||||
|
width: container.width
|
||||||
|
color: hovered ? Style.current.blue : "white"
|
||||||
|
|
||||||
|
Identicon {
|
||||||
|
id: accountImage
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: Style.current.smallPadding
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
source: suggestion.identicon
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: textComponent
|
||||||
|
color: delegateItem.hovered ? Style.current.white : Style.current.black
|
||||||
|
text: suggestion[container.property.split(",").map(p => p.trim()).find(p => !!suggestion[p])]
|
||||||
|
width: parent.width
|
||||||
|
height: parent.height
|
||||||
|
anchors.left: accountImage.right
|
||||||
|
anchors.leftMargin: Style.current.padding
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
font.pixelSize: 15
|
||||||
|
}
|
||||||
|
MouseArea {
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
onEntered: {
|
||||||
|
delegateItem.hovered = true
|
||||||
|
}
|
||||||
|
onExited: {
|
||||||
|
delegateItem.hovered = false
|
||||||
|
}
|
||||||
|
onClicked: container.itemSelected(delegateItem.suggestion)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
import QtQuick 2.13
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: component
|
||||||
|
property alias model: filterModel
|
||||||
|
|
||||||
|
property QtObject sourceModel: undefined
|
||||||
|
property string filter: ""
|
||||||
|
property string property: ""
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
onFilterChanged: invalidateFilter()
|
||||||
|
onPropertyChanged: invalidateFilter()
|
||||||
|
onSourceModelChanged: invalidateFilter()
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: invalidateFilter()
|
||||||
|
|
||||||
|
ListModel {
|
||||||
|
id: filterModel
|
||||||
|
}
|
||||||
|
|
||||||
|
function invalidateFilter() {
|
||||||
|
if (sourceModel === undefined)
|
||||||
|
return;
|
||||||
|
|
||||||
|
filterModel.clear();
|
||||||
|
|
||||||
|
if (!isFilteringPropertyOk())
|
||||||
|
return
|
||||||
|
|
||||||
|
var length = sourceModel.count
|
||||||
|
for (var i = 0; i < length; ++i) {
|
||||||
|
var item = sourceModel.get(i);
|
||||||
|
if (isAcceptedItem(item)) {
|
||||||
|
filterModel.append(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function isAcceptedItem(item) {
|
||||||
|
let properties = this.property.split(",")
|
||||||
|
.map(p => p.trim())
|
||||||
|
.filter(p => !!item[p])
|
||||||
|
|
||||||
|
if (properties.length == 0) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.filter.endsWith("@")) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
let lastAt = this.filter.lastIndexOf("@")
|
||||||
|
|
||||||
|
if (lastAt == -1) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
let filterWithoutAt = this.filter.substring(lastAt+1)
|
||||||
|
|
||||||
|
if (filterWithoutAt == "") {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return !properties.every(p => item[p].toLowerCase().match(filterWithoutAt.toLowerCase()) == null)
|
||||||
|
}
|
||||||
|
|
||||||
|
function isFilteringPropertyOk() {
|
||||||
|
if(this.property === undefined || this.property === "") {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,2 +1,4 @@
|
||||||
ContactsColumn 1.0 ContactsColumn.qml
|
ContactsColumn 1.0 ContactsColumn.qml
|
||||||
ChatColumn 1.0 ChatColumn.qml
|
ChatColumn 1.0 ChatColumn.qml
|
||||||
|
SuggestionBox 1.0 SuggestionBox.qml
|
||||||
|
SuggestionFilter 1.0 SuggestionFilter.qml
|
||||||
|
|
Loading…
Reference in New Issue