11package project
22
33import (
4- "encoding/json"
5- "fmt"
64 "net/http"
5+ "time"
76
87 "github.com/cli/cli/api"
98 "github.com/cli/cli/internal/ghrepo"
109 "github.com/cli/cli/pkg/cmdutil"
1110 "github.com/cli/cli/pkg/iostreams"
11+ "github.com/gdamore/tcell/v2"
12+ "github.com/mattn/go-runewidth"
1213 "github.com/spf13/cobra"
1314)
1415
@@ -47,35 +48,6 @@ func NewCmdProject(f *cmdutil.Factory, runF func(*ProjectOptions) error) *cobra.
4748 return cmd
4849}
4950
50- func projectRun (opts * ProjectOptions ) error {
51- // TODO interactively ask which project they want since these IDs are not easy to get
52- projectID := 3514315
53-
54- c , err := opts .HttpClient ()
55- if err != nil {
56- return err
57- }
58- client := api .NewClientFromHTTP (c )
59-
60- baseRepo , err := opts .BaseRepo ()
61- if err != nil {
62- return err
63- }
64-
65- project , err := getProject (client , baseRepo , projectID )
66- if err != nil {
67- return err
68- }
69-
70- fmt .Printf ("DBG %#v\n " , project )
71-
72- for _ , c := range project .Columns {
73- fmt .Printf ("DBG %s: %d cards\n " , c .Name , len (c .Cards ))
74- }
75-
76- return nil
77- }
78-
7951type Card struct {
8052 Note string
8153 ID int
@@ -93,40 +65,91 @@ type Project struct {
9365 Columns []* Column
9466}
9567
96- func getProject (client * api.Client , baseRepo ghrepo.Interface , projectID int ) (* Project , error ) {
97- data , err := client .GetProject (baseRepo , projectID )
68+ func projectRun (opts * ProjectOptions ) error {
69+ // TODO interactively ask which project they want since these IDs are not easy to get
70+ projectID := 3514315
71+
72+ c , err := opts .HttpClient ()
9873 if err != nil {
99- return nil , err
74+ return err
10075 }
76+ client := api .NewClientFromHTTP (c )
10177
102- project := & Project {}
103-
104- err = json .Unmarshal (data , project )
78+ baseRepo , err := opts .BaseRepo ()
10579 if err != nil {
106- return nil , err
80+ return err
10781 }
10882
109- data , err = client . GetProjectColumns ( baseRepo , projectID )
83+ project , err := getProject ( client , baseRepo , projectID )
11084 if err != nil {
111- return nil , err
85+ return err
11286 }
11387
114- err = json .Unmarshal (data , & project .Columns )
88+ style := tcell .StyleDefault
89+
90+ s , err := tcell .NewScreen ()
11591 if err != nil {
116- return nil , err
92+ return err
93+ }
94+ if err = s .Init (); err != nil {
95+ return err
11796 }
11897
119- for _ , column := range project .Columns {
120- data , err := client .GetProjectCards (baseRepo , column .ID )
121- if err != nil {
122- return nil , err
98+ s .SetStyle (style )
99+
100+ // some kind of controller struct to track modal state?
101+
102+ quit := make (chan struct {})
103+ go func () {
104+ for {
105+ ev := s .PollEvent ()
106+ switch ev := ev .(type ) {
107+ case * tcell.EventKey :
108+ switch ev .Rune () {
109+ case 'q' :
110+ close (quit )
111+ return
112+ }
113+ switch ev .Key () {
114+ case tcell .KeyEscape :
115+ close (quit )
116+ return
117+ case tcell .KeyCtrlL :
118+ s .Sync ()
119+ }
120+ case * tcell.EventResize :
121+ s .Sync ()
122+ }
123123 }
124-
125- err = json .Unmarshal (data , & column .Cards )
126- if err != nil {
127- return nil , err
124+ }()
125+
126+ loop:
127+ for {
128+ select {
129+ case <- quit :
130+ break loop
131+ case <- time .After (time .Millisecond * 500 ):
128132 }
133+ s .Clear ()
134+ drawStr (s , 0 , 0 , style , project .Name )
135+ s .Show ()
129136 }
130137
131- return project , nil
138+ s .Fini ()
139+
140+ return nil
141+ }
142+
143+ func drawStr (s tcell.Screen , x , y int , style tcell.Style , str string ) {
144+ for _ , c := range str {
145+ var comb []rune
146+ w := runewidth .RuneWidth (c )
147+ if w == 0 {
148+ comb = []rune {c }
149+ c = ' '
150+ w = 1
151+ }
152+ s .SetContent (x , y , c , comb , style )
153+ x += w
154+ }
132155}
0 commit comments