2023-02-22 01:48:49 +03:00
|
|
|
// SPDX-FileCopyrightText: Nheko Contributors
|
2021-07-15 21:37:52 +03:00
|
|
|
//
|
|
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
|
|
|
|
import "../"
|
|
|
|
import QtGraphicalEffects 1.0
|
|
|
|
import QtQuick 2.9
|
|
|
|
import QtQuick.Controls 2.3
|
|
|
|
import QtQuick.Layouts 1.3
|
|
|
|
import im.nheko 1.0
|
|
|
|
import im.nheko.EmojiModel 1.0
|
|
|
|
|
|
|
|
Menu {
|
|
|
|
id: stickerPopup
|
|
|
|
|
|
|
|
property var callback
|
|
|
|
property var colors
|
2021-07-19 18:45:55 +03:00
|
|
|
property string roomid
|
2021-07-19 18:49:57 +03:00
|
|
|
property alias model: gridView.model
|
2021-07-15 21:37:52 +03:00
|
|
|
property var textArea
|
|
|
|
property real highlightHue: Nheko.colors.highlight.hslHue
|
|
|
|
property real highlightSat: Nheko.colors.highlight.hslSaturation
|
|
|
|
property real highlightLight: Nheko.colors.highlight.hslLightness
|
|
|
|
readonly property int stickerDim: 128
|
|
|
|
readonly property int stickerDimPad: 128 + Nheko.paddingSmall
|
|
|
|
readonly property int stickersPerRow: 3
|
2023-05-20 01:31:47 +03:00
|
|
|
readonly property int sidebarAvatarSize: 24
|
2021-07-15 21:37:52 +03:00
|
|
|
|
2021-07-19 18:45:55 +03:00
|
|
|
function show(showAt, roomid_, callback) {
|
2021-07-15 21:37:52 +03:00
|
|
|
console.debug("Showing sticker picker");
|
2021-07-19 18:45:55 +03:00
|
|
|
roomid = roomid_;
|
2021-07-15 21:37:52 +03:00
|
|
|
stickerPopup.callback = callback;
|
|
|
|
popup(showAt ? showAt : null);
|
|
|
|
}
|
|
|
|
|
2023-01-12 23:41:08 +03:00
|
|
|
margins: 2
|
|
|
|
bottomPadding: 0
|
|
|
|
leftPadding: 0
|
|
|
|
rightPadding: 0
|
|
|
|
topPadding: 0
|
2021-07-15 21:37:52 +03:00
|
|
|
modal: true
|
|
|
|
focus: true
|
|
|
|
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
|
2023-05-20 01:31:47 +03:00
|
|
|
width: sidebarAvatarSize + Nheko.paddingSmall + stickersPerRow * stickerDimPad + 20
|
2021-07-15 21:37:52 +03:00
|
|
|
|
|
|
|
Rectangle {
|
|
|
|
color: Nheko.colors.window
|
2023-01-12 23:41:08 +03:00
|
|
|
height: columnView.implicitHeight + Nheko.paddingSmall*2
|
2023-05-20 01:31:47 +03:00
|
|
|
width: sidebarAvatarSize + Nheko.paddingSmall + stickersPerRow * stickerDimPad + 20
|
2021-07-15 21:37:52 +03:00
|
|
|
|
2023-05-20 01:31:47 +03:00
|
|
|
GridLayout {
|
2021-07-15 21:37:52 +03:00
|
|
|
id: columnView
|
|
|
|
|
2023-01-12 23:41:08 +03:00
|
|
|
anchors.leftMargin: Nheko.paddingSmall
|
|
|
|
anchors.rightMargin: Nheko.paddingSmall
|
2021-07-15 21:37:52 +03:00
|
|
|
anchors.bottom: parent.bottom
|
|
|
|
anchors.left: parent.left
|
|
|
|
anchors.right: parent.right
|
2023-05-20 01:31:47 +03:00
|
|
|
columns: 2
|
|
|
|
rows: 2
|
2021-07-15 21:37:52 +03:00
|
|
|
|
|
|
|
// Search field
|
|
|
|
TextField {
|
|
|
|
id: emojiSearch
|
|
|
|
|
2023-01-12 23:41:08 +03:00
|
|
|
Layout.preferredWidth: stickersPerRow * stickerDimPad + 20 - Nheko.paddingSmall
|
2023-05-20 01:31:47 +03:00
|
|
|
Layout.row: 0
|
|
|
|
Layout.column: 1
|
2021-07-15 21:37:52 +03:00
|
|
|
palette: Nheko.colors
|
|
|
|
background: null
|
|
|
|
placeholderTextColor: Nheko.colors.buttonText
|
|
|
|
color: Nheko.colors.text
|
|
|
|
placeholderText: qsTr("Search")
|
|
|
|
selectByMouse: true
|
|
|
|
rightPadding: clearSearch.width
|
|
|
|
onTextChanged: searchTimer.restart()
|
|
|
|
onVisibleChanged: {
|
|
|
|
if (visible)
|
|
|
|
forceActiveFocus();
|
2022-02-02 19:24:20 +03:00
|
|
|
else
|
|
|
|
clear();
|
2021-07-15 21:37:52 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
Timer {
|
|
|
|
id: searchTimer
|
|
|
|
|
|
|
|
interval: 350 // tweak as needed?
|
|
|
|
onTriggered: stickerPopup.model.searchString = emojiSearch.text
|
|
|
|
}
|
|
|
|
|
2023-01-12 23:41:08 +03:00
|
|
|
ImageButton {
|
2021-07-15 21:37:52 +03:00
|
|
|
id: clearSearch
|
|
|
|
|
|
|
|
visible: emojiSearch.text !== ''
|
2023-01-12 23:41:08 +03:00
|
|
|
|
|
|
|
image: ":/icons/icons/ui/round-remove-button.svg"
|
2021-07-15 21:37:52 +03:00
|
|
|
focusPolicy: Qt.NoFocus
|
|
|
|
onClicked: emojiSearch.clear()
|
|
|
|
hoverEnabled: true
|
|
|
|
anchors {
|
2023-01-12 23:41:08 +03:00
|
|
|
top: parent.top
|
|
|
|
bottom: parent.bottom
|
2021-07-15 21:37:52 +03:00
|
|
|
right: parent.right
|
2023-01-12 23:41:08 +03:00
|
|
|
rightMargin: Nheko.paddingSmall
|
2021-07-15 21:37:52 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-05-19 04:15:55 +03:00
|
|
|
// sticker grid
|
|
|
|
ListView {
|
2021-07-15 21:37:52 +03:00
|
|
|
id: gridView
|
|
|
|
|
2023-05-19 04:15:55 +03:00
|
|
|
model: roomid ? TimelineManager.completerFor("stickergrid", roomid) : null
|
2023-05-20 01:31:47 +03:00
|
|
|
Layout.row: 1
|
|
|
|
Layout.column: 1
|
2021-07-15 21:37:52 +03:00
|
|
|
Layout.preferredHeight: cellHeight * 3.5
|
2023-01-12 23:41:08 +03:00
|
|
|
Layout.preferredWidth: stickersPerRow * stickerDimPad + 20 - Nheko.paddingSmall
|
2023-05-19 04:15:55 +03:00
|
|
|
property int cellHeight: stickerDimPad
|
2021-07-15 21:37:52 +03:00
|
|
|
boundsBehavior: Flickable.StopAtBounds
|
|
|
|
clip: true
|
|
|
|
currentIndex: -1 // prevent sorting from stealing focus
|
2023-05-19 04:15:55 +03:00
|
|
|
|
|
|
|
section.property: "packname"
|
|
|
|
section.criteria: ViewSection.FullString
|
2023-05-20 01:31:47 +03:00
|
|
|
section.delegate: Rectangle {
|
|
|
|
width: gridView.width
|
|
|
|
height: childrenRect.height
|
|
|
|
color: Nheko.colors.alternateBase
|
|
|
|
|
|
|
|
required property string section
|
|
|
|
|
|
|
|
Text {
|
|
|
|
anchors.left: parent.left
|
|
|
|
anchors.right: parent.right
|
|
|
|
text: parent.section
|
|
|
|
color: Nheko.colors.text
|
|
|
|
font.bold: true
|
|
|
|
}
|
|
|
|
}
|
2023-05-19 04:15:55 +03:00
|
|
|
section.labelPositioning: ViewSection.InlineLabels | ViewSection.CurrentLabelAtStart
|
2021-07-15 21:37:52 +03:00
|
|
|
|
2023-05-20 00:19:04 +03:00
|
|
|
spacing: Nheko.paddingSmall
|
|
|
|
|
2021-07-19 15:57:10 +03:00
|
|
|
ScrollHelper {
|
|
|
|
flickable: parent
|
|
|
|
anchors.fill: parent
|
|
|
|
enabled: !Settings.mobileMode
|
|
|
|
}
|
|
|
|
|
2021-07-15 21:37:52 +03:00
|
|
|
// Individual emoji
|
2023-05-19 04:15:55 +03:00
|
|
|
delegate: Row {
|
|
|
|
required property var row;
|
|
|
|
|
2023-05-20 00:19:04 +03:00
|
|
|
spacing: Nheko.paddingSmall
|
|
|
|
|
2023-05-19 04:15:55 +03:00
|
|
|
Repeater {
|
|
|
|
model: row
|
|
|
|
|
2023-05-20 00:19:04 +03:00
|
|
|
delegate: AbstractButton {
|
|
|
|
width: stickerDim
|
|
|
|
height: stickerDim
|
|
|
|
hoverEnabled: true
|
|
|
|
ToolTip.text: ":" + modelData.shortcode + ": - " + modelData.body
|
|
|
|
ToolTip.visible: hovered
|
|
|
|
// TODO: maybe add favorites at some point?
|
|
|
|
onClicked: {
|
|
|
|
console.debug("Picked " + modelData.descriptor);
|
|
|
|
stickerPopup.close();
|
|
|
|
callback(modelData.descriptor);
|
|
|
|
}
|
|
|
|
|
|
|
|
contentItem: Image {
|
|
|
|
height: stickerDim
|
|
|
|
width: stickerDim
|
|
|
|
source: modelData.url.replace("mxc://", "image://MxcImage/") + "?scale"
|
|
|
|
fillMode: Image.PreserveAspectFit
|
|
|
|
}
|
|
|
|
|
|
|
|
background: Rectangle {
|
|
|
|
anchors.fill: parent
|
|
|
|
color: hovered ? Nheko.colors.highlight : 'transparent'
|
|
|
|
radius: 5
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2021-07-15 21:37:52 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ScrollBar.vertical: ScrollBar {
|
|
|
|
id: emojiScroll
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2023-05-20 01:31:47 +03:00
|
|
|
ListView {
|
|
|
|
Layout.row: 1
|
|
|
|
Layout.column: 0
|
|
|
|
Layout.preferredWidth: sidebarAvatarSize
|
|
|
|
Layout.fillHeight: true
|
|
|
|
Layout.rightMargin: Nheko.paddingSmall
|
|
|
|
|
|
|
|
model: gridView.model ? gridView.model.sections : null
|
|
|
|
spacing: Nheko.paddingSmall
|
|
|
|
|
|
|
|
delegate: Avatar {
|
|
|
|
height: sidebarAvatarSize
|
|
|
|
width: sidebarAvatarSize
|
|
|
|
url: modelData.url.replace("mxc://", "image://MxcImage/")
|
|
|
|
displayName: modelData.name
|
|
|
|
roomid: modelData.name
|
|
|
|
|
|
|
|
hoverEnabled: true
|
|
|
|
ToolTip.visible: hovered
|
|
|
|
ToolTip.text: modelData.name
|
|
|
|
onClicked: gridView.positionViewAtIndex(modelData.firstRowWith, ListView.Beginning)
|
|
|
|
}
|
|
|
|
}
|
2021-07-15 21:37:52 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|