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

     1  package gitlabtodo
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/rivo/tview"
     7  	"github.com/wtfutil/wtf/utils"
     8  	"github.com/wtfutil/wtf/view"
     9  	gitlab "github.com/xanzy/go-gitlab"
    10  )
    11  
    12  type Widget struct {
    13  	view.ScrollableWidget
    14  
    15  	todos        []*gitlab.Todo
    16  	gitlabClient *gitlab.Client
    17  	settings     *Settings
    18  	err          error
    19  }
    20  
    21  func NewWidget(tviewApp *tview.Application, redrawChan chan bool, pages *tview.Pages, settings *Settings) *Widget {
    22  	widget := &Widget{
    23  		ScrollableWidget: view.NewScrollableWidget(tviewApp, redrawChan, pages, settings.Common),
    24  
    25  		settings: settings,
    26  	}
    27  
    28  	widget.gitlabClient, _ = gitlab.NewClient(settings.apiKey, gitlab.WithBaseURL(settings.domain))
    29  
    30  	widget.SetRenderFunction(widget.Render)
    31  	widget.initializeKeyboardControls()
    32  
    33  	return widget
    34  }
    35  
    36  /* -------------------- Exported Functions -------------------- */
    37  
    38  func (widget *Widget) Refresh() {
    39  	if widget.Disabled() {
    40  		return
    41  	}
    42  
    43  	todos, err := widget.getTodos()
    44  	widget.todos = todos
    45  	widget.err = err
    46  	widget.SetItemCount(len(todos))
    47  
    48  	widget.Render()
    49  }
    50  
    51  // Render sets up the widget data for redrawing to the screen
    52  func (widget *Widget) Render() {
    53  	widget.Redraw(widget.content)
    54  }
    55  
    56  /* -------------------- Unexported Functions -------------------- */
    57  
    58  func (widget *Widget) content() (string, string, bool) {
    59  	title := fmt.Sprintf("GitLab ToDos (%d)", len(widget.todos))
    60  
    61  	if widget.err != nil {
    62  		return title, widget.err.Error(), true
    63  	}
    64  
    65  	if widget.todos == nil {
    66  		return title, "No ToDos to display", false
    67  	}
    68  
    69  	str := widget.contentFrom(widget.todos)
    70  
    71  	return title, str, false
    72  }
    73  
    74  func (widget *Widget) getTodos() ([]*gitlab.Todo, error) {
    75  	opts := gitlab.ListTodosOptions{}
    76  
    77  	todos, _, err := widget.gitlabClient.Todos.ListTodos(&opts)
    78  	if err != nil {
    79  		return nil, err
    80  	}
    81  
    82  	return todos, nil
    83  }
    84  
    85  // trim the todo body so it fits on a single line
    86  func (widget *Widget) trimTodoBody(body string) string {
    87  	r := []rune(body)
    88  
    89  	// Cut at first occurrence of a newline
    90  	for i, a := range r {
    91  		if a == '\n' {
    92  			return string(r[:i])
    93  		}
    94  	}
    95  
    96  	return body
    97  }
    98  
    99  func (widget *Widget) contentFrom(todos []*gitlab.Todo) string {
   100  	var str string
   101  
   102  	for idx, todo := range todos {
   103  		row := fmt.Sprintf(`[%s]%2d. `, widget.RowColor(idx), idx+1)
   104  		if widget.settings.showProject {
   105  			row = fmt.Sprintf(`%s%s `, row, todo.Project.Path)
   106  		}
   107  		row = fmt.Sprintf(`%s[mediumpurple](%s)[%s] %s`,
   108  			row,
   109  			todo.Author.Username,
   110  			widget.RowColor(idx),
   111  			widget.trimTodoBody(todo.Body),
   112  		)
   113  
   114  		str += utils.HighlightableHelper(widget.View, row, idx, len(todo.Body))
   115  	}
   116  
   117  	return str
   118  }
   119  
   120  func (widget *Widget) markAsDone() {
   121  	sel := widget.GetSelected()
   122  	if sel >= 0 && widget.todos != nil && sel < len(widget.todos) {
   123  		todo := widget.todos[sel]
   124  		_, err := widget.gitlabClient.Todos.MarkTodoAsDone(todo.ID)
   125  		if err == nil {
   126  			widget.Refresh()
   127  		}
   128  	}
   129  }
   130  
   131  func (widget *Widget) openTodo() {
   132  	sel := widget.GetSelected()
   133  	if sel >= 0 && widget.todos != nil && sel < len(widget.todos) {
   134  		todo := widget.todos[sel]
   135  		utils.OpenFile(todo.TargetURL)
   136  	}
   137  }