Skip to content

Commit

Permalink
Added an ability to copy and share Code (#34)
Browse files Browse the repository at this point in the history
* Updated color scheme of markdown control. Added additional label and cations

* Added title bar to code control of Markdown
  • Loading branch information
mnikonov authored Jul 1, 2023
1 parent efceb9a commit 5819307
Show file tree
Hide file tree
Showing 19 changed files with 420 additions and 136 deletions.
19 changes: 15 additions & 4 deletions src/Gpt.Labs/ChatsPage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -119,15 +119,26 @@

<StackPanel x:Name="AddChatMsg" Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center" Padding="12 12 12 62"
x:Load="{x:Bind ViewModel.Result.ItemsCollection.Count, Converter={StaticResource CountToBooleanConverter}, Mode=OneWay}">
<FontIcon Glyph="&#xed0e;" FontSize="26"/>
<TextBlock x:Uid="AddChatLabel" Text="Add new chat" Margin="0 6 0 0" FontSize="12"></TextBlock>
<FontIcon Glyph="&#xe82f;" FontSize="26"/>
<TextBlock x:Uid="NoChatsLabel" Text="No chats to display" Margin="0 6 0 0" FontSize="12" TextAlignment="Center"></TextBlock>
</StackPanel>
</Grid>

<StackPanel x:Name="SelectChatMsg" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center" Padding="12"
x:Load="{x:Bind ViewModel.Result.SelectedElement, Converter={StaticResource ObjectToBooleanConverter}, ConverterParameter='=', Mode=OneWay}">
<FontIcon Glyph="&#xe89b;" FontSize="48"/>
<TextBlock x:Uid="SelectChatLabel" Text="Select a chat to start messaging" Margin="0 12 0 0"></TextBlock>
<FontIcon Glyph="&#xe89b;" FontSize="48" HorizontalAlignment="Center"/>

<TextBlock x:Uid="SelectChatLabel" Text="Select a chat to start messaging" Margin="0 18 0 0" TextLineBounds="Tight" HorizontalAlignment="Center"></TextBlock>

<TextBlock x:Uid="OrLabel" Text="or" Margin="0 18 0 0" HorizontalAlignment="Center" TextLineBounds="Tight"></TextBlock>

<Button x:Name="AddNewChat" Margin="0 18 0 0" HorizontalAlignment="Center" Style="{StaticResource AccentButtonStyle}"
Click="OnAddChatClick">
<StackPanel Orientation="Horizontal" Spacing="14">
<FontIcon Glyph="&#xed0e;" FontSize="24"/>
<TextBlock x:Uid="AddChatLabel" Text="Add a new one" VerticalAlignment="Center" TextLineBounds="Tight" />
</StackPanel>
</Button>
</StackPanel>

</Grid>
Expand Down
34 changes: 25 additions & 9 deletions src/Gpt.Labs/ChatsPage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Gpt.Labs.Models;
using Gpt.Labs.ViewModels;
using Gpt.Labs.ViewModels.Base;
using Gpt.Labs.ViewModels.Enums;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Input;
Expand Down Expand Up @@ -194,7 +195,12 @@ public async Task ClearBackState(params OpenAIChat[] chats)

private async void OnAddChatClick(object sender, RoutedEventArgs e)
{
await this.ViewModel.Result.AddEditChat(null);
var result = await this.ViewModel.Result.AddEditChat(null);

if (result == SaveResult.Added)
{
this.SelectChat(this.ViewModel.Result.ItemsCollection.FirstOrDefault());
}
}

private void OnChatListItemClick(object sender, ItemClickEventArgs e)
Expand All @@ -203,14 +209,7 @@ private void OnChatListItemClick(object sender, ItemClickEventArgs e)

if (this.ViewModel.Result.SelectedElement?.Id != chat?.Id)
{
this.ViewModel.Result.SelectChat(chat);

var query = new Query
{
{ "chat-id", chat.Id }
};

this.chatFrame.Navigate(typeof(MessagesPage), query.ToString(), new EntranceNavigationTransitionInfo());
this.SelectChat(chat);
}
}

Expand Down Expand Up @@ -292,6 +291,23 @@ await this.chatFrame.ExecuteOnLoaded(() =>
});
}

private void SelectChat(OpenAIChat chat)
{
if (chat == null)
{
return;
}

this.ViewModel.Result.SelectChat(chat);

var query = new Query
{
{ "chat-id", chat.Id }
};

this.chatFrame.Navigate(typeof(MessagesPage), query.ToString(), new EntranceNavigationTransitionInfo());
}

