Skip to content

Commit

Permalink
feat: list 100 messages in all channels upon connection
Browse files Browse the repository at this point in the history
Preferably it would also list messages based on scrolling
and only when a channel is viewed the first time,
but this is good enough
  • Loading branch information
thegamecracks committed Mar 13, 2024
1 parent d15231b commit 32d318a
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 6 deletions.
10 changes: 10 additions & 0 deletions src/dumdum/client/async_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,16 @@ async def list_channels(self) -> None:
data = self._protocol.list_channels()
await self._send_and_drain(data)

async def list_messages(
self,
channel_name: str,
*,
before: int | None = None,
after: int | None = None,
) -> None:
data = self._protocol.list_messages(channel_name, before=before, after=after)
await self._send_and_drain(data)

async def _read_loop(
self,
reader: asyncio.StreamReader,
Expand Down
20 changes: 16 additions & 4 deletions src/dumdum/client/chat_frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
ClientEvent,
ClientEventChannelsListed,
ClientEventMessageReceived,
ClientEventMessagesListed,
Message,
)

Expand Down Expand Up @@ -46,11 +47,22 @@ def handle_client_event(self, event: ClientEvent) -> None:
self.channels.clear()
self.channels.extend(event.channels)
self.channel_list.refresh()

for channel in event.channels:
coro = self.app.client.list_messages(channel.name)
self.app.submit(coro)

elif isinstance(event, ClientEventMessageReceived):
self.message_cache.add_message(event.message)
channel = self.get_channel(event.message.channel_name)
if channel == self.channel_list.selected_channel:
self.messages.add_message(event.message)
self.add_message(event.message)
elif isinstance(event, ClientEventMessagesListed):
for message in event.messages:
self.add_message(message)

def add_message(self, message: Message) -> None:
self.message_cache.add_message(message)
channel = self.get_channel(message.channel_name)
if channel == self.channel_list.selected_channel:
self.messages.add_message(message)

def get_channel(self, name: str) -> Channel | None:
for channel in self.channels:
Expand Down
20 changes: 18 additions & 2 deletions src/dumdum/protocol/highcommand.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,24 @@ def get_channel(self, name: str) -> Channel | None:
def remove_channel(self, name: str) -> Channel | None:
return self._channels.pop(name, None)

def get_messages(self, channel_name: str) -> Sequence[Message]:
return self._messages[channel_name]
def get_messages(
self,
channel_name: str,
*,
before: int | None = None,
after: int | None = None,
) -> Sequence[Message]:
messages = self._messages[channel_name]

if before is not None:
i = bisect.bisect_left(messages, before, key=lambda m: m.id)
messages = messages[i:]

if after is not None:
i = bisect.bisect_right(messages, after, key=lambda m: m.id)
messages = messages[:i]

return messages[-100:]

def add_message(self, message: Message) -> None:
messages = self._messages[message.channel_name]
Expand Down
12 changes: 12 additions & 0 deletions src/dumdum/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
ServerEvent,
ServerEventAuthentication,
ServerEventListChannels,
ServerEventListMessages,
ServerEventMessageReceived,
create_snowflake,
)
Expand Down Expand Up @@ -141,6 +142,8 @@ def _handle_event(self, conn: Connection, event: ServerEvent) -> None:
self._broadcast_message(conn, event)
elif isinstance(event, ServerEventListChannels):
self._list_channels(conn, event)
elif isinstance(event, ServerEventListMessages):
self._list_messages(conn, event)

def _authenticate(self, conn: Connection, event: ServerEventAuthentication) -> None:
user = self.hc.get_user(event.nick)
Expand Down Expand Up @@ -181,6 +184,15 @@ def _list_channels(self, conn: Connection, event: ServerEventListChannels) -> No
data = conn.server.list_channels(self.hc.channels)
conn.writer.write(data)

def _list_messages(self, conn: Connection, event: ServerEventListMessages) -> None:
messages = self.hc.get_messages(
event.channel_name,
before=event.before,
after=event.after,
)
data = conn.server.list_messages(messages)
conn.writer.write(data)

def _close_connection(self, conn: Connection) -> None:
self.connections.remove(conn)
if conn.nick is not None:
Expand Down

0 comments on commit 32d318a

Please sign in to comment.