blob: 026b2409611a1c35068bfcb692a9325b11228ec4 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
|
import Quickshell
import QtQuick
import QtQuick.Layouts
import qs.components
import qs.services
import qs.config
import core
IComponent {
id: root
property int cursorPosition: SelectionState.cursorPosition
property bool expand: false
height: valid ? expand ? layout.implicitHeight + (Launcher.duckduckgoSpacing * 2) : Launcher.widgetHeight : 0
name: "DuckDuckGo" // subclass of WebSearch in the future
preview: Component {
Icon {
text: "🌐"
}
}
onInputChanged: {
// TODO: think of this should be part of rs backend .query fn
DuckDuckGo.reset();
}
// TODO: decouple all query logic from process -> onInputCleanedChanged and resetting / temp state on speciifc input -> onInputChanged
onInputCleanedChanged: {
if (inputCleaned)
DuckDuckGo.query(inputCleaned);
}
process: function () {
const valid = DuckDuckGo.ok;
const answer = DuckDuckGo.title || DuckDuckGo.description_html;
return {
valid,
priority: valid,
answer,
predictiveCompletion: valid && inputCleaned.toLowerCase() != answer.toLowerCase().trim() ? ' is ' + answer : ''
};
}
exec: function () {
// FIXME: doesn't work as enter closes the launcher
// if (!expand) {
// expand = true;
// return false;
// } else
Clip.copy(`${DuckDuckGo.title}\n${DuckDuckGo.description_html}`);
}
IInnerComponent {
anchors.margins: Launcher.duckduckgoSpacing
RowLayout {
id: layout
spacing: Launcher.duckduckgoSpacing
Layout.fillWidth: true
Layout.fillHeight: true
Item {
Layout.fillWidth: true
Layout.fillHeight: true
Layout.preferredWidth: 0
Layout.maximumWidth: image.maxWidth
Layout.minimumWidth: 0
visible: image.status === Image.Ready
Image {
id: image
property real maxWidth: status === Image.Ready ? implicitWidth : 0
anchors.fill: parent
scale: root.isSelectedPriority() ? 1.01 : 0.99
fillMode: Image.PreserveAspectCrop
opacity: status === Image.Ready ? 1 : 0
source: DuckDuckGo.image
asynchronous: true
Behavior on opacity {
NumberAnimation {
duration: General.animationDuration / 4
}
}
Behavior on maxWidth {
ISpringAnimation {}
}
Behavior on scale {
ISpringAnimation {}
}
}
}
ColumnLayout {
Layout.preferredWidth: 3
Layout.minimumWidth: 0
Layout.fillHeight: true
Layout.fillWidth: true
spacing: Launcher.duckduckgoImageSpacing / 4
ITextEdit {
animate: true
Layout.alignment: Qt.AlignTop
Layout.fillWidth: true
readOnly: true
renderType: Text.CurveRendering
visible: valid
text: answer
font {
pixelSize: Launcher.widgetFontSize * 1.1
bold: root.isSelectedPriority()
}
}
ITextEdit {
animate: true
Layout.fillWidth: true
Layout.fillHeight: true
readOnly: true
renderType: Text.CurveRendering
visible: valid && DuckDuckGo.title
text: DuckDuckGo.title ? DuckDuckGo.description_html : ''
font {
pixelSize: Launcher.widgetFontSize
}
TapHandler {
gesturePolicy: TapHandler.DragThreshold
onTapped: expand = !expand
}
}
}
}
}
}
|