package main import ( "context" "fmt" "net/http" "sort" "time" "github.com/flosch/pongo2" "github.com/gofiber/fiber/v2" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson/primitive" "go.mongodb.org/mongo-driver/mongo" ) type Message struct { ID primitive.ObjectID `bson:"_id"` Content string `bson:"message"` Role string `bson:"role"` Date time.Time `bson:"date"` Model string `bson:"model"` Selected bool `bson:"selected"` LinkedMessageIds []string `bson:"linked_message_ids"` } type Conversation struct { ID string Messages []Message } func ChatPageHandler(c *fiber.Ctx) error { return c.Render("chat", fiber.Map{}, "layouts/main") } func LoadModelSelectionHandler(c *fiber.Ctx) error { CheckedModels := []string{"gpt-3.5-turbo"} // Default model out, err := popoverTmpl.Execute(pongo2.Context{ "CompanyInfos": CompanyInfos, "CheckedModels": CheckedModels, }) if err != nil { c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ "error": "Error rendering template", }) } return c.SendString(out) } func DeleteMessageHandler(c *fiber.Ctx) error { messageId := c.FormValue("id") // messageId is a string that look like ObjectID("662d6556e5328bbc8357cfb1") // Get the message from the db and delete it and all messages after it collection := mongoClient.Database("chat").Collection("messages") // Convert the messageId string to a bson.ObjectId objectID, err := primitive.ObjectIDFromHex(messageId) if err != nil { return c.Status(http.StatusBadRequest).JSON(fiber.Map{ "error": "Invalid message ID", }) } // Find the message with the given ID message := &Message{} err = collection.FindOne(c.Context(), bson.M{"_id": objectID}).Decode(message) if err != nil { if err == mongo.ErrNoDocuments { return c.Status(http.StatusNotFound).JSON(fiber.Map{ "error": "Message not found", }) } return c.Status(http.StatusInternalServerError).JSON(fiber.Map{ "error": "Error finding message", }) } // Delete the message and all messages after it _, err = collection.DeleteMany(c.Context(), bson.M{ "date": bson.M{"$gte": message.Date}, }) if err != nil { return c.Status(http.StatusInternalServerError).JSON(fiber.Map{ "error": "Error deleting messages", }) } return c.SendString(generateChatHTML()) } func LoadChatHandler(c *fiber.Ctx) error { return c.SendString(generateChatHTML()) } func ChangeSelectedMessageHandler(c *fiber.Ctx) error { messageId := c.FormValue("id") collection := mongoClient.Database("chat").Collection("messages") objectID, err := primitive.ObjectIDFromHex(messageId) if err != nil { return c.Status(http.StatusBadRequest).JSON(fiber.Map{ "error": "Invalid message ID", }) } var selectedMessage Message err = collection.FindOne(c.Context(), bson.M{"_id": objectID}).Decode(&selectedMessage) if err != nil { return c.Status(http.StatusInternalServerError).JSON(fiber.Map{ "error": "Error finding message", }) } for i := range selectedMessage.LinkedMessageIds { objectID, _ = primitive.ObjectIDFromHex(selectedMessage.LinkedMessageIds[i]) _, err = collection.UpdateOne(c.Context(), bson.M{"_id": objectID}, bson.M{"$set": bson.M{"selected": false}}) if err != nil { return c.Status(http.StatusInternalServerError).JSON(fiber.Map{ "error": "Error updating message", }) } } _, err = collection.UpdateOne(c.Context(), bson.M{"_id": objectID}, bson.M{"$set": bson.M{"selected": true}}) if err != nil { return c.Status(http.StatusInternalServerError).JSON(fiber.Map{ "error": "Error updating message", }) } return c.SendString(generateChatHTML()) } type NextMessage struct { Icon string Content string Hidden bool Id string } func generateChatHTML() string { // Get the messages from the database collection := mongoClient.Database("chat").Collection("messages") // Get all messages cursor, err := collection.Find(context.TODO(), bson.D{}) if err != nil { fmt.Println(err) } // Convert the cursor to an array of messages var Messages []Message if err = cursor.All(context.TODO(), &Messages); err != nil { fmt.Println(err) } htmlString := "