diff --git a/pkg/models/channels.go b/pkg/models/channels.go index d557ba3..35ed9cc 100644 --- a/pkg/models/channels.go +++ b/pkg/models/channels.go @@ -21,13 +21,22 @@ type Channel struct { RealmID uint `json:"realm_id"` } +type NotifyLevel = int8 + +const ( + NotifyLevelAll = NotifyLevel(iota) + NotifyLevelMentioned + NotifyLevelNone +) + type ChannelMember struct { BaseModel - ChannelID uint `json:"channel_id"` - AccountID uint `json:"account_id"` - Channel Channel `json:"channel"` - Account Account `json:"account"` + ChannelID uint `json:"channel_id"` + AccountID uint `json:"account_id"` + Channel Channel `json:"channel"` + Account Account `json:"account"` + Notify NotifyLevel `json:"notify"` Messages []Message `json:"messages" gorm:"foreignKey:SenderID"` } diff --git a/pkg/server/channel_members_api.go b/pkg/server/channel_members_api.go index 8852abf..ed976a2 100644 --- a/pkg/server/channel_members_api.go +++ b/pkg/server/channel_members_api.go @@ -85,6 +85,35 @@ func kickChannel(c *fiber.Ctx) error { } } +func editChannelMembership(c *fiber.Ctx) error { + user := c.Locals("principal").(models.Account) + channelId, _ := c.ParamsInt("channelId", 0) + + var data struct { + NotifyLevel int8 `json:"notify_level"` + } + + if err := BindAndValidate(c, &data); err != nil { + return err + } + + var membership models.ChannelMember + if err := database.C.Where(&models.ChannelMember{ + ChannelID: uint(channelId), + AccountID: user.ID, + }).First(&membership).Error; err != nil { + return fiber.NewError(fiber.StatusNotFound, err.Error()) + } + + membership.Notify = data.NotifyLevel + + if membership, err := services.EditChannelMember(membership); err != nil { + return fiber.NewError(fiber.StatusBadRequest, err.Error()) + } else { + return c.JSON(membership) + } +} + func leaveChannel(c *fiber.Ctx) error { user := c.Locals("principal").(models.Account) channelId, _ := c.ParamsInt("channelId", 0) diff --git a/pkg/server/startup.go b/pkg/server/startup.go index ff47e44..453b1b6 100644 --- a/pkg/server/startup.go +++ b/pkg/server/startup.go @@ -86,6 +86,7 @@ func NewServer() { channels.Delete("/:channelId", authMiddleware, deleteChannel) channels.Get("/:channelId/members", listChannelMembers) + channels.Put("/:channelId/members", authMiddleware, editChannelMembership) channels.Post("/:channelId/invite", authMiddleware, inviteChannel) channels.Post("/:channelId/kick", authMiddleware, kickChannel) channels.Post("/:channelId/leave", authMiddleware, leaveChannel) diff --git a/pkg/services/channel_members.go b/pkg/services/channel_members.go new file mode 100644 index 0000000..3617504 --- /dev/null +++ b/pkg/services/channel_members.go @@ -0,0 +1,64 @@ +package services + +import ( + "fmt" + "git.solsynth.dev/hydrogen/messaging/pkg/database" + "git.solsynth.dev/hydrogen/messaging/pkg/models" +) + +func ListChannelMember(channelId uint) ([]models.ChannelMember, error) { + var members []models.ChannelMember + + if err := database.C. + Where(&models.ChannelMember{ChannelID: channelId}). + Preload("Account"). + Find(&members).Error; err != nil { + return members, err + } + + return members, nil +} + +func InviteChannelMember(user models.Account, target models.Channel) error { + if _, err := GetAccountFriend(user.ID, target.AccountID, 1); err != nil { + return fmt.Errorf("you only can invite your friends to your channel") + } + + member := models.ChannelMember{ + ChannelID: target.ID, + AccountID: user.ID, + } + + err := database.C.Save(&member).Error + return err +} + +func AddChannelMember(user models.Account, target models.Channel) error { + member := models.ChannelMember{ + ChannelID: target.ID, + AccountID: user.ID, + } + + err := database.C.Save(&member).Error + return err +} + +func EditChannelMember(membership models.ChannelMember) (models.ChannelMember, error) { + if err := database.C.Save(&membership).Error; err != nil { + return membership, err + } + return membership, nil +} + +func RemoveChannelMember(user models.Account, target models.Channel) error { + var member models.ChannelMember + + if err := database.C.Where(&models.ChannelMember{ + ChannelID: target.ID, + AccountID: user.ID, + }).First(&member).Error; err != nil { + return err + } + + return database.C.Delete(&member).Error +} diff --git a/pkg/services/channels.go b/pkg/services/channels.go index 80703af..adb151a 100644 --- a/pkg/services/channels.go +++ b/pkg/services/channels.go @@ -119,56 +119,6 @@ func NewChannel(user models.Account, alias, name, description string) (models.Ch return channel, err } -func ListChannelMember(channelId uint) ([]models.ChannelMember, error) { - var members []models.ChannelMember - - if err := database.C. - Where(&models.ChannelMember{ChannelID: channelId}). - Preload("Account"). - Find(&members).Error; err != nil { - return members, err - } - - return members, nil -} - -func InviteChannelMember(user models.Account, target models.Channel) error { - if _, err := GetAccountFriend(user.ID, target.AccountID, 1); err != nil { - return fmt.Errorf("you only can invite your friends to your channel") - } - - member := models.ChannelMember{ - ChannelID: target.ID, - AccountID: user.ID, - } - - err := database.C.Save(&member).Error - return err -} - -func AddChannelMember(user models.Account, target models.Channel) error { - member := models.ChannelMember{ - ChannelID: target.ID, - AccountID: user.ID, - } - - err := database.C.Save(&member).Error - return err -} - -func RemoveChannelMember(user models.Account, target models.Channel) error { - var member models.ChannelMember - - if err := database.C.Where(&models.ChannelMember{ - ChannelID: target.ID, - AccountID: user.ID, - }).First(&member).Error; err != nil { - return err - } - - return database.C.Delete(&member).Error -} - func EditChannel(channel models.Channel, alias, name, description string) (models.Channel, error) { channel.Alias = alias channel.Name = name diff --git a/pkg/services/messages.go b/pkg/services/messages.go index 395a486..d412e7b 100644 --- a/pkg/services/messages.go +++ b/pkg/services/messages.go @@ -85,13 +85,16 @@ func NewMessage(message models.Message) (models.Message, error) { for _, member := range members { message, _ = GetMessage(message.Channel, message.ID) if member.ID != message.Sender.ID { - err = NotifyAccount(member.Account, - fmt.Sprintf("New Message #%s", message.Channel.Alias), - fmt.Sprintf("%s: %s", message.Sender.Account.Name, message.Content), - true, - ) - if err != nil { - log.Warn().Err(err).Msg("An error occurred when trying notify user.") + // TODO Check the mentioned status + if member.Notify == models.NotifyLevelAll { + err = NotifyAccount(member.Account, + fmt.Sprintf("New Message #%s", message.Channel.Alias), + fmt.Sprintf("%s: %s", message.Sender.Account.Name, message.Content), + true, + ) + if err != nil { + log.Warn().Err(err).Msg("An error occurred when trying notify user.") + } } } PushCommand(member.AccountID, models.UnifiedCommand{