morpheus

A Matrix client written in Go-QT
git clone git://archive.git.mtrnord.blog/Nordgedanken/morpheus.git
Log | Files | Refs | README | LICENSE

commit 7df3958f0519ef07eefe31fb2c7d71848cca35c3
parent abd7218ba40261da41f58576047cee7c17fd7ded
Author: MTRNord <mtrnord1@gmail.com>
Date:   Fri, 20 Oct 2017 18:32:12 +0200

Generate RoomList

Signed-off-by: MTRNord <mtrnord1@gmail.com>

Diffstat:
Melements/messageList.go | 70+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
Melements/moc.cpp | 102++++++++++++++++++++++++++++++++++++++++----------------------------------------
Melements/moc.go | 41++++++++++++++++++-----------------------
Melements/moc.h | 2+-
Melements/moc_moc.h | 105+++++++++++++++++++++++++++++++++++++++----------------------------------------
Melements/roomlist.go | 42+++++++++++++++++++-----------------------
Mmain.go | 8++++----
Mmatrix/db.go | 25+++++++++----------------
Mmatrix/login.go | 22+++++++++-------------
Amatrix/rooms.go | 178+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mmatrix/types.go | 47+++++++++++++++++++++++++++++++++--------------
Mmatrix/user.go | 21+++++++++++----------
Mqml/ui/chat.ui | 4++--
Mqml/ui/ownmessage.ui | 283+++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------
Aqml/ui/room.ui | 200+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mui/LoginUI.go | 3++-
Mui/MainUI.go | 85+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------
Mui/types.go | 13+++++++++----
18 files changed, 923 insertions(+), 328 deletions(-)

