diff --git a/src/snek/app.py b/src/snek/app.py index ecc1999..1d225cc 100644 --- a/src/snek/app.py +++ b/src/snek/app.py @@ -160,6 +160,11 @@ class Application(BaseApplication): other_user = await self.services.channel_member.get_other_dm_user(subscribed_channel["channel_uid"], request.session.get("uid")) parent_object = await subscribed_channel.get_channel() last_message =await parent_object.get_last_message() + color = None + if last_message: + last_message_user = await last_message.get_user() + color = last_message_user["color"] + item['color'] = color item["last_message_on"] = parent_object["last_message_on"] item["is_private"] = parent_object["tag"] == "dm" if other_user: @@ -168,6 +173,9 @@ class Application(BaseApplication): else: item["name"] = subscribed_channel["label"] item["uid"] = subscribed_channel["channel_uid"] + item['new_count'] = subscribed_channel['new_count'] + + print(item) channels.append(item) channels.sort(key=lambda x: x['last_message_on'] or '', reverse=True) diff --git a/src/snek/model/channel.py b/src/snek/model/channel.py index 0070948..649299e 100644 --- a/src/snek/model/channel.py +++ b/src/snek/model/channel.py @@ -13,9 +13,10 @@ class ChannelModel(BaseModel): last_message_on = ModelField(name="last_message_on", required=False, kind=str) async def get_last_message(self)->ChannelMessageModel: - async for model in self.app.services.channel_message.query("SELECT * FROM channel_message WHERE channel_uid=:channel_uid ORDER BY created_at DESC LIMIT 1",dict(channel_uid=self['uid'])): - return model + async for model in self.app.services.channel_message.query("SELECT uid FROM channel_message WHERE channel_uid=:channel_uid ORDER BY created_at DESC LIMIT 1",dict(channel_uid=self['uid'])): + + return await self.app.services.channel_message.get(uid=model['uid']) return None async def get_members(self): - return await self.app.services.channel_member.find(channel_uid=self['uid'],deleted_at=None,is_banned=False) \ No newline at end of file + return await self.app.services.channel_member.find(channel_uid=self['uid'],deleted_at=None,is_banned=False) diff --git a/src/snek/service/notification.py b/src/snek/service/notification.py index f8a87c8..a5d4ebd 100644 --- a/src/snek/service/notification.py +++ b/src/snek/service/notification.py @@ -51,6 +51,7 @@ class NotificationService(BaseService): model["message"] = ( f"New message from {user['nick']} in {channel_member['label']}." ) - if await self.save(model): - return model - raise Exception(f"Failed to create notification: {model.errors}.") + try: + await self.save(model) + except Exception as ex: + raise Exception(f"Failed to create notification: {model.errors}.") diff --git a/src/snek/templates/sidebar_channels.html b/src/snek/templates/sidebar_channels.html index 2d034b7..66371f1 100644 --- a/src/snek/templates/sidebar_channels.html +++ b/src/snek/templates/sidebar_channels.html @@ -12,13 +12,13 @@ <h2 class="no-select">Channels</h2> <ul> {% for channel in channels if not channel['is_private'] %} - <li id="channel-list-item-{{channel['uid']}}"><a class="no-select" href="/channel/{{channel['uid']}}.html">{{channel['name']}} <span class="message-count"></span></a></li> + <li id="channel-list-item-{{channel['uid']}}"><a class="no-select" {% if channel['color'] %}style="color: {{channel['color']}}"{% endif %} href="/channel/{{channel['uid']}}.html">{{channel['name']}} <span class="message-count">{% if channel['new_count'] %}({{ channel['new_count'] }}){% endif %}</span></a></li> {% endfor %} </ul> <h2 class="no-select">Private</h2> <ul> {% for channel in channels if channel['is_private'] %} - <li id="channel-list-item-{{channel['uid']}}"><a class="no-select" href="/channel/{{channel['uid']}}.html">{{channel['name']}} <span class="message-count"></span></a></li> + <li id="channel-list-item-{{channel['uid']}}"><a {% if channel['color'] %}style="color: {{channel['color']}}"{% endif %} class="no-select" href="/channel/{{channel['uid']}}.html">{{channel['name']}} <span class="message-count">{% if channel['new_count'] %}({{ channel['new_count'] }}){% endif %}</span></a></li> {% endfor %} </ul> {% endif %} @@ -28,12 +28,21 @@ constructor(el){ this.el = el } + async init(){ + + const channels = await window.app.rpc.getChannels() + channels.forEach(channel => { + if(channel.color){ + this.setMessageCount(channel.uid, channel.new_count) + this.setColor(channel.uid, channel.color) + } + }) + } get channelNodes() { return this.el.querySelectorAll("li") } channelListItemByUid(channelUid){ const id = "channel-list-item-" + channelUid; - console.error(id) return document.getElementById(id) } incrementMessageCount(channelUid){ @@ -52,11 +61,22 @@ } } setMessageCount(channelUid, count){ - const li = this.channelListItemByUid(channelUid); + + const li = this.channelListItemByUid(channelUid); if(li){ li.dataset.messageCount = new String(count) li.dataset['messageCount'] = count - li.querySelector(".message-count").textContent = '(' + count + ')' + if(!count){ + li.querySelector(".message-count").textContent = '' + }else{ + li.querySelector(".message-count").textContent = '(' + count + ')' + } + } + } + setColor(channelUid, color){ + const li = this.channelListItemByUid(channelUid); + if(li){ + li.querySelector("a").style.color = color } } notify(message){ @@ -73,4 +93,7 @@ } const channelSidebar = new ChannelSidebar(document.getElementById("channelSidebar")) + document.addEventListener("DOMContentLoaded", () => { + channelSidebar.init() + }) </script> diff --git a/src/snek/view/rpc.py b/src/snek/view/rpc.py index 55accc7..b5c3504 100644 --- a/src/snek/view/rpc.py +++ b/src/snek/view/rpc.py @@ -90,13 +90,20 @@ class RPCView(BaseView): channels = [] async for subscription in self.services.channel_member.find(user_uid=self.user_uid, is_banned=False): channel = await self.services.channel.get(uid=subscription['channel_uid']) + last_message = await channel.get_last_message() + color = None + if last_message: + last_message_user = await last_message.get_user() + color = last_message_user['color'] channels.append({ "name": subscription["label"], "uid": subscription["channel_uid"], "tag": channel["tag"], "new_count": subscription["new_count"], "is_moderator": subscription["is_moderator"], - "is_read_only": subscription["is_read_only"] + "is_read_only": subscription["is_read_only"], + 'new_count': subscription['new_count'], + 'color': color }) return channels @@ -156,9 +163,11 @@ class RPCView(BaseView): if result != "noresponse": await self._send_json({"callId": call_id, "success": success, "data": result}) except Exception as ex: + print(str(ex), flush=True) await self._send_json({"callId": call_id, "success": False, "data": str(ex)}) async def _send_json(self, obj): + print(obj, flush=True) await self.ws.send_str(json.dumps(obj, default=str)) diff --git a/src/snek/view/web.py b/src/snek/view/web.py index cdde6e3..b9271c3 100644 --- a/src/snek/view/web.py +++ b/src/snek/view/web.py @@ -46,6 +46,9 @@ class WebView(BaseView): channel_member = await self.app.services.channel_member.get(user_uid=self.session.get("uid"), channel_uid=channel["uid"]) if not channel_member: return web.HTTPNotFound() + + channel_member['new_count'] = 0 + await self.app.services.channel_member.save(channel_member) user = await self.services.user.get(uid=self.session.get("uid")) messages = [await self.app.services.channel_message.to_extended_dict(message) for message in await self.app.services.channel_message.offset( @@ -54,23 +57,5 @@ class WebView(BaseView): for message in messages: await self.app.services.notification.mark_as_read(self.session.get("uid"),message["uid"]) - channels = [] - async for subscribed_channel in self.app.services.channel_member.find(user_uid=self.session.get("uid"), deleted_at=None, is_banned=False): - item = {} - other_user = await self.app.services.channel_member.get_other_dm_user(subscribed_channel["channel_uid"], self.session.get("uid")) - parent_object = await subscribed_channel.get_channel() - last_message =await parent_object.get_last_message() - item["last_message_on"] = parent_object["last_message_on"] - item["is_private"] = parent_object["tag"] == "dm" - if other_user: - item["name"] = other_user["nick"] - item["uid"] = subscribed_channel["channel_uid"] - else: - item["name"] = subscribed_channel["label"] - item["uid"] = subscribed_channel["channel_uid"] - channels.append(item) - - channels.sort(key=lambda x: x['last_message_on'] or '', reverse=True) - name = await channel_member.get_name() - return await self.render_template("web.html", {"name": name, "channel": channel,"user": user,"messages": messages , "channels": channels}) + return await self.render_template("web.html", {"name": name, "channel": channel,"user": user,"messages": messages})