New padding.

This commit is contained in:
retoor 2025-01-29 00:33:00 +01:00
parent 9e94210bc3
commit 84e5bac1b9
11 changed files with 41 additions and 8 deletions

View File

@ -12,11 +12,17 @@ class UserModel(BaseModel):
) )
nick = ModelField( nick = ModelField(
name="nick", name="nick",
required=False, required=True,
min_length=2, min_length=2,
max_length=20, max_length=20,
regex=r"^[a-zA-Z0-9_]+$", regex=r"^[a-zA-Z0-9_]+$",
) )
color = ModelField(
name ="color",
required=True,
regex=r"^#[0-9a-fA-F]{6}$",
kind=str
)
email = ModelField( email = ModelField(
name="email", name="email",
required=False, required=False,

View File

@ -7,6 +7,7 @@ from snek.service.chat import ChatService
from snek.service.notification import NotificationService from snek.service.notification import NotificationService
from snek.service.socket import SocketService from snek.service.socket import SocketService
from snek.service.user import UserService from snek.service.user import UserService
from snek.service.util import UtilService
from snek.system.object import Object from snek.system.object import Object
@ -21,6 +22,7 @@ def get_services(app):
"chat": ChatService(app=app), "chat": ChatService(app=app),
"socket": SocketService(app=app), "socket": SocketService(app=app),
"notification": NotificationService(app=app), "notification": NotificationService(app=app),
"util": UtilService(app=app),
} }
) )

View File

