Stoat (#32): avatars and server icons were refused by the window's media protocol and never fetched again; the probe now checks they load

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
This commit is contained in:
SalastilandClaude Sonnet 5.5 committed 2026-10-23 23:43:10 -04:00
1 parent 96ea7e7623
commit d7c4e8767e
3 files changed
+18 -1

No files matched your search

+15
View File
@@ -202,6 +202,21 @@ try {
await shot('stoat-spoiler.png')
await as('bob', 'DELETE', `/channels/${channelId.General}/messages/${covered._id}`).catch(() => {})
// --- Pictures actually load in the window: a person's avatar in the member list, and the server's icon on the rail.
const loaded = (selector) => ev(`[...document.querySelectorAll(${JSON.stringify(selector)})].some((i) => i.complete && i.naturalWidth > 0)`)
const avatarId = await upload('bob', 'bob.png', png, 'image/png', 'avatars')
await as('bob', 'PATCH', '/users/@me', { avatar: avatarId })
await rpc('requestMemberList', { bufferId: general })
await ev(`window.__mohoShots.store.selectBuffer(${JSON.stringify(general)})`)
check('a person’s avatar loads in the member list', !!(await until(async () => loaded('.nick-row img'), 20000)))
await as('bob', 'PATCH', '/users/@me', { remove: ['Avatar'] })
const iconPath = path.join(out, 'icon.png')
fs.writeFileSync(iconPath, png)
await rpc('stoatManage', { bufferId: general, action: 'editServer', icon: iconPath })
check('and the server’s icon loads on the rail', !!(await until(async () => loaded('.rail-tile[aria-label="Test Hall"] img.rail-icon'), 20000)))
await shot('stoat-pictures.png')
await rpc('stoatManage', { bufferId: general, action: 'editServer', icon: '' })
// --- The window: the server’s settings opened from its tile on the rail, against the live local server.
await ev(`window.__mohoShots.store.selectBuffer(${JSON.stringify(general)})`)
await sleep(800)
+2
View File
@@ -124,6 +124,8 @@ const DAEMON_MEDIA_DIRS = [
'discord-sounds',
'telegram-media',
'telegram-avatars',
'stoat-media',
'stoat-avatars',
'transient'
]
+1 -1
View File
@@ -21,7 +21,7 @@ import { resolveMediaUrl } from './util'
/** The caches the daemon can restore from, by folder. Kick's emotes are
* not here: lib/emotecache puts Kick's own picture up at once instead. */
const RESTORABLE = /[\\/]nobilis[\\/](matrix-media|sneedchat-attachments|sneedchat-avatars|discord-thumbnails|discord-icons|telegram-media|telegram-avatars)[\\/]/
const RESTORABLE = /[\\/]nobilis[\\/](matrix-media|sneedchat-attachments|sneedchat-avatars|discord-thumbnails|discord-icons|telegram-media|telegram-avatars|stoat-media|stoat-avatars)[\\/]/
/** Paths being fetched, so a picture drawn twice asks once. */
const inFlight = new Map<string, Promise<string | null>>()