d->m: preserve unknown messages when syncing pins
This commit is contained in:
@@ -33,9 +33,10 @@ async function updatePins(channelID, roomID, convertedTimestamp) {
|
|||||||
}
|
}
|
||||||
throw e
|
throw e
|
||||||
}
|
}
|
||||||
const pinned = pinsToList.pinsToList(discordPins)
|
|
||||||
|
|
||||||
const kstate = await ks.roomToKState(roomID)
|
const kstate = await ks.roomToKState(roomID)
|
||||||
|
const pinned = pinsToList.pinsToList(discordPins, kstate)
|
||||||
|
|
||||||
const diff = ks.diffKState(kstate, {"m.room.pinned_events/": {pinned}})
|
const diff = ks.diffKState(kstate, {"m.room.pinned_events/": {pinned}})
|
||||||
await ks.applyKStateDiffToRoom(roomID, diff)
|
await ks.applyKStateDiffToRoom(roomID, diff)
|
||||||
|
|
||||||
|
@@ -4,16 +4,28 @@ const {select} = require("../../passthrough")
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {import("discord-api-types/v10").RESTGetAPIChannelPinsResult} pins
|
* @param {import("discord-api-types/v10").RESTGetAPIChannelPinsResult} pins
|
||||||
|
* @param {{"m.room.pinned_events/"?: {pinned?: string[]}}} kstate
|
||||||
*/
|
*/
|
||||||
function pinsToList(pins) {
|
function pinsToList(pins, kstate) {
|
||||||
|
let alreadyPinned = kstate["m.room.pinned_events/"]?.pinned || []
|
||||||
|
|
||||||
|
// If any of the already pinned messages are bridged messages then remove them from the already pinned list.
|
||||||
|
// * If a bridged message is still pinned then it'll be added back in the next step.
|
||||||
|
// * If a bridged message was unpinned from Discord-side then it'll be unpinned from our side due to this step.
|
||||||
|
// * Matrix-only unbridged messages that are pinned will remain pinned.
|
||||||
|
alreadyPinned = alreadyPinned.filter(event_id => {
|
||||||
|
const messageID = select("event_message", "message_id", {event_id}).pluck().get()
|
||||||
|
return !messageID || pins.find(m => m.id === messageID) // if it is bridged then remove it from the filter
|
||||||
|
})
|
||||||
|
|
||||||
/** @type {string[]} */
|
/** @type {string[]} */
|
||||||
const result = []
|
const result = []
|
||||||
for (const message of pins) {
|
for (const message of pins) {
|
||||||
const eventID = select("event_message", "event_id", {message_id: message.id, part: 0}).pluck().get()
|
const eventID = select("event_message", "event_id", {message_id: message.id, part: 0}).pluck().get()
|
||||||
if (eventID) result.push(eventID)
|
if (eventID && !alreadyPinned.includes(eventID)) result.push(eventID)
|
||||||
}
|
}
|
||||||
result.reverse()
|
result.reverse()
|
||||||
return result
|
return alreadyPinned.concat(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.pinsToList = pinsToList
|
module.exports.pinsToList = pinsToList
|
||||||
|
@@ -3,10 +3,59 @@ const data = require("../../../test/data")
|
|||||||
const {pinsToList} = require("./pins-to-list")
|
const {pinsToList} = require("./pins-to-list")
|
||||||
|
|
||||||
test("pins2list: converts known IDs, ignores unknown IDs", t => {
|
test("pins2list: converts known IDs, ignores unknown IDs", t => {
|
||||||
const result = pinsToList(data.pins.faked)
|
const result = pinsToList(data.pins.faked, {})
|
||||||
t.deepEqual(result, [
|
t.deepEqual(result, [
|
||||||
"$lnAF9IosAECTnlv9p2e18FG8rHn-JgYKHEHIh5qdFv4",
|
"$lnAF9IosAECTnlv9p2e18FG8rHn-JgYKHEHIh5qdFv4",
|
||||||
"$mtR8cJqM4fKno1bVsm8F4wUVqSntt2sq6jav1lyavuA",
|
"$mtR8cJqM4fKno1bVsm8F4wUVqSntt2sq6jav1lyavuA",
|
||||||
"$X16nfVks1wsrhq4E9SSLiqrf2N8KD0erD0scZG7U5xg"
|
"$X16nfVks1wsrhq4E9SSLiqrf2N8KD0erD0scZG7U5xg"
|
||||||
])
|
])
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test("pins2list: already pinned duplicate items are not moved", t => {
|
||||||
|
const result = pinsToList(data.pins.faked, {
|
||||||
|
"m.room.pinned_events/": {
|
||||||
|
pinned: [
|
||||||
|
"$mtR8cJqM4fKno1bVsm8F4wUVqSntt2sq6jav1lyavuA"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
t.deepEqual(result, [
|
||||||
|
"$mtR8cJqM4fKno1bVsm8F4wUVqSntt2sq6jav1lyavuA",
|
||||||
|
"$lnAF9IosAECTnlv9p2e18FG8rHn-JgYKHEHIh5qdFv4",
|
||||||
|
"$X16nfVks1wsrhq4E9SSLiqrf2N8KD0erD0scZG7U5xg"
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
test("pins2list: already pinned unknown items are not moved", t => {
|
||||||
|
const result = pinsToList(data.pins.faked, {
|
||||||
|
"m.room.pinned_events/": {
|
||||||
|
pinned: [
|
||||||
|
"$unknown1",
|
||||||
|
"$mtR8cJqM4fKno1bVsm8F4wUVqSntt2sq6jav1lyavuA",
|
||||||
|
"$unknown2"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
t.deepEqual(result, [
|
||||||
|
"$unknown1",
|
||||||
|
"$mtR8cJqM4fKno1bVsm8F4wUVqSntt2sq6jav1lyavuA",
|
||||||
|
"$unknown2",
|
||||||
|
"$lnAF9IosAECTnlv9p2e18FG8rHn-JgYKHEHIh5qdFv4",
|
||||||
|
"$X16nfVks1wsrhq4E9SSLiqrf2N8KD0erD0scZG7U5xg"
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
test("pins2list: bridged messages can be unpinned", t => {
|
||||||
|
const result = pinsToList(data.pins.faked.slice(0, -2), {
|
||||||
|
"m.room.pinned_events/": {
|
||||||
|
pinned: [
|
||||||
|
"$mtR8cJqM4fKno1bVsm8F4wUVqSntt2sq6jav1lyavuA",
|
||||||
|
"$lnAF9IosAECTnlv9p2e18FG8rHn-JgYKHEHIh5qdFv4"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
t.deepEqual(result, [
|
||||||
|
"$mtR8cJqM4fKno1bVsm8F4wUVqSntt2sq6jav1lyavuA",
|
||||||
|
"$X16nfVks1wsrhq4E9SSLiqrf2N8KD0erD0scZG7U5xg",
|
||||||
|
])
|
||||||
|
})
|
||||||
|
Reference in New Issue
Block a user