Skip to content

Commit

Permalink
Message timestamps(#56)
Browse files Browse the repository at this point in the history
  • Loading branch information
douglascdev committed Mar 23, 2024
1 parent 604738e commit 8b1e686
Show file tree
Hide file tree
Showing 8 changed files with 87 additions and 8 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
Changes:
* Add button to scroll down when chat is scrolled up(#56)
* Message timestamps(#55)
14 changes: 11 additions & 3 deletions hasherino/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,13 @@ class Hasherino:
def __init__(
self,
font_size_pubsub: PubSub,
ts_pubsub: PubSub,
memory_storage: AsyncKeyValueStorage,
persistent_storage: AsyncKeyValueStorage,
page: ft.Page,
) -> None:
self.font_size_pubsub = font_size_pubsub
self.ts_pubsub = ts_pubsub
self.memory_storage = memory_storage
self.persistent_storage = persistent_storage
self.page = page
Expand Down Expand Up @@ -85,7 +87,9 @@ async def login_click(self, _):

async def settings_click(self, _):
logging.debug("Clicked on settings")
sv = SettingsView(self.font_size_pubsub, self.persistent_storage)
sv = SettingsView(
self.font_size_pubsub, self.ts_pubsub, self.persistent_storage
)
await sv.init()
self.page.views.append(sv)
await self.page.update_async()
Expand Down Expand Up @@ -256,7 +260,10 @@ async def run(self):

self.status_column = StatusColumn(self.memory_storage, self.persistent_storage)
chat_container = ChatContainer(
self.persistent_storage, self.memory_storage, self.font_size_pubsub
self.persistent_storage,
self.memory_storage,
self.font_size_pubsub,
self.ts_pubsub,
)
self.new_message_row = NewMessageRow(
self.memory_storage,
Expand Down Expand Up @@ -379,11 +386,12 @@ async def main(page: ft.Page):
tg.create_task(persistent_storage.set("color_switcher", False))
tg.create_task(persistent_storage.set("max_messages_per_chat", 100))
tg.create_task(persistent_storage.set("not_first_run", True))
tg.create_task(persistent_storage.set("show_timestamp", True))
tg.create_task(persistent_storage.set("theme", "System"))
tg.create_task(persistent_storage.set("window_width", 500))
tg.create_task(persistent_storage.set("window_height", 800))

hasherino = Hasherino(PubSub(), memory_storage, persistent_storage, page)
hasherino = Hasherino(PubSub(), PubSub(), memory_storage, persistent_storage, page)
await hasherino.run()


Expand Down
3 changes: 3 additions & 0 deletions hasherino/components/chat_container.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,12 @@ def __init__(
persistent_storage: AsyncKeyValueStorage,
memory_storage: AsyncKeyValueStorage,
font_size_pubsub: PubSub,
ts_pubsub: PubSub,
):
self.persistent_storage = persistent_storage
self.memory_storage = memory_storage
self.font_size_pubsub = font_size_pubsub
self.ts_pubsub = ts_pubsub
self.is_chat_scrolled_down = False
self.chat = ft.ListView(
expand=True,
Expand Down Expand Up @@ -98,6 +100,7 @@ async def on_message(self, message: Message):
)
await self.add_author_to_user_set(message.user.name)
await m.subscribe_to_font_size_change(self.font_size_pubsub)
await m.subscribe_to_show_timestamp_change(self.ts_pubsub)

elif message.message_type == "login_message":
m = ft.Text(
Expand Down
40 changes: 37 additions & 3 deletions hasherino/components/chat_message.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ async def on_font_size_changed(self, new_font_size: int):
...


class ShowTimestampSubscriber(ABC):
async def on_show_timestamp_changed(self, show_timestamp: bool):
...


class ChatText(ft.Container, FontSizeSubscriber):
def __init__(self, text: str, color: str, size: int, weight=""):
try:
Expand Down Expand Up @@ -48,6 +53,17 @@ async def on_font_size_changed(self, new_font_size: int):
self.height = new_font_size * 2


class ChatTimestamp(ft.Text, ShowTimestampSubscriber):
def __init__(self, text: str, color: str, size: int):
super().__init__(text, size=size, color=color, selectable=False)

async def on_show_timestamp_changed(self, show_timestamp: bool):
if show_timestamp:
self.visible = True
else:
self.visible = False


class ChatMessage(ft.Row):
def __init__(self, message: Message, page: ft.Page, font_size: int):
super().__init__()
Expand All @@ -63,9 +79,18 @@ def __init__(self, message: Message, page: ft.Page, font_size: int):
self.add_control_elements(message)

def add_control_elements(self, message):
self.controls = [
ChatBadge(badge.url, self.font_size) for badge in message.user.badges
]
if message.timestamp is not None:
self.controls.append(
ChatTimestamp(
text=f"{message.timestamp.strftime('%H:%M')} ",
color=ft.colors.GREY,
size=max(self.font_size - 4, 4),
)
)

self.controls.extend(
[ChatBadge(badge.url, self.font_size) for badge in message.user.badges]
)

self.controls.append(
ChatText(
Expand Down Expand Up @@ -97,3 +122,12 @@ async def subscribe_to_font_size_change(self, pubsub: PubSub):
if isinstance(control, FontSizeSubscriber)
]
)

async def subscribe_to_show_timestamp_change(self, pubsub: PubSub):
await pubsub.subscribe_all(
[
control.on_show_timestamp_changed
for control in self.controls
if isinstance(control, ShowTimestampSubscriber)
]
)
19 changes: 18 additions & 1 deletion hasherino/components/settings_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,11 @@


class SettingsView(ft.View):
def __init__(self, font_size_pubsub: PubSub, storage: AsyncKeyValueStorage):
def __init__(
self, font_size_pubsub: PubSub, ts_pubsub: PubSub, storage: AsyncKeyValueStorage
):
self.font_size_pubsub = font_size_pubsub
self.ts_pubsub = ts_pubsub
self.storage = storage

async def init(self):
Expand Down Expand Up @@ -72,6 +75,16 @@ async def _get_general_tab(self) -> ft.Tab:
],
alignment=ft.MainAxisAlignment.SPACE_BETWEEN,
),
ft.Row(
controls=[
ft.Text("Show message timestamp", size=16),
ft.Checkbox(
on_change=self._show_timestamp_click,
value=await self.storage.get("show_timestamp"),
),
],
alignment=ft.MainAxisAlignment.SPACE_BETWEEN,
),
],
),
)
Expand Down Expand Up @@ -175,6 +188,10 @@ async def _theme_select(self, e):
await self.storage.set("theme", e.data)
await self.page.update_async()

