This commit is contained in:
retoor 2025-05-15 19:32:40 +02:00
parent db6d6c0106
commit 25d109beed
5 changed files with 55 additions and 19 deletions

View File

@ -1,6 +1,6 @@
from snek.model.user import UserModel
from snek.system.model import BaseModel, ModelField
from datetime import datetime,timezone
class ChannelMessageModel(BaseModel):
channel_uid = ModelField(name="channel_uid", required=True, kind=str)
@ -8,6 +8,9 @@ class ChannelMessageModel(BaseModel):
message = ModelField(name="message", required=True, kind=str)
html = ModelField(name="html", required=False, kind=str)
def get_seconds_since_last_update(self):
return int((datetime.now(timezone.utc) - datetime.fromisoformat(self["updated_at"])).total_seconds())
async def get_user(self) -> UserModel:
return await self.app.services.user.get(uid=self["user_uid"])

View File

@ -151,7 +151,7 @@ footer {
}
}
.chat-messages > picture > img {
.chat-messages picture img {
cursor: pointer;
}
.chat-messages::-webkit-scrollbar {

View File

@ -10,7 +10,7 @@
constructor() {
super();
app.ws.addEventListener("update_message_text",(data)=>{
this.updateMessageText(data.data.message_uid,data.data.text)
this.updateMessageText(data.data.uid,data.data)
})
app.ws.addEventListener("set_typing",(data)=>{
this.triggerGlow(data.data.user_uid)
@ -19,14 +19,18 @@
this.items = [];
}
updateMessageText(uid,text){
updateMessageText(uid,message){
const messageDiv = this.querySelector("div[data-uid=\""+uid+"\"]")
if(!messageDiv){
return
}
const receivedHtml = document.createElement("div")
receivedHtml.innerHTML = message.html
const html = receivedHtml.querySelector(".text").innerHTML
const textElement = messageDiv.querySelector(".text")
textElement.innerText = text
textElement.style.display = text == '' ? 'none' : 'block'
textElement.innerHTML = html
textElement.style.display = message.text == '' ? 'none' : 'block'
}
triggerGlow(uid) {

View File

@ -47,7 +47,18 @@
if(textBox.liveType == undefined){
textBox.liveType = false
}
let typeTimeout = null;
textBox.addEventListener('keydown',async (e) => {
if(typeTimeout){
clearTimeout(typeTimeout)
typeTimeout = null
}
if(e.target.liveType){
typeTimeout = setTimeout(()=>{
e.target.lastMessageUid = null
e.target.value = ''
},3000)
}
if(e.key === "ArrowUp"){
const value = findDivAboveText(e.target.value).querySelector('.text')
e.target.value = value.textContent
@ -102,7 +113,9 @@
}else{
if(textBox.liveType){
if(e.target.value.endsWith("\n") || e.target.value.endsWith(" ")){
return
}
if(e.target.value[0] == "/"){
return
}
@ -116,8 +129,10 @@
return;
}
app.rpc.updateMessageText(textBox.lastMessageUid, e.target.value)
}else{
app.rpc.set_typing(channelUid)
}
app.rpc.set_typing(channelUid)
}
});
@ -294,6 +309,10 @@
}
app.addEventListener("channel-message", (data) => {
let display = 'block';
if(!data.text || !data.text.trim()){
display = "none";
}
if (data.channel_uid !== channelUid) {
if(!isMentionForSomeoneElse(data.message)){
channelSidebar.notify(data);
@ -316,6 +335,7 @@
const message = document.createElement("div");
message.innerHTML = data.html;
message.style.display = display
document.querySelector(".chat-messages").appendChild(message.firstChild);
updateLayout(doScrollDownBecauseLastMessageIsVisible);
setTimeout(() => {
@ -373,6 +393,9 @@
if(e.target.tagName != 'IMG')
return
const img = e.target
if(e.target.classList.contains('avatar')){
return
}
const overlay = document.createElement('div');
overlay.style.position = 'fixed';
overlay.style.top = 0;

View File

@ -178,22 +178,28 @@ class RPCView(BaseView):
message = await self.services.channel_message.get(message_uid)
if message["user_uid"] != self.user_uid:
raise Exception("Not allowed")
await self.services.socket.broadcast(message["channel_uid"], {
"channel_uid": message["channel_uid"],
"event": "update_message_text",
"data": {
"message_uid": message_uid,
"text": text
}
})
message["message"] = text
if message.get_seconds_since_last_update() > 3:
return {"error": "Message too old","seconds_since_last_update": message.get_seconds_since_last_update(),"success": False}
message['message'] = text
if not text:
message['deleted_at'] = now()
else:
message['deleted_at'] = None
await self.services.channel_message.save(message)
return True
data = message.record
data['text'] = message["message"]
data['message_uid'] = message_uid
await self.services.socket.broadcast(message["channel_uid"], {
"channel_uid": message["channel_uid"],
"event": "update_message_text",
"data": message.record
})
return {"success": True}
async def send_message(self, channel_uid, message):
self._require_login()