@ -19,6 +19,7 @@ class ChatService(BaseService):
sent_to_count = await self.services.socket.broadcast(channel_uid, dict( sent_to_count = await self.services.socket.broadcast(channel_uid, dict(
message=message, message=message,
user_uid=user_uid, user_uid=user_uid,
color=user['color'],
channel_uid=channel_uid, channel_uid=channel_uid,
created_at=channel_message["created_at"], created_at=channel_message["created_at"],
updated_at=None, updated_at=None,

View File

@ -13,11 +13,17 @@ class UserService(BaseService):
return False return False
return True return True
async def save(self, user):
if not user['color']:
user['color'] = await self.services.util.random_light_hex_color()
return await super().save(user)
async def register(self, email, username, password): async def register(self, email, username, password):
if await self.exists(username=username): if await self.exists(username=username):
raise Exception("User already exists.") raise Exception("User already exists.")
model = await self.new() model = await self.new()
model["nick"] = username model["nick"] = username
model['color'] = await self.services.util.random_light_hex_color()
model.email.value = email model.email.value = email
model.username.value = username model.username.value = username
model.password.value = await security.hash(password) model.password.value = await security.hash(password)

View File

@ -20,6 +20,7 @@ class MessageListElement extends HTMLElement {
createElement(message){ createElement(message){
const element = document.createElement("div") const element = document.createElement("div")
element.dataset.uid = message.uid element.dataset.uid = message.uid
element.dataset.color = message.color
element.dataset.channel_uid = message.channel_uid element.dataset.channel_uid = message.channel_uid
element.dataset.user_nick = message.user_nick element.dataset.user_nick = message.user_nick
element.dataset.created_at = message.created_at element.dataset.created_at = message.created_at
@ -28,11 +29,13 @@ class MessageListElement extends HTMLElement {
element.classList.add("message") element.classList.add("message")
const avatar = document.createElement("div") const avatar = document.createElement("div")
avatar.classList.add("avatar") avatar.classList.add("avatar")
avatar.style.backgroundColor = message.color
avatar.innerText = message.user_nick[0] avatar.innerText = message.user_nick[0]
const messageContent = document.createElement("div") const messageContent = document.createElement("div")
messageContent.classList.add("message-content") messageContent.classList.add("message-content")
const author = document.createElement("div") const author = document.createElement("div")
author.classList.add("author") author.classList.add("author")
author.style.color = message.color
author.textContent = message.user_nick author.textContent = message.user_nick
const text = document.createElement("div") const text = document.createElement("div")
text.classList.add("text") text.classList.add("text")
@ -60,6 +63,7 @@ class MessageListElement extends HTMLElement {
message.channel_uid, message.channel_uid,
message.user_uid, message.user_uid,
message.user_nick, message.user_nick,
message.color,
message.message, message.message,
message.created_at, message.created_at,
message.updated_at message.updated_at

View File

@ -5,11 +5,13 @@ class MessageModel {
created_at = null created_at = null
updated_at = null updated_at = null
element = null element = null
constructor(uid, channel_uid,user_uid,user_nick, message,created_at, updated_at){ color = null
constructor(uid, channel_uid,user_uid,user_nick, color,message,created_at, updated_at){
this.uid = uid this.uid = uid
this.message = message this.message = message
this.user_uid = user_uid this.user_uid = user_uid
this.user_nick = user_nick this.user_nick = user_nick
this.color = color
this.channel_uid = channel_uid this.channel_uid = channel_uid
this.created_at = created_at this.created_at = created_at
this.updated_at = updated_at this.updated_at = updated_at

View File

@ -48,6 +48,7 @@ class BaseMapper:
async def save(self, model: BaseModel) -> bool: async def save(self, model: BaseModel) -> bool:
if not model.record.get("uid"): if not model.record.get("uid"):
raise Exception(f"Attempt to save without uid: {model.record}.") raise Exception(f"Attempt to save without uid: {model.record}.")
model.updated_at.update()
return self.table.upsert(model.record, ["uid"]) return self.table.upsert(model.record, ["uid"])
async def find(self, **kwargs) -> typing.AsyncGenerator: async def find(self, **kwargs) -> typing.AsyncGenerator:

View File

@ -16,9 +16,12 @@ class LoginView(BaseFormView):
async def submit(self, form): async def submit(self, form):
if await form.is_valid: if await form.is_valid:
user = await self.services.user.get(username=form.username.value,deleted_at=None) user = await self.services.user.get(username=form['username'],deleted_at=None)
# Migrate data
await self.services.user.save(user)
self.session["logged_in"] = True self.session["logged_in"] = True
self.session["username"] = form.username.value self.session["username"] = user['username']
self.session["uid"] = user["uid"] self.session["uid"] = user["uid"]
self.session["color"] = user["color"]
return {"redirect_url": "/web.html"} return {"redirect_url": "/web.html"}
return {"is_valid": False} return {"is_valid": False}

View File

@ -22,5 +22,5 @@ class RegisterView(BaseFormView):
self.request.session["uid"] = result["uid"] self.request.session["uid"] = result["uid"]
self.request.session["username"] = result["username"] self.request.session["username"] = result["username"]
self.request.session["logged_in"] = True self.request.session["logged_in"] = True
self.request.session["color"] = result["color"]
return {"redirect_url": "/web.html"} return {"redirect_url": "/web.html"}

View File

@ -14,13 +14,19 @@ class RPCView(BaseView):
self.user_uid = self.view.session.get("uid") self.user_uid = self.view.session.get("uid")
self.ws = ws self.ws = ws
async def get_user(self, user_uid):
if not user_uid:
user_uid = self.user_uid
user = await self.services.user.get(uid=user_uid)
record = user.record
del record['password']
del record['deleted_at']
del record['email']
return record
async def get_messages(self, channel_uid,offset=0): async def get_messages(self, channel_uid,offset=0):
messages = [] messages = []
async for message in self.services.channel_message.query("SELECT * FROM channel_message ORDER BY created_at DESC LIMIT 30"): #"SELECT uid, channel_uid, user_uid, message, created_at FROM channel_message WHERE channel_uid = :channel_uid ORDER BY created_at DESC LIMIT 30 OFFSET :offset",{"channel_uid":channel_uid,"offset":int(offset)}): async for message in self.services.channel_message.query("SELECT * FROM channel_message ORDER BY created_at DESC LIMIT 30"): #"SELECT uid, channel_uid, user_uid, message, created_at FROM channel_message WHERE channel_uid = :channel_uid ORDER BY created_at DESC LIMIT 30 OFFSET :offset",{"channel_uid":channel_uid,"offset":int(offset)}):
print("JEEEHHH\n",flush=True)
user = await self.services.user.get(uid=message["user_uid"]) user = await self.services.user.get(uid=message["user_uid"])
if not user: if not user:
print("User not found!",flush= True) print("User not found!",flush= True)
@ -28,6 +34,7 @@ class RPCView(BaseView):
messages.insert(0,dict( messages.insert(0,dict(
uid=message["uid"], uid=message["uid"],
color=user['color'],
user_uid=message["user_uid"], user_uid=message["user_uid"],
channel_uid=message["channel_uid"], channel_uid=message["channel_uid"],
user_nick=user['nick'], user_nick=user['nick'],

View File

@ -33,6 +33,7 @@ class StatusView(BaseView):
"email": user["email"], "email": user["email"],
"nick": user["nick"], "nick": user["nick"],
"uid": user["uid"], "uid": user["uid"],
"color": user['color'],
"memberships": memberships, "memberships": memberships,
} }