Skip to content

Commit

Permalink
Added proper selection area
Browse files Browse the repository at this point in the history
  • Loading branch information
ActiveChooN committed Nov 29, 2024
1 parent d4f149f commit 93a8a15
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 109 deletions.
49 changes: 27 additions & 22 deletions lib/pages/text_generation/playground.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,22 @@ class Playground extends StatefulWidget {
class SubmitMessageIntent extends Intent {}

class _PlaygroundState extends State<Playground> {
final textController = TextEditingController();
final scrollController = ScrollController();
final _textController = TextEditingController();
final _scrollController = ScrollController();
final _focusNode = FocusNode();
bool attachedToBottom = true;

void jumpToBottom({ offset = 0 }) {
if (scrollController.hasClients) {
scrollController.jumpTo(scrollController.position.maxScrollExtent + offset);
if (_scrollController.hasClients) {
_scrollController.jumpTo(_scrollController.position.maxScrollExtent + offset);
}
}

void message(String message) {
if (message.isEmpty) return;
final provider = Provider.of<TextInferenceProvider>(context, listen: false);
if (!provider.initialized || provider.response != null) return;
textController.text = '';
_textController.text = '';
jumpToBottom(offset: 110); //move to bottom including both
provider.message(message).catchError((e) async {
// ignore: use_build_context_synchronously
Expand All @@ -59,17 +60,17 @@ class _PlaygroundState extends State<Playground> {
@override
void initState() {
super.initState();
scrollController.addListener(() {
_scrollController.addListener(() {
setState(() {
attachedToBottom = scrollController.position.pixels + 0.001 >= scrollController.position.maxScrollExtent;
attachedToBottom = _scrollController.position.pixels + 0.001 >= _scrollController.position.maxScrollExtent;
});
});
}

@override
void dispose() {
textController.dispose();
scrollController.dispose();
_textController.dispose();
_scrollController.dispose();
super.dispose();
}

Expand Down Expand Up @@ -158,16 +159,20 @@ class _PlaygroundState extends State<Playground> {
alignment: Alignment.bottomCenter,
children: [
SingleChildScrollView(
controller: scrollController,
child: Padding(padding: const EdgeInsets.symmetric(horizontal: 64, vertical: 20), child: Column(
children: provider.messages.map((message) { switch (message.speaker) {
case Speaker.user: return Padding(
padding: const EdgeInsets.only(left: 42),
child: UserMessage(message),
);
case Speaker.system: return Text('System: ${message.message}');
case Speaker.assistant: return AssistantMessage(message);
}}).toList(),
controller: _scrollController,
child: Padding(padding: const EdgeInsets.symmetric(horizontal: 64, vertical: 20), child: SelectionArea(
child: SelectionArea(
child: Column(
children: provider.messages.map((message) { switch (message.speaker) {
case Speaker.user: return Padding(
padding: const EdgeInsets.only(left: 42),
child: UserMessage(message),
);
case Speaker.system: return Text('System: ${message.message}');
case Speaker.assistant: return AssistantMessage(message);
}}).toList(),
),
),
),),
),
Positioned(
Expand Down Expand Up @@ -221,7 +226,7 @@ class _PlaygroundState extends State<Playground> {
child: Actions(
actions: <Type, Action<Intent>>{
SubmitMessageIntent: CallbackAction<SubmitMessageIntent>(
onInvoke: (SubmitMessageIntent intent) => message(textController.text),
onInvoke: (SubmitMessageIntent intent) => message(_textController.text),
),
},
child: Column(
Expand All @@ -230,7 +235,7 @@ class _PlaygroundState extends State<Playground> {
TextBox(
placeholder: "Type a message...",
keyboardType: TextInputType.multiline,
controller: textController,
controller: _textController,
maxLines: null,
expands: true,
onSubmitted: message,
Expand Down Expand Up @@ -258,7 +263,7 @@ class _PlaygroundState extends State<Playground> {
)
: Tooltip(
message: "Send message",
child: Button(child: const Icon(FluentIcons.send, size: 18,), onPressed: () { message(textController.text); }),
child: Button(child: const Icon(FluentIcons.send, size: 18,), onPressed: () { message(_textController.text); }),
)
),
)
Expand Down
142 changes: 73 additions & 69 deletions lib/pages/text_generation/widgets/assistant_message.dart
Original file line number Diff line number Diff line change
Expand Up @@ -57,21 +57,23 @@ class _AssistantMessageState extends State<AssistantMessage> {
children: [
Padding(
padding: const EdgeInsets.only(bottom: 4),
child: Row(
children: [
Text(
inferenceProvider.project!.name,
style: TextStyle(
color: subtleTextColor.of(theme),
child: SelectionContainer.disabled(
child: Row(
children: [
Text(
inferenceProvider.project!.name,
style: TextStyle(
color: subtleTextColor.of(theme),
),
),
),
if (widget.message.time != null) Text(
DateFormat(' | yyyy-MM-dd HH:mm:ss').format(widget.message.time!),
style: TextStyle(
color: subtleTextColor.of(theme),
if (widget.message.time != null) Text(
DateFormat(' | yyyy-MM-dd HH:mm:ss').format(widget.message.time!),
style: TextStyle(
color: subtleTextColor.of(theme),
),
),
),
],
],
),
),
),
MouseRegion(
Expand All @@ -86,78 +88,80 @@ class _AssistantMessageState extends State<AssistantMessage> {
color: backgroundColor,
borderRadius: BorderRadius.circular(4),
),
child: Markdown(
data: widget.message.message,
selectable: true,
shrinkWrap: true,
padding: const EdgeInsets.all(12),
extensionSet: md.ExtensionSet(
md.ExtensionSet.gitHubFlavored.blockSyntaxes,
[md.EmojiSyntax(), ...md.ExtensionSet.gitHubFlavored.inlineSyntaxes],
child: Padding(
padding: const EdgeInsets.all(12.0),
child: MarkdownBody(
data: widget.message.message,
extensionSet: md.ExtensionSet(
md.ExtensionSet.gitHubFlavored.blockSyntaxes,
[md.EmojiSyntax(), ...md.ExtensionSet.gitHubFlavored.inlineSyntaxes],
),
),
),
),
if (_hovering)
Padding(
padding: const EdgeInsets.only(top: 4),
child: Row(
children: [
if (widget.message.metrics != null) Padding(
padding: const EdgeInsets.only(right: 8),
child: Tooltip(
message: 'Time to first token',
child: Text(
'TTF: ${nf.format(widget.message.metrics!.ttft)}ms',
style: TextStyle(
fontSize: 12,
color: subtleTextColor.of(theme),
child: SelectionContainer.disabled(
child: Row(
children: [
if (widget.message.metrics != null) Padding(
padding: const EdgeInsets.only(right: 8),
child: Tooltip(
message: 'Time to first token',
child: Text(
'TTF: ${nf.format(widget.message.metrics!.ttft)}ms',
style: TextStyle(
fontSize: 12,
color: subtleTextColor.of(theme),
),
),
),
),
),
if (widget.message.metrics != null) Padding(
padding: const EdgeInsets.only(right: 8),
child: Tooltip(
message: 'Time per output token',
child: Text(
'TPOT: ${nf.format(widget.message.metrics!.tpot)}ms',
style: TextStyle(
fontSize: 12,
color: subtleTextColor.of(theme),
if (widget.message.metrics != null) Padding(
padding: const EdgeInsets.only(right: 8),
child: Tooltip(
message: 'Time per output token',
child: Text(
'TPOT: ${nf.format(widget.message.metrics!.tpot)}ms',
style: TextStyle(
fontSize: 12,
color: subtleTextColor.of(theme),
),
),
),
),
),
if (widget.message.metrics != null) Padding(
padding: const EdgeInsets.only(right: 8),
child: Tooltip(
message: 'Generate total duration',
child: Text(
'Generate: ${nf.format(widget.message.metrics!.generate_time/1000)}s',
style: TextStyle(
fontSize: 12,
color: subtleTextColor.of(theme),
if (widget.message.metrics != null) Padding(
padding: const EdgeInsets.only(right: 8),
child: Tooltip(
message: 'Generate total duration',
child: Text(
'Generate: ${nf.format(widget.message.metrics!.generate_time/1000)}s',
style: TextStyle(
fontSize: 12,
color: subtleTextColor.of(theme),
),
),
),
),
),
IconButton(
icon: const Icon(FluentIcons.copy),
onPressed: () async{
await displayInfoBar(context, builder: (context, close) =>
InfoBar(
title: const Text('Copied to clipboard'),
severity: InfoBarSeverity.info,
action: IconButton(
icon: const Icon(FluentIcons.clear),
onPressed: close,
IconButton(
icon: const Icon(FluentIcons.copy),
onPressed: () async{
await displayInfoBar(context, builder: (context, close) =>
InfoBar(
title: const Text('Copied to clipboard'),
severity: InfoBarSeverity.info,
action: IconButton(
icon: const Icon(FluentIcons.clear),
onPressed: close,
),
),
),
);
Clipboard.setData(ClipboardData(text: widget.message.message));
},
),
],
);
Clipboard.setData(ClipboardData(text: widget.message.message));
},
),
],
),
),
) else const SizedBox(height: 34)
],
Expand Down
33 changes: 15 additions & 18 deletions lib/pages/text_generation/widgets/user_message.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,30 +13,27 @@ class UserMessage extends StatelessWidget {
final theme = FluentTheme.of(context);
return Align(
alignment: Alignment.centerRight,
child: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 1000),
child: Padding(padding: const EdgeInsets.only(bottom: 20), child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
decoration: BoxDecoration(
color: cosmosBackground.of(theme),
borderRadius: BorderRadius.circular(4),
),
child: Markdown(
child: Padding(padding: const EdgeInsets.only(bottom: 20), child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
decoration: BoxDecoration(
color: cosmosBackground.of(theme),
borderRadius: BorderRadius.circular(4),
),
child: Padding(
padding: const EdgeInsets.all(12.0),
child: MarkdownBody(
data: message.message,
selectable: true,
shrinkWrap: true,
padding: const EdgeInsets.all(12),
extensionSet: md.ExtensionSet(
md.ExtensionSet.gitHubFlavored.blockSyntaxes,
[md.EmojiSyntax(), ...md.ExtensionSet.gitHubFlavored.inlineSyntaxes],
),
),
)
],
),),
),
),
)
],
),),
);
}
}

0 comments on commit 93a8a15

Please sign in to comment.