Handle d2m events with empty guild/user avatars #106
7 changed files with 56 additions and 5 deletions
Handle d2m events with empty guild/user avatars
commit
7c1d9af31d
|
|
@ -181,7 +181,7 @@ async function channelToKState(channel, guild, di) {
|
||||||
network: {
|
network: {
|
||||||
id: guild.id,
|
id: guild.id,
|
||||||
displayname: guild.name,
|
displayname: guild.name,
|
||||||
avatar_url: {$url: file.guildIcon(guild)}
|
...(guild.icon ? {avatar_url: {$url: file.guildIcon(guild)}} : {})
|
||||||
},
|
},
|
||||||
channel: {
|
channel: {
|
||||||
id: channel.id,
|
id: channel.id,
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,7 @@ async function guildToKState(guild, privacyLevel) {
|
||||||
"m.room.name/": {name: guild.name},
|
"m.room.name/": {name: guild.name},
|
||||||
"m.room.avatar/": {
|
"m.room.avatar/": {
|
||||||
$if: guild.icon,
|
$if: guild.icon,
|
||||||
url: {$url: file.guildIcon(guild)}
|
url: guild.icon ? {$url: file.guildIcon(guild)} : null
|
||||||
},
|
},
|
||||||
"m.room.guest_access/": {guest_access: createRoom.PRIVACY_ENUMS.GUEST_ACCESS[privacyLevel]},
|
"m.room.guest_access/": {guest_access: createRoom.PRIVACY_ENUMS.GUEST_ACCESS[privacyLevel]},
|
||||||
"m.room.history_visibility/": {history_visibility: createRoom.PRIVACY_ENUMS.SPACE_HISTORY_VISIBILITY[privacyLevel]},
|
"m.room.history_visibility/": {history_visibility: createRoom.PRIVACY_ENUMS.SPACE_HISTORY_VISIBILITY[privacyLevel]},
|
||||||
|
|
|
||||||
|
|
@ -110,7 +110,10 @@ async function ensureSimJoined(pkMessage, roomID) {
|
||||||
async function memberToStateContent(pkMessage, author) {
|
async function memberToStateContent(pkMessage, author) {
|
||||||
// We prefer to use the member's avatar URL data since the image upload can be cached across channels,
|
// We prefer to use the member's avatar URL data since the image upload can be cached across channels,
|
||||||
// unlike the userAvatar URL which is unique per channel, due to the webhook ID being in the URL.
|
// unlike the userAvatar URL which is unique per channel, due to the webhook ID being in the URL.
|
||||||
const avatar = pkMessage.member.avatar_url || pkMessage.member.webhook_avatar_url || pkMessage.system.avatar_url || file.userAvatar(author)
|
const avatar = pkMessage.member.avatar_url
|
||||||
|
|| pkMessage.member.webhook_avatar_url
|
||||||
|
|| pkMessage.system.avatar_url
|
||||||
|
|| (author.avatar ? file.userAvatar(author) : null)
|
||||||
const color = pkMessage.member.color ?? pkMessage.system.color
|
const color = pkMessage.member.color ?? pkMessage.system.color
|
||||||
|
|
||||||
const content = {
|
const content = {
|
||||||
|
|
|
||||||
|
|
@ -115,7 +115,7 @@ async function ensureSimJoined(pluRalMessage, roomID) {
|
||||||
async function memberToStateContent(pluRalMessage, author) {
|
async function memberToStateContent(pluRalMessage, author) {
|
||||||
// We prefer to use the member's avatar URL data since the image upload can be cached across channels,
|
// We prefer to use the member's avatar URL data since the image upload can be cached across channels,
|
||||||
// unlike the userAvatar URL which is unique per channel, due to the webhook ID being in the URL.
|
// unlike the userAvatar URL which is unique per channel, due to the webhook ID being in the URL.
|
||||||
const avatar = pluRalMessage.member.avatar_url || file.userAvatar(author)
|
const avatar = pluRalMessage.member.avatar_url || (author.avatar ? file.userAvatar(author) : null)
|
||||||
|
|
||||||
const content = {
|
const content = {
|
||||||
displayname: author.username,
|
displayname: author.username,
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,7 @@ async function ensureSimJoined(fakeUserID, author, roomID) {
|
||||||
* @param {Ty.WebhookAuthor} author
|
* @param {Ty.WebhookAuthor} author
|
||||||
*/
|
*/
|
||||||
async function authorToStateContent(author) {
|
async function authorToStateContent(author) {
|
||||||
const avatar = file.userAvatar(author)
|
const avatar = author.avatar ? file.userAvatar(author) : null
|
||||||
|
|
||||||
const content = {
|
const content = {
|
||||||
displayname: author.username,
|
displayname: author.username,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
// @ts-check
|
// @ts-check
|
||||||
|
|
||||||
|
const assert = require("assert").strict
|
||||||
|
const DiscordTypes = require("discord-api-types/v10")
|
||||||
const passthrough = require("../passthrough")
|
const passthrough = require("../passthrough")
|
||||||
const {reg, writeRegistration} = require("./read-registration.js")
|
const {reg, writeRegistration} = require("./read-registration.js")
|
||||||
const Ty = require("../types")
|
const Ty = require("../types")
|
||||||
|
|
@ -138,11 +140,21 @@ async function _actuallyUploadDiscordFileToMxc(url) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {DiscordTypes.APIGuild} guild
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
function guildIcon(guild) {
|
function guildIcon(guild) {
|
||||||
|
assert(guild.icon, `guild ${guild.id} has no icon`)
|
||||||
return `/icons/${guild.id}/${guild.icon}.png?size=${IMAGE_SIZE}`
|
return `/icons/${guild.id}/${guild.icon}.png?size=${IMAGE_SIZE}`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {DiscordTypes.APIUser | Ty.WebhookAuthor} user
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
function userAvatar(user) {
|
function userAvatar(user) {
|
||||||
|
assert(user.avatar, `user ${user.id} has no avatar`)
|
||||||
return `/avatars/${user.id}/${user.avatar}.png?size=${IMAGE_SIZE}`
|
return `/avatars/${user.id}/${user.avatar}.png?size=${IMAGE_SIZE}`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,3 +26,39 @@ test("removeExpiryParams: works on media proxy and keeps quality", t => {
|
||||||
const result = file._removeExpiryParams(url)
|
const result = file._removeExpiryParams(url)
|
||||||
t.equal(result, "https://media.discordapp.net/attachments/1160894080998461480/1548665030898094240/855064e9-bdae-487a-a497-c662bd510487.png?format=webp")
|
t.equal(result, "https://media.discordapp.net/attachments/1160894080998461480/1548665030898094240/855064e9-bdae-487a-a497-c662bd510487.png?format=webp")
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test("guildIcon: returns icon path", t => {
|
||||||
|
t.equal(
|
||||||
|
// @ts-ignore
|
||||||
|
file.guildIcon({id: "112760669178241024", icon: "a_f83622e09ead74f0c5c527fe241f8f8c"}),
|
||||||
|
"/icons/112760669178241024/a_f83622e09ead74f0c5c527fe241f8f8c.png?size=1024"
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
test("guildIcon: throws if guild has no icon", t => {
|
||||||
|
let err
|
||||||
|
try {
|
||||||
|
// @ts-ignore
|
||||||
|
file.guildIcon({id: "112760669178241024", icon: null})
|
||||||
|
} catch (e) {
|
||||||
|
err = e
|
||||||
|
}
|
||||||
|
t.match(err?.message, /has no icon/)
|
||||||
|
})
|
||||||
|
|
||||||
|
test("userAvatar: returns avatar path", t => {
|
||||||
|
t.equal(
|
||||||
|
file.userAvatar({id: "113340068197859328", username: "kumaccino", avatar: "b48302623a12bc7c59a71328f72ccb39"}),
|
||||||
|
"/avatars/113340068197859328/b48302623a12bc7c59a71328f72ccb39.png?size=1024"
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
test("userAvatar: throws if user has no avatar", t => {
|
||||||
|
let err
|
||||||
|
try {
|
||||||
|
file.userAvatar({id: "113340068197859328", username: "kumaccino", avatar: null})
|
||||||
|
} catch (e) {
|
||||||
|
err = e
|
||||||
|
}
|
||||||
|
t.match(err?.message, /has no avatar/)
|
||||||
|
})
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue