diff --git a/changelog.md b/changelog.md index de749269dd..9520275964 100644 --- a/changelog.md +++ b/changelog.md @@ -43,6 +43,7 @@ - [#4322](https://github.com/ignite/cli/pull/4322) Create a message for authenticate buf for generate ts-client - [#4319](https://github.com/ignite/cli/pull/4319) Remove fee abstraction module from open api code generation - [#4317](https://github.com/ignite/cli/pull/4317) Remove xchisel dependency +- [#4345](https://github.com/ignite/cli/pull/4345) Added survey link ### Fixes diff --git a/ignite/cmd/model/chain_serve.go b/ignite/cmd/model/chain_serve.go index 5e4429b1d1..0a24d0d9e0 100644 --- a/ignite/cmd/model/chain_serve.go +++ b/ignite/cmd/model/chain_serve.go @@ -7,6 +7,7 @@ import ( tea "github.com/charmbracelet/bubbletea" + "github.com/ignite/cli/v29/ignite/pkg/announcements" "github.com/ignite/cli/v29/ignite/pkg/cliui/colors" "github.com/ignite/cli/v29/ignite/pkg/cliui/icons" cliuimodel "github.com/ignite/cli/v29/ignite/pkg/cliui/model" @@ -260,6 +261,7 @@ func (m ChainServe) renderQuitView() string { } fmt.Fprintf(&view, "%s %s\n", icons.Info, colors.Info("Stopped")) + view.WriteString(announcements.GetAnnouncements()) return view.String() } diff --git a/ignite/pkg/announcements/announcement.go b/ignite/pkg/announcements/announcement.go new file mode 100644 index 0000000000..3de7b67eee --- /dev/null +++ b/ignite/pkg/announcements/announcement.go @@ -0,0 +1,50 @@ +package announcements + +import ( + "encoding/json" + "fmt" + "net/http" + "strings" + + "github.com/ignite/cli/v29/ignite/pkg/cliui/icons" +) + +var ( + SurveyLink = "https://bit.ly/3WZS2uS" + AnnouncementAPI = "http://api.ignite.com/announcements" +) + +type announcement struct { + Announcements []string `json:"announcements"` +} + +func GetAnnouncements() string { + resp, err := http.Get(AnnouncementAPI) + if err != nil || resp.StatusCode != 200 { + return fallbackData() + } + defer resp.Body.Close() + + var data announcement + if err := json.NewDecoder(resp.Body).Decode(&data); err != nil { + return fallbackData() + } + + // is this needed? or if its empty we don't want to show anything? + if len(data.Announcements) == 0 { + return fallbackData() + } + + var out strings.Builder + fmt.Fprintf(&out, "\n%s %s\n", icons.Announcement, "Announcements") + + for _, announcement := range data.Announcements { + fmt.Fprintf(&out, "%s %s\n", icons.Bullet, announcement) + } + + return out.String() +} + +func fallbackData() string { + return fmt.Sprintf("\n%s Survey: %s\n", icons.Survey, SurveyLink) +} diff --git a/ignite/pkg/announcements/announcement_test.go b/ignite/pkg/announcements/announcement_test.go new file mode 100644 index 0000000000..fa06e3518f --- /dev/null +++ b/ignite/pkg/announcements/announcement_test.go @@ -0,0 +1,65 @@ +package announcements_test + +import ( + "fmt" + "net/http" + "net/http/httptest" + "testing" + + "github.com/ignite/cli/v29/ignite/pkg/announcements" +) + +func TestGetAnnouncements(t *testing.T) { + fallbackData := fmt.Sprintf("\nšŸ’¬ Survey: %s\n", announcements.SurveyLink) + + tests := []struct { + name string + mockResponse string + statusCode int + expected string + }{ + { + name: "successful retrieval", + mockResponse: `{"announcements":["Announcement 1","Announcement 2"]}`, + statusCode: http.StatusOK, + expected: "\nšŸ—£ļø Announcements\nā‹† Announcement 1\nā‹† Announcement 2\n", + }, + { + name: "empty announcements", + mockResponse: `{"announcements":[]}`, + statusCode: http.StatusOK, + expected: fallbackData, + }, + { + name: "invalid JSON response", + mockResponse: `invalid json`, + statusCode: http.StatusOK, + expected: fallbackData, + }, + { + name: "non-200 HTTP response", + mockResponse: ``, + statusCode: http.StatusInternalServerError, + expected: fallbackData, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + w.WriteHeader(tt.statusCode) + w.Write([]byte(tt.mockResponse)) + })) + defer server.Close() + + originalAPI := announcements.AnnouncementAPI + announcements.AnnouncementAPI = server.URL + defer func() { announcements.AnnouncementAPI = originalAPI }() + + result := announcements.GetAnnouncements() + if result != tt.expected { + t.Errorf("expected %q, got %q", tt.expected, result) + } + }) + } +} diff --git a/ignite/pkg/cliui/icons/icon.go b/ignite/pkg/cliui/icons/icon.go index 31ad42fc68..85a05dd93b 100644 --- a/ignite/pkg/cliui/icons/icon.go +++ b/ignite/pkg/cliui/icons/icon.go @@ -5,10 +5,12 @@ import ( ) var ( - Earth = "šŸŒ" - CD = "šŸ’æ" - User = "šŸ‘¤" - Tada = "šŸŽ‰" + Earth = "šŸŒ" + CD = "šŸ’æ" + User = "šŸ‘¤" + Tada = "šŸŽ‰" + Survey = "šŸ’¬" + Announcement = "šŸ—£ļø" // OK is an OK mark. OK = colors.SprintFunc(colors.Green)("āœ”")