You saw in Chapter 15 that ANSI codes contain a different variety of code that can be used to develop text-based user interfaces. You also saw examples of using ANSI codes and learned what the different codes mean. There are a number of user interface libraries for Go that take care of user interface operations, thereby making development easier and faster. In this chapter, you will look at these libraries and explore in detail how they work internally.
In this chapter, you will look at two libraries. The first library is a simple library called uiprogress that allows an application to create a text-based progress bar. The other is called bubbletea and it is a more comprehensive library that allows an application to create different kinds of text-based UIs such as text input, boxes, spinners, and more.
How to use the libraries
How the libraries work internally
uiprogress
![](https://imgdetail.ebookreading.net/2023/10/9781484287316/9781484287316__9781484287316__files__images__527551_1_En_16_Chapter__527551_1_En_16_Fig1_HTML.jpg)
A screenshot of the output screen. The text reads app deployment started app 1 and app 2. app 1 starts from 4s and goes to 86 percent and app 2 starts from 4s and goes to 100 percent.
uiprogress progress bar
![](https://imgdetail.ebookreading.net/2023/10/9781484287316/9781484287316__9781484287316__files__images__527551_1_En_16_Chapter__527551_1_En_16_Fig2_HTML.jpg)
A screenshot of the output screen. The text reads 1s 84 percent.
Progress bar output from simple.go
Code Flow
![](https://imgdetail.ebookreading.net/2023/10/9781484287316/9781484287316__9781484287316__files__images__527551_1_En_16_Chapter__527551_1_En_16_Fig3_HTML.jpg)
A flow diagram of a code starts from simple. go and divided into 5 factors named to start, add a bar, app end completed, prepend lapsed, and Inc to bars, print, and listen with the help of append and loop.
Code flow from simple.go to the library
The function is in a for{} loop and calls the print() function at an interval that has been set at the default of 10 milliseconds.
Updating Progress
AppendCompleted() adds a function that will print out the percentage completed when the progress bar has completed its operation.
PrependElapsed() prefixes the progress bar with the time it has taken to complete so far.
The code will look as long as the bar.Incr() returns true and will sleep for 20 milliseconds before incrementing again.
From your code perspective, the library takes care of updating and managing the progress bar, allowing your application to focus on its main task. All the application needs to do is just inform the library about the new value of the bar by calling the Incr() or Decr() function.
In the next section, you will look at a more comprehensive library that provides a better user interface for an application.
Bubbletea
In the previous section, you saw the uiprogress progress bar library and looked at how it works internally. In this section, you will take a look at another user interface framework called bubbletea. The code can be checked out from https://github.com/charmbracelet/bubbletea.
![](https://imgdetail.ebookreading.net/2023/10/9781484287316/9781484287316__9781484287316__files__images__527551_1_En_16_Chapter__527551_1_En_16_Fig4_HTML.jpg)
A screenshot explains the output. The output is five works finished at 817, 727, 658, 219, and 190-meter seconds.
tui-daemon-combo sample output
![](https://imgdetail.ebookreading.net/2023/10/9781484287316/9781484287316__9781484287316__files__images__527551_1_En_16_Chapter__527551_1_En_16_Fig5_HTML.jpg)
A screenshot explains the three application functions such as int, update, and view. All three are connected parallel to the bubble tea function.
Application functions for bubbletea interaction
In the next few sections, you will use the tui-daemon-combo sample code to work out how the code flows inside the library.
Now you have defined the different functions that will be called by the library when constructing and updating the UI. Next, you will look at how each of these functions are used by the library.
Init
After bubbletea completes calling the application Init() function, it kickstarts the process. Internally, it uses channels to read different incoming messages to perform different user interface operations, so in your sample code case, it processes the batchMsg array and starts calling the Cmd function types.
![](https://imgdetail.ebookreading.net/2023/10/9781484287316/9781484287316__9781484287316__files__images__527551_1_En_16_Chapter__527551_1_En_16_Fig6_HTML.jpg)
A framework of the sample code starts from the main function and then starts. Start returns the model and then classified into three parts named S I G N T, initCmD, and Msg.
Initialization of the internal execution flow
Update
The Update function receives different kinds of tea.Msg because it is defined as an interface, so the code needs to do type checking and handle the type it wants to handle. For example, when the function receives spinner.TickMsg, it updates the spinner by calling the spinner.Update() function, and when it receives tea.KeyMsg, it quits the application.
The function only needs to process messages that it is interested in and process any user interface state management that it needs to do. Other heavy operations must be avoided in the function.
View
The last function, View(), is called by the library to update the user interface. The application is given the freedom to update the user interface as it sees fit. This flexibility allows the application to render a user interface that suits its needs.
The app combines all the user interfaces that it needs to display to the user by extracting the different values from the different variables. For example, it extract the results array values to show it to the user. The results array is populated in the Update function when it receives the processFinishedMsg message type.
The function returns a string containing the user interface that will be rendered by the library to the terminal.
Figure 16-7 shows at a high level the different goroutines that are spun off by the library and that take care of the different parts of the user interfaces such as user input using the keyboard, mouse, terminal resizing, and more.
![](https://imgdetail.ebookreading.net/2023/10/9781484287316/9781484287316__9781484287316__files__images__527551_1_En_16_Chapter__527551_1_En_16_Fig7_HTML.png)
A framework of process messages has six factors such as user input, process Cmds, terminal resize, tea dot msg function, update function, and view function.
Centralized processing of messages
Summary
In this chapter, you look at two different terminal-based user interface frameworks that provide APIs for developers to build command-line user interfaces. You looked at sample applications of how to use the frameworks to build simple command-line user interfaces.
You looked at the internals of the frameworks to understand how they work. Knowing this gives you better insight into how to troubleshoot issues when using these kinds of frameworks. And understanding the complexity of these frameworks helps you build your own asynchronous applications.