From 9c50ddffdc9e36fbc2316bc24aea7787d73a3c37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=83=9E=E3=83=AA=E3=82=A6=E3=82=B9?= Date: Fri, 30 Dec 2022 23:57:03 -0500 Subject: [PATCH] Implemented Forum --- models/forum/forum.go | 6 +++ models/post/post.go | 11 ++++- system/discourse/categories.go | 88 ++++++++++++++++++++++++++++++++++ system/discourse/client.go | 6 ++- system/discourse/discourse.go | 26 ++++++++++ system/lemmy/lemmy.go | 6 +++ ui/views/posts/posts.go | 25 ++-------- 7 files changed, 143 insertions(+), 25 deletions(-) create mode 100644 models/forum/forum.go create mode 100644 system/discourse/categories.go diff --git a/models/forum/forum.go b/models/forum/forum.go new file mode 100644 index 0000000..165d132 --- /dev/null +++ b/models/forum/forum.go @@ -0,0 +1,6 @@ +package forum + +type Forum struct { + ID string + Name string +} diff --git a/models/post/post.go b/models/post/post.go index 198a285..09a3554 100644 --- a/models/post/post.go +++ b/models/post/post.go @@ -1,9 +1,11 @@ package post import ( + "fmt" "time" "github.com/mrusme/gobbs/models/author" + "github.com/mrusme/gobbs/models/forum" "github.com/mrusme/gobbs/models/reply" ) @@ -22,6 +24,8 @@ type Post struct { Author author.Author + Forum forum.Forum + Replies []reply.Reply SysIDX int @@ -36,5 +40,10 @@ func (post Post) Title() string { } func (post Post) Description() string { - return post.ID + return fmt.Sprintf( + "%s in %s on %s", + post.Author.Name, + post.Forum.Name, + post.CreatedAt.Format("Jan 2 2006"), + ) } diff --git a/system/discourse/categories.go b/system/discourse/categories.go new file mode 100644 index 0000000..21060a6 --- /dev/null +++ b/system/discourse/categories.go @@ -0,0 +1,88 @@ +package discourse + +import ( + "context" + "net/http" +) + +const CategoriesBaseURL = "/categories" + +type LatestCategoriesResponse struct { + CategoryList struct { + CanCreateCategory bool `json:"can_create_category"` + CanCreateTopic bool `json:"can_create_topic"` + + Categories []CategoryModel `json:"categories"` + } `json:"category_list"` +} + +type CategoryModel struct { + ID int `json:"id"` + Name string `json:"name"` + Color string `json:"color"` + TextColor string `json:"text_color"` + Slug string `json:"slug"` + TopicCount int `json:"topic_count"` + PostCount int `json:"post_count"` + Position int `json:"position"` + Description string `json:"description"` + DescriptionText string `json:"description_text"` + DescriptionExcerpt string `json:"description_excerpt"` + TopicUrl string `json:"topic_url"` + ReadRestricted bool `json:"read_restricted"` + Permission int `json:"permission"` + NotificationLevel int `json:"notification_level"` + CanEdit bool `json:"can_edit"` + TopicTemplate string `json:"topic_template"` + HasChildren bool `json:"has_children"` + SortOrder string `json:"sort_order"` + SortAscending string `json:"sort_ascending"` + ShowSubcategoryList bool `json:"show_subcategory_list"` + NumFeaturedTopics int `json:"num_featured_topics"` + DefaultView string `json:"default_view"` + SubcategoryListStyle string `json:"subcategory_list_style"` + DefaultTopPeriod string `json:"default_top_period"` + DefaultListFilter string `json:"default_list_filter"` + MinimumRequiredTags int `json:"minimum_required_tags"` + NavigateToFirstPostAfterRead bool `json:"navigate_to_first_post_after_read"` + TopicsDay int `json:"topics_day"` + TopicsWeek int `json:"topics_week"` + TopicsMonth int `json:"topics_month"` + TopicsYear int `json:"topics_year"` + TopicsAllTime int `json:"topics_all_time"` + IsUncategorized bool `json:"is_uncategorized"` + SubcategoryIDs []string `json:"subcategory_ids"` + SubcategoryList []CategoryModel `json:"subcategory_list"` + UploadedLogo string `json:"uploaded_logo"` + UploadedLogoDark string `json:"uploaded_logo_dark"` + UploadedBackground string `json:"uploaded_background"` +} + +type CategoriesService interface { + List( + ctx context.Context, + ) (*LatestCategoriesResponse, error) +} + +type CategoryServiceHandler struct { + client *Client +} + +// List +func (a *CategoryServiceHandler) List( + ctx context.Context, +) (*LatestCategoriesResponse, error) { + uri := CategoriesBaseURL + ".json" + + req, err := a.client.NewRequest(ctx, http.MethodGet, uri, nil) + if err != nil { + return nil, err + } + + response := new(LatestCategoriesResponse) + if err = a.client.Do(ctx, req, response); err != nil { + return nil, err + } + + return response, nil +} diff --git a/system/discourse/client.go b/system/discourse/client.go index b99fd98..135c95d 100644 --- a/system/discourse/client.go +++ b/system/discourse/client.go @@ -68,8 +68,9 @@ type Client struct { credentials map[string]string logger Logger - Posts PostsService - Topics TopicsService + Posts PostsService + Topics TopicsService + Categories CategoriesService } func NewDefaultClientConfig( @@ -99,6 +100,7 @@ func NewClient(cc *ClientConfig) *Client { c.Posts = &PostServiceHandler{client: c} c.Topics = &TopicServiceHandler{client: c} + c.Categories = &CategoryServiceHandler{client: c} return c } diff --git a/system/discourse/discourse.go b/system/discourse/discourse.go index 632774e..cfce8bb 100644 --- a/system/discourse/discourse.go +++ b/system/discourse/discourse.go @@ -9,6 +9,7 @@ import ( md "github.com/JohannesKaufmann/html-to-markdown" "github.com/araddon/dateparse" "github.com/mrusme/gobbs/models/author" + "github.com/mrusme/gobbs/models/forum" "github.com/mrusme/gobbs/models/post" "github.com/mrusme/gobbs/models/reply" "github.com/mrusme/gobbs/system/adapter" @@ -74,6 +75,11 @@ func (sys *System) Load() error { } func (sys *System) ListPosts(sysIdx int) ([]post.Post, error) { + cats, err := sys.client.Categories.List(context.Background()) + if err != nil { + return []post.Post{}, err + } + items, err := sys.client.Topics.ListLatest(context.Background()) if err != nil { return []post.Post{}, err @@ -98,6 +104,21 @@ func (sys *System) ListPosts(sysIdx int) ([]post.Post, error) { lastCommentedAt = time.Now() // TODO: Errrrr } + var forumName string = "" + for _, cat := range cats.CategoryList.Categories { + if cat.ID == i.CategoryID { + forumName = cat.Name + break + } + + for _, subcat := range cat.SubcategoryList { + if subcat.ID == i.CategoryID { + forumName = subcat.Name + break + } + } + } + models = append(models, post.Post{ ID: strconv.Itoa(i.ID), @@ -116,6 +137,11 @@ func (sys *System) ListPosts(sysIdx int) ([]post.Post, error) { Name: userName, }, + Forum: forum.Forum{ + ID: strconv.Itoa(i.CategoryID), + Name: forumName, + }, + SysIDX: sysIdx, }) } diff --git a/system/lemmy/lemmy.go b/system/lemmy/lemmy.go index 91c95f7..7c9d342 100644 --- a/system/lemmy/lemmy.go +++ b/system/lemmy/lemmy.go @@ -7,6 +7,7 @@ import ( "github.com/araddon/dateparse" "github.com/mrusme/gobbs/models/author" + "github.com/mrusme/gobbs/models/forum" "github.com/mrusme/gobbs/models/post" "github.com/mrusme/gobbs/models/reply" "github.com/mrusme/gobbs/system/adapter" @@ -126,6 +127,11 @@ func (sys *System) ListPosts(sysIdx int) ([]post.Post, error) { Name: i.Creator.Name, }, + Forum: forum.Forum{ + ID: strconv.Itoa(i.Post.CommunityID), + Name: i.Community.Name, + }, + SysIDX: sysIdx, }) } diff --git a/ui/views/posts/posts.go b/ui/views/posts/posts.go index 0a3fbc0..c38c752 100644 --- a/ui/views/posts/posts.go +++ b/ui/views/posts/posts.go @@ -72,10 +72,9 @@ var ( ) type KeyMap struct { - Refresh key.Binding - Select key.Binding - SwitchFocus key.Binding - Close key.Binding + Refresh key.Binding + Select key.Binding + Close key.Binding } var DefaultKeyMap = KeyMap{ @@ -87,10 +86,6 @@ var DefaultKeyMap = KeyMap{ key.WithKeys("enter"), key.WithHelp("enter", "select"), ), - SwitchFocus: key.NewBinding( - key.WithKeys("tab"), - key.WithHelp("tab", "switch focus"), - ), Close: key.NewBinding( key.WithKeys("esc"), key.WithHelp("esc", "close"), @@ -107,9 +102,6 @@ type Model struct { glam *glamour.TermRenderer - focused int - focusables [2]tea.Model - viewportOpen bool } @@ -120,13 +112,9 @@ func (m Model) Init() tea.Cmd { func NewModel(c *ctx.Ctx) Model { m := Model{ keymap: DefaultKeyMap, - focused: 0, viewportOpen: false, } - // m.focusables = append(m.focusables, m.list) - // m.focusables = append(m.focusables, m.viewport) - m.list = list.New(m.items, list.NewDefaultDelegate(), 0, 0) m.list.Title = "Posts" m.ctx = c @@ -145,13 +133,6 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { m.ctx.Loading = true cmds = append(cmds, m.refresh()) - case key.Matches(msg, m.keymap.SwitchFocus): - m.focused++ - if m.focused >= len(m.focusables) { - m.focused = 0 - } - // return m, nil - case key.Matches(msg, m.keymap.Select): i, ok := m.list.SelectedItem().(post.Post) if ok {