feat: add channel switcher when hitting CTRL+K

This commit is contained in:
Jonathan Rainville 2020-12-28 15:03:57 -05:00 committed by Iuri Matias
parent 6afe9088e9
commit 825097f007
4 changed files with 174 additions and 13 deletions

View File

@ -44,7 +44,7 @@ Rectangle {
anchors.left: parent.left anchors.left: parent.left
radius: 8 radius: 8
// Hide the box if it is filtered out // Hide the box if it is filtered out
property bool isVisible: searchStr == "" || name.includes(searchStr) property bool isVisible: searchStr === "" || name.includes(searchStr)
visible: isVisible ? true : false visible: isVisible ? true : false
height: isVisible ? !isCompact ? 64 : contactImage.height + Style.current.smallPadding * 2 : 0 height: isVisible ? !isCompact ? 64 : contactImage.height + Style.current.smallPadding * 2 : 0

View File

@ -69,6 +69,47 @@ RowLayout {
shortcut: "Ctrl+4, Ctrl+," shortcut: "Ctrl+4, Ctrl+,"
onTriggered: changeAppSection(Constants.profile) onTriggered: changeAppSection(Constants.profile)
} }
Action {
shortcut: "Ctrl+K"
onTriggered: {
if (channelPicker.opened) {
channelPicker.close()
} else {
channelPicker.open()
}
}
}
Component {
id: statusIdenticonComponent
StatusIdenticon {}
}
StatusInputListPopup {
id: channelPicker
title: qsTr("Where do you want to go?")
showSearchBox: true
width: 350
x: parent.width / 2 - width / 2
y: parent.height / 2 - height / 2
modelList: chatsModel.chats
getText: function (modelData) {
return modelData.name
}
getImageComponent: function (parent, modelData) {
return statusIdenticonComponent.createObject(parent, {
width: channelPicker.imageWidth,
height: channelPicker.imageHeight,
chatName: modelData.name,
chatType: modelData.chatType,
identicon: modelData.identicon
});
}
onClicked: function (index) {
chatsModel.setActiveChannelByIndex(index)
appMain.changeAppSection(Constants.chat)
channelPicker.close()
}
}
function changeAppSection(section) { function changeAppSection(section) {
let sectionId = -1 let sectionId = -1

View File

@ -32,7 +32,8 @@ Item {
signal textEdited(string inputValue) signal textEdited(string inputValue)
id: inputBox id: inputBox
height: inputRectangle.height + (hasLabel ? inputLabel.height + labelMargin : 0) + (!!validationError ? (validationErrorText.height + validationErrorTopMargin) : 0) implicitHeight: inputRectangle.height + (hasLabel ? inputLabel.height + labelMargin : 0) + (!!validationError ? (validationErrorText.height + validationErrorTopMargin) : 0)
height: implicitHeight
anchors.right: parent.right anchors.right: parent.right
anchors.left: parent.left anchors.left: parent.left

View File

@ -2,31 +2,53 @@ import QtQuick 2.13
import QtQuick.Controls 2.13 import QtQuick.Controls 2.13
import QtGraphicalEffects 1.12 import QtGraphicalEffects 1.12
import QtQuick.Dialogs 1.3 import QtQuick.Dialogs 1.3
import QtQuick.Layouts 1.13
import "../../imports" import "../../imports"
import "../../shared" import "../../shared"
Popup { Popup {
property var modelList property var modelList
property alias listView: listView property alias listView: listView
property var getImageSource: function () {} property var getImageSource
property var getImageComponent
property var getText: function () {} property var getText: function () {}
property var onClicked: function () {} property var onClicked: function () {}
property int imageWidth: 22 property int imageWidth: 22
property int imageHeight: 22 property int imageHeight: 22
property string title
property bool showSearchBox: false
function openPopup(listParam) { function openPopup(listParam) {
modelList = listParam modelList = listParam
popup.open() popup.open()
} }
onOpened: {
listView.currentIndex = 0
if (showSearchBox) {
searchBox.textField.forceActiveFocus()
}
}
id: popup id: popup
padding: Style.current.smallPadding
width: messageInput.width width: messageInput.width
height: Math.min(400, listView.contentHeight + Style.current.smallPadding) height: {
let possibleHeight = listView.contentHeight + Style.current.smallPadding * 2
if (popupTitle.visible) {
possibleHeight += popupTitle.height + Style.current.smallPadding
}
if (searchBox.visible) {
possibleHeight += searchBox.height + Style.current.smallPadding
}
return Math.min(400, possibleHeight)
}
x: messageInput.x x: messageInput.x
y: -height y: -height
background: Rectangle { background: Rectangle {
id: bgRectangle id: bgRectangle
visible: !!popup.modelList && popup.modelList.length > 0 visible: !!popup.title || (!!popup.modelList && popup.modelList.length > 0)
color: Style.current.background color: Style.current.background
border.width: 0 border.width: 0
radius: Style.current.radius radius: Style.current.radius
@ -46,36 +68,133 @@ Popup {
} }
} }
StyledText {
id: popupTitle
visible: !!popup.title
height: visible ? implicitHeight : 0
text: popup.title
font.pixelSize: 17
anchors.top: parent.top
}
SearchBox {
id: searchBox
visible: showSearchBox
height: visible ? implicitHeight : 0
width: parent.width
anchors.top: popupTitle.bottom
anchors.topMargin: popupTitle.visible ? Style.current.smallPadding : 0
function goToNextAvailableIndex(up) {
do {
if (!up && listView.currentIndex === listView.count - 1) {
listView.currentIndex = 0
return
} else if (up && listView.currentIndex === 0) {
listView.currentIndex = listView.count - 1
return
}
if (up) {
listView.decrementCurrentIndex()
} else {
listView.incrementCurrentIndex()
}
} while (!listView.currentItem.visible)
}
Keys.onReleased: function onKeyPress(event) {
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 popup.close()
}
if (event.key === Qt.Key_Enter || event.key === Qt.Key_Return) {
return popup.onClicked(listView.currentIndex)
}
}
}
ListView { ListView {
id: listView id: listView
model: popup.modelList || [] model: popup.modelList || []
keyNavigationEnabled: true keyNavigationEnabled: true
anchors.fill: parent Layout.fillHeight: true
width: parent.width
anchors.top: searchBox.bottom
anchors.topMargin: searchBox.visible ? Style.current.smallPadding : 0
anchors.bottom: parent.bottom
clip: true clip: true
delegate: Rectangle { delegate: Rectangle {
property string myText: {
if (typeof modelData === "undefined") {
return popup.getText(model)
}
return popup.getText(modelData)
}
id: rectangle id: rectangle
visible: searchBox.text === "" || myText.includes(searchBox.text)
color: listView.currentIndex === index ? Style.current.backgroundHover : Style.current.transparent color: listView.currentIndex === index ? Style.current.backgroundHover : Style.current.transparent
border.width: 0 border.width: 0
width: parent.width width: parent.width
height: 42 height: visible ? 42 : 0
radius: Style.current.radius radius: Style.current.radius
SVGImage { Loader {
id: image id: imageLoader
source: popup.getImageSource(modelData) active: !!popup.getImageComponent || !!popup.getImageSource
width: popup.imageWidth width: popup.imageWidth
height: popup.imageHeight height: popup.imageHeight
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left anchors.left: parent.left
anchors.leftMargin: Style.current.smallPadding anchors.leftMargin: Style.current.smallPadding
sourceComponent: popup.getImageComponent ? customImageComponent : normalImageComponent
}
Component {
id: customImageComponent
Item {
id: imageComponentContainer
children: {
if (!popup.getImageComponent) {
return ""
}
if (typeof modelData === "undefined") {
return popup.getImageComponent(imageComponentContainer, model)
}
return popup.getImageComponent(imageComponentContainer, modelData)
}
}
}
Component {
id: normalImageComponent
SVGImage {
visible: !!source
width: popup.imageWidth
height: popup.imageHeight
source: {
if (!popup.getImageSource) {
return ""
}
if (typeof modelData === "undefined") {
return popup.getImageSource(model)
}
return popup.getImageSource(modelData)
}
}
} }
StyledText { StyledText {
text: popup.getText(modelData) text: rectangle.myText
color: Style.current.textColor color: Style.current.textColor
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
anchors.left: image.right anchors.left: imageLoader.right
anchors.leftMargin: Style.current.smallPadding anchors.leftMargin: Style.current.smallPadding
font.pixelSize: 15 font.pixelSize: 15
} }