185 lines
4.5 KiB
Go
185 lines
4.5 KiB
Go
package internal
|
|
|
|
import (
|
|
"fmt"
|
|
"os/user"
|
|
|
|
"github.com/HikariKnight/ls-iommu/pkg/errorcheck"
|
|
"github.com/charmbracelet/bubbles/list"
|
|
"github.com/charmbracelet/bubbles/textinput"
|
|
tea "github.com/charmbracelet/bubbletea"
|
|
)
|
|
|
|
// Make a status type
|
|
type status int
|
|
|
|
// List item struct
|
|
type item struct {
|
|
title, desc string
|
|
}
|
|
|
|
// Functions needed for item struct
|
|
func (i item) Title() string { return i.title }
|
|
func (i item) Description() string { return i.desc }
|
|
func (i item) FilterValue() string { return i.title }
|
|
|
|
// Main Model
|
|
type model struct {
|
|
fetched []bool
|
|
lists []list.Model
|
|
gpu_group string
|
|
gpu_IDs []string
|
|
vbios_path string
|
|
focused status
|
|
offsetx []int
|
|
offsety []int
|
|
width int
|
|
height int
|
|
authDialog textinput.Model
|
|
installOutput []string
|
|
}
|
|
|
|
// Consts used to navigate the main model
|
|
const (
|
|
INTRO status = iota
|
|
GPUS
|
|
GPU_GROUP
|
|
VBIOS
|
|
VIDEO
|
|
USB
|
|
USB_GROUP
|
|
INSTALL
|
|
WORKING
|
|
DONE
|
|
)
|
|
|
|
func NewModel() *model {
|
|
// Get the username
|
|
user, err := user.Current()
|
|
errorcheck.ErrorCheck(err, "Error getting username")
|
|
username := user.Username
|
|
|
|
// Create the auth input and focus it
|
|
authInput := textinput.New()
|
|
authInput.EchoMode = textinput.EchoPassword
|
|
authInput.Prompt = fmt.Sprintf("\n[sudo] password for %s: ", username)
|
|
authInput.Focus()
|
|
|
|
// Create a blank model and return it
|
|
return &model{
|
|
authDialog: authInput,
|
|
}
|
|
}
|
|
|
|
func (m model) Init() tea.Cmd {
|
|
return nil
|
|
}
|
|
|
|
func (m *model) initLists(width, height int) {
|
|
defaultList := list.New([]list.Item{}, list.NewDefaultDelegate(), 0, 10)
|
|
choiceList := list.New([]list.Item{}, choiceDelegate{}, 0, 7)
|
|
|
|
// Disable features we wont need
|
|
defaultList.SetShowTitle(false)
|
|
defaultList.SetFilteringEnabled(false)
|
|
defaultList.SetSize(m.width, m.height)
|
|
choiceList.SetShowTitle(false)
|
|
choiceList.SetFilteringEnabled(false)
|
|
|
|
// Add height and width to our model so we can use it later
|
|
m.width = width
|
|
m.height = height
|
|
|
|
m.lists = []list.Model{
|
|
choiceList,
|
|
defaultList,
|
|
defaultList,
|
|
choiceList,
|
|
choiceList,
|
|
defaultList,
|
|
defaultList,
|
|
choiceList,
|
|
choiceList,
|
|
choiceList,
|
|
}
|
|
|
|
// Configure offsets for sizing
|
|
m.offsetx = []int{
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
}
|
|
m.offsety = []int{
|
|
18, 2, 3, 13, 5, 2, 3, 12, 0, 0,
|
|
}
|
|
|
|
// Update the styles with the correct width
|
|
dialogStyle = dialogStyle.Width(m.width)
|
|
listStyle = listStyle.Width(m.width)
|
|
titleStyle = titleStyle.Width(m.width - 4)
|
|
choiceStyle = choiceStyle.Width(m.width)
|
|
|
|
// Make m.fetched and set all values to FALSE
|
|
m.fetched = []bool{}
|
|
for range m.lists {
|
|
m.fetched = append(m.fetched, false)
|
|
}
|
|
|
|
// Set INTRO to the focused view
|
|
m.focused = INTRO
|
|
|
|
// Init INTRO choices
|
|
items := []list.Item{
|
|
item{title: "CONTINUE"},
|
|
}
|
|
//m.lists[INTRO].SetHeight(5)
|
|
m.lists[INTRO].SetItems(items)
|
|
m.lists[INTRO].SetSize(m.width-m.offsetx[INTRO], m.height-m.offsety[INTRO])
|
|
|
|
// Init GPU list
|
|
items = iommuList2ListItem(getIOMMU("-g", "-F", "vendor:,prod_name,optional_revision:,device_id"))
|
|
m.lists[GPUS].SetItems(items)
|
|
m.lists[GPUS].SetSize(m.width-m.offsetx[GPUS], m.height-m.offsety[GPUS])
|
|
m.fetched[GPUS] = true
|
|
|
|
// Setup the initial GPU_GROUP list
|
|
// The content in this list is generated from the selected choice from the GPU view
|
|
m.lists[GPU_GROUP].SetSize(m.width-m.offsetx[GPU_GROUP], m.height-m.offsety[GPU_GROUP])
|
|
|
|
// Init USB Controller list
|
|
items = iommuList2ListItem(getIOMMU("-u", "-F", "vendor:,prod_name,optional_revision:,device_id"))
|
|
m.lists[USB].SetItems(items)
|
|
m.lists[USB].SetSize(m.width-m.offsetx[USB], m.height-m.offsety[USB])
|
|
m.fetched[USB] = true
|
|
|
|
// Setup the initial USB_GROUP list
|
|
// The content in this list is generated from the selected choice from the USB view
|
|
m.lists[USB_GROUP].SetSize(m.width-m.offsetx[USB_GROUP], m.height-m.offsety[USB_GROUP])
|
|
|
|
// Init VBIOS choices
|
|
items = []list.Item{
|
|
item{title: "OK"},
|
|
}
|
|
m.lists[VBIOS].SetItems(items)
|
|
m.lists[VBIOS].SetSize(m.width-m.offsetx[VBIOS], m.height-m.offsety[VBIOS])
|
|
|
|
// Init VIDEO disable choises
|
|
items = []list.Item{
|
|
item{title: "YES"},
|
|
item{title: "NO"},
|
|
}
|
|
m.lists[VIDEO].SetItems(items)
|
|
m.lists[VIDEO].SetSize(m.width-m.offsetx[VIDEO], m.height-m.offsety[VIDEO])
|
|
|
|
// Init DONE choises
|
|
items = []list.Item{
|
|
item{title: "WAITING"},
|
|
}
|
|
m.lists[WORKING].SetItems(items)
|
|
m.lists[WORKING].SetSize(m.width-m.offsetx[WORKING], m.height-m.offsety[WORKING])
|
|
|
|
// Init DONE choises
|
|
items = []list.Item{
|
|
item{title: "FINISH"},
|
|
}
|
|
m.lists[DONE].SetItems(items)
|
|
m.lists[DONE].SetSize(m.width-m.offsetx[DONE], m.height-m.offsety[DONE])
|
|
}
|