chat_back_go/internal/service/messages.go

201 lines
5.6 KiB
Go

package service
import (
"errors"
"git.urec56.ru/urec/chat_back_go/internal/domain"
"git.urec56.ru/urec/chat_back_go/internal/logger"
"git.urec56.ru/urec/chat_back_go/internal/repository"
)
type messageService struct {
repo repository.Message
u User
l *logger.Logger
}
func newMessageService(repo repository.Message, u User, l *logger.Logger) *messageService {
return &messageService{repo: repo, u: u, l: l}
}
func (s *messageService) AddAvatarImageAndUsernameToMessage(msgRaw domain.MessageRaw) (domain.Message, error) {
u, err := s.u.GetCachedUser(msgRaw.UserID)
if err != nil {
return domain.Message{}, domain.InternalServerError
}
return domain.Message{
ID: msgRaw.ID,
Message: msgRaw.Message,
ImageUrl: msgRaw.ImageUrl,
ChatID: msgRaw.ChatID,
UserID: msgRaw.UserID,
Username: u.Username,
AvatarImage: u.AvatarImage,
CreatedAt: msgRaw.CreatedAt,
AnswerID: msgRaw.AnswerID,
AnswerMessage: msgRaw.AnswerMessage,
AnswerImageUrl: msgRaw.AnswerImageUrl,
}, nil
}
func (s *messageService) AddAvatarImageAndUsernameToMessages(msgsRaw []domain.MessageRaw) []domain.Message {
msgs := make([]domain.Message, 0, len(msgsRaw))
for _, v := range msgsRaw {
msg, err := s.AddAvatarImageAndUsernameToMessage(v)
if err != nil {
continue
}
msgs = append(msgs, msg)
}
return msgs
}
func (s *messageService) GetMessage(ID domain.UUID) (domain.Message, error) {
rawMessage, err := s.GetRaw(ID)
if err != nil {
s.l.Infof("error getting message: %s", err.Error())
return domain.Message{}, domain.InternalServerError
}
newMessage, err := s.AddAvatarImageAndUsernameToMessage(rawMessage)
if err != nil {
return domain.Message{}, domain.InternalServerError
}
return newMessage, nil
}
func (s *messageService) GetRaw(ID domain.UUID) (domain.MessageRaw, error) {
rawMessage, err := s.repo.Get(ID)
if err != nil {
s.l.Infof("error getting message: %s", err.Error())
return domain.MessageRaw{}, domain.InternalServerError
}
return rawMessage, nil
}
func (s *messageService) GetPinned(chatID int) ([]domain.Message, error) {
IDs, err := s.repo.GetPinnedIDs(chatID)
if err != nil {
s.l.Infof("error getting pinned ids: %s", err.Error())
return nil, domain.InternalServerError
}
rawMessages, err := s.repo.GetByIDs(IDs)
if err != nil {
s.l.Infof("error messages by ids: %s", err.Error())
return nil, domain.InternalServerError
}
messages := s.AddAvatarImageAndUsernameToMessages(rawMessages)
return messages, nil
}
func (s *messageService) GetSome(chatID, messageNumberFrom, messagesToGet int) ([]domain.Message, error) {
messagesRaw, err := s.repo.GetSome(repository.GetSome{ChatID: chatID, MessageNumberFrom: messageNumberFrom, MessagesToGet: messagesToGet})
if err != nil {
s.l.Infof("error getting some messages: %s", err.Error())
return nil, err
}
messages := s.AddAvatarImageAndUsernameToMessages(messagesRaw)
return messages, nil
}
func (s *messageService) SendMessage(userID, chatID int, message domain.SendMessage) (domain.Message, error) {
var messageID domain.UUID
var err error
if message.Answer.IsZero() {
messageID, err = s.repo.Send(repository.SendMessage{
Message: message.Message,
ImageUrl: message.ImageUrl,
ChatID: chatID,
UserID: userID,
})
if err != nil {
s.l.Infof("error sending message: %s", err.Error())
return domain.Message{}, domain.InternalServerError
}
} else {
answerMessage, err := s.GetRaw(message.Answer)
if err != nil {
s.l.Infof("error getting message: %s", err.Error())
return domain.Message{}, domain.InternalServerError
}
messageID, err = s.repo.Send(repository.SendMessage{
Message: message.Message,
ImageUrl: message.ImageUrl,
ChatID: chatID,
UserID: userID,
AnswerID: message.Answer,
AnswerMessage: answerMessage.Message,
AnswerImageUrl: answerMessage.ImageUrl,
})
if err != nil {
s.l.Infof("error sending message: %s", err.Error())
return domain.Message{}, domain.InternalServerError
}
}
newMessage, err := s.GetMessage(messageID)
if err != nil {
s.l.Infof("error getting message: %s", err.Error())
return domain.Message{}, domain.InternalServerError
}
return newMessage, nil
}
func (s *messageService) Delete(ID domain.UUID) error {
if err := s.repo.Delete(ID); err != nil {
s.l.Infof("error deleting message: %s", err.Error())
return domain.InternalServerError
}
return nil
}
func (s *messageService) Edit(ID domain.UUID, newMessage, newImageUrl string) error {
if err := s.repo.Edit(repository.EditMessage{ID: ID, Message: newMessage, ImageUrl: newImageUrl}); err != nil {
s.l.Infof("error editing message: %s", err.Error())
return domain.InternalServerError
}
return nil
}
func (s *messageService) Pin(chatID, userID int, messageID domain.UUID) (domain.Message, error) {
err := s.repo.Pin(repository.PinMessage{ChatID: chatID, UserID: userID, MessageID: messageID})
if err != nil {
if errors.Is(err, domain.MessageAlreadyPinnedError) {
return domain.Message{}, err
}
s.l.Infof("error pinning message: %s", err.Error())
return domain.Message{}, domain.InternalServerError
}
message, err := s.GetMessage(messageID)
if err != nil {
s.l.Infof("error getting message: %s", err.Error())
return domain.Message{}, domain.InternalServerError
}
return message, nil
}
func (s *messageService) Unpin(chatID int, messageID domain.UUID) error {
err := s.repo.Unpin(repository.UnpinMessage{ChatID: chatID, MessageID: messageID})
if err != nil {
s.l.Infof("error unpinning message: %s", err.Error())
return domain.InternalServerError
}
return nil
}