Compare commits

..

7 Commits
main ... main

Author SHA1 Message Date
b27149b5ba Update. 2025-07-25 17:10:03 +02:00
eb1284060a Update attributes. 2025-07-25 17:06:15 +02:00
4266ac1f12 Less stars 2025-07-25 17:06:15 +02:00
6b4709d011 Merge pull request 'Add support for once event listeners and improve event removal' () from BordedDev/snek:feat/once-event-listener into main
Reviewed-on: 
Reviewed-by: retoor <retoor@noreply@molodetz.nl>
2025-07-24 23:36:50 +02:00
ef8d3068a8 Merge pull request 'Fix some message rendering' () from BordedDev/snek:bugfix/message-list-rendering into main
Reviewed-on: 
Reviewed-by: retoor <retoor@noreply@molodetz.nl>
2025-07-24 23:35:49 +02:00
BordedDev
a23c14389b Fix some message rendering 2025-07-24 16:14:51 +02:00
BordedDev
6dfd8db0a6 Add support for once event listeners and improve event removal 2025-07-24 15:59:17 +02:00
5 changed files with 33 additions and 29 deletions

View File

@ -69,7 +69,6 @@ class ChannelMessageService(BaseService):
"color": user["color"], "color": user["color"],
} }
) )
context['message'] = whitelist_attributes(context['message'])
try: try:
template = self.app.jinja2_env.get_template("message.html") template = self.app.jinja2_env.get_template("message.html")
model["html"] = template.render(**context) model["html"] = template.render(**context)
@ -118,7 +117,6 @@ class ChannelMessageService(BaseService):
async def save(self, model): async def save(self, model):
context = {} context = {}
context.update(model.record) context.update(model.record)
context['message'] = whitelist_attributes(context['message'])
user = await self.app.services.user.get(model["user_uid"]) user = await self.app.services.user.get(model["user_uid"])
context.update( context.update(
{ {

View File

@ -3,8 +3,15 @@ export class EventHandler {
this.subscribers = {}; this.subscribers = {};
} }
addEventListener(type, handler) { addEventListener(type, handler, { once = false } = {}) {
if (!this.subscribers[type]) this.subscribers[type] = []; if (!this.subscribers[type]) this.subscribers[type] = [];
if (once) {
const originalHandler = handler;
handler = (...args) => {
originalHandler(...args);
this.removeEventListener(type, handler);
};
}
this.subscribers[type].push(handler); this.subscribers[type].push(handler);
} }
@ -12,4 +19,15 @@ export class EventHandler {
if (this.subscribers[type]) if (this.subscribers[type])
this.subscribers[type].forEach((handler) => handler(...data)); this.subscribers[type].forEach((handler) => handler(...data));
} }
removeEventListener(type, handler) {
if (!this.subscribers[type]) return;
this.subscribers[type] = this.subscribers[type].filter(
(h) => h !== handler
);
if (this.subscribers[type].length === 0) {
delete this.subscribers[type];
}
}
} }

View File

@ -57,17 +57,6 @@ export class ReplyEvent extends Event {
class MessageElement extends HTMLElement { class MessageElement extends HTMLElement {
// static observedAttributes = ['data-uid', 'data-color', 'data-channel_uid', 'data-user_nick', 'data-created_at', 'data-user_uid']; // static observedAttributes = ['data-uid', 'data-color', 'data-channel_uid', 'data-user_nick', 'data-created_at', 'data-user_uid'];
isVisible() {
if (!this) return false;
const rect = this.getBoundingClientRect();
return (
rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
rect.right <= (window.innerWidth || document.documentElement.clientWidth)
);
}
updateUI() { updateUI() {
if (this._originalChildren === undefined) { if (this._originalChildren === undefined) {
const { color, user_nick, created_at, user_uid} = this.dataset; const { color, user_nick, created_at, user_uid} = this.dataset;
@ -104,8 +93,8 @@ class MessageElement extends HTMLElement {
}) })
} }
if (!this.siblingGenerated && this.nextElementSibling) { if ((!this.siblingGenerated || this.siblingGenerated !== this.nextElementSibling) && this.nextElementSibling) {
this.siblingGenerated = true; this.siblingGenerated = this.nextElementSibling;
if (this.nextElementSibling?.dataset?.user_uid !== this.dataset.user_uid) { if (this.nextElementSibling?.dataset?.user_uid !== this.dataset.user_uid) {
this.classList.add('switch-user'); this.classList.add('switch-user');
} else { } else {
@ -177,6 +166,10 @@ class MessageList extends HTMLElement {
threshold: 0, threshold: 0,
}) })
this.endOfMessages = document.createElement('div');
this.endOfMessages.classList.add('message-list-bottom');
this.prepend(this.endOfMessages);
for(const c of this.children) { for(const c of this.children) {
this._observer.observe(c); this._observer.observe(c);
if (c instanceof MessageElement) { if (c instanceof MessageElement) {
@ -184,10 +177,6 @@ class MessageList extends HTMLElement {
} }
} }
this.endOfMessages = document.createElement('div');
this.endOfMessages.classList.add('message-list-bottom');
this.prepend(this.endOfMessages);
this.scrollToBottom(true); this.scrollToBottom(true);
} }
@ -243,13 +232,13 @@ class MessageList extends HTMLElement {
); );
} }
isScrolledToBottom() { isScrolledToBottom() {
return this.isElementVisible(this.endOfMessages); return this.visibleSet.has(this.endOfMessages)
} }
scrollToBottom(force = false, behavior= 'instant') { scrollToBottom(force = false, behavior= 'instant') {
if (force || !this.isScrolledToBottom()) { if (force || !this.isScrolledToBottom()) {
this.firstElementChild.scrollIntoView({ behavior, block: 'end' }); this.endOfMessages.scrollIntoView({ behavior, block: 'end' });
setTimeout(() => { setTimeout(() => {
this.firstElementChild.scrollIntoView({ behavior, block: 'end' }); this.endOfMessages.scrollIntoView({ behavior, block: 'end' });
}, 200); }, 200);
} }
} }
@ -302,7 +291,7 @@ class MessageList extends HTMLElement {
} }
const scrolledToBottom = this.isScrolledToBottom(); const scrolledToBottom = this.isScrolledToBottom();
this.prepend(message); this.endOfMessages.after(message);
if (scrolledToBottom) this.scrollToBottom(true); if (scrolledToBottom) this.scrollToBottom(true);
} }
} }

View File

@ -142,10 +142,9 @@ export class Socket extends EventHandler {
method, method,
args, args,
}; };
const me = this;
return new Promise((resolve) => { return new Promise((resolve) => {
me.addEventListener(call.callId, (data) => resolve(data)); this.addEventListener(call.callId, (data) => resolve(data), { once: true});
me.sendJson(call); this.sendJson(call);
}); });
} }
} }

View File

@ -12,7 +12,7 @@ function showTerm(options){
class StarField { class StarField {
constructor({ count = 100, container = document.body } = {}) { constructor({ count = 50, container = document.body } = {}) {
this.container = container; this.container = container;
this.starCount = count; this.starCount = count;
this.stars = []; this.stars = [];
@ -567,7 +567,7 @@ const count = Array.from(messages).filter(el => el.textContent.trim() === text).
const starField = new StarField({starCount: 100}); const starField = new StarField({starCount: 50});
app.starField = starField; app.starField = starField;
class DemoSequence { class DemoSequence {