mlmym/state.go

789 lines
20 KiB
Go
Raw Normal View History

2023-06-30 19:41:35 +00:00
package main
import (
"bytes"
"context"
_ "embed"
"encoding/json"
"errors"
"fmt"
"io"
2023-12-17 03:10:31 +00:00
"math/rand"
2023-06-30 19:41:35 +00:00
"mime/multipart"
"net/http"
"net/url"
2023-07-16 02:07:19 +00:00
"os"
"regexp"
2023-06-30 19:41:35 +00:00
"sort"
"strconv"
"strings"
2023-12-17 01:09:35 +00:00
"github.com/rystaf/go-lemmy"
2023-06-30 19:41:35 +00:00
)
type Comment struct {
2023-12-16 14:43:43 +00:00
P lemmy.CommentView
2023-06-30 19:41:35 +00:00
C []Comment
Selected bool
State *State
Op string
ChildCount int
}
func (c *Comment) Submitter() bool {
return c.P.Comment.CreatorID == c.P.Post.CreatorID
}
2023-12-16 14:43:43 +00:00
func (c *Comment) ParentID() int64 {
2023-07-13 13:45:51 +00:00
path := strings.Split(c.P.Comment.Path, ".")
2023-12-16 14:43:43 +00:00
id, _ := strconv.ParseInt(path[len(path)-2], 10, 64)
2023-07-13 13:45:51 +00:00
return id
}
2023-06-30 19:41:35 +00:00
type Person struct {
2023-12-16 14:43:43 +00:00
lemmy.PersonView
2023-06-30 19:41:35 +00:00
}
type Activity struct {
2023-12-17 01:09:35 +00:00
Timestamp lemmy.LemmyTime
2023-06-30 19:41:35 +00:00
Comment *Comment
Post *Post
2023-12-16 14:43:43 +00:00
Message *lemmy.PrivateMessageView
2023-06-30 19:41:35 +00:00
}
type Post struct {
2023-12-16 14:43:43 +00:00
lemmy.PostView
2024-04-27 19:22:57 +00:00
Rank int
State *State
CrossPosts int
2023-06-30 19:41:35 +00:00
}
type Session struct {
2023-07-24 02:12:01 +00:00
UserName string
UserID int
2023-12-16 14:43:43 +00:00
Communities []lemmy.CommunityView
2023-06-30 19:41:35 +00:00
}
type State struct {
2023-07-26 20:53:06 +00:00
Watch bool
2023-07-23 22:19:53 +00:00
Version string
Client *lemmy.Client
HTTPClient *http.Client
Session *Session
Status int
Error error
Alert string
Host string
CommunityName string
2023-12-16 14:43:43 +00:00
Community *lemmy.GetCommunityResponse
TopCommunities []lemmy.CommunityView
Communities []lemmy.CommunityView
UnreadCount int64
Sort string
CommentSort string
Listing string
Page int
Parts []string
Posts []Post
Comments []Comment
Activities []Activity
CommentCount int
2023-12-16 14:43:43 +00:00
PostID int64
CommentID int64
Context int
UserName string
2023-12-16 14:43:43 +00:00
User *lemmy.GetPersonDetailsResponse
Now int64
XHR bool
Op string
2023-12-16 14:43:43 +00:00
Site *lemmy.GetSiteResponse
2023-12-17 03:10:31 +00:00
Tagline string
Query string
Content string
SearchType string
2023-12-16 14:43:43 +00:00
Captcha *lemmy.CaptchaResponse
2023-12-21 14:30:41 +00:00
Dark *bool
ShowNSFW bool
HideInstanceNames bool
HideThumbnails bool
2024-06-02 23:08:22 +00:00
HideSidebar bool
2024-06-21 21:21:42 +00:00
CollapseMedia bool
LinksInNewWindow bool
SubmitURL string
SubmitTitle string
SubmitBody string
2023-06-30 19:41:35 +00:00
}
2023-09-03 16:48:04 +00:00
func (s State) UserBlocked() bool {
if s.User == nil || s.Site == nil || !s.Site.MyUser.IsValid() {
return false
}
2023-12-16 14:43:43 +00:00
for _, p := range s.Site.MyUser.ValueOrZero().PersonBlocks {
2023-09-03 16:48:04 +00:00
if p.Target.ID == s.User.PersonView.Person.ID {
return true
}
}
return false
}
2023-07-16 02:07:19 +00:00
func (s State) Unknown() string {
2024-05-14 23:46:33 +00:00
fmt.Printf("%v\n", s.Error)
2023-07-16 02:07:19 +00:00
re := regexp.MustCompile(`(.*?)@(.*?)@`)
if strings.Contains(fmt.Sprintf("%v", s.Error), "couldnt_find_community") {
matches := re.FindAllStringSubmatch(s.CommunityName+"@", -1)
if len(matches) < 1 || len(matches[0]) < 3 {
return ""
}
if matches[0][2] != s.Host {
remote := "/" + matches[0][2] + "/c/" + matches[0][1]
if os.Getenv("LEMMY_DOMAIN") != "" {
remote = "https:/" + remote
}
return remote
}
}
if strings.Contains(fmt.Sprintf("%v", s.Error), "couldnt_find_that_username_or_email") {
matches := re.FindAllStringSubmatch(s.UserName+"@", -1)
if len(matches) < 1 || len(matches[0]) < 3 {
return ""
}
if matches[0][2] != s.Host {
remote := "/" + matches[0][2] + "/u/" + matches[0][1]
if os.Getenv("LEMMY_DOMAIN") != "" {
remote = "https:/" + remote
}
return remote
}
}
return ""
}
2023-06-30 19:41:35 +00:00
func (p State) SortBy(v string) string {
var q string
if p.Query != "" || p.SearchType == "Communities" {
2024-04-27 19:22:47 +00:00
q = "q=" + url.QueryEscape(p.Query) + "&communityname=" + p.CommunityName + "&username=" + p.UserName + "&searchtype=" + p.SearchType + "&"
2023-06-30 19:41:35 +00:00
}
2024-05-12 04:14:39 +00:00
if p.Op == "Saved" {
q = "view=Saved&"
}
2023-06-30 19:41:35 +00:00
return "?" + q + "sort=" + v + "&listingType=" + p.Listing
}
func (p State) ListBy(v string) string {
var q string
if p.Query != "" || p.SearchType == "Communities" {
2024-04-27 19:22:47 +00:00
q = "q=" + url.QueryEscape(p.Query) + "&communityname=" + p.CommunityName + "&username=" + p.UserName + "&searchtype=" + p.SearchType + "&"
2023-06-30 19:41:35 +00:00
}
return "?" + q + "sort=" + p.Sort + "&listingType=" + v
}
func (p State) PrevPage() string {
listing := "&listingType=" + p.Listing
2023-06-30 19:41:35 +00:00
var q string
if p.Query != "" || p.SearchType == "Communities" {
q = "q=" + p.Query + "&communityname=" + p.CommunityName + "&username=" + p.UserName + "&searchtype=" + p.SearchType + "&"
}
page := strconv.Itoa(p.Page - 1)
return "?" + q + "sort=" + p.Sort + listing + "&page=" + page
}
func (p State) NextPage() string {
listing := "&listingType=" + p.Listing
2023-06-30 19:41:35 +00:00
var q string
if p.Query != "" || p.SearchType == "Communities" {
q = "q=" + p.Query + "&communityname=" + p.CommunityName + "&username=" + p.UserName + "&searchtype=" + p.SearchType + "&"
}
page := strconv.Itoa(p.Page + 1)
return "?" + q + "sort=" + p.Sort + listing + "&page=" + page
}
func (p State) Rank(v int) int {
return ((p.Page - 1) * 25) + v + 1
}
func (u *Person) FullUserName() string {
if u.Person.Local {
return u.Person.Name
}
l, err := url.Parse(u.Person.ActorID)
if err != nil {
fmt.Println(err)
return u.Person.Name
}
return u.Person.Name + "@" + l.Host
}
func (state *State) ParseQuery(RawQuery string) {
if RawQuery == "" {
return
}
m, _ := url.ParseQuery(RawQuery)
if len(m["listingType"]) > 0 {
state.Listing = m["listingType"][0]
}
if len(m["sort"]) > 0 {
state.Sort = m["sort"][0]
state.CommentSort = m["sort"][0]
2023-06-30 19:41:35 +00:00
}
if len(m["communityname"]) > 0 {
state.CommunityName = m["communityname"][0]
}
if len(m["username"]) > 0 {
state.UserName = m["username"][0]
}
if len(m["q"]) > 0 {
state.Query = m["q"][0]
}
if len(m["xhr"]) > 0 {
state.XHR = true
}
2023-07-05 14:20:07 +00:00
if len(m["view"]) > 0 {
if m["view"][0] == "Saved" {
state.Op = "Saved"
}
}
2023-06-30 19:41:35 +00:00
//if len(m["op"]) > 0 {
// state.Op = m["op"][0]
//}
if len(m["page"]) > 0 {
i, _ := strconv.Atoi(m["page"][0])
state.Page = i
}
}
2023-07-01 14:57:04 +00:00
func (state *State) LemmyError(domain string) error {
var nodeInfo NodeInfo
res, err := state.HTTPClient.Get("https://" + domain + "/nodeinfo/2.0.json")
if err != nil {
return err
}
if res.StatusCode != http.StatusOK {
2024-05-14 23:46:33 +00:00
return fmt.Errorf("status code: %v", res.StatusCode)
2023-07-01 14:57:04 +00:00
}
err = json.NewDecoder(res.Body).Decode(&nodeInfo)
if err != nil {
return err
}
if nodeInfo.Software.Name == "lemmy" {
return nil
}
2024-05-14 23:46:33 +00:00
return errors.New("not a lemmy instance")
2023-07-01 14:57:04 +00:00
}
2023-06-30 19:41:35 +00:00
func (state *State) GetCaptcha() {
2023-12-16 14:43:43 +00:00
resp, err := state.Client.Captcha(context.Background())
2023-06-30 19:41:35 +00:00
if err != nil {
fmt.Printf("Get %v %v", err, resp)
} else {
captcha, _ := resp.Ok.Value()
if resp.Ok.IsValid() {
state.Captcha = &captcha
}
}
}
func (state *State) GetSite() {
2023-12-16 14:43:43 +00:00
resp, err := state.Client.Site(context.Background())
2023-06-30 19:41:35 +00:00
if err != nil {
2023-07-20 23:35:42 +00:00
fmt.Println(err)
2023-06-30 19:41:35 +00:00
state.Status = http.StatusInternalServerError
2023-07-11 14:21:57 +00:00
state.Host = "."
2023-07-20 23:35:42 +00:00
state.Error = errors.New("unable to retrieve site")
2023-06-30 19:41:35 +00:00
return
}
state.Site = resp
2023-12-17 03:10:31 +00:00
if len(state.Site.Taglines) > 0 {
state.Tagline = state.Site.Taglines[rand.Intn(len(state.Site.Taglines))].Content
}
2023-07-24 02:12:01 +00:00
if !state.Site.MyUser.IsValid() {
return
}
2023-12-16 14:43:43 +00:00
for _, c := range state.Site.MyUser.ValueOrZero().Follows {
state.Session.Communities = append(state.Session.Communities, lemmy.CommunityView{
2023-07-24 02:12:01 +00:00
Community: c.Community,
Subscribed: "Subscribed",
})
}
sort.Slice(state.Session.Communities, func(a, b int) bool {
return state.Session.Communities[a].Community.Name < state.Session.Communities[b].Community.Name
})
2023-06-30 19:41:35 +00:00
}
func (state *State) GetSingleComment(commentid int64) {
state.CommentID = commentid
cresp, err := state.Client.Comment(context.Background(), lemmy.GetComment{
ID: commentid,
})
if err != nil {
fmt.Println(err)
state.Status = http.StatusInternalServerError
return
}
2024-05-14 23:46:33 +00:00
state.Comments = []Comment{{
P: cresp.CommentView,
State: state,
Op: state.Op,
}}
}
2023-12-16 14:43:43 +00:00
func (state *State) GetComment(commentid int64) {
if state.Sort != "Hot" && state.Sort != "Top" && state.Sort != "Old" && state.Sort != "New" {
state.Sort = "Hot"
}
2023-06-30 19:41:35 +00:00
state.CommentID = commentid
2023-12-16 14:43:43 +00:00
cresp, err := state.Client.Comments(context.Background(), lemmy.GetComments{
ParentID: lemmy.NewOptional(state.CommentID),
Sort: lemmy.NewOptional(lemmy.CommentSortType(state.CommentSort)),
Type: lemmy.NewOptional(lemmy.ListingType("All")),
Limit: lemmy.NewOptional(int64(50)),
2023-06-30 19:41:35 +00:00
})
if err != nil {
fmt.Println(err)
state.Status = http.StatusInternalServerError
return
}
state.CommentCount = len(cresp.Comments)
for _, c := range cresp.Comments {
if c.Comment.ID == state.CommentID {
state.PostID = c.Comment.PostID
//if state.Session != nil && state.Session.UserID
comment := Comment{
P: c,
Selected: !state.XHR,
State: state,
Op: state.Op,
}
getChildren(&comment, cresp.Comments, c.Post.CreatorID)
state.Comments = append(state.Comments, comment)
}
}
if len(state.Comments) == 0 {
return
}
2023-07-13 13:45:51 +00:00
ctx, err := state.GetContext(state.Context, state.Comments[0])
if err != nil {
fmt.Println(err)
} else {
state.Comments = []Comment{ctx}
}
}
func (state *State) GetContext(depth int, comment Comment) (ctx Comment, err error) {
if depth < 1 || comment.ParentID() == 0 {
return comment, nil
}
2023-12-16 14:43:43 +00:00
cresp, err := state.Client.Comment(context.Background(), lemmy.GetComment{
2023-07-13 13:45:51 +00:00
ID: comment.ParentID(),
})
if err != nil {
return
}
ctx, err = state.GetContext(depth-1, Comment{
P: cresp.CommentView,
State: state,
C: []Comment{comment},
ChildCount: comment.ChildCount + 1,
})
return
2023-06-30 19:41:35 +00:00
}
func (state *State) GetComments() {
if state.Sort != "Hot" && state.Sort != "Top" && state.Sort != "Old" && state.Sort != "New" {
state.Sort = "Hot"
}
2023-12-16 14:43:43 +00:00
cresp, err := state.Client.Comments(context.Background(), lemmy.GetComments{
PostID: lemmy.NewOptional(state.PostID),
Sort: lemmy.NewOptional(lemmy.CommentSortType(state.CommentSort)),
Type: lemmy.NewOptional(lemmy.ListingType("All")),
Limit: lemmy.NewOptional(int64(50)),
Page: lemmy.NewOptional(int64(state.Page)),
2023-06-30 19:41:35 +00:00
})
if err != nil {
state.Status = http.StatusInternalServerError
fmt.Println(err)
2023-06-30 19:41:35 +00:00
return
}
state.CommentCount = len(cresp.Comments)
for _, c := range cresp.Comments {
levels := strings.Split(c.Comment.Path, ".")
if len(levels) != 2 {
continue
}
comment := Comment{P: c, State: state}
2023-12-16 14:43:43 +00:00
var postCreatorID int64
2023-06-30 19:41:35 +00:00
if len(state.Posts) > 0 {
postCreatorID = state.Posts[0].Post.CreatorID
}
getChildren(&comment, cresp.Comments, postCreatorID)
state.Comments = append(state.Comments, comment)
}
}
func (state *State) GetMessages() {
2023-12-16 14:43:43 +00:00
if resp, err := state.Client.PrivateMessages(context.Background(), lemmy.GetPrivateMessages{
Page: lemmy.NewOptional(int64(state.Page)),
2023-06-30 19:41:35 +00:00
}); err != nil {
fmt.Println(err)
state.Status = http.StatusInternalServerError
return
} else {
for _, m := range resp.PrivateMessages {
message := m
state.Activities = append(state.Activities, Activity{
2023-12-16 14:43:43 +00:00
Timestamp: m.PrivateMessage.Published,
2023-06-30 19:41:35 +00:00
Message: &message,
})
}
}
2023-12-16 14:43:43 +00:00
if resp, err := state.Client.PersonMentions(context.Background(), lemmy.GetPersonMentions{
Page: lemmy.NewOptional(int64(state.Page)),
2023-06-30 19:41:35 +00:00
}); err != nil {
fmt.Println(err)
state.Status = http.StatusInternalServerError
return
} else {
for _, m := range resp.Mentions {
var unread string
if !m.PersonMention.Read {
unread = "unread"
}
comment := Comment{
2023-12-16 14:43:43 +00:00
P: lemmy.CommentView{
2023-06-30 19:41:35 +00:00
Comment: m.Comment,
},
Op: unread,
State: state,
}
state.Activities = append(state.Activities, Activity{
2023-12-16 14:43:43 +00:00
Timestamp: m.Comment.Published,
2023-06-30 19:41:35 +00:00
Comment: &comment,
})
}
}
2023-12-16 14:43:43 +00:00
if resp, err := state.Client.Replies(context.Background(), lemmy.GetReplies{
Page: lemmy.NewOptional(int64(state.Page)),
2023-06-30 19:41:35 +00:00
}); err != nil {
fmt.Println(err)
state.Status = http.StatusInternalServerError
return
} else {
for _, m := range resp.Replies {
var unread string
if !m.CommentReply.Read {
unread = "unread"
}
comment := Comment{
2023-12-16 14:43:43 +00:00
P: lemmy.CommentView{
2023-06-30 19:41:35 +00:00
Comment: m.Comment,
Post: m.Post,
Creator: m.Creator,
Community: m.Community,
Counts: m.Counts,
MyVote: m.MyVote,
2023-06-30 19:41:35 +00:00
},
Op: unread,
State: state,
}
state.Activities = append(state.Activities, Activity{
2023-12-16 14:43:43 +00:00
Timestamp: m.Comment.Published,
2023-06-30 19:41:35 +00:00
Comment: &comment,
})
}
}
2024-05-10 15:59:39 +00:00
sort.Slice(state.Activities, func(i, j int) bool {
return state.Activities[i].Timestamp.After(state.Activities[j].Timestamp.Time)
})
2023-06-30 19:41:35 +00:00
}
func (state *State) GetUser(username string) {
state.UserName = username
limit := 12
if state.Op == "send_message" {
limit = 1
}
2023-12-16 14:43:43 +00:00
resp, err := state.Client.PersonDetails(context.Background(), lemmy.GetPersonDetails{
Username: lemmy.NewOptional(state.UserName),
Page: lemmy.NewOptional(int64(state.Page)),
Limit: lemmy.NewOptional(int64(limit)),
SavedOnly: lemmy.NewOptional(state.Op == "Saved"),
2024-05-10 00:55:37 +00:00
Sort: lemmy.NewOptional(lemmy.SortType(state.Sort)),
2023-06-30 19:41:35 +00:00
})
if err != nil {
fmt.Println(err)
2023-07-16 02:07:19 +00:00
state.Error = err
2023-06-30 19:41:35 +00:00
state.Status = http.StatusInternalServerError
return
}
state.User = resp
if state.Query != "" {
return
}
2024-05-10 15:07:59 +00:00
for _, c := range resp.Comments {
comment := Comment{P: c, State: state}
state.Activities = append(state.Activities, Activity{
Timestamp: c.Comment.Published,
Comment: &comment,
})
}
2023-06-30 19:41:35 +00:00
for i, p := range resp.Posts {
post := Post{
PostView: resp.Posts[i],
Rank: -1,
State: state,
}
state.Activities = append(state.Activities, Activity{
2023-12-16 14:43:43 +00:00
Timestamp: p.Post.Published,
2023-06-30 19:41:35 +00:00
Post: &post,
})
}
sort.Slice(state.Activities, func(i, j int) bool {
2024-05-10 15:07:59 +00:00
switch state.Sort {
case "New":
return state.Activities[i].Timestamp.After(state.Activities[j].Timestamp.Time)
case "Old":
return state.Activities[i].Timestamp.Before(state.Activities[j].Timestamp.Time)
}
// TODO Top and Controversial
return false
2023-06-30 19:41:35 +00:00
})
}
func (state *State) GetUnreadCount() {
2023-12-16 14:43:43 +00:00
resp, err := state.Client.UnreadCount(context.Background())
2023-06-30 19:41:35 +00:00
if err != nil {
fmt.Println(err)
return
}
state.UnreadCount = resp.PrivateMessages + resp.Mentions + resp.Replies
}
func (state *State) GetCommunities() {
2023-12-16 14:43:43 +00:00
resp, err := state.Client.Communities(context.Background(), lemmy.ListCommunities{
Sort: lemmy.NewOptional(lemmy.SortType("TopAll")),
Limit: lemmy.NewOptional(int64(20)),
2023-06-30 19:41:35 +00:00
})
if err != nil {
return
}
state.TopCommunities = resp.Communities
}
func (state *State) MarkAllAsRead() {
2023-12-16 14:43:43 +00:00
_, err := state.Client.MarkAllAsRead(context.Background())
2023-06-30 19:41:35 +00:00
if err != nil {
fmt.Println(err)
return
}
}
func (state *State) GetPosts() {
2023-12-16 14:43:43 +00:00
posts := lemmy.GetPosts{
Sort: lemmy.NewOptional(lemmy.SortType(state.Sort)),
Type: lemmy.NewOptional(lemmy.ListingType(state.Listing)),
Limit: lemmy.NewOptional(int64(25)),
Page: lemmy.NewOptional(int64(state.Page)),
}
if state.CommunityName != "" {
2023-12-16 14:43:43 +00:00
posts.CommunityName = lemmy.NewOptional(state.CommunityName)
}
resp, err := state.Client.Posts(context.Background(), posts)
2023-06-30 19:41:35 +00:00
if err != nil {
fmt.Println(err)
state.Status = http.StatusInternalServerError
return
} else {
for i, p := range resp.Posts {
state.Posts = append(state.Posts, Post{
PostView: p,
Rank: (state.Page-1)*25 + i + 1,
State: state,
})
}
}
}
func (state *State) Search(searchtype string) {
if state.Query == "" && searchtype == "Communities" {
if state.Listing == "Subscribed" {
if state.Page > 1 {
return
}
2023-07-24 02:12:01 +00:00
if state.Site == nil {
state.GetSite()
}
2023-07-24 02:12:01 +00:00
state.Communities = state.Session.Communities
return
}
2023-12-16 14:43:43 +00:00
resp, err := state.Client.Communities(context.Background(), lemmy.ListCommunities{
Type: lemmy.NewOptional(lemmy.ListingType(state.Listing)),
Sort: lemmy.NewOptional(lemmy.SortType(state.Sort)),
Limit: lemmy.NewOptional(int64(25)),
Page: lemmy.NewOptional(int64(state.Page)),
2023-06-30 19:41:35 +00:00
})
if err != nil {
fmt.Println(err)
return
}
state.Communities = resp.Communities
return
}
2023-12-16 14:43:43 +00:00
search := lemmy.Search{
2023-06-30 19:41:35 +00:00
Q: state.Query,
2023-12-16 14:43:43 +00:00
Sort: lemmy.NewOptional(lemmy.SortType(state.Sort)),
ListingType: lemmy.NewOptional(lemmy.ListingType(state.Listing)),
Type: lemmy.NewOptional(lemmy.SearchType(searchtype)),
Limit: lemmy.NewOptional(int64(25)),
Page: lemmy.NewOptional(int64(state.Page)),
2023-06-30 19:41:35 +00:00
}
if state.CommunityName != "" {
2023-12-16 14:43:43 +00:00
search.CommunityName = lemmy.NewOptional(state.CommunityName)
2023-06-30 19:41:35 +00:00
}
if state.User != nil {
2023-12-16 14:43:43 +00:00
search.CreatorID = lemmy.NewOptional(state.User.PersonView.Person.ID)
2023-06-30 19:41:35 +00:00
}
resp, err := state.Client.Search(context.Background(), search)
if err != nil {
fmt.Println(err)
state.Status = http.StatusInternalServerError
return
} else {
for i, p := range resp.Posts {
2024-04-27 19:22:47 +00:00
post := Post{
2023-06-30 19:41:35 +00:00
PostView: p,
Rank: (state.Page-1)*25 + i + 1,
State: state,
2024-04-27 19:22:47 +00:00
}
state.Activities = append(state.Activities, Activity{
Timestamp: p.Post.Published,
Post: &post,
2023-06-30 19:41:35 +00:00
})
}
for _, c := range resp.Comments {
2023-07-13 13:45:51 +00:00
comment := Comment{
2023-06-30 19:41:35 +00:00
P: c,
State: state,
2023-07-13 13:45:51 +00:00
}
state.Activities = append(state.Activities, Activity{
2023-12-16 14:43:43 +00:00
Timestamp: c.Comment.Published,
2023-07-13 13:45:51 +00:00
Comment: &comment,
2023-06-30 19:41:35 +00:00
})
}
2024-04-27 19:22:47 +00:00
sort.Slice(state.Activities, func(i, j int) bool {
return state.Activities[i].Timestamp.After(state.Activities[j].Timestamp.Time)
})
2023-06-30 19:41:35 +00:00
state.Communities = resp.Communities
}
}
2023-12-16 14:43:43 +00:00
func (state *State) GetPost(postid int64) {
2023-06-30 19:41:35 +00:00
if postid == 0 {
return
}
state.PostID = postid
// get post
2023-12-16 14:43:43 +00:00
resp, err := state.Client.Post(context.Background(), lemmy.GetPost{
ID: lemmy.NewOptional(state.PostID),
2023-06-30 19:41:35 +00:00
})
if err != nil {
state.Status = http.StatusInternalServerError
2023-07-16 13:00:49 +00:00
state.Error = err
2023-06-30 19:41:35 +00:00
return
}
2024-04-27 19:22:57 +00:00
post := Post{
PostView: resp.PostView,
State: state,
CrossPosts: len(resp.CrossPosts),
}
if state.Listing == "Local" && post.Post.Local {
for _, p := range resp.CrossPosts {
if !p.Post.Local {
post.CrossPosts--
}
}
}
state.Posts = []Post{post}
2023-07-16 13:00:49 +00:00
if state.CommentID > 0 && len(state.Posts) > 0 {
state.Posts[0].Rank = -1
}
state.CommunityName = resp.PostView.Community.Name
2023-12-16 14:43:43 +00:00
cresp := lemmy.GetCommunityResponse{
2023-07-16 13:00:49 +00:00
CommunityView: resp.CommunityView,
Moderators: resp.Moderators,
}
state.Community = &cresp
2023-06-30 19:41:35 +00:00
}
func (state *State) GetCommunity(communityName string) {
if communityName != "" {
state.CommunityName = communityName
}
if state.CommunityName == "" {
return
}
2023-12-16 14:43:43 +00:00
resp, err := state.Client.Community(context.Background(), lemmy.GetCommunity{
Name: lemmy.NewOptional(state.CommunityName),
2023-06-30 19:41:35 +00:00
})
if err != nil {
state.Error = err
} else {
state.Community = resp
}
}
func (state *State) UploadImage(file multipart.File, header *multipart.FileHeader) (*PictrsResponse, error) {
defer file.Close()
body := new(bytes.Buffer)
writer := multipart.NewWriter(body)
part, err := writer.CreateFormFile("images[]", header.Filename)
if err != nil {
return nil, err
}
io.Copy(part, file)
writer.Close()
2024-02-02 03:54:22 +00:00
host := state.Host
if host == "." {
host = os.Getenv("LEMMY_DOMAIN")
}
req, err := http.NewRequest("POST", "https://"+host+"/pictrs/image", body)
2023-06-30 19:41:35 +00:00
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", writer.FormDataContentType())
req.Header.Set("Cookie", "jwt="+state.Client.Token)
res, err := state.HTTPClient.Do(req)
if err != nil {
return nil, err
}
defer res.Body.Close()
var pres PictrsResponse
if err := json.NewDecoder(res.Body).Decode(&pres); err != nil {
return nil, err
}
if pres.Message != "ok" {
return &pres, errors.New(pres.Message)
}
return &pres, nil
}
2023-12-16 14:43:43 +00:00
func getChildren(parent *Comment, pool []lemmy.CommentView, postCreatorID int64) {
2023-06-30 19:41:35 +00:00
var children []Comment
2023-12-16 14:43:43 +00:00
var total int64
2023-06-30 19:41:35 +00:00
for _, c := range pool {
levels := strings.Split(c.Comment.Path, ".")
for i, l := range levels {
2023-12-16 14:43:43 +00:00
id, _ := strconv.ParseInt(l, 10, 64)
2023-06-30 19:41:35 +00:00
if id == parent.P.Comment.ID {
if i == (len(levels) - 2) {
children = append(children, Comment{
P: c,
C: children,
State: parent.State,
})
total += c.Counts.ChildCount
2023-06-30 19:41:35 +00:00
}
}
}
}
2024-05-14 23:46:33 +00:00
for i := range children {
2023-06-30 19:41:35 +00:00
getChildren(&children[i], pool, postCreatorID)
parent.ChildCount += 1
2023-06-30 19:41:35 +00:00
}
parent.C = children
parent.P.Counts.ChildCount -= total
2023-06-30 19:41:35 +00:00
}