Build system, messages support and more
This commit is contained in:
@@ -7,7 +7,14 @@ Rectangle {
|
||||
property int dimension: HStyle.avatar.size
|
||||
property bool hidden: false
|
||||
|
||||
function hue_from_name(name) {
|
||||
function stripUserId(user_id) {
|
||||
return user_id.substring(1) // Remove leading @
|
||||
}
|
||||
function stripRoomName(name) {
|
||||
return name[0] == "#" ? name.substring(1) : name
|
||||
}
|
||||
|
||||
function hueFromName(name) {
|
||||
var hue = 0
|
||||
for (var i = 0; i < name.length; i++) {
|
||||
hue += name.charCodeAt(i) * 99
|
||||
@@ -24,7 +31,7 @@ Rectangle {
|
||||
|
||||
color: name ?
|
||||
Qt.hsla(
|
||||
hue_from_name(name),
|
||||
hueFromName(name),
|
||||
HStyle.avatar.background.saturation,
|
||||
HStyle.avatar.background.lightness,
|
||||
HStyle.avatar.background.alpha
|
||||
|
@@ -32,11 +32,6 @@ Button {
|
||||
signal pressed
|
||||
signal released
|
||||
|
||||
function loadingUntilFutureDone(future) {
|
||||
loading = true
|
||||
future.onGotResult.connect(function() { loading = false })
|
||||
}
|
||||
|
||||
id: button
|
||||
|
||||
background: Rectangle {
|
||||
|
@@ -1,85 +1,112 @@
|
||||
import QtQuick 2.7
|
||||
import SortFilterProxyModel 0.2
|
||||
|
||||
ListModel {
|
||||
SortFilterProxyModel {
|
||||
// To initialize a HListModel with items,
|
||||
// use `Component.onCompleted: extend([{"foo": 1, "bar": 2}, ...])`
|
||||
|
||||
id: listModel
|
||||
id: sortFilteredModel
|
||||
|
||||
property var model: ListModel {}
|
||||
sourceModel: model // Can't assign a "ListModel {}" directly here
|
||||
|
||||
function append(dict) { return model.append(dict) }
|
||||
function clear() { return model.clear() }
|
||||
function insert(index, dict) { return model.inset(index, dict) }
|
||||
function move(from, to, n) { return model.move(from, to, n) }
|
||||
function remove(index, count) { return model.remove(index, count) }
|
||||
function set(index, dict) { return model.set(index, dict) }
|
||||
function sync() { return model.sync() }
|
||||
function setProperty(index, prop, value) {
|
||||
return model.setProperty(index, prop, value)
|
||||
}
|
||||
|
||||
function extend(new_items) {
|
||||
for (var i = 0; i < new_items.length; i++) {
|
||||
listModel.append(new_items[i])
|
||||
model.append(new_items[i])
|
||||
}
|
||||
}
|
||||
|
||||
function getIndices(where_role, is, max) { // max: undefined or int
|
||||
function getIndices(where_roles_are, max_results, max_tries) {
|
||||
// max arguments: unefined or int
|
||||
var results = []
|
||||
|
||||
for (var i = 0; i < listModel.count; i++) {
|
||||
if (listModel.get(i)[where_role] == is) {
|
||||
results.push(i)
|
||||
for (var i = 0; i < model.count; i++) {
|
||||
var item = model.get(i)
|
||||
var include = true
|
||||
|
||||
if (max && results.length >= max) {
|
||||
for (var role in where_roles_are) {
|
||||
if (item[role] != where_roles_are[role]) {
|
||||
include = false
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (include) {
|
||||
results.push(i)
|
||||
if (max_results && results.length >= max_results) {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (max_tries && i >= max_tries) {
|
||||
break
|
||||
}
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
function getWhere(where_role, is, max) {
|
||||
var indices = getIndices(where_role, is, max)
|
||||
var results = []
|
||||
function getWhere(roles_are, max_results, max_tries) {
|
||||
var indices = getIndices(roles_are, max_results, max_tries)
|
||||
var items = []
|
||||
|
||||
for (var i = 0; i < indices.length; i++) {
|
||||
results.push(listModel.get(indices[i]))
|
||||
items.push(model.get(indices[i]))
|
||||
}
|
||||
return results
|
||||
return items
|
||||
}
|
||||
|
||||
function forEachWhere(where_role, is, max, func) {
|
||||
var items = getWhere(where_role, is, max)
|
||||
function forEachWhere(roles_are, func, max_results, max_tries) {
|
||||
var items = getWhere(roles_are, max_results, max_tries)
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
func(item)
|
||||
func(items[i])
|
||||
}
|
||||
}
|
||||
|
||||
function upsert(where_role, is, new_item, update_if_exist) {
|
||||
// new_item can contain only the keys we're interested in updating
|
||||
|
||||
var indices = getIndices(where_role, is, 1)
|
||||
function upsert(where_roles_are, new_item, update_if_exist, max_tries) {
|
||||
var indices = getIndices(where_roles_are, 1, max_tries)
|
||||
|
||||
if (indices.length == 0) {
|
||||
listModel.append(new_item)
|
||||
return listModel.get(listModel.count)
|
||||
model.append(new_item)
|
||||
return model.get(model.count)
|
||||
}
|
||||
|
||||
if (update_if_exist != false) {
|
||||
listModel.set(indices[0], new_item)
|
||||
model.set(indices[0], new_item)
|
||||
}
|
||||
return listModel.get(indices[0])
|
||||
return model.get(indices[0])
|
||||
}
|
||||
|
||||
function pop(index) {
|
||||
var item = listModel.get(index)
|
||||
listModel.remove(index)
|
||||
var item = model.get(index)
|
||||
model.remove(index)
|
||||
return item
|
||||
}
|
||||
|
||||
function popWhere(where_role, is, max) {
|
||||
var indices = getIndices(where_role, is, max)
|
||||
var results = []
|
||||
function popWhere(roles_are, max_results, max_tries) {
|
||||
var indices = getIndices(roles_are, max_results, max_tries)
|
||||
var items = []
|
||||
|
||||
for (var i = 0; i < indices.length; i++) {
|
||||
results.push(listModel.get(indices[i]))
|
||||
listModel.remove(indices[i])
|
||||
items.push(model.get(indices[i]))
|
||||
model.remove(indices[i])
|
||||
}
|
||||
return results
|
||||
return items
|
||||
}
|
||||
|
||||
|
||||
function toObject(item_list) {
|
||||
item_list = item_list || listModel
|
||||
item_list = item_list || sortFilteredModel
|
||||
var obj_list = []
|
||||
|
||||
for (var i = 0; i < item_list.count; i++) {
|
||||
|
@@ -6,6 +6,7 @@ Banner {
|
||||
|
||||
color: HStyle.chat.inviteBanner.background
|
||||
|
||||
// TODO: get disp name from models.users, inviter = userid now
|
||||
avatar.name: inviter ? inviter.displayname : ""
|
||||
//avatar.imageUrl: inviter ? inviter.avatar_url : ""
|
||||
|
||||
|
@@ -10,27 +10,27 @@ HColumnLayout {
|
||||
property string category: ""
|
||||
property string roomId: ""
|
||||
|
||||
readonly property var roomInfo:
|
||||
Backend.accounts.get(userId)
|
||||
.roomCategories.get(category)
|
||||
.rooms.get(roomId)
|
||||
readonly property var roomInfo: models.rooms.getWhere(
|
||||
{"userId": userId, "roomId": roomId, "category": category}, 1
|
||||
)[0]
|
||||
|
||||
readonly property var sender: Backend.users.get(userId)
|
||||
readonly property var sender:
|
||||
models.users.getWhere({"userId": userId}, 1)[0]
|
||||
|
||||
readonly property bool hasUnknownDevices:
|
||||
category == "Rooms" ?
|
||||
Backend.clients.get(userId).roomHasUnknownDevices(roomId) : false
|
||||
readonly property bool hasUnknownDevices: false
|
||||
//category == "Rooms" ?
|
||||
//Backend.clients.get(userId).roomHasUnknownDevices(roomId) : false
|
||||
|
||||
id: chatPage
|
||||
onFocusChanged: sendBox.setFocus()
|
||||
|
||||
Component.onCompleted: Backend.signals.roomCategoryChanged.connect(
|
||||
function(forUserId, forRoomId, previous, now) {
|
||||
if (chatPage && forUserId == userId && forRoomId == roomId) {
|
||||
chatPage.category = now
|
||||
}
|
||||
}
|
||||
)
|
||||
//Component.onCompleted: Backend.signals.roomCategoryChanged.connect(
|
||||
//function(forUserId, forRoomId, previous, now) {
|
||||
//if (chatPage && forUserId == userId && forRoomId == roomId) {
|
||||
//chatPage.category = now
|
||||
//}
|
||||
//}
|
||||
//)
|
||||
|
||||
RoomHeader {
|
||||
id: roomHeader
|
||||
@@ -77,72 +77,72 @@ HColumnLayout {
|
||||
}
|
||||
}
|
||||
|
||||
RoomSidePane {
|
||||
id: roomSidePane
|
||||
// RoomSidePane {
|
||||
//id: roomSidePane
|
||||
|
||||
activeView: roomHeader.activeButton
|
||||
property int oldWidth: width
|
||||
onActiveViewChanged:
|
||||
activeView ? restoreAnimation.start() : hideAnimation.start()
|
||||
//activeView: roomHeader.activeButton
|
||||
//property int oldWidth: width
|
||||
//onActiveViewChanged:
|
||||
//activeView ? restoreAnimation.start() : hideAnimation.start()
|
||||
|
||||
NumberAnimation {
|
||||
id: hideAnimation
|
||||
target: roomSidePane
|
||||
properties: "width"
|
||||
duration: HStyle.animationDuration
|
||||
from: target.width
|
||||
to: 0
|
||||
//NumberAnimation {
|
||||
//id: hideAnimation
|
||||
//target: roomSidePane
|
||||
//properties: "width"
|
||||
//duration: HStyle.animationDuration
|
||||
//from: target.width
|
||||
//to: 0
|
||||
|
||||
onStarted: {
|
||||
target.oldWidth = target.width
|
||||
target.Layout.minimumWidth = 0
|
||||
}
|
||||
}
|
||||
//onStarted: {
|
||||
//target.oldWidth = target.width
|
||||
//target.Layout.minimumWidth = 0
|
||||
//}
|
||||
//}
|
||||
|
||||
NumberAnimation {
|
||||
id: restoreAnimation
|
||||
target: roomSidePane
|
||||
properties: "width"
|
||||
duration: HStyle.animationDuration
|
||||
from: 0
|
||||
to: target.oldWidth
|
||||
//NumberAnimation {
|
||||
//id: restoreAnimation
|
||||
//target: roomSidePane
|
||||
//properties: "width"
|
||||
//duration: HStyle.animationDuration
|
||||
//from: 0
|
||||
//to: target.oldWidth
|
||||
|
||||
onStopped: target.Layout.minimumWidth = Qt.binding(
|
||||
function() { return HStyle.avatar.size }
|
||||
)
|
||||
}
|
||||
//onStopped: target.Layout.minimumWidth = Qt.binding(
|
||||
//function() { return HStyle.avatar.size }
|
||||
//)
|
||||
//}
|
||||
|
||||
collapsed: width < HStyle.avatar.size + 8
|
||||
//collapsed: width < HStyle.avatar.size + 8
|
||||
|
||||
property bool wasSnapped: false
|
||||
property int referenceWidth: roomHeader.buttonsWidth
|
||||
onReferenceWidthChanged: {
|
||||
if (chatSplitView.canAutoSize || wasSnapped) {
|
||||
if (wasSnapped) { chatSplitView.canAutoSize = true }
|
||||
width = referenceWidth
|
||||
}
|
||||
}
|
||||
//property bool wasSnapped: false
|
||||
//property int referenceWidth: roomHeader.buttonsWidth
|
||||
//onReferenceWidthChanged: {
|
||||
//if (chatSplitView.canAutoSize || wasSnapped) {
|
||||
//if (wasSnapped) { chatSplitView.canAutoSize = true }
|
||||
//width = referenceWidth
|
||||
//}
|
||||
//}
|
||||
|
||||
property int currentWidth: width
|
||||
onCurrentWidthChanged: {
|
||||
if (referenceWidth != width &&
|
||||
referenceWidth - 15 < width &&
|
||||
width < referenceWidth + 15)
|
||||
{
|
||||
currentWidth = referenceWidth
|
||||
width = referenceWidth
|
||||
wasSnapped = true
|
||||
currentWidth = Qt.binding(
|
||||
function() { return roomSidePane.width }
|
||||
)
|
||||
} else {
|
||||
wasSnapped = false
|
||||
}
|
||||
}
|
||||
//property int currentWidth: width
|
||||
//onCurrentWidthChanged: {
|
||||
//if (referenceWidth != width &&
|
||||
//referenceWidth - 15 < width &&
|
||||
//width < referenceWidth + 15)
|
||||
//{
|
||||
//currentWidth = referenceWidth
|
||||
//width = referenceWidth
|
||||
//wasSnapped = true
|
||||
//currentWidth = Qt.binding(
|
||||
//function() { return roomSidePane.width }
|
||||
//)
|
||||
//} else {
|
||||
//wasSnapped = false
|
||||
//}
|
||||
//}
|
||||
|
||||
width: referenceWidth // Initial width
|
||||
Layout.minimumWidth: HStyle.avatar.size
|
||||
Layout.maximumWidth: parent.width
|
||||
}
|
||||
//width: referenceWidth // Initial width
|
||||
//Layout.minimumWidth: HStyle.avatar.size
|
||||
//Layout.maximumWidth: parent.width
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
@@ -2,7 +2,7 @@ import QtQuick 2.7
|
||||
import "../../Base"
|
||||
|
||||
HNoticePage {
|
||||
text: dateTime.toLocaleDateString()
|
||||
text: model.date.toLocaleDateString()
|
||||
color: HStyle.chat.daybreak.foreground
|
||||
backgroundColor: HStyle.chat.daybreak.background
|
||||
radius: HStyle.chat.daybreak.radius
|
||||
|
@@ -16,7 +16,7 @@ Row {
|
||||
|
||||
HAvatar {
|
||||
id: avatar
|
||||
name: sender.displayName.value
|
||||
name: sender.displayName || stripUserId(sender.userId)
|
||||
hidden: combine
|
||||
dimension: 28
|
||||
}
|
||||
|
@@ -10,7 +10,7 @@ Row {
|
||||
HAvatar {
|
||||
id: avatar
|
||||
hidden: combine
|
||||
name: sender.displayName.value
|
||||
name: senderInfo.displayName || stripUserId(model.senderId)
|
||||
dimension: 48
|
||||
}
|
||||
|
||||
@@ -38,8 +38,8 @@ Row {
|
||||
visible: height > 0
|
||||
|
||||
id: nameLabel
|
||||
text: sender.displayName.value
|
||||
color: Qt.hsla(Backend.hueFromString(text),
|
||||
text: senderInfo.displayName || model.senderId
|
||||
color: Qt.hsla(avatar.hueFromName(avatar.name),
|
||||
HStyle.displayName.saturation,
|
||||
HStyle.displayName.lightness,
|
||||
1)
|
||||
@@ -56,17 +56,16 @@ Row {
|
||||
width: parent.width
|
||||
|
||||
id: contentLabel
|
||||
text: (dict.formatted_body ?
|
||||
Backend.htmlFilter.filter(dict.formatted_body) :
|
||||
dict.body) +
|
||||
text: model.content +
|
||||
" <font size=" + HStyle.fontSize.small +
|
||||
"px color=" + HStyle.chat.message.date + ">" +
|
||||
Qt.formatDateTime(dateTime, "hh:mm:ss") +
|
||||
Qt.formatDateTime(model.date, "hh:mm:ss") +
|
||||
"</font>" +
|
||||
(isLocalEcho ?
|
||||
(model.isLocalEcho ?
|
||||
" <font size=" + HStyle.fontSize.small +
|
||||
"px>⏳</font>" : "")
|
||||
textFormat: Text.RichText
|
||||
textFormat: model.type == "text" ?
|
||||
Text.PlainText : Text.RichText
|
||||
color: HStyle.chat.message.body
|
||||
wrapMode: Text.Wrap
|
||||
|
||||
|
@@ -1,7 +1,6 @@
|
||||
import QtQuick 2.7
|
||||
import QtQuick.Layouts 1.3
|
||||
import "../../Base"
|
||||
import "../utils.js" as ChatJS
|
||||
|
||||
Column {
|
||||
id: roomEventDelegate
|
||||
@@ -10,46 +9,47 @@ Column {
|
||||
return Math.round((((date2 - date1) % 86400000) % 3600000) / 60000)
|
||||
}
|
||||
|
||||
function getIsMessage(type_) { return type_.startsWith("RoomMessage") }
|
||||
|
||||
function getPreviousItem() {
|
||||
return index < roomEventListView.model.count - 1 ?
|
||||
roomEventListView.model.get(index + 1) : null
|
||||
}
|
||||
|
||||
function getIsMessage(type) {
|
||||
return true
|
||||
}
|
||||
|
||||
property var previousItem: getPreviousItem()
|
||||
signal reloadPreviousItem()
|
||||
onReloadPreviousItem: previousItem = getPreviousItem()
|
||||
|
||||
readonly property bool isMessage: getIsMessage(type)
|
||||
property var senderInfo: null
|
||||
Component.onCompleted:
|
||||
senderInfo = models.users.getUser(chatPage.userId, senderId)
|
||||
|
||||
readonly property bool isUndecryptableEvent:
|
||||
type === "OlmEvent" || type === "MegolmEvent"
|
||||
//readonly property bool isMessage: ! model.type.match(/^event.*/)
|
||||
readonly property bool isMessage: getIsMessage(model.type)
|
||||
|
||||
readonly property var sender: Backend.users.get(dict.sender)
|
||||
readonly property bool isOwn: chatPage.userId === senderId
|
||||
|
||||
readonly property bool isOwn:
|
||||
chatPage.userId === dict.sender
|
||||
|
||||
readonly property bool isFirstEvent: type == "RoomCreateEvent"
|
||||
readonly property bool isFirstEvent: model.type == "eventCreate"
|
||||
|
||||
readonly property bool combine:
|
||||
previousItem &&
|
||||
! talkBreak &&
|
||||
! dayBreak &&
|
||||
getIsMessage(previousItem.type) === isMessage &&
|
||||
previousItem.dict.sender === dict.sender &&
|
||||
minsBetween(previousItem.dateTime, dateTime) <= 5
|
||||
previousItem.senderId === senderId &&
|
||||
minsBetween(previousItem.date, model.date) <= 5
|
||||
|
||||
readonly property bool dayBreak:
|
||||
isFirstEvent ||
|
||||
previousItem &&
|
||||
dateTime.getDate() != previousItem.dateTime.getDate()
|
||||
model.date.getDate() != previousItem.date.getDate()
|
||||
|
||||
readonly property bool talkBreak:
|
||||
previousItem &&
|
||||
! dayBreak &&
|
||||
minsBetween(previousItem.dateTime, dateTime) >= 20
|
||||
minsBetween(previousItem.date, model.date) >= 20
|
||||
|
||||
|
||||
property int standardSpacing: 16
|
||||
|
@@ -1,4 +1,5 @@
|
||||
import QtQuick 2.7
|
||||
import SortFilterProxyModel 0.2
|
||||
import "../../Base"
|
||||
|
||||
HRectangle {
|
||||
@@ -8,10 +9,19 @@ HRectangle {
|
||||
|
||||
HListView {
|
||||
id: roomEventListView
|
||||
delegate: RoomEventDelegate {}
|
||||
model: Backend.roomEvents.get(chatPage.roomId)
|
||||
clip: true
|
||||
|
||||
model: HListModel {
|
||||
sourceModel: models.timelines
|
||||
|
||||
filters: ValueFilter {
|
||||
roleName: "roomId"
|
||||
value: chatPage.roomId
|
||||
}
|
||||
}
|
||||
|
||||
delegate: RoomEventDelegate {}
|
||||
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: space
|
||||
anchors.rightMargin: space
|
||||
@@ -29,7 +39,7 @@ HRectangle {
|
||||
|
||||
onYPosChanged: {
|
||||
if (chatPage.category != "Invites" && yPos <= 0.1) {
|
||||
Backend.loadPastEvents(chatPage.roomId)
|
||||
//Backend.loadPastEvents(chatPage.roomId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -3,7 +3,7 @@ import QtQuick.Layouts 1.3
|
||||
import "../Base"
|
||||
|
||||
HRectangle {
|
||||
property string displayName: ""
|
||||
property var displayName: ""
|
||||
property string topic: ""
|
||||
|
||||
property alias buttonsImplicitWidth: viewButtons.implicitWidth
|
||||
@@ -22,7 +22,7 @@ HRectangle {
|
||||
|
||||
HAvatar {
|
||||
id: avatar
|
||||
name: displayName
|
||||
name: stripRoomName(displayName) || qsTr("Empty room")
|
||||
dimension: roomHeader.height
|
||||
Layout.alignment: Qt.AlignTop
|
||||
}
|
||||
|
@@ -15,7 +15,7 @@ MouseArea {
|
||||
|
||||
HAvatar {
|
||||
id: memberAvatar
|
||||
name: member.displayName.value
|
||||
name: member.displayName || stripUserId(member.userId)
|
||||
}
|
||||
|
||||
HColumnLayout {
|
||||
|
@@ -18,7 +18,7 @@ HRectangle {
|
||||
|
||||
HAvatar {
|
||||
id: avatar
|
||||
name: chatPage.sender.displayName.value
|
||||
name: chatPage.sender.displayName || stripUserId(chatPage.userId)
|
||||
dimension: root.Layout.minimumHeight
|
||||
}
|
||||
|
||||
|
@@ -1,26 +1,28 @@
|
||||
function clientId(user_id, category, room_id) {
|
||||
return user_id + " " + room_id + " " + category
|
||||
}
|
||||
|
||||
|
||||
function onRoomUpdated(user_id, category, room_id, display_name, avatar_url,
|
||||
topic, last_event_date, inviter, left_event) {
|
||||
|
||||
var client_id = clientId(user_id, category, room_id)
|
||||
var rooms = models.rooms
|
||||
models.roomCategories.upsert({"userId": user_id, "name": category}, {
|
||||
"userId": user_id,
|
||||
"name": category
|
||||
})
|
||||
|
||||
var rooms = models.rooms
|
||||
|
||||
function roles(for_category) {
|
||||
return {"userId": user_id, "roomId": room_id, "category": for_category}
|
||||
}
|
||||
|
||||
if (category == "Invites") {
|
||||
rooms.popWhere("clientId", clientId(user_id, "Rooms", room_id))
|
||||
rooms.popWhere("clientId", clientId(user_id, "Left", room_id))
|
||||
rooms.popWhere(roles("Rooms"), 1)
|
||||
rooms.popWhere(roles("Left"), 1)
|
||||
}
|
||||
else if (category == "Rooms") {
|
||||
rooms.popWhere("clientId", clientId(user_id, "Invites", room_id))
|
||||
rooms.popWhere("clientId", clientId(user_id, "Left", room_id))
|
||||
rooms.popWhere(roles("Invites"), 1)
|
||||
rooms.popWhere(roles("Left"), 1)
|
||||
}
|
||||
else if (category == "Left") {
|
||||
var old_room =
|
||||
rooms.popWhere("clientId", clientId(user_id, "Rooms", room_id)) ||
|
||||
rooms.popWhere("clientId", clientId(user_id, "Invites", room_id))
|
||||
var old_room = rooms.popWhere(roles("Invites"), 1)[0] ||
|
||||
rooms.popWhere(roles("Rooms"), 1)[0]
|
||||
|
||||
if (old_room) {
|
||||
display_name = old_room.displayName
|
||||
@@ -30,8 +32,7 @@ function onRoomUpdated(user_id, category, room_id, display_name, avatar_url,
|
||||
}
|
||||
}
|
||||
|
||||
rooms.upsert("clientId", client_id , {
|
||||
"clientId": client_id,
|
||||
rooms.upsert(roles(category), {
|
||||
"userId": user_id,
|
||||
"category": category,
|
||||
"roomId": room_id,
|
||||
@@ -47,8 +48,8 @@ function onRoomUpdated(user_id, category, room_id, display_name, avatar_url,
|
||||
|
||||
|
||||
function onRoomDeleted(user_id, category, room_id) {
|
||||
var client_id = clientId(user_id, category, room_id)
|
||||
return models.rooms.popWhere("clientId", client_id, 1)
|
||||
var roles = {"userId": user_id, "roomId": room_id, "category": category}
|
||||
models.rooms.popWhere(roles, 1)
|
||||
}
|
||||
|
||||
|
||||
|
@@ -0,0 +1,12 @@
|
||||
function onHtmlMessageReceived(type, room_id, event_id, sender_id, date,
|
||||
is_local_echo, content) {
|
||||
models.timelines.upsert({"eventId": event_id}, {
|
||||
"type": type,
|
||||
"roomId": room_id,
|
||||
"eventId": event_id,
|
||||
"senderId": sender_id,
|
||||
"date": date,
|
||||
"isLocalEcho": is_local_echo,
|
||||
"content": content,
|
||||
}, true, 1000)
|
||||
}
|
||||
|
@@ -2,18 +2,17 @@ function onAccountUpdated(user_id) {
|
||||
models.accounts.append({"userId": user_id})
|
||||
}
|
||||
|
||||
function AccountDeleted(user_id) {
|
||||
models.accounts.popWhere("userId", user_id, 1)
|
||||
function onAccountDeleted(user_id) {
|
||||
models.accounts.popWhere({"userId": user_id}, 1)
|
||||
}
|
||||
|
||||
function onUserUpdated(user_id, display_name, avatar_url, status_message) {
|
||||
models.users.upsert("userId", user_id, {
|
||||
models.users.upsert({"userId": user_id}, {
|
||||
"userId": user_id,
|
||||
"displayName": display_name,
|
||||
"avatarUrl": avatar_url,
|
||||
"statusMessage": status_message
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
function onDeviceUpdated(user_id, device_id, ed25519_key, trust, display_name,
|
||||
|
@@ -1,4 +1,5 @@
|
||||
import QtQuick 2.7
|
||||
import SortFilterProxyModel 0.2
|
||||
import "Base"
|
||||
|
||||
QtObject {
|
||||
@@ -8,7 +9,7 @@ QtObject {
|
||||
function getUser(as_account_id, wanted_user_id) {
|
||||
wanted_user_id = wanted_user_id || as_account_id
|
||||
|
||||
var found = users.getWhere("userId", wanted_user_id, 1)
|
||||
var found = users.getWhere({"userId": wanted_user_id}, 1)
|
||||
if (found.length > 0) { return found[0] }
|
||||
|
||||
users.append({
|
||||
@@ -22,13 +23,20 @@ QtObject {
|
||||
as_account_id, "request_user_update_event", [wanted_user_id]
|
||||
)
|
||||
|
||||
return users.getWhere("userId", wanted_user_id, 1)[0]
|
||||
return users.getWhere({"userId": wanted_user_id}, 1)[0]
|
||||
}
|
||||
}
|
||||
|
||||
property HListModel devices: HListModel {}
|
||||
|
||||
property HListModel roomCategories: HListModel {}
|
||||
|
||||
property HListModel rooms: HListModel {}
|
||||
|
||||
property HListModel timelines: HListModel {}
|
||||
property HListModel timelines: HListModel {
|
||||
sorters: RoleSorter {
|
||||
roleName: "date"
|
||||
sortOrder: Qt.DescendingOrder
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -4,7 +4,7 @@ import "../Base"
|
||||
|
||||
Item {
|
||||
property string loginWith: "username"
|
||||
property var client: null
|
||||
property string userId: ""
|
||||
|
||||
HInterfaceBox {
|
||||
id: rememberBox
|
||||
@@ -20,10 +20,13 @@ Item {
|
||||
|
||||
buttonCallbacks: {
|
||||
"yes": function(button) {
|
||||
Backend.clients.remember(client)
|
||||
py.callCoro("save_account", [userId])
|
||||
pageStack.showPage("Default")
|
||||
},
|
||||
"no": function(button) {
|
||||
py.callCoro("forget_account", [userId])
|
||||
pageStack.showPage("Default")
|
||||
},
|
||||
"no": function(button) { pageStack.showPage("Default") },
|
||||
}
|
||||
|
||||
HLabel {
|
||||
|
@@ -4,7 +4,7 @@ import "../Base"
|
||||
|
||||
Item {
|
||||
property string loginWith: "username"
|
||||
onFocusChanged: identifierField.forceActiveFocus()
|
||||
onFocusChanged: idField.forceActiveFocus()
|
||||
|
||||
HInterfaceBox {
|
||||
id: signInBox
|
||||
@@ -23,15 +23,15 @@ Item {
|
||||
"register": function(button) {},
|
||||
|
||||
"login": function(button) {
|
||||
var future = Backend.clients.new(
|
||||
"matrix.org", identifierField.text, passwordField.text
|
||||
)
|
||||
button.loadingUntilFutureDone(future)
|
||||
future.onGotResult.connect(function(client) {
|
||||
button.loading = true
|
||||
var args = [idField.text, passwordField.text]
|
||||
|
||||
py.callCoro("login_client", args, {}, function(user_id) {
|
||||
pageStack.showPage(
|
||||
"RememberAccount",
|
||||
{"loginWith": loginWith, "client": client}
|
||||
{"loginWith": loginWith, "userId": user_id}
|
||||
)
|
||||
button.loading = false
|
||||
})
|
||||
},
|
||||
|
||||
@@ -58,7 +58,7 @@ Item {
|
||||
}
|
||||
|
||||
HTextField {
|
||||
id: identifierField
|
||||
id: idField
|
||||
placeholderText: qsTr(
|
||||
loginWith === "email" ? "Email" :
|
||||
loginWith === "phone" ? "Phone" :
|
||||
|
@@ -9,6 +9,7 @@ Python {
|
||||
property bool ready: false
|
||||
property var pendingCoroutines: ({})
|
||||
|
||||
signal willLoadAccounts(bool will)
|
||||
property bool loadingAccounts: false
|
||||
|
||||
function callCoro(name, args, kwargs, callback) {
|
||||
@@ -32,18 +33,20 @@ Python {
|
||||
}
|
||||
}
|
||||
|
||||
addImportPath("../..")
|
||||
importNames("src", ["APP"], function() {
|
||||
call("APP.start", [Qt.application.arguments], function(debug_on) {
|
||||
window.debug = debug_on
|
||||
addImportPath("src")
|
||||
addImportPath("qrc:/")
|
||||
importNames("python", ["APP"], function() {
|
||||
call("APP.is_debug_on", [Qt.application.arguments], function(on) {
|
||||
window.debug = on
|
||||
|
||||
callCoro("has_saved_accounts", [], {}, function(has) {
|
||||
loadingAccounts = has
|
||||
py.ready = true
|
||||
willLoadAccounts(has)
|
||||
|
||||
if (has) {
|
||||
py.loadingAccounts = true
|
||||
py.callCoro("load_saved_accounts", [], {}, function() {
|
||||
loadingAccounts = false
|
||||
py.loadingAccounts = false
|
||||
})
|
||||
}
|
||||
})
|
||||
|
@@ -20,7 +20,7 @@ Column {
|
||||
|
||||
HAvatar {
|
||||
id: avatar
|
||||
name: user.displayName
|
||||
name: user.displayName || stripUserId(user.userId)
|
||||
}
|
||||
|
||||
HColumnLayout {
|
||||
|
@@ -4,6 +4,8 @@ import "../Base"
|
||||
HRowLayout {
|
||||
id: toolBar
|
||||
|
||||
property alias roomFilter: filterField.text
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: HStyle.bottomElementsHeight
|
||||
|
||||
@@ -17,8 +19,6 @@ HRowLayout {
|
||||
placeholderText: qsTr("Filter rooms")
|
||||
backgroundColor: HStyle.sidePane.filterRooms.background
|
||||
|
||||
onTextChanged: Backend.setRoomFilter(text)
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: parent.height
|
||||
}
|
||||
|
@@ -1,11 +1,20 @@
|
||||
import QtQuick 2.7
|
||||
import QtQuick.Layouts 1.3
|
||||
import SortFilterProxyModel 0.2
|
||||
import "../Base"
|
||||
|
||||
HListView {
|
||||
property string userId: ""
|
||||
|
||||
id: roomCategoriesList
|
||||
model: Backend.accounts.get(userId).roomCategories
|
||||
|
||||
model: SortFilterProxyModel {
|
||||
sourceModel: models.roomCategories
|
||||
filters: ValueFilter {
|
||||
roleName: "userId"
|
||||
value: userId
|
||||
}
|
||||
}
|
||||
|
||||
delegate: RoomCategoryDelegate {}
|
||||
}
|
||||
|
@@ -12,11 +12,11 @@ MouseArea {
|
||||
|
||||
HRowLayout {
|
||||
width: parent.width
|
||||
spacing: roomList.spacing
|
||||
spacing: sidePane.normalSpacing
|
||||
|
||||
HAvatar {
|
||||
id: roomAvatar
|
||||
name: displayName
|
||||
name: stripRoomName(displayName) || qsTr("Empty room")
|
||||
}
|
||||
|
||||
HColumnLayout {
|
||||
@@ -35,27 +35,27 @@ MouseArea {
|
||||
Layout.maximumWidth: parent.width
|
||||
}
|
||||
|
||||
HLabel {
|
||||
function getText() {
|
||||
return SidePaneJS.getLastRoomEventText(
|
||||
roomId, roomList.userId
|
||||
)
|
||||
}
|
||||
//HLabel {
|
||||
//function getText() {
|
||||
//return SidePaneJS.getLastRoomEventText(
|
||||
//roomId, roomList.userId
|
||||
//)
|
||||
//}
|
||||
|
||||
property var lastEvTime: lastEventDateTime
|
||||
onLastEvTimeChanged: subtitleLabel.text = getText()
|
||||
//property var lastEvTime: lastEventDateTime
|
||||
//onLastEvTimeChanged: subtitleLabel.text = getText()
|
||||
|
||||
id: subtitleLabel
|
||||
visible: text !== ""
|
||||
text: getText()
|
||||
textFormat: Text.StyledText
|
||||
//id: subtitleLabel
|
||||
//visible: text !== ""
|
||||
//text: getText()
|
||||
//textFormat: Text.StyledText
|
||||
|
||||
font.pixelSize: HStyle.fontSize.small
|
||||
elide: Text.ElideRight
|
||||
maximumLineCount: 1
|
||||
//font.pixelSize: HStyle.fontSize.small
|
||||
//elide: Text.ElideRight
|
||||
//maximumLineCount: 1
|
||||
|
||||
Layout.maximumWidth: parent.width
|
||||
}
|
||||
//Layout.maximumWidth: parent.width
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,6 @@
|
||||
import QtQuick 2.7
|
||||
import QtQuick.Layouts 1.3
|
||||
import SortFilterProxyModel 0.2
|
||||
import "../Base"
|
||||
|
||||
HListView {
|
||||
@@ -7,8 +8,37 @@ HListView {
|
||||
property string category: ""
|
||||
|
||||
id: roomList
|
||||
spacing: accountList.spacing
|
||||
model:
|
||||
Backend.accounts.get(userId).roomCategories.get(category).sortedRooms
|
||||
spacing: sidePane.normalSpacing
|
||||
|
||||
model: SortFilterProxyModel {
|
||||
sourceModel: models.rooms
|
||||
filters: AllOf {
|
||||
ValueFilter {
|
||||
roleName: "category"
|
||||
value: category
|
||||
}
|
||||
|
||||
ValueFilter {
|
||||
roleName: "userId"
|
||||
value: userId
|
||||
}
|
||||
|
||||
ExpressionFilter {
|
||||
expression: {
|
||||
var filter = paneToolBar.roomFilter.toLowerCase()
|
||||
var words = filter.split(" ")
|
||||
var room_name = displayName.toLowerCase()
|
||||
|
||||
for (var i = 0; i < words.length; i++) {
|
||||
if (words[i] && room_name.indexOf(words[i]) == -1) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delegate: RoomDelegate {}
|
||||
}
|
||||
|
@@ -15,16 +15,18 @@ HRectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
spacing: collapsed ? 0 : normalSpacing
|
||||
topMargin: spacing
|
||||
bottomMargin: spacing
|
||||
Layout.leftMargin: spacing
|
||||
spacing: collapsed ? 0 : normalSpacing * 3
|
||||
topMargin: normalSpacing
|
||||
bottomMargin: normalSpacing
|
||||
Layout.leftMargin: normalSpacing
|
||||
|
||||
Behavior on spacing {
|
||||
NumberAnimation { duration: HStyle.animationDuration }
|
||||
}
|
||||
}
|
||||
|
||||
PaneToolBar {}
|
||||
PaneToolBar {
|
||||
id: paneToolBar
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -8,10 +8,15 @@ import "SidePane"
|
||||
Item {
|
||||
id: mainUI
|
||||
|
||||
Connections {
|
||||
target: py
|
||||
onWillLoadAccounts: function(will) {
|
||||
pageStack.showPage(will ? "Default" : "SignIn")
|
||||
}
|
||||
}
|
||||
|
||||
property bool accountsPresent:
|
||||
models.accounts.count > 0 || py.loadingAccounts
|
||||
onAccountsPresentChanged:
|
||||
pageStack.showPage(accountsPresent ? "Default" : "SignIn")
|
||||
|
||||
HImage {
|
||||
id: mainUIBackground
|
||||
|
Reference in New Issue
Block a user