diff --git a/server/handlers/auth/feed.go b/server/handlers/auth/feed.go new file mode 100644 index 0000000..0d55a54 --- /dev/null +++ b/server/handlers/auth/feed.go @@ -0,0 +1,80 @@ +package auth + +import ( + "github.com/gofiber/fiber/v2" + "github.com/lareii/copl.uk/server/models" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/bson/primitive" +) + +type PostsResponse struct { + Message string `json:"message"` + Posts []models.PostResponseContent `json:"posts"` +} + +func GetFeed(c *fiber.Ctx) error { + limit := c.QueryInt("limit", 10) + offset := c.QueryInt("offset", 0) + + user, ok := c.Locals("user").(models.User) + if !ok { + return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{ + "message": "User not authenticated.", + }) + } + + posts, err := models.GetPosts( + int64(limit), + int64(offset), + bson.M{"author": bson.M{"$in": user.Following}}, + bson.M{"created_at": -1}, + ) + if err != nil { + return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ + "message": "Error fetching posts.", + }) + } + + var authorIDs []primitive.ObjectID + for _, post := range posts { + authorIDs = append(authorIDs, post.Author) + } + + authorMap := make(map[primitive.ObjectID]models.User) + for _, authorID := range authorIDs { + author, err := models.GetUserByID(authorID) + if err != nil { + return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ + "message": "Error fetching post authors.", + }) + } + authorMap[author.ID] = author + } + + var responsePosts []models.PostResponseContent + for _, post := range posts { + author := authorMap[post.Author] + + responsePosts = append(responsePosts, models.PostResponseContent{ + ID: post.ID, + CreatedAt: post.CreatedAt, + UpdatedAt: post.UpdatedAt, + Author: models.PostResponseAuthor{ + ID: author.ID, + CreatedAt: author.CreatedAt, + DisplayName: author.DisplayName, + Username: author.Username, + About: author.About, + Points: author.Points, + }, + Content: post.Content, + Likes: post.Likes, + Comments: post.Comments, + }) + } + + return c.Status(fiber.StatusOK).JSON(PostsResponse{ + Message: "Posts found.", + Posts: responsePosts, + }) +} diff --git a/server/handlers/posts/get_posts.go b/server/handlers/posts/get_posts.go index ec97fa5..af314a9 100644 --- a/server/handlers/posts/get_posts.go +++ b/server/handlers/posts/get_posts.go @@ -3,6 +3,7 @@ package posts import ( "github.com/gofiber/fiber/v2" "github.com/lareii/copl.uk/server/models" + "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson/primitive" ) @@ -15,7 +16,7 @@ func GetPosts(c *fiber.Ctx) error { limit := c.QueryInt("limit", 10) offset := c.QueryInt("offset", 0) - posts, err := models.GetPosts(int64(limit), int64(offset)) + posts, err := models.GetPosts(int64(limit), int64(offset), nil, bson.M{"created_at": -1}) if err != nil { return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ "message": "Error fetching posts.", diff --git a/server/handlers/users/get_user_posts.go b/server/handlers/users/get_user_posts.go index c7e2b89..6191a18 100644 --- a/server/handlers/users/get_user_posts.go +++ b/server/handlers/users/get_user_posts.go @@ -3,6 +3,7 @@ package users import ( "github.com/gofiber/fiber/v2" "github.com/lareii/copl.uk/server/models" + "go.mongodb.org/mongo-driver/bson" ) func GetUserPosts(c *fiber.Ctx) error { @@ -22,7 +23,7 @@ func GetUserPosts(c *fiber.Ctx) error { limit := c.QueryInt("limit", 10) offset := c.QueryInt("offset", 0) - posts, err := models.GetPostsByUser(user, int64(limit), int64(offset)) + posts, err := models.GetPosts(int64(limit), int64(offset), bson.M{"author": user.ID}, bson.M{"created_at": -1}) if err != nil { return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ "message": "Error fetching user posts.", diff --git a/server/models/post.go b/server/models/post.go index 84bc880..6be4657 100644 --- a/server/models/post.go +++ b/server/models/post.go @@ -55,31 +55,12 @@ func GetPostByID(postID primitive.ObjectID) (Post, error) { return post, nil } -func GetPosts(limit, offset int64) ([]Post, error) { +func GetPosts(limit, offset int64, filter, sort bson.M) ([]Post, error) { var posts []Post - cursor, err := database.Posts.Find(context.Background(), bson.M{}, &options.FindOptions{ + cursor, err := database.Posts.Find(context.Background(), filter, &options.FindOptions{ Limit: &limit, Skip: &offset, - Sort: bson.M{"created_at": -1}, - }) - if err != nil { - return posts, fmt.Errorf("error fetching posts: %v", err) - } - - err = cursor.All(context.Background(), &posts) - if err != nil { - return posts, fmt.Errorf("error decoding posts: %v", err) - } - - return posts, nil -} - -func GetPostsByUser(user User, limit, offset int64) ([]Post, error) { - var posts []Post - cursor, err := database.Posts.Find(context.Background(), bson.M{"author": user.ID}, &options.FindOptions{ - Limit: &limit, - Skip: &offset, - Sort: bson.M{"created_at": -1}, + Sort: sort, }) if err != nil { return posts, fmt.Errorf("error fetching posts: %v", err) diff --git a/server/router/router.go b/server/router/router.go index 12bd44d..553f675 100644 --- a/server/router/router.go +++ b/server/router/router.go @@ -19,6 +19,7 @@ func SetupRouter(app *fiber.App) { authGroup.Post("/logout", auth.Logout) authGroup.Get("/me", middlewares.AuthMiddleware(), auth.User) authGroup.Patch("/me", middlewares.AuthMiddleware(), auth.UpdateUser) + authGroup.Get("/me/feed", middlewares.AuthMiddleware(), auth.GetFeed) userGroup := app.Group("/users") userGroup.Get("/", middlewares.AuthMiddleware(), users.GetUsers)