Skip to content

Commit 402d9e8

Browse files
committed
Add Markdown text style, scroll-end trigger, lenient setVariable values
TextNode.markdown (MarkdownStyle) renders a text as Markdown. A new scrollEnd trigger on lists, grids and rows/columns runs when they near their end. SetVariableAction reads JSON booleans, numbers, lists and maps as the text newValue holds. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015oUVfxbYsbTuDQJkxfcXev
1 parent 79c3a55 commit 402d9e8

15 files changed

Lines changed: 271 additions & 16 deletions

‎lib/src/api/models/action/set_variable_action.dart‎

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import 'dart:convert';
2+
13
import 'package:json_annotation/json_annotation.dart';
24
import 'package:equatable/equatable.dart';
35

@@ -86,8 +88,19 @@ class SetVariableAction extends ActionModel
8688
);
8789

8890
/// Creates a new [SetVariableAction] instance from a JSON data.
89-
factory SetVariableAction.fromJson(Map json) =>
90-
_$SetVariableActionFromJson(json);
91+
///
92+
/// [newValue] is text; JSON written by hand often gives `true`, `20` or a
93+
/// list instead, which becomes its text (lists and maps as JSON).
94+
factory SetVariableAction.fromJson(Map json) {
95+
final Object? value = json['newValue'];
96+
if (value == null || value is String) {
97+
return _$SetVariableActionFromJson(json);
98+
}
99+
return _$SetVariableActionFromJson({
100+
...json,
101+
'newValue': value is List || value is Map ? jsonEncode(value) : '$value',
102+
});
103+
}
91104

92105
@override
93106
Map toJson() =>
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import 'package:equatable/equatable.dart';
2+
import 'package:json_annotation/json_annotation.dart';
3+
4+
import '../mixins.dart';
5+
import 'models.dart';
6+
7+
part 'markdown_style.g.dart';
8+
9+
/// Renders a text's characters as Markdown: `**bold**`, `_italic_`,
10+
/// `` `code` ``, links, `@mentions`, `- ` and `1. ` list items and blank-line
11+
/// paragraphs. Set on a [TextNode] (`markdown`) for text from data such as
12+
/// message bodies, and on a text field to style what's typed live.
13+
///
14+
/// Colors default to the text's own color where null.
15+
@JsonSerializable()
16+
class MarkdownStyle with Equatable, SerializableMixin {
17+
/// Inline code text color.
18+
final ColorRGBA? codeColor;
19+
20+
/// Inline code background.
21+
final ColorRGBA? codeBackground;
22+
23+
/// Inline code font family.
24+
final String codeFontFamily;
25+
26+
/// Link color (links are underlined).
27+
final ColorRGBA? linkColor;
28+
29+
/// `@mention` color.
30+
final ColorRGBA? mentionColor;
31+
32+
/// `@mention` background.
33+
final ColorRGBA? mentionBackground;
34+
35+
/// Handles that count as mentions, without `@`. Empty: any `@word`.
36+
final List<String> mentions;
37+
38+
/// Bullet and list number color.
39+
final ColorRGBA? bulletColor;
40+
41+
/// Extra space between paragraphs (blank lines), in pixels.
42+
final double paragraphGap;
43+
44+
/// Keeps the markers (`**`, `_`, backticks, list markers) visible, dimmed
45+
/// to [markerColor]: the live preview of a text being typed.
46+
final bool showMarkers;
47+
48+
/// Color of visible markers.
49+
final ColorRGBA? markerColor;
50+
51+
/// Creates a [MarkdownStyle].
52+
const MarkdownStyle({
53+
this.codeColor,
54+
this.codeBackground,
55+
this.codeFontFamily = 'JetBrains Mono',
56+
this.linkColor,
57+
this.mentionColor,
58+
this.mentionBackground,
59+
this.mentions = const [],
60+
this.bulletColor,
61+
this.paragraphGap = 8,
62+
this.showMarkers = false,
63+
this.markerColor,
64+
});
65+
66+
/// Creates a [MarkdownStyle] from JSON. Colors may be `#RRGGBB` or
67+
/// `#AARRGGBB` text.
68+
factory MarkdownStyle.fromJson(Map json) => _$MarkdownStyleFromJson(json);
69+
70+
@override
71+
Map toJson() => _$MarkdownStyleOmitDefaults(this, _$MarkdownStyleToJson(this));
72+
73+
@override
74+
List<Object?> get props => [
75+
codeColor,
76+
codeBackground,
77+
codeFontFamily,
78+
linkColor,
79+
mentionColor,
80+
mentionBackground,
81+
mentions,
82+
bulletColor,
83+
paragraphGap,
84+
showMarkers,
85+
markerColor,
86+
];
87+
}

‎lib/src/api/models/markdown_style.g.dart‎

Lines changed: 68 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎lib/src/api/models/models.dart‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ export 'input_border.dart';
5757
export 'input_decoration.dart';
5858
export 'letter_spacing.dart';
5959
export 'line_height.dart';
60+
export 'markdown_style.dart';
6061
export 'motion.dart';
6162
export 'list_tile_control_affinity.dart';
6263
export 'loop_animation.dart';

‎lib/src/api/models/trigger.dart‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,11 @@ enum TriggerType {
102102
/// key's label: `a`, `ArrowLeft`, `Delete`, `Escape`, ...),
103103
/// `${result.shift}`, `${result.alt}` and `${result.meta}` (Command on
104104
/// macOS, Control elsewhere). [TriggerModel.key] limits it to one key.
105-
keyDown;
105+
keyDown,
106+
107+
/// A scrolling list, grid, row or column came within a short distance of
108+
/// its end (or its content doesn't fill it): load the next page.
109+
scrollEnd;
106110

107111
/// The triggers for the mouse cursor entering and leaving the target.
108112
static const List<TriggerType> hovers = [
@@ -177,6 +181,8 @@ enum TriggerType {
177181
return 'Drag End';
178182
case TriggerType.keyDown:
179183
return 'Key Down';
184+
case TriggerType.scrollEnd:
185+
return 'Reached End';
180186
}
181187
}
182188
}

‎lib/src/api/models/trigger.g.dart‎

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎lib/src/api/nodes/grid_view_node.dart‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ class GridViewNode extends SinglePlaceholderNode
2929
@override
3030
bool get isScrollingEnforced => true;
3131

32+
@override
33+
List<TriggerType> get triggerTypes => [TriggerType.scrollEnd];
34+
3235
@override
3336
bool get canBeMarked => true;
3437

‎lib/src/api/nodes/grid_view_node.g.dart‎

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎lib/src/api/nodes/list_view_node.dart‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ class ListViewNode extends SinglePlaceholderNode
2626
@override
2727
bool get isScrollingEnforced => true;
2828

29+
@override
30+
List<TriggerType> get triggerTypes => [TriggerType.scrollEnd];
31+
2932
@override
3033
bool get canBeMarked => true;
3134

‎lib/src/api/nodes/list_view_node.g.dart‎

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)