1// SPDX-FileCopyrightText: Amolith <amolith@secluded.site>
2//
3// SPDX-License-Identifier: AGPL-3.0-or-later
4
5package note
6
7import (
8 "encoding/json"
9 "fmt"
10
11 "git.secluded.site/go-lunatask"
12 "git.secluded.site/lune/internal/client"
13 "git.secluded.site/lune/internal/config"
14 "git.secluded.site/lune/internal/ui"
15 "git.secluded.site/lune/internal/validate"
16 "github.com/spf13/cobra"
17)
18
19// ShowCmd displays a note by ID. Exported for potential use by shortcuts.
20var ShowCmd = &cobra.Command{
21 Use: "show ID",
22 Short: "Show note details",
23 Long: `Show detailed information for a note.
24
25Accepts a UUID or lunatask:// deep link.
26
27Note: Due to end-to-end encryption, note name and content
28are not available through the API. Only metadata is shown.`,
29 Args: cobra.ExactArgs(1),
30 RunE: runShow,
31}
32
33func init() {
34 ShowCmd.Flags().Bool("json", false, "Output as JSON")
35}
36
37func runShow(cmd *cobra.Command, args []string) error {
38 id, err := validate.Reference(args[0])
39 if err != nil {
40 return err
41 }
42
43 apiClient, err := client.New()
44 if err != nil {
45 return err
46 }
47
48 note, err := ui.Spin("Fetching note…", func() (*lunatask.Note, error) {
49 return apiClient.GetNote(cmd.Context(), id)
50 })
51 if err != nil {
52 return err
53 }
54
55 if mustGetBoolFlag(cmd, "json") {
56 return outputNoteJSON(cmd, note)
57 }
58
59 return printNoteDetails(cmd, note)
60}
61
62func outputNoteJSON(cmd *cobra.Command, note *lunatask.Note) error {
63 enc := json.NewEncoder(cmd.OutOrStdout())
64 enc.SetIndent("", " ")
65
66 if err := enc.Encode(note); err != nil {
67 return fmt.Errorf("encoding JSON: %w", err)
68 }
69
70 return nil
71}
72
73func printNoteDetails(cmd *cobra.Command, note *lunatask.Note) error {
74 link, _ := lunatask.BuildDeepLink(lunatask.ResourceNote, note.ID)
75
76 fmt.Fprintf(cmd.OutOrStdout(), "%s\n", ui.H1.Render("Note"))
77 fmt.Fprintf(cmd.OutOrStdout(), " ID: %s\n", note.ID)
78 fmt.Fprintf(cmd.OutOrStdout(), " Link: %s\n", link)
79
80 printNotebook(cmd, note)
81
82 if note.DateOn != nil {
83 fmt.Fprintf(cmd.OutOrStdout(), " Date: %s\n", ui.FormatDate(note.DateOn.Time))
84 }
85
86 if note.Pinned {
87 fmt.Fprintf(cmd.OutOrStdout(), " Pinned: yes\n")
88 }
89
90 if len(note.Sources) > 0 {
91 fmt.Fprintf(cmd.OutOrStdout(), " Sources:\n")
92
93 for _, src := range note.Sources {
94 fmt.Fprintf(cmd.OutOrStdout(), " - %s: %s\n", src.Source, src.SourceID)
95 }
96 }
97
98 fmt.Fprintf(cmd.OutOrStdout(), " Created: %s\n", ui.FormatDate(note.CreatedAt))
99 fmt.Fprintf(cmd.OutOrStdout(), " Updated: %s\n", ui.FormatDate(note.UpdatedAt))
100
101 return nil
102}
103
104func printNotebook(cmd *cobra.Command, note *lunatask.Note) {
105 if note.NotebookID == nil {
106 return
107 }
108
109 notebookDisplay := *note.NotebookID
110 cfg, _ := config.Load()
111
112 if cfg != nil {
113 if notebook := cfg.NotebookByID(*note.NotebookID); notebook != nil {
114 notebookDisplay = fmt.Sprintf("%s (%s)", notebook.Name, notebook.Key)
115 }
116 }
117
118 fmt.Fprintf(cmd.OutOrStdout(), " Notebook: %s\n", notebookDisplay)
119}