Don't pass Python Future objects to QML
Returning a Future doesn't work on Windows for some reason (https://github.com/thp/pyotherside/issues/116). Instead of using these objects from QML to cancel running coroutines, call a Python QMLBridge function that takes a coroutine UUID and will take care of the cancelling.
This commit is contained in:
@@ -13,7 +13,7 @@ import "Timeline"
|
||||
HColumnPage {
|
||||
id: chatPage
|
||||
|
||||
property var loadMembersFuture: null
|
||||
property string loadMembersFutureId: ""
|
||||
|
||||
readonly property alias roomHeader: roomHeader
|
||||
readonly property alias eventList: eventList
|
||||
@@ -29,16 +29,17 @@ HColumnPage {
|
||||
padding: 0
|
||||
column.spacing: 0
|
||||
|
||||
Component.onDestruction: if (loadMembersFuture) loadMembersFuture.cancel()
|
||||
Component.onDestruction:
|
||||
if (loadMembersFutureId) py.cancelCoro(loadMembersFutureId)
|
||||
|
||||
Timer {
|
||||
interval: 200
|
||||
running: ! chat.roomInfo.inviter_id && ! chat.roomInfo.left
|
||||
onTriggered: loadMembersFuture = py.callClientCoro(
|
||||
onTriggered: loadMembersFutureId = py.callClientCoro(
|
||||
chat.userId,
|
||||
"load_all_room_members",
|
||||
[chat.roomId],
|
||||
() => { loadMembersFuture = null },
|
||||
() => { loadMembersFutureId = "" },
|
||||
)
|
||||
}
|
||||
|
||||
|
@@ -7,13 +7,12 @@ import "../../../.."
|
||||
import "../../../../Base"
|
||||
import "../../../../Base/HTile"
|
||||
import "../../../../Popups"
|
||||
import "../../../../PythonBridge"
|
||||
|
||||
HTile {
|
||||
id: member
|
||||
|
||||
property bool colorName: hovered
|
||||
property Future getPresenceFuture: null
|
||||
property string getPresenceFutureId: ""
|
||||
|
||||
backgroundColor: theme.chat.roomPane.listView.member.background
|
||||
contentOpacity:
|
||||
@@ -155,11 +154,15 @@ HTile {
|
||||
|
||||
Component.onCompleted:
|
||||
if (model.presence === "offline" && model.last_active_at < new Date(1))
|
||||
getPresenceFuture = py.callClientCoro(
|
||||
chat.userId, "get_offline_presence", [model.id],
|
||||
getPresenceFutureId = py.callClientCoro(
|
||||
chat.userId,
|
||||
"get_offline_presence",
|
||||
[model.id],
|
||||
() => { getPresenceFutureId = "" }
|
||||
)
|
||||
|
||||
Component.onDestruction: if (getPresenceFuture) getPresenceFuture.cancel()
|
||||
Component.onDestruction:
|
||||
if (getPresenceFutureId) py.cancelCoro(getPresenceFutureId)
|
||||
|
||||
Behavior on contentOpacity { HNumberAnimation {} }
|
||||
Behavior on spacing { HNumberAnimation {} }
|
||||
|
@@ -6,7 +6,6 @@ import QtQuick.Layouts 1.12
|
||||
import "../../../.."
|
||||
import "../../../../Base"
|
||||
import "../../../../Base/Buttons"
|
||||
import "../../../../PythonBridge"
|
||||
|
||||
HListView {
|
||||
id: root
|
||||
@@ -21,8 +20,8 @@ HListView {
|
||||
|
||||
property bool powerLevelFieldFocused: false
|
||||
|
||||
property Future setPowerFuture: null
|
||||
property Future getPresenceFuture: null
|
||||
property string setPowerFutureId: ""
|
||||
property string getPresenceFutureId: ""
|
||||
|
||||
function loadDevices() {
|
||||
py.callClientCoro(userId, "member_devices", [member.id], devices => {
|
||||
@@ -246,14 +245,14 @@ HListView {
|
||||
ApplyButton {
|
||||
id: applyButton
|
||||
enabled: ! powerLevel.item.fieldOverMaximum
|
||||
loading: setPowerFuture !== null
|
||||
loading: setPowerFutureId !== ""
|
||||
text: ""
|
||||
onClicked: {
|
||||
setPowerFuture = py.callClientCoro(
|
||||
setPowerFutureId = py.callClientCoro(
|
||||
userId,
|
||||
"room_set_member_power",
|
||||
[roomId, member.id, powerLevel.item.level],
|
||||
() => { setPowerFuture = null }
|
||||
() => { setPowerFutureId = "" }
|
||||
)
|
||||
}
|
||||
|
||||
@@ -264,8 +263,8 @@ HListView {
|
||||
CancelButton {
|
||||
text: ""
|
||||
onClicked: {
|
||||
setPowerFuture.cancel()
|
||||
setPowerFuture = null
|
||||
py.cancelCoro(setPowerFutureId)
|
||||
setPowerFutureId = ""
|
||||
powerLevel.item.reset()
|
||||
}
|
||||
|
||||
@@ -289,14 +288,18 @@ HListView {
|
||||
if (member.presence === "offline" &&
|
||||
member.last_active_at < new Date(1))
|
||||
{
|
||||
getPresenceFuture =
|
||||
py.callClientCoro(userId, "get_offline_presence", [member.id])
|
||||
getPresenceFutureId = py.callClientCoro(
|
||||
userId,
|
||||
"get_offline_presence",
|
||||
[member.id],
|
||||
() => { getPresenceFutureId = "" }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Component.onDestruction: {
|
||||
if (setPowerFuture) setPowerFuture.cancel()
|
||||
if (getPresenceFuture) getPresenceFuture.cancel()
|
||||
if (setPowerFutureId) py.cancelCoro(setPowerFutureId)
|
||||
if (getPresenceFutureId) py.cancelCoro(getPresenceFutureId)
|
||||
}
|
||||
|
||||
Keys.onEnterPressed: Keys.onReturnPressed(event)
|
||||
|
@@ -10,7 +10,7 @@ import "../../../Base/Buttons"
|
||||
HFlickableColumnPage {
|
||||
id: settingsView
|
||||
|
||||
property var saveFuture: null
|
||||
property string saveFutureId: ""
|
||||
|
||||
readonly property bool anyChange:
|
||||
nameField.item.changed || topicArea.item.area.changed ||
|
||||
@@ -20,7 +20,7 @@ HFlickableColumnPage {
|
||||
readonly property Item keybindFocusItem: nameField.item
|
||||
|
||||
function save() {
|
||||
if (saveFuture) saveFuture.cancel()
|
||||
if (saveFutureId) py.cancelCoro(saveFutureId)
|
||||
|
||||
const args = [
|
||||
chat.roomId,
|
||||
@@ -35,17 +35,17 @@ HFlickableColumnPage {
|
||||
forbidGuestsCheckBox.checked : undefined,
|
||||
]
|
||||
|
||||
function onDone() { saveFuture = null }
|
||||
function onDone() { saveFutureId = "" }
|
||||
|
||||
saveFuture = py.callClientCoro(
|
||||
saveFutureId = py.callClientCoro(
|
||||
chat.userId, "room_set", args, onDone, onDone,
|
||||
)
|
||||
}
|
||||
|
||||
function cancel() {
|
||||
if (saveFuture) {
|
||||
saveFuture.cancel()
|
||||
saveFuture = null
|
||||
if (saveFutureId) {
|
||||
py.cancelCoro(saveFutureId)
|
||||
saveFutureId = ""
|
||||
}
|
||||
|
||||
nameField.item.reset()
|
||||
@@ -66,14 +66,14 @@ HFlickableColumnPage {
|
||||
ApplyButton {
|
||||
id: applyButton
|
||||
enabled: anyChange
|
||||
loading: saveFuture !== null
|
||||
loading: saveFutureId !== ""
|
||||
disableWhileLoading: false
|
||||
onClicked: save()
|
||||
|
||||
}
|
||||
|
||||
CancelButton {
|
||||
enabled: anyChange || saveFuture !== null
|
||||
enabled: anyChange || saveFutureId !== ""
|
||||
onClicked: cancel()
|
||||
}
|
||||
}
|
||||
|
@@ -6,12 +6,11 @@ import QtQuick.Layouts 1.12
|
||||
import Clipboard 0.1
|
||||
import "../../.."
|
||||
import "../../../Base"
|
||||
import "../../../PythonBridge"
|
||||
|
||||
HColumnLayout {
|
||||
id: eventDelegate
|
||||
|
||||
property var fetchProfilesFuture: null
|
||||
property string fetchProfilesFutureId: ""
|
||||
|
||||
// Remember timeline goes from newest message at index 0 to oldest
|
||||
readonly property var previousModel: eventList.model.get(model.index + 1)
|
||||
@@ -72,16 +71,16 @@ HColumnLayout {
|
||||
onCursorShapeChanged: eventList.cursorShape = cursorShape
|
||||
|
||||
Component.onCompleted: if (model.fetch_profile)
|
||||
fetchProfilesFuture = py.callClientCoro(
|
||||
fetchProfilesFutureId = py.callClientCoro(
|
||||
chat.userId,
|
||||
"get_event_profiles",
|
||||
[chat.roomId, model.id],
|
||||
// The if avoids segfault if eventDelegate is already destroyed
|
||||
() => { if (eventDelegate) fetchProfilesFuture = null }
|
||||
() => { if (eventDelegate) fetchProfilesFutureId = "" }
|
||||
)
|
||||
|
||||
Component.onDestruction:
|
||||
if (fetchProfilesFuture) fetchProfilesFuture.cancel()
|
||||
if (fetchProfilesFutureId) py.cancelCoro(fetchProfilesFutureId)
|
||||
|
||||
ListView.onRemove: eventList.uncheck(model.id)
|
||||
|
||||
|
@@ -218,8 +218,8 @@ Rectangle {
|
||||
HListView {
|
||||
id: eventList
|
||||
|
||||
property Future updateMarkerFuture: null
|
||||
property Future loadPastEventsFuture: null
|
||||
property string updateMarkerFutureId: ""
|
||||
property string loadPastEventsFutureId: ""
|
||||
property bool moreToLoad: true
|
||||
|
||||
property bool ownEventsOnLeft:
|
||||
@@ -355,13 +355,13 @@ Rectangle {
|
||||
}
|
||||
|
||||
function loadPastEvents() {
|
||||
loadPastEventsFuture = py.callClientCoro(
|
||||
loadPastEventsFutureId = py.callClientCoro(
|
||||
chat.userId,
|
||||
"load_past_events",
|
||||
[chat.roomId],
|
||||
more => {
|
||||
moreToLoad = more
|
||||
loadPastEventsFuture = null
|
||||
moreToLoad = more
|
||||
loadPastEventsFutureId = ""
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -519,7 +519,7 @@ Rectangle {
|
||||
footer: Item {
|
||||
width: eventList.width
|
||||
height: (button.height + theme.spacing * 2) * opacity
|
||||
opacity: eventList.loadPastEventsFuture ? 1 : 0
|
||||
opacity: eventList.loadPastEventsFutureId ? 1 : 0
|
||||
visible: opacity > 0
|
||||
|
||||
Behavior on opacity { HNumberAnimation {} }
|
||||
@@ -554,14 +554,14 @@ Rectangle {
|
||||
interval: 200
|
||||
running:
|
||||
eventList.shouldLoadPastEvents &&
|
||||
! eventList.loadPastEventsFuture
|
||||
! eventList.loadPastEventsFutureId
|
||||
triggeredOnStart: true
|
||||
onTriggered: eventList.loadPastEvents()
|
||||
|
||||
}
|
||||
|
||||
Component.onDestruction: {
|
||||
if (loadPastEventsFuture) loadPastEventsFuture.cancel()
|
||||
if (loadPastEventsFutureId) py.cancelCoro(loadPastEventsFutureId)
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
@@ -585,7 +585,7 @@ Rectangle {
|
||||
interval: Math.max(100, window.settings.markRoomReadMsecDelay)
|
||||
|
||||
running:
|
||||
! eventList.updateMarkerFuture &&
|
||||
! eventList.updateMarkerFutureId &&
|
||||
(
|
||||
chat.roomInfo.unreads ||
|
||||
chat.roomInfo.highlights ||
|
||||
@@ -600,11 +600,11 @@ Rectangle {
|
||||
const item = eventList.model.get(i)
|
||||
|
||||
if (item.sender !== chat.userId) {
|
||||
eventList.updateMarkerFuture = py.callCoro(
|
||||
eventList.updateMarkerFutureId = py.callCoro(
|
||||
"update_room_read_marker",
|
||||
[chat.roomId, item.event_id],
|
||||
() => { eventList.updateMarkerFuture = null },
|
||||
() => { eventList.updateMarkerFuture = null },
|
||||
() => { eventList.updateMarkerFutureId = "" },
|
||||
() => { eventList.updateMarkerFutureId = "" },
|
||||
)
|
||||
return
|
||||
}
|
||||
|
Reference in New Issue
Block a user