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:
miruka
2020-09-28 23:06:50 -04:00
parent 53d2ab17af
commit ee1091b4dc
20 changed files with 161 additions and 178 deletions

View File

@@ -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 = "" },
)
}

View File

@@ -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 {} }

View File

@@ -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)

View File

@@ -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()
}
}

View File

@@ -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)

View File

@@ -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
}