async def _show_timestamp_click(self, e):
await self.storage.set("show_timestamp", e.control.value)
await self.ts_pubsub.send(e.control.value)

async def _log_path_copy_click(self, _):
await self.page.set_clipboard_async(str(LOG_PATH.absolute()))

Expand Down
4 changes: 4 additions & 0 deletions hasherino/factory.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from datetime import datetime

from hasherino.hasherino_dataclasses import Emote, HasherinoUser, Message
from hasherino.parse_irc import ParsedMessage

Expand All @@ -22,6 +24,7 @@ def message_factory(
elements=elements,
message_type="chat_message",
me=False,
timestamp=datetime.now(),
)
elif isinstance(message, ParsedMessage):
emote_map = emote_map.copy()
Expand All @@ -34,6 +37,7 @@ def message_factory(
elements=elements,
message_type="chat_message",
me=message.is_me(),
timestamp=message.get_timestamp(),
)
else:
raise TypeError("The message parameter can only be an str or ParsedMessage.")
3 changes: 2 additions & 1 deletion hasherino/hasherino_dataclasses.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from dataclasses import dataclass
from datetime import datetime
from enum import Enum
from json import dumps


@dataclass
Expand Down Expand Up @@ -35,3 +35,4 @@ class Message:
elements: list[str | Emote]
message_type: str
me: bool
timestamp: datetime | None = None
11 changes: 11 additions & 0 deletions hasherino/parse_irc.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import logging
from collections import defaultdict
from datetime import datetime
from enum import Enum, auto

from hasherino.hasherino_dataclasses import Badge, Emote
Expand Down Expand Up @@ -98,6 +99,13 @@ def get_command(self) -> Command:

return result

def get_timestamp(self) -> datetime | None:
if not self.tags or not self.tags.get("tmi-sent-ts"):
return None

ts = int(self.tags["tmi-sent-ts"])
return datetime.fromtimestamp(ts / 1000)

def is_me(self) -> bool:
"""
Messages sent with /me, coloring the whole line with the user's chat color
Expand Down Expand Up @@ -346,6 +354,9 @@ def _parse_tags(self, raw_tags: str):
case "emote-sets":
dict_parsed_tags["emote-sets"] = tag_value

case "tmi-sent-ts":
dict_parsed_tags["tmi-sent-ts"] = tag_value

case _:
pass

Expand Down

0 comments on commit 8b1e686

Please sign in to comment.