diff --git a/elements/messageList.go b/elements/messageList.go @@ -2,13 +2,14 @@ package elements import ( "fmt" + "time" + "github.com/Nordgedanken/Morpheus/matrix" "github.com/matrix-org/gomatrix" "github.com/rhinoman/go-commonmark" "github.com/therecipe/qt/core" "github.com/therecipe/qt/uitools" "github.com/therecipe/qt/widgets" - "time" ) //////////////////////////////////////////////////// @@ -86,6 +87,73 @@ func (messageViewLayout *QVBoxLayoutWithTriggerSlot) NewMessage(body string, cli timestampContent.SetText(timestampString) avatarLogo.SetPixmap(avatar) + var lineLength int + lineLength = messageContent.FontMetrics().Width(messageContent.Text(), -1) - 87 + fmt.Println(scrollArea.Widget().Size().Width()) + fmt.Println("lineLengthO: ", lineLength) + if lineLength >= scrollArea.Widget().Size().Width() { + lineLength = scrollArea.Widget().Size().Width() - 20 - 87 + } + fmt.Println("lineLengthN: ", lineLength) + + messageContent.SetMinimumWidth(lineLength + 10) + + messageWidget.SetMinimumWidth(lineLength) + messageWidget.Resize2(lineLength, wrapperWidget.Size().Height()) + + messageViewLayout.SetSpacing(1) + messageViewLayout.SetContentsMargins(0, 0, 0, 0) + + messageViewLayout.AddWidget(messageWidget, 0, core.Qt__AlignBottom) + scrollArea.Widget().SetLayout(messageViewLayout) + + return +} + +// NewOwnMessage adds a new message object to the view +func (messageViewLayout *QVBoxLayoutWithTriggerSlot) NewOwnMessage(body string, cli *gomatrix.Client, sender string, timestamp int64, scrollArea *widgets.QScrollArea) (err error) { + avatar, AvatarErr := matrix.GetUserAvatar(cli, sender, 61) + if AvatarErr != nil { + err = AvatarErr + return + } + + var widget = widgets.NewQWidget(nil, 0) + + var loader = uitools.NewQUiLoader(nil) + var file = core.NewQFile2(":/qml/ui/ownmessage.ui") + + file.Open(core.QIODevice__ReadOnly) + var wrapperWidget = loader.Load(file, widget) + file.Close() + + timestampFormat := time.Unix(0, int64(timestamp)*int64(time.Millisecond)) + timestampString := timestampFormat.Format("15:04:05 - Mon 2.01.2006") + + messageWidget := widgets.NewQWidgetFromPointer(widget.FindChild("message", core.Qt__FindChildrenRecursively).Pointer()) + avatarLogo := widgets.NewQLabelFromPointer(widget.FindChild("avatar", core.Qt__FindChildrenRecursively).Pointer()) + messageContent := widgets.NewQLabelFromPointer(widget.FindChild("messageContent", core.Qt__FindChildrenRecursively).Pointer()) + timestampContent := widgets.NewQLabelFromPointer(widget.FindChild("timestamp", core.Qt__FindChildrenRecursively).Pointer()) + senderContent := widgets.NewQLabelFromPointer(widget.FindChild("sender", core.Qt__FindChildrenRecursively).Pointer()) + + markdownMessage := commonmark.Md2Html(body, 0) + + messageContent.SetText(markdownMessage) + + senderDisplayNameResp, _ := cli.GetDisplayName(sender) + var senderDisplayName string + if senderDisplayNameResp == nil { + senderDisplayName = sender + } else if senderDisplayNameResp.DisplayName == "" { + senderDisplayName = sender + } else { + senderDisplayName = senderDisplayNameResp.DisplayName + } + fmt.Println(senderDisplayName) + senderContent.SetText(senderDisplayName) + timestampContent.SetText(timestampString) + avatarLogo.SetPixmap(avatar) + messageContent.SetMinimumWidth(messageContent.LineWidth()) messageWidget.SetMinimumWidth(messageContent.LineWidth() + 100) diff --git a/elements/moc.cpp b/elements/moc.cpp @@ -27,6 +27,55 @@ #include <QWidget> +class QRoomVBoxLayoutWithTriggerSlot: public QVBoxLayout +{ +Q_OBJECT +public: + QRoomVBoxLayoutWithTriggerSlot() : QVBoxLayout() {qRegisterMetaType<quintptr>("quintptr");QRoomVBoxLayoutWithTriggerSlot_QRoomVBoxLayoutWithTriggerSlot_QRegisterMetaType();QRoomVBoxLayoutWithTriggerSlot_QRoomVBoxLayoutWithTriggerSlot_QRegisterMetaTypes();callbackQRoomVBoxLayoutWithTriggerSlot_Constructor(this);}; + QRoomVBoxLayoutWithTriggerSlot(QWidget *parent) : QVBoxLayout(parent) {qRegisterMetaType<quintptr>("quintptr");QRoomVBoxLayoutWithTriggerSlot_QRoomVBoxLayoutWithTriggerSlot_QRegisterMetaType();QRoomVBoxLayoutWithTriggerSlot_QRoomVBoxLayoutWithTriggerSlot_QRegisterMetaTypes();callbackQRoomVBoxLayoutWithTriggerSlot_Constructor(this);}; + QLayoutItem * takeAt(int index) { return static_cast<QLayoutItem*>(callbackQRoomVBoxLayoutWithTriggerSlot_TakeAt(this, index)); }; + void addItem(QLayoutItem * item) { callbackQRoomVBoxLayoutWithTriggerSlot_AddItem(this, item); }; + void invalidate() { callbackQRoomVBoxLayoutWithTriggerSlot_Invalidate(this); }; + void setGeometry(const QRect & r) { callbackQRoomVBoxLayoutWithTriggerSlot_SetGeometry(this, const_cast<QRect*>(&r)); }; + QLayoutItem * itemAt(int index) const { return static_cast<QLayoutItem*>(callbackQRoomVBoxLayoutWithTriggerSlot_ItemAt(const_cast<void*>(static_cast<const void*>(this)), index)); }; + QSize maximumSize() const { return *static_cast<QSize*>(callbackQRoomVBoxLayoutWithTriggerSlot_MaximumSize(const_cast<void*>(static_cast<const void*>(this)))); }; + QSize minimumSize() const { return *static_cast<QSize*>(callbackQRoomVBoxLayoutWithTriggerSlot_MinimumSize(const_cast<void*>(static_cast<const void*>(this)))); }; + QSize sizeHint() const { return *static_cast<QSize*>(callbackQRoomVBoxLayoutWithTriggerSlot_SizeHint(const_cast<void*>(static_cast<const void*>(this)))); }; + Qt::Orientations expandingDirections() const { return static_cast<Qt::Orientation>(callbackQRoomVBoxLayoutWithTriggerSlot_ExpandingDirections(const_cast<void*>(static_cast<const void*>(this)))); }; + bool hasHeightForWidth() const { return callbackQRoomVBoxLayoutWithTriggerSlot_HasHeightForWidth(const_cast<void*>(static_cast<const void*>(this))) != 0; }; + int count() const { return callbackQRoomVBoxLayoutWithTriggerSlot_Count(const_cast<void*>(static_cast<const void*>(this))); }; + int heightForWidth(int w) const { return callbackQRoomVBoxLayoutWithTriggerSlot_HeightForWidth(const_cast<void*>(static_cast<const void*>(this)), w); }; + int minimumHeightForWidth(int w) const { return callbackQRoomVBoxLayoutWithTriggerSlot_MinimumHeightForWidth(const_cast<void*>(static_cast<const void*>(this)), w); }; + QLayout * layout() { return static_cast<QLayout*>(callbackQRoomVBoxLayoutWithTriggerSlot_Layout(this)); }; + void childEvent(QChildEvent * e) { callbackQRoomVBoxLayoutWithTriggerSlot_ChildEvent(this, e); }; + QRect geometry() const { return *static_cast<QRect*>(callbackQRoomVBoxLayoutWithTriggerSlot_Geometry(const_cast<void*>(static_cast<const void*>(this)))); }; + QSizePolicy::ControlTypes controlTypes() const { return static_cast<QSizePolicy::ControlType>(callbackQRoomVBoxLayoutWithTriggerSlot_ControlTypes(const_cast<void*>(static_cast<const void*>(this)))); }; + bool isEmpty() const { return callbackQRoomVBoxLayoutWithTriggerSlot_IsEmpty(const_cast<void*>(static_cast<const void*>(this))) != 0; }; + int indexOf(QWidget * widget) const { return callbackQRoomVBoxLayoutWithTriggerSlot_IndexOf(const_cast<void*>(static_cast<const void*>(this)), widget); }; + bool event(QEvent * e) { return callbackQRoomVBoxLayoutWithTriggerSlot_Event(this, e) != 0; }; + bool eventFilter(QObject * watched, QEvent * event) { return callbackQRoomVBoxLayoutWithTriggerSlot_EventFilter(this, watched, event) != 0; }; + void connectNotify(const QMetaMethod & sign) { callbackQRoomVBoxLayoutWithTriggerSlot_ConnectNotify(this, const_cast<QMetaMethod*>(&sign)); }; + void customEvent(QEvent * event) { callbackQRoomVBoxLayoutWithTriggerSlot_CustomEvent(this, event); }; + void deleteLater() { callbackQRoomVBoxLayoutWithTriggerSlot_DeleteLater(this); }; + void Signal_Destroyed(QObject * obj) { callbackQRoomVBoxLayoutWithTriggerSlot_Destroyed(this, obj); }; + void disconnectNotify(const QMetaMethod & sign) { callbackQRoomVBoxLayoutWithTriggerSlot_DisconnectNotify(this, const_cast<QMetaMethod*>(&sign)); }; + void Signal_ObjectNameChanged(const QString & objectName) { QByteArray taa2c4f = objectName.toUtf8(); Moc_PackedString objectNamePacked = { const_cast<char*>(taa2c4f.prepend("WHITESPACE").constData()+10), taa2c4f.size()-10 };callbackQRoomVBoxLayoutWithTriggerSlot_ObjectNameChanged(this, objectNamePacked); }; + void timerEvent(QTimerEvent * event) { callbackQRoomVBoxLayoutWithTriggerSlot_TimerEvent(this, event); }; + + QSpacerItem * spacerItem() { return static_cast<QSpacerItem*>(callbackQRoomVBoxLayoutWithTriggerSlot_SpacerItem(this)); }; + QWidget * widget() { return static_cast<QWidget*>(callbackQRoomVBoxLayoutWithTriggerSlot_Widget(this)); }; +signals: +public slots: + void TriggerRoom(QString roomID) { QByteArray tdf131c = roomID.toUtf8(); Moc_PackedString roomIDPacked = { const_cast<char*>(tdf131c.prepend("WHITESPACE").constData()+10), tdf131c.size()-10 };callbackQRoomVBoxLayoutWithTriggerSlot_TriggerRoom(this, roomIDPacked); }; +private: +}; + +Q_DECLARE_METATYPE(QRoomVBoxLayoutWithTriggerSlot*) + + +void QRoomVBoxLayoutWithTriggerSlot_QRoomVBoxLayoutWithTriggerSlot_QRegisterMetaTypes() { +} + class QVBoxLayoutWithTriggerSlot: public QVBoxLayout { Q_OBJECT @@ -76,58 +125,9 @@ Q_DECLARE_METATYPE(QVBoxLayoutWithTriggerSlot*) void QVBoxLayoutWithTriggerSlot_QVBoxLayoutWithTriggerSlot_QRegisterMetaTypes() { } -class QRoomVBoxLayoutWithTriggerSlot: public QVBoxLayout -{ -Q_OBJECT -public: - QRoomVBoxLayoutWithTriggerSlot() : QVBoxLayout() {qRegisterMetaType<quintptr>("quintptr");QRoomVBoxLayoutWithTriggerSlot_QRoomVBoxLayoutWithTriggerSlot_QRegisterMetaType();QRoomVBoxLayoutWithTriggerSlot_QRoomVBoxLayoutWithTriggerSlot_QRegisterMetaTypes();callbackQRoomVBoxLayoutWithTriggerSlot_Constructor(this);}; - QRoomVBoxLayoutWithTriggerSlot(QWidget *parent) : QVBoxLayout(parent) {qRegisterMetaType<quintptr>("quintptr");QRoomVBoxLayoutWithTriggerSlot_QRoomVBoxLayoutWithTriggerSlot_QRegisterMetaType();QRoomVBoxLayoutWithTriggerSlot_QRoomVBoxLayoutWithTriggerSlot_QRegisterMetaTypes();callbackQRoomVBoxLayoutWithTriggerSlot_Constructor(this);}; - QLayoutItem * takeAt(int index) { return static_cast<QLayoutItem*>(callbackQRoomVBoxLayoutWithTriggerSlot_TakeAt(this, index)); }; - void addItem(QLayoutItem * item) { callbackQRoomVBoxLayoutWithTriggerSlot_AddItem(this, item); }; - void invalidate() { callbackQRoomVBoxLayoutWithTriggerSlot_Invalidate(this); }; - void setGeometry(const QRect & r) { callbackQRoomVBoxLayoutWithTriggerSlot_SetGeometry(this, const_cast<QRect*>(&r)); }; - QLayoutItem * itemAt(int index) const { return static_cast<QLayoutItem*>(callbackQRoomVBoxLayoutWithTriggerSlot_ItemAt(const_cast<void*>(static_cast<const void*>(this)), index)); }; - QSize maximumSize() const { return *static_cast<QSize*>(callbackQRoomVBoxLayoutWithTriggerSlot_MaximumSize(const_cast<void*>(static_cast<const void*>(this)))); }; - QSize minimumSize() const { return *static_cast<QSize*>(callbackQRoomVBoxLayoutWithTriggerSlot_MinimumSize(const_cast<void*>(static_cast<const void*>(this)))); }; - QSize sizeHint() const { return *static_cast<QSize*>(callbackQRoomVBoxLayoutWithTriggerSlot_SizeHint(const_cast<void*>(static_cast<const void*>(this)))); }; - Qt::Orientations expandingDirections() const { return static_cast<Qt::Orientation>(callbackQRoomVBoxLayoutWithTriggerSlot_ExpandingDirections(const_cast<void*>(static_cast<const void*>(this)))); }; - bool hasHeightForWidth() const { return callbackQRoomVBoxLayoutWithTriggerSlot_HasHeightForWidth(const_cast<void*>(static_cast<const void*>(this))) != 0; }; - int count() const { return callbackQRoomVBoxLayoutWithTriggerSlot_Count(const_cast<void*>(static_cast<const void*>(this))); }; - int heightForWidth(int w) const { return callbackQRoomVBoxLayoutWithTriggerSlot_HeightForWidth(const_cast<void*>(static_cast<const void*>(this)), w); }; - int minimumHeightForWidth(int w) const { return callbackQRoomVBoxLayoutWithTriggerSlot_MinimumHeightForWidth(const_cast<void*>(static_cast<const void*>(this)), w); }; - QLayout * layout() { return static_cast<QLayout*>(callbackQRoomVBoxLayoutWithTriggerSlot_Layout(this)); }; - void childEvent(QChildEvent * e) { callbackQRoomVBoxLayoutWithTriggerSlot_ChildEvent(this, e); }; - QRect geometry() const { return *static_cast<QRect*>(callbackQRoomVBoxLayoutWithTriggerSlot_Geometry(const_cast<void*>(static_cast<const void*>(this)))); }; - QSizePolicy::ControlTypes controlTypes() const { return static_cast<QSizePolicy::ControlType>(callbackQRoomVBoxLayoutWithTriggerSlot_ControlTypes(const_cast<void*>(static_cast<const void*>(this)))); }; - bool isEmpty() const { return callbackQRoomVBoxLayoutWithTriggerSlot_IsEmpty(const_cast<void*>(static_cast<const void*>(this))) != 0; }; - int indexOf(QWidget * widget) const { return callbackQRoomVBoxLayoutWithTriggerSlot_IndexOf(const_cast<void*>(static_cast<const void*>(this)), widget); }; - bool event(QEvent * e) { return callbackQRoomVBoxLayoutWithTriggerSlot_Event(this, e) != 0; }; - bool eventFilter(QObject * watched, QEvent * event) { return callbackQRoomVBoxLayoutWithTriggerSlot_EventFilter(this, watched, event) != 0; }; - void connectNotify(const QMetaMethod & sign) { callbackQRoomVBoxLayoutWithTriggerSlot_ConnectNotify(this, const_cast<QMetaMethod*>(&sign)); }; - void customEvent(QEvent * event) { callbackQRoomVBoxLayoutWithTriggerSlot_CustomEvent(this, event); }; - void deleteLater() { callbackQRoomVBoxLayoutWithTriggerSlot_DeleteLater(this); }; - void Signal_Destroyed(QObject * obj) { callbackQRoomVBoxLayoutWithTriggerSlot_Destroyed(this, obj); }; - void disconnectNotify(const QMetaMethod & sign) { callbackQRoomVBoxLayoutWithTriggerSlot_DisconnectNotify(this, const_cast<QMetaMethod*>(&sign)); }; - void Signal_ObjectNameChanged(const QString & objectName) { QByteArray taa2c4f = objectName.toUtf8(); Moc_PackedString objectNamePacked = { const_cast<char*>(taa2c4f.prepend("WHITESPACE").constData()+10), taa2c4f.size()-10 };callbackQRoomVBoxLayoutWithTriggerSlot_ObjectNameChanged(this, objectNamePacked); }; - void timerEvent(QTimerEvent * event) { callbackQRoomVBoxLayoutWithTriggerSlot_TimerEvent(this, event); }; - - QSpacerItem * spacerItem() { return static_cast<QSpacerItem*>(callbackQRoomVBoxLayoutWithTriggerSlot_SpacerItem(this)); }; - QWidget * widget() { return static_cast<QWidget*>(callbackQRoomVBoxLayoutWithTriggerSlot_Widget(this)); }; -signals: -public slots: - void TriggerMessage(QString messageBody, QString sender) { QByteArray t59bf16 = messageBody.toUtf8(); Moc_PackedString messageBodyPacked = { const_cast<char*>(t59bf16.prepend("WHITESPACE").constData()+10), t59bf16.size()-10 };QByteArray tacc6a3 = sender.toUtf8(); Moc_PackedString senderPacked = { const_cast<char*>(tacc6a3.prepend("WHITESPACE").constData()+10), tacc6a3.size()-10 };callbackQRoomVBoxLayoutWithTriggerSlot_TriggerMessage(this, messageBodyPacked, senderPacked); }; -private: -}; - -Q_DECLARE_METATYPE(QRoomVBoxLayoutWithTriggerSlot*) - - -void QRoomVBoxLayoutWithTriggerSlot_QRoomVBoxLayoutWithTriggerSlot_QRegisterMetaTypes() { -} - -void QRoomVBoxLayoutWithTriggerSlot_TriggerMessage(void* ptr, struct Moc_PackedString messageBody, struct Moc_PackedString sender) +void QRoomVBoxLayoutWithTriggerSlot_TriggerRoom(void* ptr, struct Moc_PackedString roomID) { - QMetaObject::invokeMethod(static_cast<QRoomVBoxLayoutWithTriggerSlot*>(ptr), "TriggerMessage", Q_ARG(QString, QString::fromUtf8(messageBody.data, messageBody.len)), Q_ARG(QString, QString::fromUtf8(sender.data, sender.len))); + QMetaObject::invokeMethod(static_cast<QRoomVBoxLayoutWithTriggerSlot*>(ptr), "TriggerRoom", Q_ARG(QString, QString::fromUtf8(roomID.data, roomID.len))); } int QRoomVBoxLayoutWithTriggerSlot_QRoomVBoxLayoutWithTriggerSlot_QRegisterMetaType() diff --git a/elements/moc.go b/elements/moc.go @@ -77,48 +77,43 @@ func callbackQRoomVBoxLayoutWithTriggerSlot_Constructor(ptr unsafe.Pointer) { qt.Register(ptr, gPtr) } -//export callbackQRoomVBoxLayoutWithTriggerSlot_TriggerMessage -func callbackQRoomVBoxLayoutWithTriggerSlot_TriggerMessage(ptr unsafe.Pointer, messageBody C.struct_Moc_PackedString, sender C.struct_Moc_PackedString) { - if signal := qt.GetSignal(ptr, "TriggerMessage"); signal != nil { - signal.(func(string, string))(cGoUnpackString(messageBody), cGoUnpackString(sender)) +//export callbackQRoomVBoxLayoutWithTriggerSlot_TriggerRoom +func callbackQRoomVBoxLayoutWithTriggerSlot_TriggerRoom(ptr unsafe.Pointer, roomID C.struct_Moc_PackedString) { + if signal := qt.GetSignal(ptr, "TriggerRoom"); signal != nil { + signal.(func(string))(cGoUnpackString(roomID)) } } -func (ptr *QRoomVBoxLayoutWithTriggerSlot) ConnectTriggerMessage(f func(messageBody string, sender string)) { +func (ptr *QRoomVBoxLayoutWithTriggerSlot) ConnectTriggerRoom(f func(roomID string)) { if ptr.Pointer() != nil { - if signal := qt.LendSignal(ptr.Pointer(), "TriggerMessage"); signal != nil { - qt.ConnectSignal(ptr.Pointer(), "TriggerMessage", func(messageBody string, sender string) { - signal.(func(string, string))(messageBody, sender) - f(messageBody, sender) + if signal := qt.LendSignal(ptr.Pointer(), "TriggerRoom"); signal != nil { + qt.ConnectSignal(ptr.Pointer(), "TriggerRoom", func(roomID string) { + signal.(func(string))(roomID) + f(roomID) }) } else { - qt.ConnectSignal(ptr.Pointer(), "TriggerMessage", f) + qt.ConnectSignal(ptr.Pointer(), "TriggerRoom", f) } } } -func (ptr *QRoomVBoxLayoutWithTriggerSlot) DisconnectTriggerMessage() { +func (ptr *QRoomVBoxLayoutWithTriggerSlot) DisconnectTriggerRoom() { if ptr.Pointer() != nil { - qt.DisconnectSignal(ptr.Pointer(), "TriggerMessage") + qt.DisconnectSignal(ptr.Pointer(), "TriggerRoom") } } -func (ptr *QRoomVBoxLayoutWithTriggerSlot) TriggerMessage(messageBody string, sender string) { +func (ptr *QRoomVBoxLayoutWithTriggerSlot) TriggerRoom(roomID string) { if ptr.Pointer() != nil { - var messageBodyC *C.char - if messageBody != "" { - messageBodyC = C.CString(messageBody) - defer C.free(unsafe.Pointer(messageBodyC)) - } - var senderC *C.char - if sender != "" { - senderC = C.CString(sender) - defer C.free(unsafe.Pointer(senderC)) + var roomIDC *C.char + if roomID != "" { + roomIDC = C.CString(roomID) + defer C.free(unsafe.Pointer(roomIDC)) } - C.QRoomVBoxLayoutWithTriggerSlot_TriggerMessage(ptr.Pointer(), C.struct_Moc_PackedString{data: messageBodyC, len: C.longlong(len(messageBody))}, C.struct_Moc_PackedString{data: senderC, len: C.longlong(len(sender))}) + C.QRoomVBoxLayoutWithTriggerSlot_TriggerRoom(ptr.Pointer(), C.struct_Moc_PackedString{data: roomIDC, len: C.longlong(len(roomID))}) } } diff --git a/elements/moc.h b/elements/moc.h @@ -17,7 +17,7 @@ extern "C" { struct Moc_PackedString { char* data; long long len; }; struct Moc_PackedList { void* data; long long len; }; -void QRoomVBoxLayoutWithTriggerSlot_TriggerMessage(void* ptr, struct Moc_PackedString messageBody, struct Moc_PackedString sender); +void QRoomVBoxLayoutWithTriggerSlot_TriggerRoom(void* ptr, struct Moc_PackedString roomID); int QRoomVBoxLayoutWithTriggerSlot_QRoomVBoxLayoutWithTriggerSlot_QRegisterMetaType(); int QRoomVBoxLayoutWithTriggerSlot_QRoomVBoxLayoutWithTriggerSlot_QRegisterMetaType2(char* typeName); int QRoomVBoxLayoutWithTriggerSlot_QRoomVBoxLayoutWithTriggerSlot_QmlRegisterType(); diff --git a/elements/moc_moc.h b/elements/moc_moc.h @@ -19,31 +19,29 @@ QT_BEGIN_MOC_NAMESPACE QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED -struct qt_meta_stringdata_QVBoxLayoutWithTriggerSlot_t { - QByteArrayData data[6]; - char stringdata0[72]; +struct qt_meta_stringdata_QRoomVBoxLayoutWithTriggerSlot_t { + QByteArrayData data[4]; + char stringdata0[51]; }; #define QT_MOC_LITERAL(idx, ofs, len) \ Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \ - qptrdiff(offsetof(qt_meta_stringdata_QVBoxLayoutWithTriggerSlot_t, stringdata0) + ofs \ + qptrdiff(offsetof(qt_meta_stringdata_QRoomVBoxLayoutWithTriggerSlot_t, stringdata0) + ofs \ - idx * sizeof(QByteArrayData)) \ ) -static const qt_meta_stringdata_QVBoxLayoutWithTriggerSlot_t qt_meta_stringdata_QVBoxLayoutWithTriggerSlot = { +static const qt_meta_stringdata_QRoomVBoxLayoutWithTriggerSlot_t qt_meta_stringdata_QRoomVBoxLayoutWithTriggerSlot = { { -QT_MOC_LITERAL(0, 0, 26), // "QVBoxLayoutWithTriggerSlot" -QT_MOC_LITERAL(1, 27, 14), // "TriggerMessage" -QT_MOC_LITERAL(2, 42, 0), // "" -QT_MOC_LITERAL(3, 43, 11), // "messageBody" -QT_MOC_LITERAL(4, 55, 6), // "sender" -QT_MOC_LITERAL(5, 62, 9) // "timestamp" +QT_MOC_LITERAL(0, 0, 30), // "QRoomVBoxLayoutWithTriggerSlot" +QT_MOC_LITERAL(1, 31, 11), // "TriggerRoom" +QT_MOC_LITERAL(2, 43, 0), // "" +QT_MOC_LITERAL(3, 44, 6) // "roomID" }, - "QVBoxLayoutWithTriggerSlot\0TriggerMessage\0" - "\0messageBody\0sender\0timestamp" + "QRoomVBoxLayoutWithTriggerSlot\0" + "TriggerRoom\0\0roomID" }; #undef QT_MOC_LITERAL -static const uint qt_meta_data_QVBoxLayoutWithTriggerSlot[] = { +static const uint qt_meta_data_QRoomVBoxLayoutWithTriggerSlot[] = { // content: 7, // revision @@ -57,46 +55,46 @@ static const uint qt_meta_data_QVBoxLayoutWithTriggerSlot[] = { 0, // signalCount // slots: name, argc, parameters, tag, flags - 1, 3, 19, 2, 0x0a /* Public */, + 1, 1, 19, 2, 0x0a /* Public */, // slots: parameters - QMetaType::Void, QMetaType::QString, QMetaType::QString, QMetaType::LongLong, 3, 4, 5, + QMetaType::Void, QMetaType::QString, 3, 0 // eod }; -void QVBoxLayoutWithTriggerSlot::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) +void QRoomVBoxLayoutWithTriggerSlot::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) { if (_c == QMetaObject::InvokeMetaMethod) { - QVBoxLayoutWithTriggerSlot *_t = static_cast<QVBoxLayoutWithTriggerSlot *>(_o); + QRoomVBoxLayoutWithTriggerSlot *_t = static_cast<QRoomVBoxLayoutWithTriggerSlot *>(_o); Q_UNUSED(_t) switch (_id) { - case 0: _t->TriggerMessage((*reinterpret_cast< QString(*)>(_a[1])),(*reinterpret_cast< QString(*)>(_a[2])),(*reinterpret_cast< qint64(*)>(_a[3]))); break; + case 0: _t->TriggerRoom((*reinterpret_cast< QString(*)>(_a[1]))); break; default: ; } } } -const QMetaObject QVBoxLayoutWithTriggerSlot::staticMetaObject = { - { &QVBoxLayout::staticMetaObject, qt_meta_stringdata_QVBoxLayoutWithTriggerSlot.data, - qt_meta_data_QVBoxLayoutWithTriggerSlot, qt_static_metacall, nullptr, nullptr} +const QMetaObject QRoomVBoxLayoutWithTriggerSlot::staticMetaObject = { + { &QVBoxLayout::staticMetaObject, qt_meta_stringdata_QRoomVBoxLayoutWithTriggerSlot.data, + qt_meta_data_QRoomVBoxLayoutWithTriggerSlot, qt_static_metacall, nullptr, nullptr} }; -const QMetaObject *QVBoxLayoutWithTriggerSlot::metaObject() const +const QMetaObject *QRoomVBoxLayoutWithTriggerSlot::metaObject() const { return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject; } -void *QVBoxLayoutWithTriggerSlot::qt_metacast(const char *_clname) +void *QRoomVBoxLayoutWithTriggerSlot::qt_metacast(const char *_clname) { if (!_clname) return nullptr; - if (!strcmp(_clname, qt_meta_stringdata_QVBoxLayoutWithTriggerSlot.stringdata0)) - return static_cast<void*>(const_cast< QVBoxLayoutWithTriggerSlot*>(this)); + if (!strcmp(_clname, qt_meta_stringdata_QRoomVBoxLayoutWithTriggerSlot.stringdata0)) + return static_cast<void*>(const_cast< QRoomVBoxLayoutWithTriggerSlot*>(this)); return QVBoxLayout::qt_metacast(_clname); } -int QVBoxLayoutWithTriggerSlot::qt_metacall(QMetaObject::Call _c, int _id, void **_a) +int QRoomVBoxLayoutWithTriggerSlot::qt_metacall(QMetaObject::Call _c, int _id, void **_a) { _id = QVBoxLayout::qt_metacall(_c, _id, _a); if (_id < 0) @@ -112,30 +110,31 @@ int QVBoxLayoutWithTriggerSlot::qt_metacall(QMetaObject::Call _c, int _id, void } return _id; } -struct qt_meta_stringdata_QRoomVBoxLayoutWithTriggerSlot_t { - QByteArrayData data[5]; - char stringdata0[66]; +struct qt_meta_stringdata_QVBoxLayoutWithTriggerSlot_t { + QByteArrayData data[6]; + char stringdata0[72]; }; #define QT_MOC_LITERAL(idx, ofs, len) \ Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \ - qptrdiff(offsetof(qt_meta_stringdata_QRoomVBoxLayoutWithTriggerSlot_t, stringdata0) + ofs \ + qptrdiff(offsetof(qt_meta_stringdata_QVBoxLayoutWithTriggerSlot_t, stringdata0) + ofs \ - idx * sizeof(QByteArrayData)) \ ) -static const qt_meta_stringdata_QRoomVBoxLayoutWithTriggerSlot_t qt_meta_stringdata_QRoomVBoxLayoutWithTriggerSlot = { +static const qt_meta_stringdata_QVBoxLayoutWithTriggerSlot_t qt_meta_stringdata_QVBoxLayoutWithTriggerSlot = { { -QT_MOC_LITERAL(0, 0, 30), // "QRoomVBoxLayoutWithTriggerSlot" -QT_MOC_LITERAL(1, 31, 14), // "TriggerMessage" -QT_MOC_LITERAL(2, 46, 0), // "" -QT_MOC_LITERAL(3, 47, 11), // "messageBody" -QT_MOC_LITERAL(4, 59, 6) // "sender" +QT_MOC_LITERAL(0, 0, 26), // "QVBoxLayoutWithTriggerSlot" +QT_MOC_LITERAL(1, 27, 14), // "TriggerMessage" +QT_MOC_LITERAL(2, 42, 0), // "" +QT_MOC_LITERAL(3, 43, 11), // "messageBody" +QT_MOC_LITERAL(4, 55, 6), // "sender" +QT_MOC_LITERAL(5, 62, 9) // "timestamp" }, - "QRoomVBoxLayoutWithTriggerSlot\0" - "TriggerMessage\0\0messageBody\0sender" + "QVBoxLayoutWithTriggerSlot\0TriggerMessage\0" + "\0messageBody\0sender\0timestamp" }; #undef QT_MOC_LITERAL -static const uint qt_meta_data_QRoomVBoxLayoutWithTriggerSlot[] = { +static const uint qt_meta_data_QVBoxLayoutWithTriggerSlot[] = { // content: 7, // revision @@ -149,46 +148,46 @@ static const uint qt_meta_data_QRoomVBoxLayoutWithTriggerSlot[] = { 0, // signalCount // slots: name, argc, parameters, tag, flags - 1, 2, 19, 2, 0x0a /* Public */, + 1, 3, 19, 2, 0x0a /* Public */, // slots: parameters - QMetaType::Void, QMetaType::QString, QMetaType::QString, 3, 4, + QMetaType::Void, QMetaType::QString, QMetaType::QString, QMetaType::LongLong, 3, 4, 5, 0 // eod }; -void QRoomVBoxLayoutWithTriggerSlot::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) +void QVBoxLayoutWithTriggerSlot::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) { if (_c == QMetaObject::InvokeMetaMethod) { - QRoomVBoxLayoutWithTriggerSlot *_t = static_cast<QRoomVBoxLayoutWithTriggerSlot *>(_o); + QVBoxLayoutWithTriggerSlot *_t = static_cast<QVBoxLayoutWithTriggerSlot *>(_o); Q_UNUSED(_t) switch (_id) { - case 0: _t->TriggerMessage((*reinterpret_cast< QString(*)>(_a[1])),(*reinterpret_cast< QString(*)>(_a[2]))); break; + case 0: _t->TriggerMessage((*reinterpret_cast< QString(*)>(_a[1])),(*reinterpret_cast< QString(*)>(_a[2])),(*reinterpret_cast< qint64(*)>(_a[3]))); break; default: ; } } } -const QMetaObject QRoomVBoxLayoutWithTriggerSlot::staticMetaObject = { - { &QVBoxLayout::staticMetaObject, qt_meta_stringdata_QRoomVBoxLayoutWithTriggerSlot.data, - qt_meta_data_QRoomVBoxLayoutWithTriggerSlot, qt_static_metacall, nullptr, nullptr} +const QMetaObject QVBoxLayoutWithTriggerSlot::staticMetaObject = { + { &QVBoxLayout::staticMetaObject, qt_meta_stringdata_QVBoxLayoutWithTriggerSlot.data, + qt_meta_data_QVBoxLayoutWithTriggerSlot, qt_static_metacall, nullptr, nullptr} }; -const QMetaObject *QRoomVBoxLayoutWithTriggerSlot::metaObject() const +const QMetaObject *QVBoxLayoutWithTriggerSlot::metaObject() const { return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject; } -void *QRoomVBoxLayoutWithTriggerSlot::qt_metacast(const char *_clname) +void *QVBoxLayoutWithTriggerSlot::qt_metacast(const char *_clname) { if (!_clname) return nullptr; - if (!strcmp(_clname, qt_meta_stringdata_QRoomVBoxLayoutWithTriggerSlot.stringdata0)) - return static_cast<void*>(const_cast< QRoomVBoxLayoutWithTriggerSlot*>(this)); + if (!strcmp(_clname, qt_meta_stringdata_QVBoxLayoutWithTriggerSlot.stringdata0)) + return static_cast<void*>(const_cast< QVBoxLayoutWithTriggerSlot*>(this)); return QVBoxLayout::qt_metacast(_clname); } -int QRoomVBoxLayoutWithTriggerSlot::qt_metacall(QMetaObject::Call _c, int _id, void **_a) +int QVBoxLayoutWithTriggerSlot::qt_metacall(QMetaObject::Call _c, int _id, void **_a) { _id = QVBoxLayout::qt_metacall(_c, _id, _a); if (_id < 0) diff --git a/elements/roomlist.go b/elements/roomlist.go @@ -2,8 +2,6 @@ package elements import ( "github.com/Nordgedanken/Morpheus/matrix" - "github.com/matrix-org/gomatrix" - "github.com/rhinoman/go-commonmark" "github.com/therecipe/qt/core" "github.com/therecipe/qt/uitools" "github.com/therecipe/qt/widgets" @@ -24,7 +22,7 @@ import ( type QRoomVBoxLayoutWithTriggerSlot struct { widgets.QVBoxLayout - _ func(messageBody, sender string) `slot:"TriggerMessage"` + _ func(roomID string) `slot:"TriggerRoom"` } // NewRoomList generates a new QRoomVBoxLayoutWithTriggerSlot and adds it to the room scrollArea @@ -41,45 +39,43 @@ func NewRoomList(scrollArea *widgets.QScrollArea, roomView *widgets.QWidget) (ro } // NewRoom adds a new room object to the view -func (roomViewLayout *QRoomVBoxLayoutWithTriggerSlot) NewRoom(body string, cli *gomatrix.Client, sender string, scrollArea *widgets.QScrollArea) (err error) { - avatar, AvatarErr := matrix.GetUserAvatar(cli, sender, 84) - if err != nil { - err = AvatarErr +func (roomViewLayout *QRoomVBoxLayoutWithTriggerSlot) NewRoom(room *matrix.Room, scrollArea *widgets.QScrollArea) (err error) { + roomAvatar, roomAvatarErr := room.GetRoomAvatar() + if roomAvatarErr != nil { + err = roomAvatarErr return } var widget = widgets.NewQWidget(nil, 0) var loader = uitools.NewQUiLoader(nil) - var file = core.NewQFile2(":/qml/ui/message.ui") + var file = core.NewQFile2(":/qml/ui/room.ui") file.Open(core.QIODevice__ReadOnly) var wrapperWidget = loader.Load(file, widget) file.Close() - messageWidget := widgets.NewQWidgetFromPointer(widget.FindChild("message", core.Qt__FindChildrenRecursively).Pointer()) - avatarLogo := widgets.NewQLabelFromPointer(widget.FindChild("avatar", core.Qt__FindChildrenRecursively).Pointer()) - messageContent := widgets.NewQLabelFromPointer(widget.FindChild("messageContent", core.Qt__FindChildrenRecursively).Pointer()) - senderContent := widgets.NewQLabelFromPointer(widget.FindChild("sender", core.Qt__FindChildrenRecursively).Pointer()) + roomWidget := widgets.NewQWidgetFromPointer(widget.FindChild("room", core.Qt__FindChildrenRecursively).Pointer()) + roomAvatarQLabel := widgets.NewQLabelFromPointer(widget.FindChild("roomAvatar", core.Qt__FindChildrenRecursively).Pointer()) + roomName := widgets.NewQLabelFromPointer(widget.FindChild("roomName", core.Qt__FindChildrenRecursively).Pointer()) + /*lastMessageContent := widgets.NewQLabelFromPointer(widget.FindChild("lastMessage", core.Qt__FindChildrenRecursively).Pointer())*/ - markdownMessage := commonmark.Md2Html(body, 0) + roomAvatarQLabel.SetPixmap(roomAvatar) + roomName.SetText(room.GetRoomName()) - messageContent.SetText(markdownMessage) + /* + messageContent.SetText(markdownMessage) - senderDisplayNameResp, _ := cli.GetDisplayName(sender) - senderDisplayName := senderDisplayNameResp.DisplayName - senderContent.SetText(senderDisplayName) - avatarLogo.SetPixmap(avatar) + messageContent.SetMinimumWidth(messageContent.LineWidth()) - messageContent.SetMinimumWidth(messageContent.LineWidth()) - - messageWidget.SetMinimumWidth(messageContent.LineWidth() + 100) - messageWidget.Resize(wrapperWidget.Size()) + roomWidget.SetMinimumWidth(messageContent.LineWidth() + 100) + */ + roomWidget.Resize(wrapperWidget.Size()) roomViewLayout.SetSpacing(1) roomViewLayout.SetContentsMargins(0, 0, 0, 0) - roomViewLayout.AddWidget(messageWidget, 0, core.Qt__AlignBottom) + roomViewLayout.AddWidget(roomWidget, 0, core.Qt__AlignBottom) scrollArea.Widget().SetLayout(roomViewLayout) return diff --git a/main.go b/main.go @@ -3,6 +3,7 @@ package main import ( "log" "os" + "sync" "github.com/Nordgedanken/Morpheus/matrix" "github.com/Nordgedanken/Morpheus/ui" @@ -12,7 +13,6 @@ import ( "github.com/therecipe/qt/gui" "github.com/therecipe/qt/widgets" "github.com/tidwall/buntdb" - "sync" ) var window *widgets.QMainWindow @@ -80,7 +80,7 @@ func main() { // Get cache DBErr := db.View(func(tx *buntdb.Tx) error { - accessTokenErr := tx.AscendKeys("user:accessToken", + accessTokenErr := tx.AscendKeys("user|accessToken", func(key, value string) bool { accessToken = value return true @@ -88,7 +88,7 @@ func main() { if accessTokenErr != nil { return accessTokenErr } - homeserverURLErr := tx.AscendKeys("user:homeserverURL", + homeserverURLErr := tx.AscendKeys("user|homeserverURL", func(key, value string) bool { homeserverURL = value return true @@ -96,7 +96,7 @@ func main() { if homeserverURLErr != nil { return homeserverURLErr } - userIDErr := tx.AscendKeys("user:userID", + userIDErr := tx.AscendKeys("user|userID", func(key, value string) bool { userID = value return true diff --git a/matrix/db.go b/matrix/db.go @@ -3,11 +3,11 @@ package matrix import ( "os" "path/filepath" + "strconv" "github.com/matrix-org/gomatrix" "github.com/shibukawa/configdir" "github.com/tidwall/buntdb" - "strconv" ) // OpenCacheDB opens or generates the Database file for settings and Cache @@ -60,15 +60,8 @@ func InitData(cli *gomatrix.Client) (err error) { } defer db.Close() - roomsURL := cli.BuildURL("joined_rooms") - var rooms JoinedRooms - _, ReqErr := cli.MakeRequest("GET", roomsURL, nil, &rooms) - if ReqErr != nil { - err = ReqErr - return - } - - for _, room := range rooms.JoinedRooms { + // Todo Get aliases + /*for _, room := range rooms.JoinedRooms { var roomAliases RoomAliases if StateEventErr := cli.StateEvent(room, "m.room.aliases", "", &roomAliases); StateEventErr != nil { localLog.Println(StateEventErr) @@ -79,7 +72,7 @@ func InitData(cli *gomatrix.Client) (err error) { // Update cache DBerr := db.Update(func(tx *buntdb.Tx) error { localLog.Println(room) - _, _, DBSetErr := tx.Set("room:"+room+":aliases:"+string(index), alias, nil) + _, _, DBSetErr := tx.Set("room|"+room+"|aliases|"+string(index), alias, nil) return DBSetErr }) if DBerr != nil { @@ -88,7 +81,7 @@ func InitData(cli *gomatrix.Client) (err error) { } } - } + }*/ return } @@ -103,23 +96,23 @@ func CacheMessageEvents(id, sender, roomID, message string, timestamp int64) (er // Update cache DBerr := db.Update(func(tx *buntdb.Tx) error { localLog.Println(roomID) - _, _, DBSetIDErr := tx.Set("room:"+roomID+":messages:"+id+":id", id, nil) + _, _, DBSetIDErr := tx.Set("room|"+roomID+"|messages|"+id+"|id", id, nil) if DBSetIDErr != nil { return DBSetIDErr } - _, _, DBSetSenderErr := tx.Set("room:"+roomID+":messages:"+id+":sender", sender, nil) + _, _, DBSetSenderErr := tx.Set("room|"+roomID+"|messages|"+id+"|sender", sender, nil) if DBSetSenderErr != nil { return DBSetSenderErr } - _, _, DBSetMessageErr := tx.Set("room:"+roomID+":messages:"+id+":message", message, nil) + _, _, DBSetMessageErr := tx.Set("room|"+roomID+"|messages|"+id+"|message", message, nil) if DBSetMessageErr != nil { return DBSetMessageErr } timestampString := strconv.FormatInt(timestamp, 10) - _, _, DBSeTimestampErr := tx.Set("room:"+roomID+":messages:"+id+":timestamp", timestampString, nil) + _, _, DBSeTimestampErr := tx.Set("room|"+roomID+"|messages|"+id+"|timestamp", timestampString, nil) return DBSeTimestampErr }) diff --git a/matrix/login.go b/matrix/login.go @@ -1,12 +1,12 @@ package matrix import ( + "log" "strings" + "sync" "github.com/matrix-org/gomatrix" "github.com/tidwall/buntdb" - "log" - "sync" ) //GetClient returns a Client @@ -23,22 +23,18 @@ func GetClient(homeserverURL, userID, accessToken string) (client *gomatrix.Clie return } - if db == nil { - localLog.Println("FUCK") - } - DBErr := db.Update(func(tx *buntdb.Tx) error { - _, _, DBSetAccessTokenErr := tx.Set("user:accessToken", client.AccessToken, nil) + _, _, DBSetAccessTokenErr := tx.Set("user|accessToken", client.AccessToken, nil) if DBSetAccessTokenErr != nil { return DBSetAccessTokenErr } - _, _, DBSetHomeserverURLErr := tx.Set("user:homeserverURL", client.HomeserverURL.String(), nil) + _, _, DBSetHomeserverURLErr := tx.Set("user|homeserverURL", client.HomeserverURL.String(), nil) if DBSetHomeserverURLErr != nil { return DBSetHomeserverURLErr } - _, _, DBSetUserIDErr := tx.Set("user:userID", client.UserID, nil) + _, _, DBSetUserIDErr := tx.Set("user|userID", client.UserID, nil) return DBSetUserIDErr }) if DBErr != nil { @@ -82,22 +78,22 @@ func LoginUser(username, password string) (*gomatrix.Client, error) { defer db.Close() cli.SetCredentials(resp.UserID, resp.AccessToken) DBerr := db.Update(func(tx *buntdb.Tx) error { - _, _, DBSetAccessTokenErr := tx.Set("user:accessToken", resp.AccessToken, nil) + _, _, DBSetAccessTokenErr := tx.Set("user|accessToken", resp.AccessToken, nil) if DBSetAccessTokenErr != nil { return DBSetAccessTokenErr } - _, _, DBSetDeviceIDErr := tx.Set("user:deviceID", resp.DeviceID, nil) + _, _, DBSetDeviceIDErr := tx.Set("user|deviceID", resp.DeviceID, nil) if DBSetDeviceIDErr != nil { return DBSetDeviceIDErr } - _, _, DBSetHomeserverURLErr := tx.Set("user:homeserverURL", resp.HomeServer, nil) + _, _, DBSetHomeserverURLErr := tx.Set("user|homeserverURL", resp.HomeServer, nil) if DBSetHomeserverURLErr != nil { return DBSetHomeserverURLErr } - _, _, DBSetUserIDErr := tx.Set("user:userID", resp.UserID, nil) + _, _, DBSetUserIDErr := tx.Set("user|userID", resp.UserID, nil) return DBSetUserIDErr }) if DBerr != nil { diff --git a/matrix/rooms.go b/matrix/rooms.go @@ -0,0 +1,178 @@ +package matrix + +import ( + "bytes" + "image" + "image/draw" + "image/png" + "strings" + + "github.com/matrix-org/gomatrix" + "github.com/therecipe/qt/gui" + "github.com/tidwall/buntdb" +) + +// Room saves the information of a Room +type Room struct { + cli *gomatrix.Client + RoomID string + RoomName string + RoomAvatarURL string +} + +// NewRoom Inits a new Room struct +func NewRoom(roomID string, cli *gomatrix.Client) (room *Room) { + room = &Room{RoomID: roomID, cli: cli} + return +} + +func (r *Room) crawlRoomAvatarURL() { + roomAvatar := struct { + URL string `json:"url"` + }{} + r.cli.StateEvent(r.RoomID, "m.room.avatar", "", &roomAvatar) + r.RoomAvatarURL = roomAvatar.URL +} + +// GetRoomAvatar generates the Avatar Image for a Room +func (r *Room) GetRoomAvatar() (avatarResp *gui.QPixmap, err error) { + // Get the Avatar URL if needed + if r.RoomAvatarURL == "" { + r.crawlRoomAvatarURL() + } + + // Get the image Data + db, DBOpenErr := OpenCacheDB() + if DBOpenErr != nil { + localLog.Fatalln(DBOpenErr) + } + defer db.Close() + + // Init local vars + var roomAvatarData string + var IMGdata string + + // Get cache + DBErr := db.View(func(tx *buntdb.Tx) error { + QueryErr := tx.AscendKeys("room|"+r.RoomID+"|84x84", + func(key, value string) bool { + roomAvatarData = value + return true + }) + return QueryErr + }) + if DBErr != nil { + err = DBErr + return + } + + //If cache is empty do a ServerQuery + if roomAvatarData == "" { + // If avatarURL is not empty (aka. has a avatar set) download it at the size of 100x100. Else make the data string empty + if r.RoomAvatarURL != "" { + hsURL := r.cli.HomeserverURL.String() + roomAvatarURLSplits := strings.Split(strings.Replace(r.RoomAvatarURL, "mxc://", "", -1), "/") + + urlPath := hsURL + "/_matrix/media/r0/thumbnail/" + roomAvatarURLSplits[0] + "/" + roomAvatarURLSplits[1] + "?width=84&height=84&method=crop" + + data, ReqErr := r.cli.MakeRequest("GET", urlPath, nil, nil) + if ReqErr != nil { + err = ReqErr + return + } + IMGdata = string(data[:]) + } else { + localLog.Println("Generating Room Avatar") + var GenerateImgErr error + var roomName string + if r.RoomName == "" { + r.crawlRoomName() + } + roomName = r.RoomName + localLog.Println(roomName) + if roomName == "" { + roomName = "#" + } + IMGdata, GenerateImgErr = generateGenericImages(roomName, 84) + if GenerateImgErr != nil { + err = GenerateImgErr + return + } + } + + // Update cache + DBerr := db.Update(func(tx *buntdb.Tx) error { + _, _, DBSetErr := tx.Set("room|"+r.RoomID+"|84x84", IMGdata, nil) + return DBSetErr + }) + if DBerr != nil { + err = DBErr + return + } + } else { + IMGdata = roomAvatarData + } + + reader := bytes.NewReader([]byte(IMGdata)) + srcIMG, _, DecodeErr := image.Decode(reader) + if DecodeErr != nil { + err = DecodeErr + } + + // Convert avatarimage to QPixmap for usage in QT + canvas := image.NewRGBA(srcIMG.Bounds()) + cx := srcIMG.Bounds().Min.X + srcIMG.Bounds().Dx()/2 + cy := srcIMG.Bounds().Min.Y + srcIMG.Bounds().Dy()/2 + draw.DrawMask(canvas, canvas.Bounds(), srcIMG, image.ZP, &circle{image.Point{cx, cy}, cx}, image.ZP, draw.Over) + + avatar := gui.NewQPixmap() + buf := new(bytes.Buffer) + ConvErr := png.Encode(buf, canvas) + if ConvErr != nil { + err = ConvErr + } + + str := buf.String() + avatar.LoadFromData(str, uint(len(str)), "", 0) + avatarResp = avatar + return + + return +} + +func (r *Room) crawlRoomName() { + roomName := struct { + Name string `json:"name"` + }{} + roomCanoncialAlias := struct { + Alias string `json:"alias"` + }{} + + if roomNameStateEventErr := r.cli.StateEvent(r.RoomID, "m.room.name", "", &roomName); roomNameStateEventErr != nil { + localLog.Println(roomNameStateEventErr) + // Not returning as a Error NotFound is allowed + } + if roomName.Name == "" { + if roomCanoncialAliasStateEventErr := r.cli.StateEvent(r.RoomID, "m.room.canonical_alias", "", &roomCanoncialAlias); roomCanoncialAliasStateEventErr != nil { + localLog.Println(roomCanoncialAliasStateEventErr) + // Not returning as a Error NotFound is allowed + } + if roomCanoncialAlias.Alias == "" { + r.RoomName = r.RoomID + } else { + r.RoomName = roomCanoncialAlias.Alias + } + } else { + r.RoomName = roomName.Name + } + +} + +// GetRoomName gives you the name of the current Room +func (r *Room) GetRoomName() (name string) { + if r.RoomName == "" { + r.crawlRoomName() + } + name = r.RoomName + return +} diff --git a/matrix/types.go b/matrix/types.go @@ -2,27 +2,46 @@ package matrix // HTMLMessage is the contents of a Matrix formated message event. type HTMLMessage struct { - MsgType string `json:"msgtype"` - Body string `json:"body"` - FormattedBody string `json:"formatted_body"` - Format string `json:"format"` + MsgType string `json:"msgtype,omitempty"` + Body string `json:"body,omitempty"` + FormattedBody string `json:"formatted_body,omitempty"` + Format string `json:"format,omitempty"` } // RoomAliases is the json response when getting the room aliases type RoomAliases struct { - Age int `json:"age"` + Age int `json:"age,omitempty"` Content struct { - Aliases []string `json:"aliases"` - } `json:"content"` - EventID string `json:"event_id"` - OriginServerTs int64 `json:"origin_server_ts"` - RoomID string `json:"room_id"` - Sender string `json:"sender"` - StateKey string `json:"state_key"` - Type string `json:"type"` + Aliases []string `json:"aliases,omitempty"` + } `json:"content,omitempty"` + EventID string `json:"event_id,omitempty"` + OriginServerTs int64 `json:"origin_server_ts,omitempty"` + RoomID string `json:"room_id,omitempty"` + Sender string `json:"sender,omitempty"` + StateKey string `json:"state_key,omitempty"` + Type string `json:"type,omitempty"` } // JoinedRooms is the json response when getting the joined rooms list type JoinedRooms struct { - JoinedRooms []string `json:"joined_rooms"` + JoinedRooms []string `json:"joined_rooms,omitempty"` +} + +type RoomAvatar struct { + Age int `json:"age,omitempty"` + Content struct { + Info struct { + H int `json:"h,omitempty"` + Mimetype string `json:"mimetype,omitempty"` + Size int `json:"size,omitempty"` + W int `json:"w,omitempty"` + } `json:"info,omitempty"` + URL string `json:"url,omitempty"` + } `json:"content,omitempty"` + EventID string `json:"event_id,omitempty"` + OriginServerTs int64 `json:"origin_server_ts,omitempty"` + RoomID string `json:"room_id,omitempty"` + Sender string `json:"sender,omitempty"` + StateKey string `json:"state_key,omitempty"` + Type string `json:"type,omitempty"` } diff --git a/matrix/user.go b/matrix/user.go @@ -1,29 +1,30 @@ package matrix import ( + "bytes" + "image" + "image/color" + "image/draw" + "image/png" "log" "os" + "strconv" "strings" + "unicode" + "unicode/utf8" - "bytes" "github.com/Nordgedanken/Morpheus/util" "github.com/disintegration/letteravatar" "github.com/matrix-org/gomatrix" "github.com/therecipe/qt/gui" "github.com/tidwall/buntdb" - "image" - "image/color" - "image/draw" + // image/jpeg needed to load jpeg images _ "image/jpeg" // golang.org/x/image/webp needed to load webp images _ "golang.org/x/image/webp" // golang.org/x/image/bmp needed to load bmp images _ "golang.org/x/image/bmp" - "image/png" - "strconv" - "unicode" - "unicode/utf8" ) var localLog *log.Logger @@ -106,7 +107,7 @@ func GetUserAvatar(cli *gomatrix.Client, mxid string, size int) (avatarResp *gui // Get cache DBErr := db.View(func(tx *buntdb.Tx) error { - QueryErr := tx.AscendKeys("user:"+mxid+":avatarData"+strconv.Itoa(size)+"x"+strconv.Itoa(size), + QueryErr := tx.AscendKeys("user|"+mxid+"|avatarData"+strconv.Itoa(size)+"x"+strconv.Itoa(size), func(key, value string) bool { avatarData = value return true @@ -160,7 +161,7 @@ func GetUserAvatar(cli *gomatrix.Client, mxid string, size int) (avatarResp *gui // Update cache DBerr := db.Update(func(tx *buntdb.Tx) error { - _, _, DBSetErr := tx.Set("user:"+mxid+":avatarData"+strconv.Itoa(size)+"x"+strconv.Itoa(size), IMGdata, nil) + _, _, DBSetErr := tx.Set("user|"+mxid+"|avatarData"+strconv.Itoa(size)+"x"+strconv.Itoa(size), IMGdata, nil) return DBSetErr }) if DBerr != nil { diff --git a/qml/ui/chat.ui b/qml/ui/chat.ui @@ -561,7 +561,7 @@ border-radius: 5px;</string> </widget> </item> <item> - <widget class="QScrollArea" name="roomBarArea"> + <widget class="QScrollArea" name="roomScroll"> <property name="sizePolicy"> <sizepolicy hsizetype="Preferred" vsizetype="Expanding"> <horstretch>0</horstretch> @@ -589,7 +589,7 @@ border-radius: 5px;</string> <property name="alignment"> <set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set> </property> - <widget class="QWidget" name="scrollAreaWidgetContents_2"> + <widget class="QWidget" name="roomScrollAreaContent"> <property name="geometry"> <rect> <x>0</x> diff --git a/qml/ui/ownmessage.ui b/qml/ui/ownmessage.ui @@ -1,117 +1,202 @@ <?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> - <class>Form</class> - <widget class="QWidget" name="Form"> + <class>message</class> + <widget class="QWidget" name="message"> <property name="geometry"> <rect> <x>0</x> <y>0</y> - <width>560</width> - <height>83</height> + <width>365</width> + <height>106</height> </rect> </property> <property name="windowTitle"> <string>Form</string> </property> - <widget class="QWidget" name="widget_2" native="true"> - <property name="geometry"> - <rect> - <x>476</x> - <y>0</y> - <width>84</width> - <height>84</height> - </rect> + <property name="styleSheet"> + <string notr="true">background-color:transparent;</string> + </property> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> </property> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> + <property name="rightMargin"> + <number>0</number> </property> - <widget class="QLabel" name="avatar"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>84</width> - <height>84</height> - </rect> - </property> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string/> - </property> - <property name="pixmap"> - <pixmap>../../../../../../../Downloads/avatar512.png</pixmap> - </property> - <property name="scaledContents"> - <bool>true</bool> - </property> - </widget> - </widget> - <widget class="QWidget" name="widget" native="true"> - <property name="geometry"> - <rect> - <x>10</x> - <y>10</y> - <width>437</width> - <height>61</height> - </rect> + <property name="bottomMargin"> + <number>0</number> </property> - <layout class="QVBoxLayout" name="verticalLayout"> - <property name="spacing"> - <number>0</number> - </property> - <property name="leftMargin"> - <number>0</number> - </property> - <property name="topMargin"> - <number>0</number> - </property> - <property name="rightMargin"> - <number>0</number> - </property> - <property name="bottomMargin"> - <number>0</number> - </property> - <item> - <widget class="QLabel" name="messageContent"> - <property name="font"> - <font> - <family>Arial</family> - <pointsize>12</pointsize> - <stylestrategy>PreferAntialias</stylestrategy> - </font> - </property> - <property name="styleSheet"> - <string notr="true">background-color: rgb(121, 198, 246); + <item> + <widget class="QWidget" name="widget_2" native="true"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="1"> + <widget class="QWidget" name="widget_3" native="true"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>61</width> + <height>61</height> + </size> + </property> + <widget class="QLabel" name="avatar"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>61</width> + <height>61</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string/> + </property> + <property name="pixmap"> + <pixmap>../../../../../../../Downloads/avatar512.png</pixmap> + </property> + <property name="scaledContents"> + <bool>true</bool> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + <property name="wordWrap"> + <bool>false</bool> + </property> + <property name="textInteractionFlags"> + <set>Qt::NoTextInteraction</set> + </property> + </widget> + </widget> + </item> + <item row="0" column="0"> + <widget class="QWidget" name="widget" native="true"> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QLabel" name="messageContent"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="font"> + <font> + <family>Arial</family> + <pointsize>12</pointsize> + <stylestrategy>PreferAntialias</stylestrategy> + </font> + </property> + <property name="styleSheet"> + <string notr="true">/*OLD COLOR +background-color: rgb(242, 244, 248); */ +background-color: rgb(123, 199, 248); border: 0; -border-radius:5px;</string> - </property> - <property name="text"> - <string>Test</string> - </property> - <property name="alignment"> - <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> - </property> - <property name="wordWrap"> - <bool>true</bool> - </property> - <property name="margin"> - <number>4</number> - </property> - <property name="openExternalLinks"> - <bool>true</bool> - </property> - </widget> - </item> - </layout> - </widget> +border-radius:7px;</string> + </property> + <property name="text"> + <string>Test</string> + </property> + <property name="scaledContents"> + <bool>false</bool> + </property> + <property name="alignment"> + <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + <property name="margin"> + <number>4</number> + </property> + <property name="openExternalLinks"> + <bool>true</bool> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + <item> + <widget class="QWidget" name="subMessageWidget" native="true"> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QLabel" name="timestamp"> + <property name="font"> + <font> + <pointsize>8</pointsize> + </font> + </property> + <property name="styleSheet"> + <string notr="true">color:grey;</string> + </property> + <property name="text"> + <string>Way to early to say a time^^</string> + </property> + <property name="alignment"> + <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set> + </property> + <property name="openExternalLinks"> + <bool>true</bool> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse</set> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="sender"> + <property name="font"> + <font> + <pointsize>8</pointsize> + </font> + </property> + <property name="styleSheet"> + <string notr="true">color:grey;</string> + </property> + <property name="text"> + <string>MTRNord</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="openExternalLinks"> + <bool>true</bool> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + </item> + </layout> </widget> <resources/> <connections/> diff --git a/qml/ui/room.ui b/qml/ui/room.ui @@ -0,0 +1,200 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>room</class> + <widget class="QWidget" name="room"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>365</width> + <height>106</height> + </rect> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + <property name="styleSheet"> + <string notr="true">background-color:transparent;</string> + </property> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <widget class="QWidget" name="widget_2" native="true"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <widget class="QWidget" name="widget_3" native="true"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>61</width> + <height>61</height> + </size> + </property> + <widget class="QLabel" name="roomAvatar"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>61</width> + <height>61</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string/> + </property> + <property name="pixmap"> + <pixmap>../../../../../../../Downloads/avatar512.png</pixmap> + </property> + <property name="scaledContents"> + <bool>true</bool> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + <property name="wordWrap"> + <bool>false</bool> + </property> + <property name="textInteractionFlags"> + <set>Qt::NoTextInteraction</set> + </property> + </widget> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QWidget" name="widget" native="true"> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QLabel" name="roomName"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="font"> + <font> + <family>Arial</family> + <pointsize>12</pointsize> + <weight>75</weight> + <italic>false</italic> + <bold>true</bold> + <stylestrategy>PreferAntialias</stylestrategy> + <kerning>true</kerning> + </font> + </property> + <property name="styleSheet"> + <string notr="true">border: 0;</string> + </property> + <property name="text"> + <string>Test</string> + </property> + <property name="scaledContents"> + <bool>false</bool> + </property> + <property name="alignment"> + <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + <property name="margin"> + <number>4</number> + </property> + <property name="openExternalLinks"> + <bool>true</bool> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + <item> + <widget class="QWidget" name="subMessageWidget" native="true"> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QLabel" name="lastMessage"> + <property name="font"> + <font> + <pointsize>8</pointsize> + </font> + </property> + <property name="styleSheet"> + <string notr="true">color:grey;</string> + </property> + <property name="text"> + <string>MTRNord</string> + </property> + <property name="openExternalLinks"> + <bool>true</bool> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse</set> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="timestamp"> + <property name="font"> + <font> + <pointsize>8</pointsize> + </font> + </property> + <property name="styleSheet"> + <string notr="true">color:grey;</string> + </property> + <property name="text"> + <string>Way to early to say a time^^</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="openExternalLinks"> + <bool>true</bool> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse</set> + </property> + </widget> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/ui/LoginUI.go b/ui/LoginUI.go @@ -1,12 +1,13 @@ package ui import ( + "sync" + "github.com/Nordgedanken/Morpheus/matrix" "github.com/Nordgedanken/Morpheus/util" "github.com/matrix-org/gomatrix" "github.com/therecipe/qt/core" "github.com/therecipe/qt/widgets" - "sync" ) // NewLoginUIStruct gives you a LoginUI struct with prefilled data diff --git a/ui/MainUI.go b/ui/MainUI.go @@ -1,6 +1,10 @@ package ui import ( + "fmt" + "log" + "sync" + "github.com/Nordgedanken/Morpheus/elements" "github.com/Nordgedanken/Morpheus/matrix" "github.com/Nordgedanken/Morpheus/util" @@ -11,8 +15,6 @@ import ( "github.com/therecipe/qt/uitools" "github.com/therecipe/qt/widgets" "github.com/tidwall/buntdb" - "log" - "sync" ) // NewMainUIStruct gives you a MainUI struct with prefilled data @@ -24,6 +26,7 @@ func NewMainUIStruct(windowWidth, windowHeight int, window *widgets.QMainWindow) mainUIStruct = MainUI{ config: configStruct, window: window, + rooms: make(map[string]*matrix.Room), } return } @@ -61,6 +64,7 @@ func (m *MainUI) InitLogger() error { // NewUI initializes a new Main Screen func (m *MainUI) NewUI() (err error) { + fmt.Println((m.window.Width() / 3) / 2) var widget = widgets.NewQWidget(nil, 0) var loader = uitools.NewQUiLoader(nil) @@ -78,6 +82,8 @@ func (m *MainUI) NewUI() (err error) { messageScrollArea := widgets.NewQScrollAreaFromPointer(widget.FindChild("messageScroll", core.Qt__FindChildrenRecursively).Pointer()) messagesScrollAreaContent := widgets.NewQWidgetFromPointer(widget.FindChild("messagesScrollAreaContent", core.Qt__FindChildrenRecursively).Pointer()) + roomScrollArea := widgets.NewQScrollAreaFromPointer(widget.FindChild("roomScroll", core.Qt__FindChildrenRecursively).Pointer()) + roomScrollAreaContent := widgets.NewQWidgetFromPointer(widget.FindChild("roomScrollAreaContent", core.Qt__FindChildrenRecursively).Pointer()) mainWidget.SetWindowTitle("Morpheus - MatrixHQ") @@ -102,6 +108,11 @@ func (m *MainUI) NewUI() (err error) { event.Accept() }) + roomScrollArea.ConnectResizeEvent(func(event *gui.QResizeEvent) { + roomScrollArea.Resize(event.Size()) + event.Accept() + }) + //Set Avatar avatarLogo := widgets.NewQLabelFromPointer(widget.FindChild("UserAvatar", core.Qt__FindChildrenRecursively).Pointer()) avatar, AvatarErr := matrix.GetOwnUserAvatar(m.cli) @@ -124,19 +135,47 @@ func (m *MainUI) NewUI() (err error) { // Init Message View messageListLayout := elements.NewMessageList(messageScrollArea, messagesScrollAreaContent) - messageListLayout.ConnectTriggerMessage(func(messageBody, sender string, timestamp int64) { - NewMessageErr := messageListLayout.NewMessage(messageBody, m.cli, sender, timestamp, messageScrollArea) - if NewMessageErr != nil { - err = NewMessageErr - return - } - }) + // Init Room View + roomListLayout := elements.NewRoomList(roomScrollArea, roomScrollAreaContent) + messageScrollArea.SetWidgetResizable(true) messageScrollArea.SetHorizontalScrollBarPolicy(core.Qt__ScrollBarAlwaysOff) messageScrollArea.SetContentsMargins(0, 0, 0, 0) + roomScrollArea.SetWidgetResizable(true) + roomScrollArea.SetHorizontalScrollBarPolicy(core.Qt__ScrollBarAlwaysOff) + roomScrollArea.SetContentsMargins(0, 0, 0, 0) + + messageListLayout.ConnectTriggerMessage(func(messageBody, sender string, timestamp int64) { + if sender == m.cli.UserID { + NewOwnMessageErr := messageListLayout.NewOwnMessage(messageBody, m.cli, sender, timestamp, messageScrollArea) + if NewOwnMessageErr != nil { + err = NewOwnMessageErr + return + } + } else { + NewMessageErr := messageListLayout.NewMessage(messageBody, m.cli, sender, timestamp, messageScrollArea) + if NewMessageErr != nil { + err = NewMessageErr + return + } + } + }) + m.startSync(messageListLayout) + roomListLayout.ConnectTriggerRoom(func(roomID string) { + room := m.rooms[roomID] + + NewRoomErr := roomListLayout.NewRoom(room, roomScrollArea) + if NewRoomErr != nil { + err = NewRoomErr + return + } + }) + + m.initRoomList(roomListLayout) + var message string messageInput := widgets.NewQLineEditFromPointer(widget.FindChild("MessageInput", core.Qt__FindChildrenRecursively).Pointer()) messageInput.ConnectTextChanged(func(value string) { @@ -249,12 +288,17 @@ func (m *MainUI) logout(widget *widgets.QWidget, messageScrollArea *widgets.QScr func (m *MainUI) startSync(messageListLayout *elements.QVBoxLayoutWithTriggerSlot) (err error) { //Start Syncer! m.syncer = m.cli.Syncer.(*gomatrix.DefaultSyncer) - customStore := gomatrix.NewInMemoryStore() - m.cli.Store = customStore - m.syncer.Store = customStore + m.storage = gomatrix.NewInMemoryStore() + m.cli.Store = m.storage + m.syncer.Store = m.storage m.syncer.OnEventType("m.room.message", func(ev *gomatrix.Event) { - msg, _ := ev.Body() + fomrattedBody, _ := ev.Content["formatted_body"] + var msg string + msg, _ = fomrattedBody.(string) + if msg == "" { + msg, _ = ev.Body() + } room := ev.RoomID sender := ev.Sender id := ev.ID @@ -275,3 +319,18 @@ func (m *MainUI) startSync(messageListLayout *elements.QVBoxLayoutWithTriggerSlo }() return } + +func (m *MainUI) initRoomList(roomListLayout *elements.QRoomVBoxLayoutWithTriggerSlot) (err error) { + rooms, ReqErr := m.cli.JoinedRooms() + if ReqErr != nil { + err = ReqErr + return + } + + for _, roomID := range rooms.JoinedRooms { + m.rooms[roomID] = matrix.NewRoom(roomID, m.cli) + roomListLayout.TriggerRoom(roomID) + } + + return +} diff --git a/ui/types.go b/ui/types.go @@ -1,9 +1,11 @@ package ui import ( + "log" + + "github.com/Nordgedanken/Morpheus/matrix" "github.com/matrix-org/gomatrix" "github.com/therecipe/qt/widgets" - "log" ) // Config holds important reused information in the UI @@ -26,9 +28,12 @@ type logger struct { type MainUI struct { logger config - widget *widgets.QWidget - window *widgets.QMainWindow - syncer *gomatrix.DefaultSyncer + widget *widgets.QWidget + window *widgets.QMainWindow + syncer *gomatrix.DefaultSyncer + storage *gomatrix.InMemoryStore + rooms map[string]*matrix.Room + currentRoom string } // LoginUI holds information about the LoginUI