status-im/status-go

View on GitHub
protocol/group_chat_system_messages.go

Summary

Maintainability
A
0 mins
Test Coverage
A
100%
package protocol

import (
    "strings"
    "time"

    "github.com/status-im/status-go/eth-node/crypto"
    "github.com/status-im/status-go/eth-node/types"
    "github.com/status-im/status-go/protocol/common"
    "github.com/status-im/status-go/protocol/protobuf"
    v1protocol "github.com/status-im/status-go/protocol/v1"
)

var defaultSystemMessagesTranslations = new(systemMessageTranslationsMap)

func init() {
    defaultSystemMessagesTranslationSet := map[protobuf.MembershipUpdateEvent_EventType]string{
        protobuf.MembershipUpdateEvent_CHAT_CREATED:   "{{from}} created the group {{name}}",
        protobuf.MembershipUpdateEvent_NAME_CHANGED:   "{{from}} changed the group's name to {{name}}",
        protobuf.MembershipUpdateEvent_MEMBERS_ADDED:  "{{from}} has added {{members}}",
        protobuf.MembershipUpdateEvent_ADMINS_ADDED:   "{{from}} has made {{members}} admin",
        protobuf.MembershipUpdateEvent_MEMBER_REMOVED: "{{member}} left the group",
        protobuf.MembershipUpdateEvent_ADMIN_REMOVED:  "{{member}} is not admin anymore",
        protobuf.MembershipUpdateEvent_COLOR_CHANGED:  "{{from}} changed the group's color",
        protobuf.MembershipUpdateEvent_IMAGE_CHANGED:  "{{from}} changed the group's image",
    }
    defaultSystemMessagesTranslations.Init(defaultSystemMessagesTranslationSet)
}

func tsprintf(format string, params map[string]string) string {
    for key, val := range params {
        format = strings.Replace(format, "{{"+key+"}}", val, -1)
    }
    return format
}

func eventToSystemMessage(e v1protocol.MembershipUpdateEvent, translations *systemMessageTranslationsMap) *common.Message {
    var text string
    switch e.Type {
    case protobuf.MembershipUpdateEvent_CHAT_CREATED:
        message, _ := translations.Load(protobuf.MembershipUpdateEvent_CHAT_CREATED)
        text = tsprintf(message, map[string]string{"from": "@" + e.From, "name": e.Name})
    case protobuf.MembershipUpdateEvent_NAME_CHANGED:
        message, _ := translations.Load(protobuf.MembershipUpdateEvent_NAME_CHANGED)
        text = tsprintf(message, map[string]string{"from": "@" + e.From, "name": e.Name})
    case protobuf.MembershipUpdateEvent_COLOR_CHANGED:
        message, _ := translations.Load(protobuf.MembershipUpdateEvent_COLOR_CHANGED)
        text = tsprintf(message, map[string]string{"from": "@" + e.From})
    case protobuf.MembershipUpdateEvent_IMAGE_CHANGED:
        message, _ := translations.Load(protobuf.MembershipUpdateEvent_IMAGE_CHANGED)
        text = tsprintf(message, map[string]string{"from": "@" + e.From})
    case protobuf.MembershipUpdateEvent_MEMBERS_ADDED:

        var memberMentions []string
        for _, s := range e.Members {
            memberMentions = append(memberMentions, "@"+s)
        }
        message, _ := translations.Load(protobuf.MembershipUpdateEvent_MEMBERS_ADDED)
        text = tsprintf(message, map[string]string{"from": "@" + e.From, "members": strings.Join(memberMentions, ", ")})
    case protobuf.MembershipUpdateEvent_ADMINS_ADDED:
        var memberMentions []string
        for _, s := range e.Members {
            memberMentions = append(memberMentions, "@"+s)
        }
        message, _ := translations.Load(protobuf.MembershipUpdateEvent_ADMINS_ADDED)
        text = tsprintf(message, map[string]string{"from": "@" + e.From, "members": strings.Join(memberMentions, ", ")})
    case protobuf.MembershipUpdateEvent_MEMBER_REMOVED:
        message, _ := translations.Load(protobuf.MembershipUpdateEvent_MEMBER_REMOVED)
        text = tsprintf(message, map[string]string{"member": "@" + e.Members[0]})
    case protobuf.MembershipUpdateEvent_ADMIN_REMOVED:
        message, _ := translations.Load(protobuf.MembershipUpdateEvent_ADMIN_REMOVED)
        text = tsprintf(message, map[string]string{"member": "@" + e.Members[0]})

    }
    timestamp := v1protocol.TimestampInMsFromTime(time.Now())
    message := &common.Message{
        ChatMessage: &protobuf.ChatMessage{
            ChatId:      e.ChatID,
            Text:        text,
            MessageType: protobuf.MessageType_SYSTEM_MESSAGE_PRIVATE_GROUP,
            ContentType: protobuf.ChatMessage_SYSTEM_MESSAGE_CONTENT_PRIVATE_GROUP,
            Clock:       e.ClockValue,
            Timestamp:   timestamp,
        },
        From:             e.From,
        WhisperTimestamp: timestamp,
        LocalChatID:      e.ChatID,
        Seen:             true,
        ID:               types.EncodeHex(crypto.Keccak256(e.Signature)),
    }
    // We don't pass an identity here as system messages don't need the mentioned flag
    _ = message.PrepareContent("")
    return message
}

func buildSystemMessages(events []v1protocol.MembershipUpdateEvent, translations *systemMessageTranslationsMap) []*common.Message {
    var messages []*common.Message

    for _, e := range events {
        if e.Type == protobuf.MembershipUpdateEvent_MEMBER_JOINED {
            // explicit join has been removed, ignore this event
            continue
        }

        messages = append(messages, eventToSystemMessage(e, translations))
    }

    return messages
}