mirror of
https://github.com/paul-nameless/tg
synced 2024-11-22 20:03:17 +00:00
Merge pull request #35 from paul-nameless/chats-scrolling
Chats scrolling
This commit is contained in:
commit
35ee2b58f5
3 changed files with 127 additions and 15 deletions
|
@ -1,4 +1,5 @@
|
|||
import logging
|
||||
from typing import Dict, Any, Optional
|
||||
import os
|
||||
import threading
|
||||
from datetime import datetime
|
||||
|
@ -47,7 +48,14 @@ class Controller:
|
|||
self.tg = tg
|
||||
self.handlers = {
|
||||
"updateNewMessage": self.update_new_msg,
|
||||
"updateMessageContent": self.update_msg_content,
|
||||
"updateChatIsPinned": self.update_chat_is_pinned,
|
||||
"updateChatIsMarkedAsUnread": self.update_chat_marked_as_unread,
|
||||
"updateChatReadInbox": self.update_chat_read_inbox,
|
||||
"updateChatTitle": self.update_chat_title,
|
||||
"updateChatLastMessage": self.update_chat_last_msg,
|
||||
"updateChatDraftMessage": self.update_chat_draft_msg,
|
||||
"updateChatOrder": self.update_chat_order,
|
||||
"updateMessageSendSucceeded": self.update_msg_send_succeeded,
|
||||
"updateFile": self.update_file,
|
||||
}
|
||||
|
@ -278,6 +286,16 @@ class Controller:
|
|||
)
|
||||
self.view.msgs.draw(current_msg_idx, msgs, MSGS_LEFT_SCROLL_THRESHOLD)
|
||||
|
||||
@handle_exception
|
||||
def update_msg_content(self, update):
|
||||
content = MsgProxy(update["new_content"])
|
||||
chat_id = update["chat_id"]
|
||||
message_id = update["message_id"]
|
||||
self.model.msgs.update_msg_content(chat_id, message_id, content)
|
||||
current_chat_id = self.model.chats.id_by_index(self.model.current_chat)
|
||||
if current_chat_id == chat_id:
|
||||
self.refresh_msgs()
|
||||
|
||||
@handle_exception
|
||||
def update_new_msg(self, update):
|
||||
msg = MsgProxy(update["message"])
|
||||
|
@ -289,6 +307,9 @@ class Controller:
|
|||
if msg.file_id and msg.size <= config.max_download_size:
|
||||
self.download(msg.file_id, chat_id, msg["id"])
|
||||
|
||||
self._notify_for_message(chat_id, msg)
|
||||
|
||||
def _notify_for_message(self, chat_id: int, msg: Dict[str, Any]):
|
||||
# do not notify, if muted
|
||||
# TODO: optimize
|
||||
chat = None
|
||||
|
@ -318,12 +339,85 @@ class Controller:
|
|||
notify(text, title=name)
|
||||
|
||||
@handle_exception
|
||||
def update_chat_last_msg(self, update):
|
||||
def update_chat_order(self, update: Dict[str, Any]):
|
||||
log.info("Proccessing updateChatOrder")
|
||||
current_chat_id = self.model.chats.id_by_index(self.model.current_chat)
|
||||
chat_id = update["chat_id"]
|
||||
order = update["order"]
|
||||
|
||||
self.model.chats.update_chat(chat_id, order=order)
|
||||
self._refresh_current_chat(current_chat_id)
|
||||
|
||||
@handle_exception
|
||||
def update_chat_title(self, update: Dict[str, Any]):
|
||||
log.info("Proccessing updateChatTitle")
|
||||
chat_id = update["chat_id"]
|
||||
title = update["title"]
|
||||
current_chat_id = self.model.chats.id_by_index(self.model.current_chat)
|
||||
self.model.chats.update_chat(chat_id, title=title)
|
||||
self._refresh_current_chat(current_chat_id)
|
||||
|
||||
@handle_exception
|
||||
def update_chat_marked_as_unread(self, update: Dict[str, Any]):
|
||||
log.info("Proccessing updateChatIsMarkedAsUnread")
|
||||
chat_id = update["chat_id"]
|
||||
is_marked_as_unread = update["is_marked_as_unread"]
|
||||
current_chat_id = self.model.chats.id_by_index(self.model.current_chat)
|
||||
self.model.chats.update_chat(
|
||||
chat_id, is_marked_as_unread=is_marked_as_unread
|
||||
)
|
||||
self._refresh_current_chat(current_chat_id)
|
||||
|
||||
@handle_exception
|
||||
def update_chat_is_pinned(self, update: Dict[str, Any]):
|
||||
log.info("Proccessing updateChatIsPinned")
|
||||
chat_id = update["chat_id"]
|
||||
is_pinned = update["is_pinned"]
|
||||
order = update["order"]
|
||||
current_chat_id = self.model.chats.id_by_index(self.model.current_chat)
|
||||
self.model.chats.update_chat(chat_id, is_pinned=is_pinned, order=order)
|
||||
self._refresh_current_chat(current_chat_id)
|
||||
|
||||
@handle_exception
|
||||
def update_chat_read_inbox(self, update: Dict[str, Any]):
|
||||
log.info("Proccessing updateChatReadInbox")
|
||||
chat_id = update["chat_id"]
|
||||
last_read_inbox_message_id = update["last_read_inbox_message_id"]
|
||||
unread_count = update["unread_count"]
|
||||
current_chat_id = self.model.chats.id_by_index(self.model.current_chat)
|
||||
self.model.chats.update_chat(
|
||||
chat_id,
|
||||
last_read_inbox_message_id=last_read_inbox_message_id,
|
||||
unread_count=unread_count,
|
||||
)
|
||||
self._refresh_current_chat(current_chat_id)
|
||||
|
||||
@handle_exception
|
||||
def update_chat_draft_msg(self, update: Dict[str, Any]):
|
||||
log.info("Proccessing updateChatDraftMessage")
|
||||
chat_id = update["chat_id"]
|
||||
# FIXME: ignoring draft message itself for now because UI can't show it
|
||||
# draft_message = update["draft_message"]
|
||||
order = update["order"]
|
||||
current_chat_id = self.model.chats.id_by_index(self.model.current_chat)
|
||||
self.model.chats.update_chat(chat_id, order=order)
|
||||
self._refresh_current_chat(current_chat_id)
|
||||
|
||||
@handle_exception
|
||||
def update_chat_last_msg(self, update: Dict[str, Any]):
|
||||
log.info("Proccessing updateChatLastMessage")
|
||||
chat_id = update["chat_id"]
|
||||
message = update["last_message"]
|
||||
order = update["order"]
|
||||
current_chat_id = self.model.chats.id_by_index(self.model.current_chat)
|
||||
self.model.chats.update_last_message(chat_id, message)
|
||||
self.model.chats.update_chat(
|
||||
chat_id, last_message=message, order=order
|
||||
)
|
||||
self._refresh_current_chat(current_chat_id)
|
||||
|
||||
def _refresh_current_chat(self, current_chat_id: Optional[int]):
|
||||
if current_chat_id is None:
|
||||
return
|
||||
# TODO: we can create <index> for chats, it's faster than sqlite anyway
|
||||
# though need to make sure that creatinng index is atomic operation
|
||||
# requires locks for read, until index and chats will be the same
|
||||
|
|
|
@ -174,18 +174,19 @@ class ChatModel:
|
|||
return {}
|
||||
return result.update
|
||||
|
||||
def update_last_message(self, chat_id, message):
|
||||
def update_chat(self, chat_id: int, **updates: Dict[str, Any]) -> bool:
|
||||
for i, c in enumerate(self.chats):
|
||||
if c["id"] != chat_id:
|
||||
continue
|
||||
self.chats[i]["last_message"] = message
|
||||
self.chats[i].update(updates)
|
||||
self.chats = sorted(
|
||||
self.chats,
|
||||
key=lambda it: it["last_message"]["date"],
|
||||
# recommended chat order, for more info see
|
||||
# https://core.telegram.org/tdlib/getting-started#getting-the-lists-of-chats
|
||||
key=lambda it: (it["order"], it["id"]),
|
||||
reverse=True,
|
||||
)
|
||||
|
||||
log.info("Updated last message")
|
||||
log.info(f"Updated chat with keys {list(updates)}")
|
||||
return True
|
||||
else:
|
||||
log.error(f"Can't find chat {chat_id} in existing chats")
|
||||
|
@ -232,6 +233,16 @@ class MsgModel:
|
|||
msg_set.remove(msg_id)
|
||||
return True
|
||||
|
||||
def update_msg_content(
|
||||
self, chat_id: int, msg_id: int, message_content: Dict[str, Any]
|
||||
) -> bool:
|
||||
log.info(f"updating {msg_id=} {message_content=}")
|
||||
for msg in self.msgs[chat_id]:
|
||||
if msg["id"] != msg_id:
|
||||
continue
|
||||
msg["content"] = message_content
|
||||
return True
|
||||
|
||||
def add_message(self, chat_id: int, message: Dict[str, Any]) -> bool:
|
||||
msg_id = message["id"]
|
||||
msg_set = self.msg_ids[chat_id]
|
||||
|
|
|
@ -145,12 +145,13 @@ class ChatView:
|
|||
self.win.vline(0, self.w - 1, curses.ACS_VLINE, self.h)
|
||||
for i, chat in enumerate(chats):
|
||||
is_selected = i == current
|
||||
date, title, unread_count, last_msg = (
|
||||
get_date(chat),
|
||||
chat["title"],
|
||||
chat["unread_count"],
|
||||
get_last_msg(chat),
|
||||
unread_count = (
|
||||
chat["unread_count"] or 1 if chat["is_marked_as_unread"] else 0
|
||||
)
|
||||
date = get_date(chat)
|
||||
title = chat["title"]
|
||||
is_pinned = chat["is_pinned"]
|
||||
last_msg = get_last_msg(chat)
|
||||
offset = 0
|
||||
for attr, elem in zip(
|
||||
self._msg_attribures(is_selected), [f"{date} ", title]
|
||||
|
@ -173,7 +174,9 @@ class ChatView:
|
|||
|
||||
self.win.addstr(i, offset, last_msg, self._msg_color(is_selected))
|
||||
|
||||
if left_label := self._get_chat_label(unread_count, chat):
|
||||
if left_label := self._get_chat_label(
|
||||
unread_count, is_pinned, chat
|
||||
):
|
||||
self.win.addstr(
|
||||
i,
|
||||
self.w - len(left_label) - 1,
|
||||
|
@ -184,10 +187,14 @@ class ChatView:
|
|||
self._refresh()
|
||||
|
||||
@staticmethod
|
||||
def _get_chat_label(unread_count: int, chat: Dict[str, Any]) -> str:
|
||||
def _get_chat_label(
|
||||
unread_count: int, is_pinned: bool, chat: Dict[str, Any]
|
||||
) -> str:
|
||||
label = ""
|
||||
if is_pinned:
|
||||
label += "pinned "
|
||||
if unread_count:
|
||||
label = f"{unread_count} "
|
||||
label += f"{unread_count} "
|
||||
|
||||
if chat["notification_settings"]["mute_for"]:
|
||||
label = f"muted {label}"
|
||||
|
|
Loading…
Reference in a new issue