#endregion
}
}
32 changes: 17 additions & 15 deletions src/Gpt.Labs/Controls/Dialogs/EditChatDialog.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,7 @@
Text="{x:Bind ViewModel.Title, Mode=TwoWay}"
PlaceholderText="Enter title">
</TextBox>

<TextBlock x:Uid="SystemMessageLabel" Style="{StaticResource LabelStyle}"
Text="System message"/>

<TextBox x:Name="SystemMessageTextBox" x:Uid="SystemMessageTextBox"
TextWrapping="Wrap" AcceptsReturn="True" MaxLength="2500"
MaxHeight="106"
ScrollViewer.VerticalScrollBarVisibility="Auto"
Text="{x:Bind ((models:OpenAIChatSettings)ViewModel.Settings).SystemMessage, Mode=TwoWay}"
PlaceholderText="Enter system message">
</TextBox>

<TextBlock x:Uid="SystemMessageDescription" Style="{StaticResource DescriptionStyle}" />


<TextBlock x:Uid="ModelLabel" Style="{StaticResource LabelStyle}" Text="Model"/>

Expand All @@ -49,8 +37,22 @@
<Run x:Uid="ModelDescription4"/><Hyperlink NavigateUri="https://platform.openai.com/docs/models/model-endpoint-compatibility"><Run x:Uid="ModelDescription5"/></Hyperlink><Run x:Uid="ModelDescription7"/>
</TextBlock>


<TextBlock x:Uid="SystemMessageLabel" Style="{StaticResource LabelStyle}"
Text="System message"/>

<TextBox x:Name="SystemMessageTextBox" x:Uid="SystemMessageTextBox"
TextWrapping="Wrap" AcceptsReturn="True" MaxLength="2500"
MaxHeight="106"
ScrollViewer.VerticalScrollBarVisibility="Auto"
Text="{x:Bind ((models:OpenAIChatSettings)ViewModel.Settings).SystemMessage, Mode=TwoWay}"
PlaceholderText="Enter system message">
</TextBox>

<TextBlock x:Uid="SystemMessageDescription" Style="{StaticResource DescriptionStyle}" />


<TextBlock x:Uid="UserLabel" Style="{StaticResource LabelStyle}"
<TextBlock x:Uid="OpenAiUserLabel" Style="{StaticResource LabelStyle}"
Text="User"/>

<TextBox x:Name="UserTextBox" x:Uid="UserTextBox" MaxLength="250"
Expand All @@ -63,7 +65,7 @@
</TextBlock>


<TextBlock x:Name="OpenAIOrganizationLabel" x:Uid="ChatOpenAIOrganizationLabel" Text="Organization ID"
<TextBlock x:Name="OpenAIOrganizationLabel" x:Uid="OpenAIOrganizationLabel" Text="Organization ID"
Style="{StaticResource LabelStyle}"/>

<PasswordBox x:Name="OpenAIOrganizationTextBox" x:Uid="OpenAIOrganizationTextBox" MaxLength="50"
Expand Down
4 changes: 2 additions & 2 deletions src/Gpt.Labs/Controls/Dialogs/EditImageDialog.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
<TextBlock x:Uid="SizeMessageDescription" Style="{StaticResource DescriptionStyle}" />


<TextBlock x:Uid="UserLabel" Style="{StaticResource LabelStyle}"
<TextBlock x:Uid="OpenAiUserLabel" Style="{StaticResource LabelStyle}"
Text="User"/>

<TextBox x:Name="UserTextBox" x:Uid="UserTextBox" MaxLength="250"
Expand All @@ -50,7 +50,7 @@
</TextBlock>


<TextBlock x:Name="OpenAIOrganizationLabel" x:Uid="ChatOpenAIOrganizationLabel" Text="Organization ID"
<TextBlock x:Name="OpenAIOrganizationLabel" x:Uid="OpenAIOrganizationLabel" Text="Organization ID"
Style="{StaticResource LabelStyle}"/>

