Building a ChatGPT in .NET MAUI Part 2
In this second part of my post, the focus is on the application's user interface and its interaction with the ViewModel.
INFO: It is important to me that you have full confidence in the authenticity of my posts. Therefore, I want to inform you that this publication had the help of GPT-3.5. However, I always use my criteria to make sure the post is clear and easy to understand. In case I use this tool or any other again in the future, I will let you know in advance to ensure transparency at all times.
WARNING: This post emphasizes the importance of using the application ethically and responsibly, which has been developed on the .NET MAUI platform and is based on OpenAI technology. While I do not consider myself a moral authority, I do recognize that I have made mistakes in the past and that I will continue to learn and evolve as a human being in the future. This same philosophy applies to the technological field, where both users and developers must be aware of the possible ethical and social implications of their actions. It is crucial to consider the impact of technology on society and work together to ensure its appropriate and responsible use. For this, it is necessary to adopt ethical and responsible standards, such as transparency, equity and responsibility. Transparency implies adequate and clear disclosure of the processes and results of the use of technology. Equity, for its part, requires that applications be accessible and fair to all people, regardless of their origin, gender, race or beliefs. And responsibility implies assuming the consequences of our actions and decisions, as well as the social responsibility of guaranteeing that technology does not cause harm to society. In summary, the ethical and responsible use of technology is essential to move towards a more just and equitable society. We need both users and developers to embrace ethical and responsible standards, and work together to ensure that technology is used for the common good.
I want to emphasize that all the information presented in this publication is due to the valuable talk given by Luis Beltran, PhD, who gave us taught how to build a ChatGPT in .NET MAUI with the OpenAI APIs. I appreciate his contribution and hope this post can help other developers implement this technology in their own .NET applications.
Parts of ConversationView
The ConversationView view is made up of three distinct sections: the top section, the middle section, and the bottom section. The top section includes the brand image and title of the app, along with buttons to generate text and images. The middle section presents the conversation between the user and the chatbot, presented in a CollectionView. And finally, the lower section includes a field to enter text and buttons to send or capture audio by voice.
Lottie animation when message list is empty
When the app’s message list is empty, a Lottie animation is automatically activated to enhance the user experience and add a touch of personality to the app’s interface. This animation plays continuously and draws the user’s attention, indicating that they can send a query to the chatbot at any time. Once the user sends a message or receives a response from the chatbot, the animation stops automatically, allowing the user to focus on the conversation with the chatbot. In this way, animation is an effective tool to attract the user’s attention and guide them towards the use of the chatbot.
Lottie animation when message list is empty
Interaction of the UI with the ViewModel
The way the chatbot provides information depends not only on the queries that users enter in the text input field, but also on the buttons at the top that change the chatbot’s response, either through text or images. Behind the scenes, the ViewModel is in charge of managing the application logic and communicating with the OpenAI service. Below is an image that summarizes how information flows between the UI and the ViewModel.
Command flow and methods in write and image mode
For the AskQuestion method
The
CurrentCommand
instance is set to its initial state, which isAskQuestion
. In addition,OpacityModeMessage
is set to 1 andOpacityModeImage
is set to 0.5, and a toast is displayed (brief, temporary message) indicating that it is in write mode.A new instance of
AsyncRelayCommand
is created which calls theAskQuestionAsync
method.When the
AskQuestionAsync
method is called, sets theIsTextActive
flag totrue
and theIsImageActive
flag tofalse
.The
QueryManagerAsync
method is called with the_openAIService.AskQuestion
function as an argument.In
QueryManagerAsync
, the user’s message is added to the message list, theisUserMessage
flag is set totrue
, and the_openAIService.AskQuestion
function is called with the user’s query as an argument.Add the bot’s response to the message list, set the
isUserMessage
flag tofalse
and scroll to the bottom of the message list.
For the CreateImage method
When the user switches to image mode via the corresponding button, the
CreateImage
method is called. Within this method, theOpacityModeMessage
is set to 0.5 and theOpacityModeImage
is set to 1, and a toast is displayed indicating that the image mode has been activated.The
CurrentCommand
property is then assigned a new asynchronous command (AsyncRelayCommand
) which, when triggered, will execute theCreateImageAsync
method.When the
CreateImageAsync
method is called, it sets theIsTextActive
flag tofalse
and theIsImageActive
flag totrue
.The
QueryManagerAsync
method is called with the_openAIService.CreateImage
function as an argument.In
QueryManagerAsync
, the user message is added to the message list, theisUserMessage
flag is set totrue
, and the_openAIService.CreateImage
function is called with the user’s query as an argument.Add the bot’s response to the message list, set the
isUserMessage
flag tofalse
, and scroll the view to the bottom of the message list.
Data templates in ConversationView
The distinction between messages sent by the user and messages sent by the chatbot is done by using two different templates in the UI. The user message template (UserMessageItemTemplate
) is used to display messages sent by the user, while the chatbot message template (BotMessageItemTemplate
) is used to display messages sent by the chatbot. This allows a better visual organization of the conversation and makes it easier for the user to understand the messages he receives.
Selection of themes
When the application branding is clicked, the SelectTheme
method is triggered. This method, which is an asynchronous method, allows you to change the app’s theme and animate the conversation view to make the transition smoother.
First, the method gets the current theme of the application and sets the new theme as the opposite of the current (dark or light). Then, set the new theme as the app theme.
An animation is then run in the conversation view using the ScaleTo
method. For 250 milliseconds, the view shrinks to 95% of its original size, then expands to 105% of its original size for another 250 milliseconds, and finally returns to the original size for another 250 milliseconds. The animation uses the CubicOut
speedup function to slow down the animation at the end.
1
2
3
4
5
6
7
8
9
10
[RelayCommand]
private async Task SelectTheme()
{
AppTheme currentTheme = Application.Current.RequestedTheme;
AppTheme newTheme = currentTheme == AppTheme.Dark ? AppTheme.Light : AppTheme.Dark;
Application.Current.UserAppTheme = newTheme;
await ConversationView.ScaleTo(0.95, 250, Easing.CubicOut);
await ConversationView.ScaleTo(1.05, 250, Easing.CubicIn);
await ConversationView.ScaleTo(1, 250, Easing.CubicOut);
}
Repository
The project is open source and you can see it by clicking on the following image. Don’t hesitate to take a look!
Resources
- Working with GridLayout in Xamarin Forms - Written by Leomaris Reyes .
- Data Templates - Official Documentation from .NET MAUI.
- Border - Official Documentation from .NET MAUI.
- MVVM is easier than ever with Source Generators, .NET 7 and the MVVM Toolkit - .NET Conf 2022.
Publication in Spanish
Conclusions
In short, to build the chatbot UI in .NET MAUI we have shown the three different sections that make up the ConversationView, as well as the user message template (UserMessageItemTemplate) and the chatbot message template (BotMessageItemTemplate ). In addition, a Lottie animation has been introduced that is displayed when the message list is empty, which helps to improve the user experience.
Feel free to give me your opinion and with the help of my repository, draw your own conclusions. If you have any constructive questions or suggestions, I would very much like to read them. Thanks for your time.