github.com/wtfutil/wtf@v0.43.0/modules/gitlab/widget.go (about)

     1  package gitlab
     2  
     3  import (
     4  	"strconv"
     5  
     6  	"github.com/rivo/tview"
     7  	"github.com/wtfutil/wtf/utils"
     8  	"github.com/wtfutil/wtf/view"
     9  )
    10  
    11  type ContentItem struct {
    12  	Type string
    13  	ID   int
    14  }
    15  
    16  type Widget struct {
    17  	view.MultiSourceWidget
    18  	view.TextWidget
    19  
    20  	GitlabProjects []*GitlabProject
    21  
    22  	context  *context
    23  	settings *Settings
    24  	Selected int
    25  	maxItems int
    26  	Items    []ContentItem
    27  
    28  	configError error
    29  }
    30  
    31  // NewWidget creates a new instance of the widget
    32  func NewWidget(tviewApp *tview.Application, redrawChan chan bool, pages *tview.Pages, settings *Settings) *Widget {
    33  	context, err := newContext(settings)
    34  
    35  	widget := Widget{
    36  		MultiSourceWidget: view.NewMultiSourceWidget(settings.Common, "project", "projects"),
    37  		TextWidget:        view.NewTextWidget(tviewApp, redrawChan, pages, settings.Common),
    38  
    39  		context:  context,
    40  		settings: settings,
    41  
    42  		configError: err,
    43  	}
    44  
    45  	widget.GitlabProjects = widget.buildProjectCollection(context, settings.projects)
    46  
    47  	widget.initializeKeyboardControls()
    48  	widget.View.SetRegions(true)
    49  	widget.SetDisplayFunction(widget.display)
    50  
    51  	widget.Unselect()
    52  
    53  	return &widget
    54  }
    55  
    56  /* -------------------- Exported Functions -------------------- */
    57  
    58  func (widget *Widget) Refresh() {
    59  	if widget.context == nil || widget.configError != nil {
    60  		widget.displayError()
    61  		return
    62  	}
    63  
    64  	for _, project := range widget.GitlabProjects {
    65  		project.Refresh()
    66  	}
    67  
    68  	widget.display()
    69  }
    70  
    71  // SetItemCount sets the amount of PRs RRs and other PRs throughout the widgets display creation
    72  func (widget *Widget) SetItemCount(items int) {
    73  	widget.maxItems = items
    74  }
    75  
    76  // GetItemCount returns the amount of PRs RRs and other PRs calculated so far as an int
    77  func (widget *Widget) GetItemCount() int {
    78  	return widget.maxItems
    79  }
    80  
    81  // GetSelected returns the index of the currently highlighted item as an int
    82  func (widget *Widget) GetSelected() int {
    83  	if widget.Selected < 0 {
    84  		return 0
    85  	}
    86  	return widget.Selected
    87  }
    88  
    89  // Next cycles the currently highlighted text down
    90  func (widget *Widget) Next() {
    91  	widget.Selected++
    92  	if widget.Selected >= widget.maxItems {
    93  		widget.Selected = 0
    94  	}
    95  	widget.View.Highlight(strconv.Itoa(widget.Selected))
    96  	widget.View.ScrollToHighlight()
    97  }
    98  
    99  // Prev cycles the currently highlighted text up
   100  func (widget *Widget) Prev() {
   101  	widget.Selected--
   102  	if widget.Selected < 0 {
   103  		widget.Selected = widget.maxItems - 1
   104  	}
   105  	widget.View.Highlight(strconv.Itoa(widget.Selected))
   106  	widget.View.ScrollToHighlight()
   107  }
   108  
   109  // Unselect stops highlighting the text and jumps the scroll position to the top
   110  func (widget *Widget) Unselect() {
   111  	widget.Selected = -1
   112  	widget.View.Highlight()
   113  	widget.View.ScrollToBeginning()
   114  }
   115  
   116  /* -------------------- Unexported Functions -------------------- */
   117  
   118  func (widget *Widget) buildProjectCollection(context *context, projectData []string) []*GitlabProject {
   119  	gitlabProjects := []*GitlabProject{}
   120  
   121  	for _, projectPath := range projectData {
   122  		project := NewGitlabProject(context, projectPath)
   123  		gitlabProjects = append(gitlabProjects, project)
   124  	}
   125  
   126  	return gitlabProjects
   127  }
   128  
   129  func (widget *Widget) currentGitlabProject() *GitlabProject {
   130  	if len(widget.GitlabProjects) == 0 {
   131  		return nil
   132  	}
   133  
   134  	if widget.Idx < 0 || widget.Idx >= len(widget.GitlabProjects) {
   135  		return nil
   136  	}
   137  
   138  	return widget.GitlabProjects[widget.Idx]
   139  }
   140  
   141  func (widget *Widget) openItemInBrowser() {
   142  	currentSelection := widget.View.GetHighlights()
   143  	if widget.Selected >= 0 && currentSelection[0] != "" {
   144  
   145  		item := widget.Items[widget.Selected]
   146  		url := ""
   147  
   148  		project := widget.currentGitlabProject()
   149  		if project == nil {
   150  			// This is a problem. We will just bail out for now
   151  			return
   152  		}
   153  
   154  		switch item.Type {
   155  		case "MR":
   156  			url = (project.RemoteProject.WebURL + "/merge_requests/" + strconv.Itoa(item.ID))
   157  		case "ISSUE":
   158  			url = (project.RemoteProject.WebURL + "/issues/" + strconv.Itoa(item.ID))
   159  		}
   160  
   161  		utils.OpenFile(url)
   162  	}
   163  }
   164  
   165  func (widget *Widget) openRepo() {
   166  	project := widget.currentGitlabProject()
   167  	if project == nil {
   168  		return
   169  	}
   170  	url := project.RemoteProject.WebURL
   171  	utils.OpenFile(url)
   172  }
   173  
   174  func (widget *Widget) openPulls() {
   175  	project := widget.currentGitlabProject()
   176  	if project == nil {
   177  		return
   178  	}
   179  	url := project.RemoteProject.WebURL + "/merge_requests/"
   180  	utils.OpenFile(url)
   181  }
   182  
   183  func (widget *Widget) openIssues() {
   184  	project := widget.currentGitlabProject()
   185  	if project == nil {
   186  		return
   187  	}
   188  	url := project.RemoteProject.WebURL + "/issues/"
   189  	utils.OpenFile(url)
   190  }