Convert the feed to use the new thread and post functions.
This commit is contained in:
		
							parent
							
								
									9c7acd7dbb
								
							
						
					
					
						commit
						89e58c9a24
					
				| 
						 | 
					@ -4,7 +4,6 @@ import (
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"math"
 | 
						"math"
 | 
				
			||||||
	"net/http"
 | 
						"net/http"
 | 
				
			||||||
	"strconv"
 | 
					 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -30,40 +29,19 @@ type FeedData struct {
 | 
				
			||||||
func Feed(c *RequestContext) ResponseData {
 | 
					func Feed(c *RequestContext) ResponseData {
 | 
				
			||||||
	const postsPerPage = 30
 | 
						const postsPerPage = 30
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	c.Perf.StartBlock("SQL", "Count posts")
 | 
						numPosts, err := CountPosts(c.Context(), c.Conn, c.CurrentUser, PostsQuery{
 | 
				
			||||||
	numPosts, err := db.QueryInt(c.Context(), c.Conn,
 | 
							ThreadTypes: []models.ThreadType{models.ThreadTypeForumPost, models.ThreadTypeProjectBlogPost},
 | 
				
			||||||
		`
 | 
						})
 | 
				
			||||||
		SELECT COUNT(*)
 | 
					 | 
				
			||||||
		FROM
 | 
					 | 
				
			||||||
			handmade_post AS post
 | 
					 | 
				
			||||||
		WHERE
 | 
					 | 
				
			||||||
			post.thread_type = ANY ($1)
 | 
					 | 
				
			||||||
			AND deleted = FALSE
 | 
					 | 
				
			||||||
			AND post.thread_id IS NOT NULL
 | 
					 | 
				
			||||||
		`,
 | 
					 | 
				
			||||||
		[]models.ThreadType{models.ThreadTypeForumPost, models.ThreadTypeProjectBlogPost},
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
	c.Perf.EndBlock()
 | 
					 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to get count of feed posts"))
 | 
							return c.ErrorResponse(http.StatusInternalServerError, err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	numPages := int(math.Ceil(float64(numPosts) / postsPerPage))
 | 
						numPages := int(math.Ceil(float64(numPosts) / postsPerPage))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	page := 1
 | 
						page, numPages, ok := getPageInfo(c.PathParams["page"], numPosts, postsPerPage)
 | 
				
			||||||
	pageString, hasPage := c.PathParams["page"]
 | 
						if !ok {
 | 
				
			||||||
	if hasPage && pageString != "" {
 | 
					 | 
				
			||||||
		if pageParsed, err := strconv.Atoi(pageString); err == nil {
 | 
					 | 
				
			||||||
			page = pageParsed
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
		return c.Redirect(hmnurl.BuildFeed(), http.StatusSeeOther)
 | 
							return c.Redirect(hmnurl.BuildFeed(), http.StatusSeeOther)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if page < 1 || numPages < page {
 | 
					 | 
				
			||||||
		return c.Redirect(hmnurl.BuildFeedWithPage(utils.IntClamp(1, page, numPages)), http.StatusSeeOther)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	howManyPostsToSkip := (page - 1) * postsPerPage
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pagination := templates.Pagination{
 | 
						pagination := templates.Pagination{
 | 
				
			||||||
		Current: page,
 | 
							Current: page,
 | 
				
			||||||
| 
						 | 
					@ -75,17 +53,7 @@ func Feed(c *RequestContext) ResponseData {
 | 
				
			||||||
		PreviousUrl: hmnurl.BuildFeedWithPage(utils.IntClamp(1, page-1, numPages)),
 | 
							PreviousUrl: hmnurl.BuildFeedWithPage(utils.IntClamp(1, page-1, numPages)),
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var currentUserId *int
 | 
						posts, err := fetchAllPosts(c, (page-1)*postsPerPage, postsPerPage)
 | 
				
			||||||
	if c.CurrentUser != nil {
 | 
					 | 
				
			||||||
		currentUserId = &c.CurrentUser.ID
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	c.Perf.StartBlock("SQL", "Fetch subforum tree")
 | 
					 | 
				
			||||||
	subforumTree := models.GetFullSubforumTree(c.Context(), c.Conn)
 | 
					 | 
				
			||||||
	lineageBuilder := models.MakeSubforumLineageBuilder(subforumTree)
 | 
					 | 
				
			||||||
	c.Perf.EndBlock()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	posts, err := fetchAllPosts(c, lineageBuilder, currentUserId, howManyPostsToSkip, postsPerPage)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch feed posts"))
 | 
							return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch feed posts"))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -158,12 +126,7 @@ func AtomFeed(c *RequestContext) ResponseData {
 | 
				
			||||||
		feedData.AtomFeedUrl = hmnurl.BuildAtomFeed()
 | 
							feedData.AtomFeedUrl = hmnurl.BuildAtomFeed()
 | 
				
			||||||
		feedData.FeedUrl = hmnurl.BuildFeed()
 | 
							feedData.FeedUrl = hmnurl.BuildFeed()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		c.Perf.StartBlock("SQL", "Fetch subforum tree")
 | 
							posts, err := fetchAllPosts(c, 0, itemsPerFeed)
 | 
				
			||||||
		subforumTree := models.GetFullSubforumTree(c.Context(), c.Conn)
 | 
					 | 
				
			||||||
		lineageBuilder := models.MakeSubforumLineageBuilder(subforumTree)
 | 
					 | 
				
			||||||
		c.Perf.EndBlock()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		posts, err := fetchAllPosts(c, lineageBuilder, nil, 0, itemsPerFeed)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch feed posts"))
 | 
								return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch feed posts"))
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -306,78 +269,37 @@ func AtomFeed(c *RequestContext) ResponseData {
 | 
				
			||||||
	return res
 | 
						return res
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func fetchAllPosts(c *RequestContext, lineageBuilder *models.SubforumLineageBuilder, currentUserID *int, offset int, limit int) ([]templates.PostListItem, error) {
 | 
					func fetchAllPosts(c *RequestContext, offset int, limit int) ([]templates.PostListItem, error) {
 | 
				
			||||||
	c.Perf.StartBlock("SQL", "Fetch posts")
 | 
						postsAndStuff, err := FetchPosts(c.Context(), c.Conn, c.CurrentUser, PostsQuery{
 | 
				
			||||||
	type feedPostQuery struct {
 | 
							ThreadTypes:    []models.ThreadType{models.ThreadTypeForumPost, models.ThreadTypeProjectBlogPost},
 | 
				
			||||||
		Post                 models.Post        `db:"post"`
 | 
							Limit:          limit,
 | 
				
			||||||
		PostVersion          models.PostVersion `db:"version"`
 | 
							Offset:         offset,
 | 
				
			||||||
		Thread               models.Thread      `db:"thread"`
 | 
							SortDescending: true,
 | 
				
			||||||
		Proj                 models.Project     `db:"proj"`
 | 
						})
 | 
				
			||||||
		User                 models.User        `db:"auth_user"`
 | 
					 | 
				
			||||||
		ThreadLastReadTime   *time.Time         `db:"tlri.lastread"`
 | 
					 | 
				
			||||||
		SubforumLastReadTime *time.Time         `db:"slri.lastread"`
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	posts, err := db.Query(c.Context(), c.Conn, feedPostQuery{},
 | 
					 | 
				
			||||||
		`
 | 
					 | 
				
			||||||
		SELECT $columns
 | 
					 | 
				
			||||||
		FROM
 | 
					 | 
				
			||||||
			handmade_post AS post
 | 
					 | 
				
			||||||
			JOIN handmade_postversion AS version ON version.id = post.current_id
 | 
					 | 
				
			||||||
			JOIN handmade_thread AS thread ON thread.id = post.thread_id
 | 
					 | 
				
			||||||
			JOIN handmade_project AS proj ON proj.id = post.project_id
 | 
					 | 
				
			||||||
			LEFT JOIN handmade_threadlastreadinfo AS tlri ON (
 | 
					 | 
				
			||||||
				tlri.thread_id = post.thread_id
 | 
					 | 
				
			||||||
				AND tlri.user_id = $1
 | 
					 | 
				
			||||||
			)
 | 
					 | 
				
			||||||
			LEFT JOIN handmade_subforumlastreadinfo AS slri ON (
 | 
					 | 
				
			||||||
				slri.subforum_id = thread.subforum_id
 | 
					 | 
				
			||||||
				AND slri.user_id = $1
 | 
					 | 
				
			||||||
			)
 | 
					 | 
				
			||||||
			LEFT JOIN auth_user ON post.author_id = auth_user.id
 | 
					 | 
				
			||||||
		WHERE
 | 
					 | 
				
			||||||
			thread.type = ANY ($2)
 | 
					 | 
				
			||||||
			AND post.deleted = FALSE
 | 
					 | 
				
			||||||
			AND post.thread_id IS NOT NULL
 | 
					 | 
				
			||||||
		ORDER BY postdate DESC
 | 
					 | 
				
			||||||
		LIMIT $3 OFFSET $4
 | 
					 | 
				
			||||||
		`,
 | 
					 | 
				
			||||||
		currentUserID,
 | 
					 | 
				
			||||||
		[]models.ThreadType{models.ThreadTypeForumPost, models.ThreadTypeProjectBlogPost},
 | 
					 | 
				
			||||||
		limit,
 | 
					 | 
				
			||||||
		offset,
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
	c.Perf.EndBlock()
 | 
					 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						c.Perf.StartBlock("SQL", "Fetch subforum tree")
 | 
				
			||||||
 | 
						subforumTree := models.GetFullSubforumTree(c.Context(), c.Conn)
 | 
				
			||||||
 | 
						lineageBuilder := models.MakeSubforumLineageBuilder(subforumTree)
 | 
				
			||||||
 | 
						c.Perf.EndBlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	c.Perf.StartBlock("FEED", "Build post items")
 | 
						c.Perf.StartBlock("FEED", "Build post items")
 | 
				
			||||||
	var postItems []templates.PostListItem
 | 
						var postItems []templates.PostListItem
 | 
				
			||||||
	for _, iPostResult := range posts.ToSlice() {
 | 
						for _, postAndStuff := range postsAndStuff {
 | 
				
			||||||
		postResult := iPostResult.(*feedPostQuery)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		hasRead := false
 | 
					 | 
				
			||||||
		if c.CurrentUser != nil && c.CurrentUser.MarkedAllReadAt.After(postResult.Post.PostDate) {
 | 
					 | 
				
			||||||
			hasRead = true
 | 
					 | 
				
			||||||
		} else if postResult.ThreadLastReadTime != nil && postResult.ThreadLastReadTime.After(postResult.Post.PostDate) {
 | 
					 | 
				
			||||||
			hasRead = true
 | 
					 | 
				
			||||||
		} else if postResult.SubforumLastReadTime != nil && postResult.SubforumLastReadTime.After(postResult.Post.PostDate) {
 | 
					 | 
				
			||||||
			hasRead = true
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		postItem := MakePostListItem(
 | 
							postItem := MakePostListItem(
 | 
				
			||||||
			lineageBuilder,
 | 
								lineageBuilder,
 | 
				
			||||||
			&postResult.Proj,
 | 
								&postAndStuff.Project,
 | 
				
			||||||
			&postResult.Thread,
 | 
								&postAndStuff.Thread,
 | 
				
			||||||
			&postResult.Post,
 | 
								&postAndStuff.Post,
 | 
				
			||||||
			&postResult.User,
 | 
								postAndStuff.Author,
 | 
				
			||||||
			!hasRead,
 | 
								postAndStuff.ThreadUnread,
 | 
				
			||||||
			true,
 | 
								true,
 | 
				
			||||||
			c.Theme,
 | 
								c.Theme,
 | 
				
			||||||
		)
 | 
							)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		postItem.UUID = uuid.NewSHA1(uuid.NameSpaceURL, []byte(postItem.Url)).URN()
 | 
							postItem.UUID = uuid.NewSHA1(uuid.NameSpaceURL, []byte(postItem.Url)).URN()
 | 
				
			||||||
		postItem.LastEditDate = postResult.PostVersion.Date
 | 
							postItem.LastEditDate = postAndStuff.CurrentVersion.Date
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		postItems = append(postItems, postItem)
 | 
							postItems = append(postItems, postItem)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue