Skip to content

Commit edb22f6

Browse files
committed
[*] update normally
1 parent 9070a28 commit edb22f6

File tree

7 files changed

+141
-71
lines changed

7 files changed

+141
-71
lines changed

flymoon/src/logic/tr.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,7 @@ pub fn tr(text: &str) -> String {
250250
),
251251
("Increase font size", "增大字体"),
252252
("Decrease font size", "缩小字体"),
253+
("Focus question input box", "输入框获取输入焦点"),
253254
]);
254255

255256
if let Some(txt) = items.get(text) {

flymoon/ui/panel/desktop/chat/input.slint

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ export component Input inherits Rectangle {
1515
height: 130px;
1616
forward-focus: te;
1717

18+
function update-height(height: length) {
19+
root.height = Math.clamp(height, 130px, Theme.default-height / 3 * 2);
20+
}
21+
1822
function ensure-show-cursor() {
1923
if (flick.viewport-height <= flick.height) {
2024
flick.viewport-y = 0;
@@ -69,6 +73,10 @@ export component Input inherits Rectangle {
6973
flick := Flickable {
7074
y: Theme.padding * 2;
7175

76+
changed viewport-height => {
77+
root.update-height(self.viewport-height + h-btns.preferred-height);
78+
}
79+
7280
VerticalLayout {
7381
padding: Theme.padding * 2;
7482

@@ -170,7 +178,7 @@ export component Input inherits Rectangle {
170178
}
171179
}
172180

173-
HorizontalLayout {
181+
h-btns := HorizontalLayout {
174182
height: Theme.icon-size * 2;
175183
alignment: LayoutAlignment.space-between;
176184

flymoon/ui/panel/desktop/chat/md.slint

Lines changed: 61 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Theme, Store, Logic, Icons, Util } from "../../def.slint";
22
import { ChatEntry, MdElementType, MdImage, MdMath, MdElement, MdUrl, MdHeading, MdUrl, MdListItem, MdTable, MdCodeBlock } from "../../../store.slint";
33
import { IconBtn, Label, Link, ToolTipSetting, ComponentPosition } from "../../../base/widgets.slint";
44
import { SearchLink } from "../../../store.slint";
5+
import { ScrollView } from "std-widgets.slint";
56

67
export component MdText inherits HorizontalLayout {
78
in-out property text <=> txt.text;
@@ -88,35 +89,74 @@ export component MdCodeBlock inherits HorizontalLayout {
8889
text: code-block.lang;
8990
}
9091

91-
IconBtn {
92-
icon: Icons.copy;
93-
tip: Logic.tr("copy");
94-
is-show-tip: true;
95-
gain-focus-when-clicked: false;
92+
HorizontalLayout {
93+
spacing: Theme.spacing * 4;
94+
95+
IconBtn {
96+
icon: Icons.copy;
97+
tip: Logic.tr("copy");
98+
is-show-tip: true;
99+
gain-focus-when-clicked: false;
96100

97-
clicked => {
98-
Logic.copy-to-clipboard(code-block.code);
101+
clicked => {
102+
Logic.copy-to-clipboard(code-block.code);
103+
}
99104
}
100105
}
101106
}
102107
}
103108

109+
// `ScrollView` could catch scroll event. However, short content should not catch scroll event
104110
Rectangle {
105-
border-bottom-left-radius: Theme.border-radius;
106-
border-bottom-right-radius: Theme.border-radius;
107-
background: Theme.thirdly-background;
111+
private property <float> rate: 0.5;
112+
private property <bool> use-scrollview: txt-rect.preferred-height > (Theme.default-height * rate);
108113

109-
HorizontalLayout {
110-
padding: Theme.padding * 4;
111-
padding-top: Theme.padding * 2;
112-
113-
txt := TextInput {
114-
wrap: word-wrap;
115-
color: Theme.primary-text-color;
116-
font-size: Theme.title4-font-size;
117-
single-line: false;
118-
read-only: true;
119-
text: code-block.code;
114+
height: use-scrollview ? Theme.default-height * rate : txt-rect.preferred-height;
115+
116+
Rectangle {
117+
visible: !use-scrollview;
118+
border-bottom-left-radius: Theme.border-radius;
119+
border-bottom-right-radius: Theme.border-radius;
120+
background: Theme.thirdly-background;
121+
122+
HorizontalLayout {
123+
padding: Theme.padding * 4;
124+
padding-top: Theme.padding * 2;
125+
126+
TextInput {
127+
wrap: word-wrap;
128+
color: Theme.primary-text-color;
129+
font-size: Theme.title4-font-size;
130+
single-line: false;
131+
read-only: true;
132+
text: code-block.code;
133+
}
134+
}
135+
}
136+
137+
ScrollView {
138+
visible: use-scrollview;
139+
viewport-height: txt-rect.preferred-height;
140+
height: Math.min(txt-rect.preferred-height, Theme.default-height * rate);
141+
142+
txt-rect := Rectangle {
143+
border-bottom-left-radius: Theme.border-radius;
144+
border-bottom-right-radius: Theme.border-radius;
145+
background: Theme.thirdly-background;
146+
147+
HorizontalLayout {
148+
padding: Theme.padding * 4;
149+
padding-top: Theme.padding * 2;
150+
151+
txt := TextInput {
152+
wrap: word-wrap;
153+
color: Theme.primary-text-color;
154+
font-size: Theme.title4-font-size;
155+
single-line: false;
156+
read-only: true;
157+
text: code-block.code;
158+
}
159+
}
120160
}
121161
}
122162
}

flymoon/ui/panel/desktop/chat/panel.slint

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,11 @@ export component Chat inherits VerticalLayout {
1313
spacing: Theme.spacing * 2;
1414

1515
Rectangle {
16-
session := Session { }
16+
session := Session {
17+
focus-input => {
18+
input.focus();
19+
}
20+
}
1721

1822
if Store.input-prompt-list-entries.length > 0: InputPromptList {
1923
x: 0;

flymoon/ui/panel/desktop/chat/session.slint

Lines changed: 60 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,8 @@ component MCPDetail inherits Rectangle {
254254
}
255255

256256
export component Session inherits Rectangle {
257+
callback focus-input;
258+
257259
public function scroll-to-top() {
258260
lv.viewport-y = 0;
259261
Store.is-auto-scroll = false;
@@ -305,65 +307,76 @@ export component Session inherits Rectangle {
305307

306308
if Store.current-chat-session.histories.length == 0: BlankWelcome { }
307309

308-
lv := ListView {
309-
width: root.width;
310-
height: root.height;
311-
vertical-scrollbar-policy: always-off;
312-
313-
scrolled => {
314-
if (is-on-bottom()) {
315-
Store.is-auto-scroll = true;
316-
} else {
317-
Store.is-auto-scroll = false;
310+
FocusScope {
311+
key-pressed(event) => {
312+
if (event.modifiers.control) {
313+
if (event.text == "i") {
314+
focus-input();
315+
return accept;
316+
}
318317
}
318+
return reject;
319319
}
320320

321-
for entry[index] in Store.current-chat-session.histories: VerticalLayout {
322-
padding: Theme.padding * 2;
323-
padding-top: 0;
324-
padding-bottom: Theme.padding * 4;
325-
spacing: Theme.spacing * 3;
326-
327-
private property <bool> is-last-index: index == Store.current-chat-session.histories.length - 1;
321+
lv := ListView {
322+
width: root.width;
323+
height: root.height;
328324

329-
if index == 0 && !Store.current-model-name.is-empty: Label {
330-
horizontal-alignment: TextHorizontalAlignment.center;
331-
text: Store.current-model-name;
332-
color: Theme.disabled-color;
325+
scrolled => {
326+
if (is-on-bottom()) {
327+
Store.is-auto-scroll = true;
328+
} else {
329+
Store.is-auto-scroll = false;
330+
}
333331
}
334332

335-
user := User {
336-
index: index;
337-
entry: entry;
338-
}
333+
for entry[index] in Store.current-chat-session.histories: VerticalLayout {
334+
padding: Theme.padding * 2;
335+
padding-top: 0;
336+
padding-bottom: Theme.padding * 4;
337+
spacing: Theme.spacing * 3;
339338

340-
if !entry.bot-reasoner.is-empty: ReasonerText {
341-
entry: entry;
342-
index: index;
343-
}
339+
private property <bool> is-last-index: index == Store.current-chat-session.histories.length - 1;
344340

345-
if !Store.is-toggle-bot-markdown && entry.md-elems.length > 0: MdDetail {
346-
entries: entry.md-elems;
347-
urls: entry.link-urls;
348-
histories-entry-index: index;
349-
search-links: entry.search-links;
350-
}
341+
if index == 0 && !Store.current-model-name.is-empty: Label {
342+
horizontal-alignment: TextHorizontalAlignment.center;
343+
text: Store.current-model-name;
344+
color: Theme.disabled-color;
345+
}
351346

352-
if Store.is-toggle-bot-markdown && !entry.bot.is-empty: ChatDetail {
353-
text: entry.bot;
354-
}
347+
user := User {
348+
index: index;
349+
entry: entry;
350+
}
355351

356-
if entry.mcp.length > 0: MCPDetail {
357-
entries: entry.mcp;
358-
}
352+
if !entry.bot-reasoner.is-empty: ReasonerText {
353+
entry: entry;
354+
index: index;
355+
}
356+
357+
if !Store.is-toggle-bot-markdown && entry.md-elems.length > 0: MdDetail {
358+
entries: entry.md-elems;
359+
urls: entry.link-urls;
360+
histories-entry-index: index;
361+
search-links: entry.search-links;
362+
}
363+
364+
if Store.is-toggle-bot-markdown && !entry.bot.is-empty: ChatDetail {
365+
text: entry.bot;
366+
}
367+
368+
if entry.mcp.length > 0: MCPDetail {
369+
entries: entry.mcp;
370+
}
359371

360-
if is-last-index && (Store.chat-phase == ChatPhase.MCP || Store.chat-phase == ChatPhase.Searching || Store.chat-phase == ChatPhase.Thinking): Rectangle {
361-
height: 200px;
372+
if is-last-index && (Store.chat-phase == ChatPhase.MCP || Store.chat-phase == ChatPhase.Searching || Store.chat-phase == ChatPhase.Thinking): Rectangle {
373+
height: 200px;
362374

363-
sk := Skeleton {
364-
width: parent.width;
365-
height: parent.height;
366-
type: SkeletonType.List;
375+
sk := Skeleton {
376+
width: parent.width;
377+
height: parent.height;
378+
type: SkeletonType.List;
379+
}
367380
}
368381
}
369382
}

flymoon/ui/panel/setting/components/help-detail.slint

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,10 @@ component ShortcutsHelp inherits VerticalLayout {
290290
shortcut: "Ctrl + -",
291291
detail: Logic.tr("Decrease font size"),
292292
},
293+
{
294+
shortcut: "Ctrl + I",
295+
detail: Logic.tr("Focus question input box"),
296+
},
293297
{
294298
shortcut: "Enter",
295299
detail: Logic.tr("[History Tab]: Load selected historial chat"),

flymoon/ui/store.slint

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,7 @@ export global Store {
332332
mcp: [
333333
{
334334
tool-name: "Crate file",
335-
resp: "{In NixOS, you can install libalsa (ALSA library) in several ways, depending on how you want to use it. Here are the common methods}",
335+
resp: " {In NixOS, you can install libalsa (ALSA library) in several ways, depending on how you want to use it. Here are the common methods} {In NixOS, you can install libalsa (ALSA library) in several ways, depending on how you want to use it. Here are the common methods} {In NixOS, you can install libalsa (ALSA library) in several ways, depending on how you want to use it. Here are the common methods} {In NixOS, you can install libalsa (ALSA library) in several ways, depending on how you want to use it. Here are the common methods} {In NixOS, you can install libalsa (ALSA library) in several ways, depending on how you want to use it. Here are the common methods} {In NixOS, you can install libalsa (ALSA library) in several ways, depending on how you want to use it. Here are the common methods} {In NixOS, you can install libalsa (ALSA library) in several ways, depending on how you want to use it. Here are the common methods} ",
336336
},
337337
{
338338
tool-name: "Remove file",

0 commit comments

Comments
 (0)