Add conversation thumbnail fetching and other library updates
This commit is contained in:
parent
7372bc4927
commit
a5e4c30a2c
9 changed files with 1465 additions and 1064 deletions
File diff suppressed because it is too large
Load diff
|
@ -72,18 +72,20 @@ func (BugleRoute) EnumDescriptor() ([]byte, []int) {
|
|||
type ActionType int32
|
||||
|
||||
const (
|
||||
ActionType_UNKNOWN_ACTION_TYPE ActionType = 0
|
||||
ActionType_LIST_CONVERSATIONS ActionType = 1
|
||||
ActionType_LIST_MESSAGES ActionType = 2
|
||||
ActionType_SEND_MESSAGE ActionType = 3
|
||||
ActionType_LIST_CONVERSATIONS_SYNC ActionType = 1111
|
||||
ActionType_GET_UPDATES ActionType = 16
|
||||
ActionType_GET_CONVERSATION_TYPE ActionType = 21
|
||||
ActionType_NOTIFY_DITTO_ACTIVITY ActionType = 22
|
||||
ActionType_DELETE_MESSAGE ActionType = 23
|
||||
ActionType_RESEND_MESSAGE ActionType = 25
|
||||
ActionType_IS_BUGLE_DEFAULT ActionType = 31
|
||||
ActionType_SEND_REACTION ActionType = 38
|
||||
ActionType_UNKNOWN_ACTION_TYPE ActionType = 0
|
||||
ActionType_LIST_CONVERSATIONS ActionType = 1
|
||||
ActionType_LIST_MESSAGES ActionType = 2
|
||||
ActionType_SEND_MESSAGE ActionType = 3
|
||||
ActionType_LIST_CONVERSATIONS_SYNC ActionType = 1111
|
||||
ActionType_UPDATE_CONVERSATION ActionType = 15
|
||||
ActionType_GET_UPDATES ActionType = 16
|
||||
ActionType_GET_CONVERSATION_TYPE ActionType = 21
|
||||
ActionType_NOTIFY_DITTO_ACTIVITY ActionType = 22
|
||||
ActionType_DELETE_MESSAGE ActionType = 23
|
||||
ActionType_RESEND_MESSAGE ActionType = 25
|
||||
ActionType_IS_BUGLE_DEFAULT ActionType = 31
|
||||
ActionType_GET_PARTICIPANTS_THUMBNAIL ActionType = 37
|
||||
ActionType_SEND_REACTION ActionType = 38
|
||||
)
|
||||
|
||||
// Enum value maps for ActionType.
|
||||
|
@ -94,27 +96,31 @@ var (
|
|||
2: "LIST_MESSAGES",
|
||||
3: "SEND_MESSAGE",
|
||||
1111: "LIST_CONVERSATIONS_SYNC",
|
||||
15: "UPDATE_CONVERSATION",
|
||||
16: "GET_UPDATES",
|
||||
21: "GET_CONVERSATION_TYPE",
|
||||
22: "NOTIFY_DITTO_ACTIVITY",
|
||||
23: "DELETE_MESSAGE",
|
||||
25: "RESEND_MESSAGE",
|
||||
31: "IS_BUGLE_DEFAULT",
|
||||
37: "GET_PARTICIPANTS_THUMBNAIL",
|
||||
38: "SEND_REACTION",
|
||||
}
|
||||
ActionType_value = map[string]int32{
|
||||
"UNKNOWN_ACTION_TYPE": 0,
|
||||
"LIST_CONVERSATIONS": 1,
|
||||
"LIST_MESSAGES": 2,
|
||||
"SEND_MESSAGE": 3,
|
||||
"LIST_CONVERSATIONS_SYNC": 1111,
|
||||
"GET_UPDATES": 16,
|
||||
"GET_CONVERSATION_TYPE": 21,
|
||||
"NOTIFY_DITTO_ACTIVITY": 22,
|
||||
"DELETE_MESSAGE": 23,
|
||||
"RESEND_MESSAGE": 25,
|
||||
"IS_BUGLE_DEFAULT": 31,
|
||||
"SEND_REACTION": 38,
|
||||
"UNKNOWN_ACTION_TYPE": 0,
|
||||
"LIST_CONVERSATIONS": 1,
|
||||
"LIST_MESSAGES": 2,
|
||||
"SEND_MESSAGE": 3,
|
||||
"LIST_CONVERSATIONS_SYNC": 1111,
|
||||
"UPDATE_CONVERSATION": 15,
|
||||
"GET_UPDATES": 16,
|
||||
"GET_CONVERSATION_TYPE": 21,
|
||||
"NOTIFY_DITTO_ACTIVITY": 22,
|
||||
"DELETE_MESSAGE": 23,
|
||||
"RESEND_MESSAGE": 25,
|
||||
"IS_BUGLE_DEFAULT": 31,
|
||||
"GET_PARTICIPANTS_THUMBNAIL": 37,
|
||||
"SEND_REACTION": 38,
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -1651,7 +1657,7 @@ var file_messages_proto_rawDesc = []byte{
|
|||
0x4f, 0x57, 0x4e, 0x5f, 0x42, 0x55, 0x47, 0x4c, 0x45, 0x5f, 0x52, 0x4f, 0x55, 0x54, 0x45, 0x10,
|
||||
0x00, 0x12, 0x0d, 0x0a, 0x09, 0x44, 0x61, 0x74, 0x61, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x10, 0x13,
|
||||
0x12, 0x0d, 0x0a, 0x09, 0x50, 0x61, 0x69, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x10, 0x0e, 0x2a,
|
||||
0x98, 0x02, 0x0a, 0x0a, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x17,
|
||||
0xd1, 0x02, 0x0a, 0x0a, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x17,
|
||||
0x0a, 0x13, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e,
|
||||
0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12, 0x4c, 0x49, 0x53, 0x54, 0x5f,
|
||||
0x43, 0x4f, 0x4e, 0x56, 0x45, 0x52, 0x53, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x10, 0x01, 0x12,
|
||||
|
@ -1659,23 +1665,26 @@ var file_messages_proto_rawDesc = []byte{
|
|||
0x10, 0x02, 0x12, 0x10, 0x0a, 0x0c, 0x53, 0x45, 0x4e, 0x44, 0x5f, 0x4d, 0x45, 0x53, 0x53, 0x41,
|
||||
0x47, 0x45, 0x10, 0x03, 0x12, 0x1c, 0x0a, 0x17, 0x4c, 0x49, 0x53, 0x54, 0x5f, 0x43, 0x4f, 0x4e,
|
||||
0x56, 0x45, 0x52, 0x53, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x5f, 0x53, 0x59, 0x4e, 0x43, 0x10,
|
||||
0xd7, 0x08, 0x12, 0x0f, 0x0a, 0x0b, 0x47, 0x45, 0x54, 0x5f, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45,
|
||||
0x53, 0x10, 0x10, 0x12, 0x19, 0x0a, 0x15, 0x47, 0x45, 0x54, 0x5f, 0x43, 0x4f, 0x4e, 0x56, 0x45,
|
||||
0x52, 0x53, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, 0x15, 0x12, 0x19,
|
||||
0x0a, 0x15, 0x4e, 0x4f, 0x54, 0x49, 0x46, 0x59, 0x5f, 0x44, 0x49, 0x54, 0x54, 0x4f, 0x5f, 0x41,
|
||||
0x43, 0x54, 0x49, 0x56, 0x49, 0x54, 0x59, 0x10, 0x16, 0x12, 0x12, 0x0a, 0x0e, 0x44, 0x45, 0x4c,
|
||||
0x45, 0x54, 0x45, 0x5f, 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x10, 0x17, 0x12, 0x12, 0x0a,
|
||||
0x0e, 0x52, 0x45, 0x53, 0x45, 0x4e, 0x44, 0x5f, 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x10,
|
||||
0x19, 0x12, 0x14, 0x0a, 0x10, 0x49, 0x53, 0x5f, 0x42, 0x55, 0x47, 0x4c, 0x45, 0x5f, 0x44, 0x45,
|
||||
0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x1f, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x45, 0x4e, 0x44, 0x5f,
|
||||
0x52, 0x45, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x26, 0x2a, 0x50, 0x0a, 0x0b, 0x4d, 0x65,
|
||||
0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x14, 0x55, 0x4e, 0x4b,
|
||||
0x4e, 0x4f, 0x57, 0x4e, 0x5f, 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x5f, 0x54, 0x59, 0x50,
|
||||
0x45, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x42, 0x55, 0x47, 0x4c, 0x45, 0x5f, 0x4d, 0x45, 0x53,
|
||||
0x53, 0x41, 0x47, 0x45, 0x10, 0x02, 0x12, 0x14, 0x0a, 0x10, 0x42, 0x55, 0x47, 0x4c, 0x45, 0x5f,
|
||||
0x41, 0x4e, 0x4e, 0x4f, 0x54, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x10, 0x42, 0x0e, 0x5a, 0x0c,
|
||||
0x2e, 0x2e, 0x2f, 0x2e, 0x2e, 0x2f, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x62, 0x06, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x33,
|
||||
0xd7, 0x08, 0x12, 0x17, 0x0a, 0x13, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x5f, 0x43, 0x4f, 0x4e,
|
||||
0x56, 0x45, 0x52, 0x53, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x0f, 0x12, 0x0f, 0x0a, 0x0b, 0x47,
|
||||
0x45, 0x54, 0x5f, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x53, 0x10, 0x10, 0x12, 0x19, 0x0a, 0x15,
|
||||
0x47, 0x45, 0x54, 0x5f, 0x43, 0x4f, 0x4e, 0x56, 0x45, 0x52, 0x53, 0x41, 0x54, 0x49, 0x4f, 0x4e,
|
||||
0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, 0x15, 0x12, 0x19, 0x0a, 0x15, 0x4e, 0x4f, 0x54, 0x49, 0x46,
|
||||
0x59, 0x5f, 0x44, 0x49, 0x54, 0x54, 0x4f, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x56, 0x49, 0x54, 0x59,
|
||||
0x10, 0x16, 0x12, 0x12, 0x0a, 0x0e, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x5f, 0x4d, 0x45, 0x53,
|
||||
0x53, 0x41, 0x47, 0x45, 0x10, 0x17, 0x12, 0x12, 0x0a, 0x0e, 0x52, 0x45, 0x53, 0x45, 0x4e, 0x44,
|
||||
0x5f, 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x10, 0x19, 0x12, 0x14, 0x0a, 0x10, 0x49, 0x53,
|
||||
0x5f, 0x42, 0x55, 0x47, 0x4c, 0x45, 0x5f, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x1f,
|
||||
0x12, 0x1e, 0x0a, 0x1a, 0x47, 0x45, 0x54, 0x5f, 0x50, 0x41, 0x52, 0x54, 0x49, 0x43, 0x49, 0x50,
|
||||
0x41, 0x4e, 0x54, 0x53, 0x5f, 0x54, 0x48, 0x55, 0x4d, 0x42, 0x4e, 0x41, 0x49, 0x4c, 0x10, 0x25,
|
||||
0x12, 0x11, 0x0a, 0x0d, 0x53, 0x45, 0x4e, 0x44, 0x5f, 0x52, 0x45, 0x41, 0x43, 0x54, 0x49, 0x4f,
|
||||
0x4e, 0x10, 0x26, 0x2a, 0x50, 0x0a, 0x0b, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79,
|
||||
0x70, 0x65, 0x12, 0x18, 0x0a, 0x14, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x5f, 0x4d, 0x45,
|
||||
0x53, 0x53, 0x41, 0x47, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d,
|
||||
0x42, 0x55, 0x47, 0x4c, 0x45, 0x5f, 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x10, 0x02, 0x12,
|
||||
0x14, 0x0a, 0x10, 0x42, 0x55, 0x47, 0x4c, 0x45, 0x5f, 0x41, 0x4e, 0x4e, 0x4f, 0x54, 0x41, 0x54,
|
||||
0x49, 0x4f, 0x4e, 0x10, 0x10, 0x42, 0x0e, 0x5a, 0x0c, 0x2e, 0x2e, 0x2f, 0x2e, 0x2e, 0x2f, 0x62,
|
||||
0x69, 0x6e, 0x61, 0x72, 0x79, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
|
|
|
@ -5,6 +5,10 @@ option go_package = "../../binary";
|
|||
|
||||
import "reactions.proto";
|
||||
|
||||
message GetParticipantThumbnailPayload {
|
||||
string conversationID = 1;
|
||||
}
|
||||
|
||||
message ResendMessagePayload {
|
||||
string messageID = 2;
|
||||
}
|
||||
|
@ -160,7 +164,7 @@ message Conversation {
|
|||
string conversationID = 1;
|
||||
string name = 2;
|
||||
LatestMessage latestMessage = 4;
|
||||
int64 timestampMs = 5;
|
||||
int64 lastMessageTimestamp = 5;
|
||||
|
||||
bool isGroupChat = 10; // not certain
|
||||
string selfParticipantID = 11;
|
||||
|
@ -171,7 +175,7 @@ message Conversation {
|
|||
string latestMessageID = 17;
|
||||
repeated Participant participants = 20;
|
||||
repeated string otherParticipants = 21; // participant ids excluding me
|
||||
int64 type = 22;
|
||||
ConversationType type = 22;
|
||||
bool subType = 24;
|
||||
bool thirdType = 29;
|
||||
}
|
||||
|
@ -211,7 +215,13 @@ message LatestMessageStatus {
|
|||
}
|
||||
|
||||
message Muted {
|
||||
bool isMuted = 1;
|
||||
int64 isMuted = 1;
|
||||
}
|
||||
|
||||
enum ConversationType {
|
||||
UNKNOWN_CONVERSATION_TYPE = 0;
|
||||
SMS = 1;
|
||||
RCS = 2;
|
||||
}
|
||||
|
||||
enum MessageStatusType {
|
||||
|
|
|
@ -189,12 +189,14 @@ enum ActionType {
|
|||
LIST_MESSAGES = 2;
|
||||
SEND_MESSAGE = 3;
|
||||
LIST_CONVERSATIONS_SYNC = 1111;
|
||||
UPDATE_CONVERSATION = 15;
|
||||
GET_UPDATES = 16;
|
||||
GET_CONVERSATION_TYPE = 21;
|
||||
NOTIFY_DITTO_ACTIVITY = 22;
|
||||
DELETE_MESSAGE = 23;
|
||||
RESEND_MESSAGE = 25;
|
||||
IS_BUGLE_DEFAULT = 31;
|
||||
GET_PARTICIPANTS_THUMBNAIL = 37;
|
||||
SEND_REACTION = 38;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,21 @@ import "events.proto";
|
|||
import "messages.proto";
|
||||
import "conversations.proto";
|
||||
|
||||
message ParticipantThumbnail {
|
||||
repeated Thumbnail thumbnail = 1;
|
||||
}
|
||||
|
||||
message Thumbnail {
|
||||
string participantId = 1;
|
||||
ThumbnailData data = 2;
|
||||
}
|
||||
|
||||
message ThumbnailData {
|
||||
bytes imageBuffer = 3;
|
||||
int32 someInt = 4;
|
||||
conversations.Pixels pixels = 5;
|
||||
}
|
||||
|
||||
message RegisterRefreshResponse {
|
||||
RefreshAuthData tokenData = 2;
|
||||
}
|
||||
|
@ -91,7 +106,3 @@ message AuthKeyData {
|
|||
bytes tachyonAuthToken = 1;
|
||||
int64 validFor = 2;
|
||||
}
|
||||
|
||||
enum ConversationType {
|
||||
UNKNOWN_CONVERSATION_TYPE = 0;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -122,3 +122,53 @@ func (c *Conversations) SendMessage(messageBuilder *MessageBuilder) (*binary.Sen
|
|||
c.client.Logger.Debug().Any("res", res).Msg("sent message!")
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (c *Conversations) GetParticipantThumbnail(convID string) (*binary.ParticipantThumbnail, error) {
|
||||
payload := &binary.GetParticipantThumbnailPayload{ConversationID: convID}
|
||||
actionType := binary.ActionType_GET_PARTICIPANTS_THUMBNAIL
|
||||
|
||||
sentRequestId, sendErr := c.client.sessionHandler.completeSendMessage(actionType, true, payload)
|
||||
if sendErr != nil {
|
||||
return nil, sendErr
|
||||
}
|
||||
|
||||
response, err := c.client.sessionHandler.WaitForResponse(sentRequestId, actionType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res, ok := response.Data.Decrypted.(*binary.ParticipantThumbnail)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("failed to assert response into ParticipantThumbnail")
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (c *Conversations) Update(convBuilder *ConversationBuilder) (*binary.UpdateConversationResponse, error) {
|
||||
data := &binary.UpdateConversationPayload{}
|
||||
|
||||
payload, buildErr := convBuilder.Build(data)
|
||||
if buildErr != nil {
|
||||
panic(buildErr)
|
||||
}
|
||||
|
||||
actionType := binary.ActionType_UPDATE_CONVERSATION
|
||||
|
||||
sentRequestId, sendErr := c.client.sessionHandler.completeSendMessage(actionType, true, payload)
|
||||
if sendErr != nil {
|
||||
return nil, sendErr
|
||||
}
|
||||
|
||||
response, err := c.client.sessionHandler.WaitForResponse(sentRequestId, actionType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res, ok := response.Data.Decrypted.(*binary.UpdateConversationResponse)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("failed to assert response into UpdateConversationResponse")
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
|
|
@ -28,3 +28,21 @@ var GET_CONVERSATION_TYPE = Route{
|
|||
UseSessionID: false,
|
||||
UseTTL: true,
|
||||
}
|
||||
|
||||
var GET_PARTICIPANT_THUMBNAIL = Route{
|
||||
Action: binary.ActionType_GET_PARTICIPANTS_THUMBNAIL,
|
||||
MessageType: binary.MessageType_BUGLE_MESSAGE,
|
||||
BugleRoute: binary.BugleRoute_DataEvent,
|
||||
ResponseStruct: &binary.ParticipantThumbnail{},
|
||||
UseSessionID: false,
|
||||
UseTTL: true,
|
||||
}
|
||||
|
||||
var UPDATE_CONVERSATION = Route{
|
||||
Action: binary.ActionType_UPDATE_CONVERSATION,
|
||||
MessageType: binary.MessageType_BUGLE_MESSAGE,
|
||||
BugleRoute: binary.BugleRoute_DataEvent,
|
||||
ResponseStruct: &binary.UpdateConversationResponse{},
|
||||
UseSessionID: false,
|
||||
UseTTL: true,
|
||||
}
|
||||
|
|
|
@ -16,14 +16,15 @@ type Route struct {
|
|||
}
|
||||
|
||||
var Routes = map[binary.ActionType]Route{
|
||||
binary.ActionType_IS_BUGLE_DEFAULT: IS_BUGLE_DEFAULT,
|
||||
binary.ActionType_GET_UPDATES: GET_UPDATES,
|
||||
binary.ActionType_LIST_CONVERSATIONS: LIST_CONVERSATIONS,
|
||||
binary.ActionType_LIST_CONVERSATIONS_SYNC: LIST_CONVERSATIONS_WITH_UPDATES,
|
||||
binary.ActionType_NOTIFY_DITTO_ACTIVITY: NOTIFY_DITTO_ACTIVITY,
|
||||
binary.ActionType_GET_CONVERSATION_TYPE: GET_CONVERSATION_TYPE,
|
||||
binary.ActionType_LIST_MESSAGES: LIST_MESSAGES,
|
||||
binary.ActionType_SEND_MESSAGE: SEND_MESSAGE,
|
||||
binary.ActionType_SEND_REACTION: SEND_REACTION,
|
||||
binary.ActionType_DELETE_MESSAGE: DELETE_MESSAGE,
|
||||
binary.ActionType_IS_BUGLE_DEFAULT: IS_BUGLE_DEFAULT,
|
||||
binary.ActionType_GET_UPDATES: GET_UPDATES,
|
||||
binary.ActionType_LIST_CONVERSATIONS: LIST_CONVERSATIONS,
|
||||
binary.ActionType_LIST_CONVERSATIONS_SYNC: LIST_CONVERSATIONS_WITH_UPDATES,
|
||||
binary.ActionType_NOTIFY_DITTO_ACTIVITY: NOTIFY_DITTO_ACTIVITY,
|
||||
binary.ActionType_GET_CONVERSATION_TYPE: GET_CONVERSATION_TYPE,
|
||||
binary.ActionType_LIST_MESSAGES: LIST_MESSAGES,
|
||||
binary.ActionType_SEND_MESSAGE: SEND_MESSAGE,
|
||||
binary.ActionType_SEND_REACTION: SEND_REACTION,
|
||||
binary.ActionType_DELETE_MESSAGE: DELETE_MESSAGE,
|
||||
binary.ActionType_GET_PARTICIPANTS_THUMBNAIL: GET_PARTICIPANT_THUMBNAIL,
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue