Code Warning Fixes
This commit is contained in:
@@ -184,28 +184,30 @@ func TeamChatWS(c *websocket.Conn) {
|
||||
}
|
||||
|
||||
var incoming struct {
|
||||
Type string `json:"type"`
|
||||
Content string `json:"content"`
|
||||
Type string `json:"type"`
|
||||
Content string `json:"content"`
|
||||
MessageID string `json:"message_id,omitempty"`
|
||||
ReplyTo string `json:"reply_to,omitempty"`
|
||||
}
|
||||
if json.Unmarshal(msg, &incoming) != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
teamOID, err := primitive.ObjectIDFromHex(teamID)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
userOID, err := primitive.ObjectIDFromHex(userID)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if incoming.Type == "message" {
|
||||
content := strings.TrimSpace(incoming.Content)
|
||||
if content == "" || len(content) > 5000 {
|
||||
continue
|
||||
}
|
||||
|
||||
teamOID, err := primitive.ObjectIDFromHex(teamID)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
userOID, err := primitive.ObjectIDFromHex(userID)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
chatMsg := models.ChatMessage{
|
||||
ID: primitive.NewObjectID(),
|
||||
TeamID: teamOID,
|
||||
@@ -215,6 +217,12 @@ func TeamChatWS(c *websocket.Conn) {
|
||||
CreatedAt: time.Now(),
|
||||
}
|
||||
|
||||
if incoming.ReplyTo != "" {
|
||||
if replyID, err := primitive.ObjectIDFromHex(incoming.ReplyTo); err == nil {
|
||||
chatMsg.ReplyTo = &replyID
|
||||
}
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
_, _ = database.GetCollection("chat_messages").InsertOne(ctx, chatMsg)
|
||||
cancel()
|
||||
@@ -224,6 +232,56 @@ func TeamChatWS(c *websocket.Conn) {
|
||||
"message": chatMsg,
|
||||
})
|
||||
room.broadcastAll(outMsg)
|
||||
} else if incoming.Type == "edit" {
|
||||
content := strings.TrimSpace(incoming.Content)
|
||||
if content == "" || len(content) > 5000 || incoming.MessageID == "" {
|
||||
continue
|
||||
}
|
||||
msgID, err := primitive.ObjectIDFromHex(incoming.MessageID)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
res, err := database.GetCollection("chat_messages").UpdateOne(ctx,
|
||||
bson.M{"_id": msgID, "user_id": userOID, "team_id": teamOID, "deleted": bson.M{"$ne": true}},
|
||||
bson.M{"$set": bson.M{"content": content, "edited_at": now}},
|
||||
)
|
||||
cancel()
|
||||
|
||||
if err == nil && res.ModifiedCount > 0 {
|
||||
outMsg, _ := json.Marshal(map[string]interface{}{
|
||||
"type": "edit",
|
||||
"message_id": msgID.Hex(),
|
||||
"content": content,
|
||||
"edited_at": now,
|
||||
})
|
||||
room.broadcastAll(outMsg)
|
||||
}
|
||||
} else if incoming.Type == "delete" {
|
||||
if incoming.MessageID == "" {
|
||||
continue
|
||||
}
|
||||
msgID, err := primitive.ObjectIDFromHex(incoming.MessageID)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
res, err := database.GetCollection("chat_messages").UpdateOne(ctx,
|
||||
bson.M{"_id": msgID, "user_id": userOID, "team_id": teamOID},
|
||||
bson.M{"$set": bson.M{"deleted": true, "content": ""}},
|
||||
)
|
||||
cancel()
|
||||
|
||||
if err == nil && res.ModifiedCount > 0 {
|
||||
outMsg, _ := json.Marshal(map[string]interface{}{
|
||||
"type": "delete",
|
||||
"message_id": msgID.Hex(),
|
||||
})
|
||||
room.broadcastAll(outMsg)
|
||||
}
|
||||
}
|
||||
|
||||
if incoming.Type == "typing" {
|
||||
|
||||
@@ -526,12 +526,12 @@ func uploadTeamImage(c *fiber.Ctx, imageType string) error {
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Failed to save image"})
|
||||
}
|
||||
|
||||
imageURL := fmt.Sprintf("/api/teams/%s/%s", teamID.Hex(), imageType)
|
||||
imageURL := fmt.Sprintf("/api/team-media/%s/%s", teamID.Hex(), imageType)
|
||||
field := imageType + "_url"
|
||||
|
||||
col := database.GetCollection("teams")
|
||||
if _, err := col.UpdateOne(ctx, bson.M{"_id": teamID}, bson.M{"$set": bson.M{
|
||||
field: imageURL,
|
||||
field: imageURL,
|
||||
"updated_at": time.Now(),
|
||||
}}); err != nil {
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Failed to update team"})
|
||||
@@ -600,3 +600,25 @@ func ServeTeamAvatar(c *fiber.Ctx) error {
|
||||
func ServeTeamBanner(c *fiber.Ctx) error {
|
||||
return serveTeamImage(c, "banner")
|
||||
}
|
||||
|
||||
func ServePublicTeamImage(c *fiber.Ctx) error {
|
||||
teamID := c.Params("teamId")
|
||||
imageType := c.Params("imageType")
|
||||
if _, err := primitive.ObjectIDFromHex(teamID); err != nil {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid team ID"})
|
||||
}
|
||||
if imageType != "avatar" && imageType != "banner" {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid image type"})
|
||||
}
|
||||
|
||||
dir := filepath.Join("../data/teams", teamID)
|
||||
for ext := range allowedImageExts {
|
||||
p := filepath.Join(dir, imageType+ext)
|
||||
if _, err := os.Stat(p); err == nil {
|
||||
c.Set("Cache-Control", "public, max-age=3600")
|
||||
return c.SendFile(p)
|
||||
}
|
||||
}
|
||||
|
||||
return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"error": "Image not found"})
|
||||
}
|
||||
|
||||
@@ -153,7 +153,7 @@ func UploadUserAvatar(c *fiber.Ctx) error {
|
||||
|
||||
col := database.GetCollection("users")
|
||||
if _, err := col.UpdateOne(ctx, bson.M{"_id": userID}, bson.M{"$set": bson.M{
|
||||
"avatar_url": "/api/users/me/avatar",
|
||||
"avatar_url": "/api/avatar/" + userID.Hex(),
|
||||
"updated_at": time.Now(),
|
||||
}}); err != nil {
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Failed to update user"})
|
||||
@@ -184,6 +184,24 @@ func ServeUserAvatar(c *fiber.Ctx) error {
|
||||
return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"error": "Avatar not found"})
|
||||
}
|
||||
|
||||
func ServePublicAvatar(c *fiber.Ctx) error {
|
||||
userID := c.Params("userId")
|
||||
if _, err := primitive.ObjectIDFromHex(userID); err != nil {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid user ID"})
|
||||
}
|
||||
|
||||
dir := filepath.Join("../data/users", userID)
|
||||
for ext := range allowedImageExts {
|
||||
p := filepath.Join(dir, "avatar"+ext)
|
||||
if _, err := os.Stat(p); err == nil {
|
||||
c.Set("Cache-Control", "public, max-age=3600")
|
||||
return c.SendFile(p)
|
||||
}
|
||||
}
|
||||
|
||||
return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"error": "Avatar not found"})
|
||||
}
|
||||
|
||||
func ChangePassword(c *fiber.Ctx) error {
|
||||
userID, err := primitive.ObjectIDFromHex(c.Locals("user_id").(string))
|
||||
if err != nil {
|
||||
|
||||
@@ -73,20 +73,22 @@ type Subtask struct {
|
||||
}
|
||||
|
||||
type Card struct {
|
||||
ID primitive.ObjectID `bson:"_id,omitempty" json:"id"`
|
||||
ColumnID primitive.ObjectID `bson:"column_id" json:"column_id"`
|
||||
ProjectID primitive.ObjectID `bson:"project_id" json:"project_id"`
|
||||
Title string `bson:"title" json:"title"`
|
||||
Description string `bson:"description" json:"description"`
|
||||
Priority string `bson:"priority" json:"priority"`
|
||||
Color string `bson:"color" json:"color"`
|
||||
DueDate *time.Time `bson:"due_date,omitempty" json:"due_date,omitempty"`
|
||||
Assignees []string `bson:"assignees" json:"assignees"`
|
||||
Subtasks []Subtask `bson:"subtasks" json:"subtasks"`
|
||||
Position int `bson:"position" json:"position"`
|
||||
CreatedBy primitive.ObjectID `bson:"created_by" json:"created_by"`
|
||||
CreatedAt time.Time `bson:"created_at" json:"created_at"`
|
||||
UpdatedAt time.Time `bson:"updated_at" json:"updated_at"`
|
||||
ID primitive.ObjectID `bson:"_id,omitempty" json:"id"`
|
||||
ColumnID primitive.ObjectID `bson:"column_id" json:"column_id"`
|
||||
ProjectID primitive.ObjectID `bson:"project_id" json:"project_id"`
|
||||
Title string `bson:"title" json:"title"`
|
||||
Description string `bson:"description" json:"description"`
|
||||
Priority string `bson:"priority" json:"priority"`
|
||||
Color string `bson:"color" json:"color"`
|
||||
DueDate *time.Time `bson:"due_date,omitempty" json:"due_date,omitempty"`
|
||||
Assignees []string `bson:"assignees" json:"assignees"`
|
||||
EstimatedMinutes *int `bson:"estimated_minutes,omitempty" json:"estimated_minutes,omitempty"`
|
||||
ActualMinutes *int `bson:"actual_minutes,omitempty" json:"actual_minutes,omitempty"`
|
||||
Subtasks []Subtask `bson:"subtasks" json:"subtasks"`
|
||||
Position int `bson:"position" json:"position"`
|
||||
CreatedBy primitive.ObjectID `bson:"created_by" json:"created_by"`
|
||||
CreatedAt time.Time `bson:"created_at" json:"created_at"`
|
||||
UpdatedAt time.Time `bson:"updated_at" json:"updated_at"`
|
||||
}
|
||||
|
||||
type Event struct {
|
||||
@@ -175,10 +177,13 @@ type APIKey struct {
|
||||
}
|
||||
|
||||
type ChatMessage struct {
|
||||
ID primitive.ObjectID `bson:"_id,omitempty" json:"id"`
|
||||
TeamID primitive.ObjectID `bson:"team_id" json:"team_id"`
|
||||
UserID primitive.ObjectID `bson:"user_id" json:"user_id"`
|
||||
UserName string `bson:"user_name" json:"user_name"`
|
||||
Content string `bson:"content" json:"content"`
|
||||
CreatedAt time.Time `bson:"created_at" json:"created_at"`
|
||||
ID primitive.ObjectID `bson:"_id,omitempty" json:"id"`
|
||||
TeamID primitive.ObjectID `bson:"team_id" json:"team_id"`
|
||||
UserID primitive.ObjectID `bson:"user_id" json:"user_id"`
|
||||
UserName string `bson:"user_name" json:"user_name"`
|
||||
Content string `bson:"content" json:"content"`
|
||||
ReplyTo *primitive.ObjectID `bson:"reply_to,omitempty" json:"reply_to,omitempty"`
|
||||
EditedAt *time.Time `bson:"edited_at,omitempty" json:"edited_at,omitempty"`
|
||||
Deleted bool `bson:"deleted,omitempty" json:"deleted,omitempty"`
|
||||
CreatedAt time.Time `bson:"created_at" json:"created_at"`
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user