@@ -13,6 +13,7 @@ import (
1313 "github.com/manifoldco/promptui"
1414 promptlist "github.com/manifoldco/promptui/list"
1515 log "github.com/obalunenko/logger"
16+ "github.com/savioxavier/termlink"
1617 "github.com/urfave/cli/v2"
1718
1819 "github.com/obalunenko/advent-of-code/internal/command"
@@ -146,7 +147,7 @@ func searcher(items []string) promptlist.Searcher {
146147
147148func handleYearChoices (ctx context.Context , opt promptui.Select ) error {
148149 for {
149- _ , choice , err := opt .Run ()
150+ _ , yearOpt , err := opt .Run ()
150151 if err != nil {
151152 if isAbort (err ) {
152153 return nil
@@ -155,11 +156,11 @@ func handleYearChoices(ctx context.Context, opt promptui.Select) error {
155156 return fmt .Errorf ("prompt failed: %w" , err )
156157 }
157158
158- if isExit (choice ) {
159+ if isExit (yearOpt ) {
159160 return nil
160161 }
161162
162- err = menuPuzzle (ctx , choice )
163+ err = menuPuzzle (ctx , yearOpt )
163164 if err != nil {
164165 if errors .Is (err , errExit ) {
165166 return nil
@@ -174,7 +175,7 @@ func handleYearChoices(ctx context.Context, opt promptui.Select) error {
174175
175176func handlePuzzleChoices (ctx context.Context , year string , opt promptui.Select ) error {
176177 for {
177- _ , choice , err := opt .Run ()
178+ _ , dayOpt , err := opt .Run ()
178179 if err != nil {
179180 if isAbort (err ) {
180181 return errExit
@@ -183,31 +184,47 @@ func handlePuzzleChoices(ctx context.Context, year string, opt promptui.Select)
183184 return fmt .Errorf ("prompt failed: %w" , err )
184185 }
185186
186- if isExit (choice ) {
187+ if isExit (dayOpt ) {
187188 return errExit
188189 }
189190
190- if isBack (choice ) {
191+ if isBack (dayOpt ) {
191192 return nil
192193 }
193194
194195 stopSpinner := setSpinner ()
195196
196- res , err := command .Run (ctx , year , choice )
197+ res , err := command .Run (ctx , year , dayOpt )
197198 if err != nil {
198- log .WithError (ctx , err ).Error ("Puzzle run failed" )
199-
200199 stopSpinner ()
201200
201+ if errors .Is (err , command .ErrUnauthorized ) {
202+ fmt .Println (termlink .Link ("Authorize here" , "https://adventofcode.com/auth/login" ))
203+
204+ log .WithError (ctx , err ).Fatal ("Session expired" )
205+ }
206+
207+ log .WithError (ctx , err ).Error ("Puzzle run failed" )
208+
202209 continue
203210 }
204211
205- stopSpinner ()
212+ stopSpinner ("Solved!" )
213+
214+ url := getURL (year , dayOpt )
206215
207216 fmt .Println (res .String ())
217+
218+ fmt .Println (termlink .Link ("Enter puzzle answers here" , url ))
208219 }
209220}
210221
222+ func getURL (year , day string ) string {
223+ const urlFmt = "https://adventofcode.com/%s/day/%s"
224+
225+ return fmt .Sprintf (urlFmt , year , day )
226+ }
227+
211228func isExit (in string ) bool {
212229 return strings .EqualFold (exit , in )
213230}
@@ -253,13 +270,13 @@ func sessionFromCli(c *cli.Context) string {
253270}
254271
255272// setSpinner runs the displaying of spinner to handle long time operations. Returns stop func.
256- func setSpinner () func () {
273+ func setSpinner () func (msg ... string ) {
257274 const delayMs = 100
258275
259276 s := spinner .New (
260277 spinner .CharSets [62 ],
261278 delayMs * time .Millisecond ,
262- spinner .WithFinalMSG ("Solved! " ),
279+ spinner .WithFinalMSG ("" ),
263280 spinner .WithHiddenCursor (true ),
264281 spinner .WithColor ("yellow" ),
265282 spinner .WithWriter (os .Stderr ),
@@ -269,7 +286,11 @@ func setSpinner() func() {
269286
270287 s .Start ()
271288
272- return func () {
289+ return func (msg ... string ) {
290+ if len (msg ) != 0 {
291+ s .FinalMSG = msg [0 ]
292+ }
293+
273294 s .Stop ()
274295 }
275296}
0 commit comments