From aec24efbe2a41c17104ea98ad9e35463b16d5d80 Mon Sep 17 00:00:00 2001
From: trilene <trilene@runbox.com>
Date: Fri, 24 Jul 2020 13:30:12 -0400
Subject: [PATCH] Specify call type on timeline

---
 resources/langs/nheko_en.ts                 |  4 ++--
 resources/qml/delegates/MessageDelegate.qml |  2 +-
 src/EventAccessors.cpp                      | 24 +++++++++++++++++++++
 src/EventAccessors.h                        |  3 +++
 src/timeline/TimelineModel.cpp              |  4 ++++
 src/timeline/TimelineModel.h                |  1 +
 6 files changed, 35 insertions(+), 3 deletions(-)

diff --git a/resources/langs/nheko_en.ts b/resources/langs/nheko_en.ts
index 27d739f2f..f2bb04f9a 100644
--- a/resources/langs/nheko_en.ts
+++ b/resources/langs/nheko_en.ts
@@ -406,8 +406,8 @@ Example: https://server.my:8787</translation>
     </message>
     <message>
         <location line="+6"/>
-        <source>%1 placed a voice call.</source>
-        <translation>%1 placed a voice call.</translation>
+        <source>%1 placed a %2 call.</source>
+        <translation>%1 placed a %2 call.</translation>
     </message>
     <message>
         <location line="+6"/>
diff --git a/resources/qml/delegates/MessageDelegate.qml b/resources/qml/delegates/MessageDelegate.qml
index 52e628be9..ed18b2e5d 100644
--- a/resources/qml/delegates/MessageDelegate.qml
+++ b/resources/qml/delegates/MessageDelegate.qml
@@ -93,7 +93,7 @@ Item {
 		DelegateChoice {
 			roleValue: MtxEvent.CallInvite
 			NoticeMessage {
-				text: qsTr("%1 placed a voice call.").arg(model.data.userName)
+				text: qsTr("%1 placed a %2 call.").arg(model.data.userName).arg(model.data.callType)
 			}
 		}
 		DelegateChoice {
diff --git a/src/EventAccessors.cpp b/src/EventAccessors.cpp
index 7071819b0..043e24a26 100644
--- a/src/EventAccessors.cpp
+++ b/src/EventAccessors.cpp
@@ -1,5 +1,7 @@
 #include "EventAccessors.h"
 
+#include <algorithm>
+#include <cctype>
 #include <type_traits>
 
 namespace {
@@ -65,6 +67,22 @@ struct EventRoomTopic
         }
 };
 
+struct CallType
+{
+        template<class T>
+        std::string operator()(const T &e)
+        {
+                if constexpr (std::is_same_v<mtx::events::RoomEvent<mtx::events::msg::CallInvite>, T>) {
+                  const char video[] = "m=video";
+                  const std::string &sdp = e.content.sdp;
+                  return std::search(sdp.cbegin(), sdp.cend(), std::cbegin(video), std::cend(video) - 1,
+                    [](unsigned char c1, unsigned char c2) {return std::tolower(c1) == std::tolower(c2);})
+                      != sdp.cend() ? "video" : "voice";
+                }
+                return std::string();
+        }
+};
+
 struct EventBody
 {
         template<class C>
@@ -325,6 +343,12 @@ mtx::accessors::room_topic(const mtx::events::collections::TimelineEvents &event
         return std::visit(EventRoomTopic{}, event);
 }
 
+std::string
+mtx::accessors::call_type(const mtx::events::collections::TimelineEvents &event)
+{
+        return std::visit(CallType{}, event);
+}
+
 std::string
 mtx::accessors::body(const mtx::events::collections::TimelineEvents &event)
 {
diff --git a/src/EventAccessors.h b/src/EventAccessors.h
index a7577d863..fa70f3eb6 100644
--- a/src/EventAccessors.h
+++ b/src/EventAccessors.h
@@ -30,6 +30,9 @@ room_name(const mtx::events::collections::TimelineEvents &event);
 std::string
 room_topic(const mtx::events::collections::TimelineEvents &event);
 
+std::string
+call_type(const mtx::events::collections::TimelineEvents &event);
+
 std::string
 body(const mtx::events::collections::TimelineEvents &event);
 
diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp
index 8d68f24cf..e4677f538 100644
--- a/src/timeline/TimelineModel.cpp
+++ b/src/timeline/TimelineModel.cpp
@@ -282,6 +282,7 @@ TimelineModel::roleNames() const
           {RoomId, "roomId"},
           {RoomName, "roomName"},
           {RoomTopic, "roomTopic"},
+          {CallType, "callType"},
           {Dump, "dump"},
         };
 }
@@ -435,6 +436,8 @@ TimelineModel::data(const QString &id, int role) const
                 return QVariant(QString::fromStdString(room_name(event)));
         case RoomTopic:
                 return QVariant(QString::fromStdString(room_topic(event)));
+        case CallType:
+                return QVariant(QString::fromStdString(call_type(event)));
         case Dump: {
                 QVariantMap m;
                 auto names = roleNames();
@@ -464,6 +467,7 @@ TimelineModel::data(const QString &id, int role) const
                 m.insert(names[ReplyTo], data(id, static_cast<int>(ReplyTo)));
                 m.insert(names[RoomName], data(id, static_cast<int>(RoomName)));
                 m.insert(names[RoomTopic], data(id, static_cast<int>(RoomTopic)));
+                m.insert(names[CallType], data(id, static_cast<int>(CallType)));
 
                 return QVariant(m);
         }
diff --git a/src/timeline/TimelineModel.h b/src/timeline/TimelineModel.h
index ed7036c76..95584d369 100644
--- a/src/timeline/TimelineModel.h
+++ b/src/timeline/TimelineModel.h
@@ -170,6 +170,7 @@ public:
                 RoomId,
                 RoomName,
                 RoomTopic,
+                CallType,
                 Dump,
         };
 
-- 
GitLab