2020-10-09 18:10:03 +00:00
|
|
|
package ui
|
|
|
|
|
|
|
|
import (
|
|
|
|
"cwtch.im/cwtch/model"
|
|
|
|
"cwtch.im/ui/go/the"
|
2020-10-20 22:57:34 +00:00
|
|
|
"encoding/hex"
|
2020-10-09 18:10:03 +00:00
|
|
|
"git.openprivacy.ca/openprivacy/log"
|
|
|
|
"github.com/therecipe/qt/core"
|
|
|
|
"reflect"
|
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
|
|
|
type MessageModel struct {
|
|
|
|
core.QAbstractTableModel
|
|
|
|
|
2020-10-20 22:57:34 +00:00
|
|
|
ackIdx int
|
2020-10-09 18:10:03 +00:00
|
|
|
handle string
|
2020-11-23 21:13:09 +00:00
|
|
|
_ func(string) `signal:"setHandle,auto"`
|
2020-10-09 18:10:03 +00:00
|
|
|
|
|
|
|
_ map[int]*core.QByteArray `property:"roles"`
|
|
|
|
_ func() `constructor:"init"`
|
|
|
|
|
|
|
|
_ func(int) `signal:"addMessage,auto"`
|
2020-10-20 22:57:34 +00:00
|
|
|
_ func(int) `signal:"editMessage,auto"`
|
|
|
|
_ func() `signal:"requestEIR,auto"`
|
2020-10-09 18:10:03 +00:00
|
|
|
|
|
|
|
_ func(string) string `slot:"getNick,auto"`
|
|
|
|
_ func(string) string `slot:"getImage,auto"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type MessageWrapper struct {
|
|
|
|
model.Message
|
|
|
|
core.QObject
|
|
|
|
|
2020-11-23 21:13:09 +00:00
|
|
|
Timestamp int64
|
|
|
|
PeerID string
|
2020-10-09 18:10:03 +00:00
|
|
|
Acknowledged bool
|
2020-11-23 21:13:09 +00:00
|
|
|
RawMessage string
|
|
|
|
Error string
|
|
|
|
Day string
|
|
|
|
Signature string
|
|
|
|
_ bool `property:"ackd"`
|
2020-10-09 18:10:03 +00:00
|
|
|
}
|
|
|
|
|
2020-11-23 21:13:09 +00:00
|
|
|
func (this *MessageModel) Handle() string {
|
2020-10-09 18:10:03 +00:00
|
|
|
return this.handle
|
|
|
|
}
|
|
|
|
|
|
|
|
func (this *MessageModel) setHandle(handle string) {
|
|
|
|
this.handle = handle
|
|
|
|
}
|
|
|
|
|
|
|
|
func (this *MessageModel) init() {
|
|
|
|
mdt := reflect.TypeOf([]MessageWrapper{}).Elem()
|
|
|
|
roles := make(map[int]*core.QByteArray)
|
|
|
|
for i := 0; i < mdt.NumField(); i++ {
|
2020-10-20 22:57:34 +00:00
|
|
|
if mdt.Field(i).Name == "Acknowledged" {
|
|
|
|
this.ackIdx = int(core.Qt__UserRole) + 1 + i
|
|
|
|
}
|
2020-11-23 21:13:09 +00:00
|
|
|
roles[int(core.Qt__UserRole)+1+i] = core.NewQByteArray2(mdt.Field(i).Name, -1)
|
2020-10-09 18:10:03 +00:00
|
|
|
}
|
|
|
|
roles[int(core.Qt__DisplayRole)] = core.NewQByteArray2("display", -1)
|
|
|
|
this.SetRoles(roles)
|
|
|
|
|
|
|
|
this.ConnectData(this.data)
|
|
|
|
this.ConnectRowCount(this.rowCount)
|
|
|
|
this.ConnectColumnCount(this.columnCount)
|
|
|
|
this.ConnectHeaderData(this.headerData)
|
|
|
|
this.ConnectRoleNames(this.roleNames)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (this *MessageModel) roleNames() map[int]*core.QByteArray {
|
|
|
|
return this.Roles()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (this *MessageModel) isGroup() bool {
|
|
|
|
return len(this.Handle()) == 32
|
|
|
|
}
|
|
|
|
|
|
|
|
func (this *MessageModel) getNick(handle string) string {
|
|
|
|
return GetNick(handle)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (this *MessageModel) getImage(handle string) string {
|
|
|
|
return GetProfilePic(handle)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (this *MessageModel) num() int {
|
|
|
|
if this.Handle() == "" || the.Peer == nil {
|
2020-10-20 22:57:34 +00:00
|
|
|
log.Debugf("MessageModel.num: early returning 0")
|
2020-10-09 18:10:03 +00:00
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
|
|
|
if this.isGroup() {
|
|
|
|
group := the.Peer.GetGroup(this.Handle())
|
|
|
|
if group != nil {
|
|
|
|
return len(group.Timeline.Messages) + len(group.UnacknowledgedMessages)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
contact := the.Peer.GetContact(this.Handle())
|
|
|
|
if contact != nil {
|
|
|
|
return len(contact.Timeline.Messages)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-20 22:57:34 +00:00
|
|
|
log.Warnf("MessageModel.num: group/contact was nil, returning 0")
|
2020-10-09 18:10:03 +00:00
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
|
|
|
func (this *MessageModel) getMessage(idx int) *MessageWrapper {
|
2020-11-23 21:13:09 +00:00
|
|
|
modelmsg := model.Message{Message: "[an unexpected cwtch error occurred]"}
|
2020-10-20 22:57:34 +00:00
|
|
|
var ackd bool
|
2020-10-09 18:10:03 +00:00
|
|
|
|
|
|
|
if this.isGroup() {
|
|
|
|
group := the.Peer.GetGroup(this.Handle())
|
|
|
|
if idx >= len(group.Timeline.Messages) {
|
2020-11-23 21:13:09 +00:00
|
|
|
modelmsg = group.UnacknowledgedMessages[idx-len(group.Timeline.Messages)]
|
2020-10-09 18:10:03 +00:00
|
|
|
} else {
|
|
|
|
modelmsg = group.Timeline.Messages[idx]
|
2020-10-20 22:57:34 +00:00
|
|
|
ackd = true
|
2020-10-09 18:10:03 +00:00
|
|
|
}
|
|
|
|
} else {
|
2020-10-23 01:01:48 +00:00
|
|
|
if this.Handle() != "" && the.Peer != nil {
|
|
|
|
contact := the.Peer.GetContact(this.Handle())
|
|
|
|
if contact != nil {
|
|
|
|
if idx >= len(contact.Timeline.Messages) {
|
|
|
|
log.Errorf("requested message[%d] of only %d", idx, len(contact.Timeline.Messages))
|
|
|
|
} else {
|
|
|
|
modelmsg = contact.Timeline.Messages[idx]
|
|
|
|
ackd = modelmsg.Acknowledged
|
|
|
|
}
|
|
|
|
}
|
2020-10-09 18:10:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-23 21:13:09 +00:00
|
|
|
return &MessageWrapper{
|
|
|
|
Message: modelmsg,
|
|
|
|
Timestamp: modelmsg.Timestamp.Unix(),
|
|
|
|
RawMessage: modelmsg.Message,
|
|
|
|
PeerID: modelmsg.PeerID,
|
|
|
|
Error: modelmsg.Error,
|
2020-10-20 22:57:34 +00:00
|
|
|
Acknowledged: ackd,
|
2020-11-23 21:13:09 +00:00
|
|
|
Day: modelmsg.Timestamp.Format("January 2, 2006"),
|
|
|
|
Signature: hex.EncodeToString(modelmsg.Signature),
|
2020-10-09 18:10:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (this *MessageModel) data(index *core.QModelIndex, role int) *core.QVariant {
|
|
|
|
if !index.IsValid() {
|
|
|
|
return core.NewQVariant()
|
|
|
|
}
|
|
|
|
if index.Row() >= this.num() {
|
|
|
|
return core.NewQVariant()
|
|
|
|
}
|
|
|
|
|
|
|
|
if role == int(core.Qt__DisplayRole) {
|
|
|
|
role = index.Column() + int(core.Qt__UserRole) + 1
|
|
|
|
}
|
|
|
|
|
|
|
|
// modelData-element [role]-field value (aka the data ~_~)
|
|
|
|
mderfv := reflect.ValueOf(*this.getMessage(index.Row())).Field(role - int(core.Qt__UserRole) - 1)
|
|
|
|
typeStr := reflect.TypeOf([]MessageWrapper{}).Elem().Field(role - int(core.Qt__UserRole) - 1).Type.String()
|
|
|
|
if typeStr == "string" {
|
|
|
|
return core.NewQVariant1(mderfv.String())
|
|
|
|
} else if strings.HasPrefix(typeStr, "int") {
|
|
|
|
return core.NewQVariant1(mderfv.Int())
|
|
|
|
} else if strings.HasPrefix(typeStr, "float") {
|
|
|
|
return core.NewQVariant1(mderfv.Float())
|
|
|
|
} else if typeStr == "bool" {
|
|
|
|
return core.NewQVariant1(mderfv.Bool())
|
|
|
|
}
|
|
|
|
|
|
|
|
return core.NewQVariant1("unknown type " + typeStr)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (this *MessageModel) headerData(section int, orientation core.Qt__Orientation, role int) *core.QVariant {
|
|
|
|
if role != int(core.Qt__DisplayRole) || orientation == core.Qt__Vertical {
|
|
|
|
return this.HeaderDataDefault(section, orientation, role)
|
|
|
|
}
|
|
|
|
|
2020-10-20 22:57:34 +00:00
|
|
|
mdt := reflect.TypeOf([]MessageWrapper{}).Elem()
|
2020-10-09 18:10:03 +00:00
|
|
|
return core.NewQVariant12(mdt.Field(section).Name)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (this *MessageModel) rowCount(parent *core.QModelIndex) int {
|
|
|
|
return this.num()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (this *MessageModel) columnCount(parent *core.QModelIndex) int {
|
|
|
|
return reflect.TypeOf(MessageWrapper{}).NumField()
|
|
|
|
}
|
|
|
|
|
2020-10-20 22:57:34 +00:00
|
|
|
// perform this.BeginInsertRows() on the gui thread
|
|
|
|
// important:
|
|
|
|
// 1. idx MUST be set to this.num()'s value *before* calling addMessage()
|
|
|
|
// 2. insert the message yourself
|
|
|
|
// 3. this.RequestEIR() *must* be called afterward
|
2020-10-09 18:10:03 +00:00
|
|
|
func (this *MessageModel) addMessage(idx int) {
|
2020-10-20 22:57:34 +00:00
|
|
|
this.BeginInsertRows(core.NewQModelIndex(), idx, idx)
|
2020-10-09 18:10:03 +00:00
|
|
|
}
|
|
|
|
|
2020-10-20 22:57:34 +00:00
|
|
|
// perform this.EndInsertRows() on the gui thread after an AddMessage()
|
2020-10-09 18:10:03 +00:00
|
|
|
func (this *MessageModel) requestEIR() {
|
|
|
|
this.EndInsertRows()
|
|
|
|
}
|
|
|
|
|
2020-10-20 22:57:34 +00:00
|
|
|
// notify the gui that the message acknowledgement at index idx has been modified
|
|
|
|
func (this *MessageModel) editMessage(idx int) {
|
|
|
|
if idx < 0 || idx >= this.num() {
|
|
|
|
log.Errorf("cant edit message %v. probably fine", idx)
|
|
|
|
return
|
|
|
|
}
|
2020-10-09 18:10:03 +00:00
|
|
|
|
2020-10-20 22:57:34 +00:00
|
|
|
log.Debugf("editMessage(%v, %v)", idx, this.ackIdx)
|
|
|
|
indexObject := this.Index(idx, 0, core.NewQModelIndex())
|
|
|
|
// replace third param with []int{} to update all attributes instead
|
|
|
|
this.DataChanged(indexObject, indexObject, []int{this.ackIdx})
|
2020-10-09 18:10:03 +00:00
|
|
|
}
|