1// SPDX-FileCopyrightText: 2021 Nheko Contributors
2//
3// SPDX-License-Identifier: GPL-3.0-or-later
4
5import "../"
6import QtGraphicalEffects 1.0
7import QtQuick 2.9
8import QtQuick.Controls 2.3
9import QtQuick.Layouts 1.3
10import im.nheko 1.0
11import im.nheko.EmojiModel 1.0
12
13Menu {
14    id: stickerPopup
15
16    property var callback
17    property var colors
18    property string roomid
19    property alias model: gridView.model
20    property var textArea
21    property real highlightHue: Nheko.colors.highlight.hslHue
22    property real highlightSat: Nheko.colors.highlight.hslSaturation
23    property real highlightLight: Nheko.colors.highlight.hslLightness
24    readonly property int stickerDim: 128
25    readonly property int stickerDimPad: 128 + Nheko.paddingSmall
26    readonly property int stickersPerRow: 3
27
28    function show(showAt, roomid_, callback) {
29        console.debug("Showing sticker picker");
30        roomid = roomid_;
31        stickerPopup.callback = callback;
32        popup(showAt ? showAt : null);
33    }
34
35    margins: 0
36    bottomPadding: 1
37    leftPadding: 1
38    rightPadding: 1
39    modal: true
40    focus: true
41    closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
42    width: stickersPerRow * stickerDimPad + 20
43
44    Rectangle {
45        color: Nheko.colors.window
46        height: columnView.implicitHeight + 4
47        width: stickersPerRow * stickerDimPad + 20
48
49        ColumnLayout {
50            id: columnView
51
52            spacing: 0
53            anchors.leftMargin: 3
54            anchors.rightMargin: 3
55            anchors.bottom: parent.bottom
56            anchors.left: parent.left
57            anchors.right: parent.right
58            anchors.topMargin: 2
59
60            // Search field
61            TextField {
62                id: emojiSearch
63
64                Layout.topMargin: 3
65                Layout.preferredWidth: stickersPerRow * stickerDimPad + 20 - 6
66                palette: Nheko.colors
67                background: null
68                placeholderTextColor: Nheko.colors.buttonText
69                color: Nheko.colors.text
70                placeholderText: qsTr("Search")
71                selectByMouse: true
72                rightPadding: clearSearch.width
73                onTextChanged: searchTimer.restart()
74                onVisibleChanged: {
75                    if (visible)
76                        forceActiveFocus();
77
78                }
79
80                Timer {
81                    id: searchTimer
82
83                    interval: 350 // tweak as needed?
84                    onTriggered: stickerPopup.model.searchString = emojiSearch.text
85                }
86
87                ToolButton {
88                    id: clearSearch
89
90                    visible: emojiSearch.text !== ''
91                    icon.source: "image://colorimage/:/icons/icons/ui/round-remove-button.svg?" + (clearSearch.hovered ? Nheko.colors.highlight : Nheko.colors.buttonText)
92                    focusPolicy: Qt.NoFocus
93                    onClicked: emojiSearch.clear()
94                    hoverEnabled: true
95                    background: null
96
97                    anchors {
98                        verticalCenter: parent.verticalCenter
99                        right: parent.right
100                    }
101                    // clear the default hover effects.
102
103                    Image {
104                        height: parent.height - 2 * Nheko.paddingSmall
105                        width: height
106                        source: "image://colorimage/:/icons/icons/ui/round-remove-button.svg?" + (clearSearch.hovered ? Nheko.colors.highlight : Nheko.colors.buttonText)
107
108                        anchors {
109                            verticalCenter: parent.verticalCenter
110                            right: parent.right
111                            margins: Nheko.paddingSmall
112                        }
113
114                    }
115
116                }
117
118            }
119
120            // emoji grid
121            GridView {
122                id: gridView
123
124                model: roomid ? TimelineManager.completerFor("stickers", roomid) : null
125                Layout.preferredHeight: cellHeight * 3.5
126                Layout.preferredWidth: stickersPerRow * stickerDimPad + 20
127                Layout.leftMargin: 4
128                cellWidth: stickerDimPad
129                cellHeight: stickerDimPad
130                boundsBehavior: Flickable.StopAtBounds
131                clip: true
132                currentIndex: -1 // prevent sorting from stealing focus
133                cacheBuffer: 500
134
135                ScrollHelper {
136                    flickable: parent
137                    anchors.fill: parent
138                    enabled: !Settings.mobileMode
139                }
140
141                // Individual emoji
142                delegate: AbstractButton {
143                    width: stickerDim
144                    height: stickerDim
145                    hoverEnabled: true
146                    ToolTip.text: ":" + model.shortcode + ": - " + model.body
147                    ToolTip.visible: hovered
148                    // TODO: maybe add favorites at some point?
149                    onClicked: {
150                        console.debug("Picked " + model.shortcode);
151                        stickerPopup.close();
152                        callback(model.originalRow);
153                    }
154
155                    contentItem: Image {
156                        height: stickerDim
157                        width: stickerDim
158                        source: model.url.replace("mxc://", "image://MxcImage/")
159                        fillMode: Image.PreserveAspectFit
160                    }
161
162                    background: Rectangle {
163                        anchors.fill: parent
164                        color: hovered ? Nheko.colors.highlight : 'transparent'
165                        radius: 5
166                    }
167
168                }
169
170                ScrollBar.vertical: ScrollBar {
171                    id: emojiScroll
172                }
173
174            }
175
176        }
177
178    }
179
180}
181