<PasswordBox x:Name="OpenAIOrganizationTextBox" x:Uid="OpenAIOrganizationTextBox" MaxLength="50"
Expand Down
129 changes: 129 additions & 0 deletions src/Gpt.Labs/Controls/Markdown/ExtendedMarkdownRenderer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
using CommunityToolkit.Common.Parsers.Markdown.Blocks;
using CommunityToolkit.Common.Parsers.Markdown.Render;
using CommunityToolkit.Common.Parsers.Markdown;
using CommunityToolkit.WinUI.UI.Controls.Markdown.Render;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml;
using System.Linq;
using Windows.UI;
using Windows.ApplicationModel.DataTransfer;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using CommunityToolkit.WinUI.UI;
using Gpt.Labs.Helpers;
using OpenAI.Chat;
using Gpt.Labs.Helpers.Extensions;
using Gpt.Labs.Models;

namespace Gpt.Labs.Controls.Markdown
{
public class ExtendedMarkdownRenderer : MarkdownRenderer
{
public ExtendedMarkdownRenderer(MarkdownDocument document, ILinkRegister linkRegister, IImageResolver imageResolver, ICodeBlockResolver codeBlockResolver)
: base(document, linkRegister, imageResolver, codeBlockResolver)
{
}

protected override void RenderCode(CodeBlock element, IRenderContext context)
{
// Renders the Code Block in the standard fashion.
base.RenderCode(element, context);

// Grab the Local context and cast it.
var localContext = context as UIElementCollectionRenderContext;
var collection = localContext?.BlockUIElementCollection;

// Don't go through with it, if there is an issue with the context or collection.
if (localContext == null || collection?.Any() != true)
{
return;
}

var scrollViewer = collection.Last() as ScrollViewer;

if (scrollViewer == null)
{
return;
}

collection.Remove(scrollViewer);

// Unify all Code Language headers for C#.
var language = element.CodeLanguage?.ToUpper();

if (!string.IsNullOrEmpty(language))
{
switch (language)
{
case "CSHARP":
case "CS":
language = "C#";
break;
}
}

var copyButton = new AppBarButton
{
Label = "Copy",
Icon = new FontIcon() { Glyph = "\uE8C8" },
};

ToolTipService.SetToolTip(copyButton, new ToolTip() { Content = App.ResourceLoader.GetString("CopyToolTip/Content") });

copyButton.Click += (s, e) =>
{
var content = new DataPackage();
content.SetText(element.Text.ConvertCrLfToLf());
Clipboard.SetContent(content);
};

var shareButton = new AppBarButton
{
Label = "Share",
Icon = new FontIcon() { Glyph = "\uE72D" }
};

ToolTipService.SetToolTip(shareButton, new ToolTip() { Content = App.ResourceLoader.GetString("ShareToolTip/Content") });

shareButton.Click += (s, e) =>
{
var windows = ((UIElement)s).GetParent<BasePage>()?.Window;

if (windows == null)
{
return;
}

windows.SetShareContent(new ShareContent
{
Title = language,
Message = element.Text.ConvertCrLfToLf()
});

windows.ShowShareUI();
};

var panel = new TitledContentPanel()
{
Background = scrollViewer.Background,
BorderBrush = scrollViewer.BorderBrush,
BorderThickness = scrollViewer.BorderThickness,
Margin = scrollViewer.Margin,
Padding = new Thickness(0),
Title = language
};

scrollViewer.Background = null;
scrollViewer.BorderBrush = null;
scrollViewer.BorderThickness = new Thickness(0);
scrollViewer.Margin = new Thickness(0);

panel.PrimaryCommands.Add(copyButton);
panel.PrimaryCommands.Add(shareButton);

panel.Content = scrollViewer;

collection.Add(panel);
}
}
}
31 changes: 19 additions & 12 deletions src/Gpt.Labs/Controls/MessagesControl.xaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<UserControl
<UserControl
x:Class="Gpt.Labs.Controls.MessagesControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Expand All @@ -14,6 +14,13 @@
<ThemeShadow x:Name="SharedShadow" />
</Grid.Resources>

<StackPanel x:Name="StartChatMsg" HorizontalAlignment="Center" VerticalAlignment="Center" Padding="12 12 12 126"
x:Load="{x:Bind ViewModel.ItemsCollection.Count, Converter={StaticResource CountToBooleanConverter}, Mode=OneWay}">
<TextBlock Text="🫡" FontSize="62" HorizontalAlignment="Center"/>

<TextBlock x:Uid="StartChatLabel" Text="Do you have a question for me?" Margin="0 12 0 0" HorizontalAlignment="Center" TextAlignment="Center"></TextBlock>
</StackPanel>

<ListView x:Name="MessagesList" IsItemClickEnabled="False" Padding="0 12 0 126"
SelectionMode="{x:Bind ViewModel.MultiSelectModeEnabled, Converter={StaticResource ListViewSelectionModeConverter}, ConverterParameter='None', Mode=OneWay}"
ItemsSource="{x:Bind ViewModel.ItemsCollection, Mode=OneWay}"
Expand Down Expand Up @@ -114,7 +121,6 @@
IsEnabled="{x:Bind ViewModel.ProcessingMessage, Converter={StaticResource InvertBooleanConverter}, Mode=OneWay}"
IsEnabledChanged="OnMessagePanelIsEnabledChanged">


<Grid Grid.Row="1" CornerRadius="4" Translation="0 0 32"
Background="{ThemeResource CardStrokeColorDefaultSolidBrush}"
Shadow="{StaticResource SharedShadow}">
Expand All @@ -124,16 +130,17 @@
<RowDefinition Height="50"></RowDefinition>
</Grid.RowDefinitions>

<TextBox x:Name="MessageTextBox" Grid.Row="0" Grid.RowSpan="2" TextWrapping="Wrap" AcceptsReturn="True"
Padding="12 6 12 50"
CornerRadius="4"
MaxHeight="244"
MinHeight="102"
Background="{ThemeResource CardBackgroundFillColorSecondaryBrush}"
ScrollViewer.VerticalScrollBarVisibility="Hidden"
Text="{x:Bind ViewModel.Message, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
PreviewKeyDown="OnMessageTextBoxPreviewKeyDown"
PreviewKeyUp="OnMessageTextBoxPreviewKeyUp">
<TextBox x:Name="MessageTextBox" x:Uid="MessageTextBox" Grid.Row="0" Grid.RowSpan="2" TextWrapping="Wrap" AcceptsReturn="True"
Padding="12 6 12 50"
CornerRadius="4"
MaxHeight="244"
MinHeight="102"
Background="{ThemeResource CardBackgroundFillColorSecondaryBrush}"
ScrollViewer.VerticalScrollBarVisibility="Hidden"
Text="{x:Bind ViewModel.Message, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
PreviewKeyDown="OnMessageTextBoxPreviewKeyDown"
PreviewKeyUp="OnMessageTextBoxPreviewKeyUp"
PlaceholderText="Write a message...">
<TextBox.Resources>
<SolidColorBrush x:Key="TextControlBackgroundPointerOver" Color="{ThemeResource CardBackgroundFillColorSecondary}" />
</TextBox.Resources>
Expand Down
2 changes: 1 addition & 1 deletion src/Gpt.Labs/Controls/OpenAiChatControl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ private async void OnEditButtonClick(object sender, RoutedEventArgs e)
{
var result = await this.ParentViewViewModel.AddEditChat(this.ViewModel);

if (result && this.ParentViewViewModel.SelectedElement != null && this.ViewModel.Id == this.ParentViewViewModel.SelectedElement.Id)
if (result == ViewModels.Enums.SaveResult.Edited && this.ParentViewViewModel.SelectedElement != null && this.ViewModel.Id == this.ParentViewViewModel.SelectedElement.Id)
{
((MessagesPage)this.ParentPage.GetInnerFrame().Content).ViewModel.Result.Chat = this.ParentViewViewModel.SelectedElement;
}
Expand Down
3 changes: 3 additions & 0 deletions src/Gpt.Labs/Controls/OpenAiMessageControl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using Microsoft.UI.Xaml.Input;
using Gpt.Labs.Helpers;
using Gpt.Labs.ViewModels;
using Gpt.Labs.Controls.Markdown;

namespace Gpt.Labs.Controls
{
Expand Down Expand Up @@ -71,6 +72,8 @@ protected override void OnApplyTemplate()
//this.textBlock.ImageResolving += this.OnMarkdownTextBlockImageResolving;
this.textBlock.ImageClicked -= this.OnMarkdownTextBlockImageClicked;
this.textBlock.ImageClicked += this.OnMarkdownTextBlockImageClicked;

this.textBlock.SetRenderer<ExtendedMarkdownRenderer>();
}

if (this.copyButton != null)
Expand Down
10 changes: 10 additions & 0 deletions src/Gpt.Labs/Helpers/Extensions/StringExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace Gpt.Labs.Helpers.Extensions
{
public static class StringExtensions
{
public static string ConvertCrLfToLf(this string value)
{
return value.Replace("\r\n", "\n");
}
}
}
Loading

0 comments on commit 5819307

Please sign in to comment.