mirror of
https://github.com/paul-nameless/tg
synced 2024-11-22 03:43:19 +00:00
Introduced more (configurable) colours in chat messages to better distinguish different message types
This commit is contained in:
parent
2b0c0cf199
commit
d76891a578
2 changed files with 64 additions and 28 deletions
15
tg/config.py
15
tg/config.py
|
@ -5,6 +5,7 @@ overwritten by external config file
|
||||||
import os
|
import os
|
||||||
import platform
|
import platform
|
||||||
import runpy
|
import runpy
|
||||||
|
import tg.colors
|
||||||
from typing import Dict, Optional
|
from typing import Dict, Optional
|
||||||
|
|
||||||
_os_name = platform.system()
|
_os_name = platform.system()
|
||||||
|
@ -74,6 +75,20 @@ URL_VIEW = "urlview"
|
||||||
|
|
||||||
USERS_COLORS = tuple(range(2, 16))
|
USERS_COLORS = tuple(range(2, 16))
|
||||||
|
|
||||||
|
COLOR_TITLE = tg.colors.cyan
|
||||||
|
COLOR_TIME = tg.colors.cyan
|
||||||
|
COLOR_FLAGS = tg.colors.yellow
|
||||||
|
COLOR_UNREAD_COUNT = tg.colors.yellow
|
||||||
|
COLOR_MSG_MINE = -1 #unset
|
||||||
|
BGCOLOR_MSG_MINE = tg.colors.black
|
||||||
|
COLOR_MSG_MEDIA = tg.colors.magenta
|
||||||
|
COLOR_MSG_URL = tg.colors.blue
|
||||||
|
COLOR_MSG_REPLY = tg.colors.cyan
|
||||||
|
COLOR_MSG_NORMAL = tg.colors.white
|
||||||
|
|
||||||
|
#preview of last message in chat window
|
||||||
|
COLOR_MSG_LAST = tg.colors.white
|
||||||
|
|
||||||
KEEP_MEDIA = 7
|
KEEP_MEDIA = 7
|
||||||
|
|
||||||
FILE_PICKER_CMD = "ranger --choosefile={file_path}"
|
FILE_PICKER_CMD = "ranger --choosefile={file_path}"
|
||||||
|
|
77
tg/views.py
77
tg/views.py
|
@ -6,7 +6,7 @@ from typing import Any, Dict, List, Optional, Tuple, Union, cast
|
||||||
from _curses import window # type: ignore
|
from _curses import window # type: ignore
|
||||||
|
|
||||||
from tg import config
|
from tg import config
|
||||||
from tg.colors import bold, cyan, get_color, magenta, reverse, white, yellow
|
from tg.colors import bold, get_color, reverse, white
|
||||||
from tg.models import Model, UserModel
|
from tg.models import Model, UserModel
|
||||||
from tg.msg import MsgProxy
|
from tg.msg import MsgProxy
|
||||||
from tg.tdlib import ChatType, get_chat_type, is_group
|
from tg.tdlib import ChatType, get_chat_type, is_group
|
||||||
|
@ -171,13 +171,13 @@ class ChatView:
|
||||||
self.win.resize(self.h, self.w)
|
self.win.resize(self.h, self.w)
|
||||||
|
|
||||||
def _msg_color(self, is_selected: bool = False) -> int:
|
def _msg_color(self, is_selected: bool = False) -> int:
|
||||||
color = get_color(white, -1)
|
color = get_color(config.COLOR_MSG_LAST, -1)
|
||||||
if is_selected:
|
if is_selected:
|
||||||
return color | reverse
|
return color | reverse
|
||||||
return color
|
return color
|
||||||
|
|
||||||
def _unread_color(self, is_selected: bool = False) -> int:
|
def _unread_color(self, is_selected: bool = False) -> int:
|
||||||
color = get_color(magenta, -1)
|
color = get_color(config.COLOR_UNREAD_COUNT, -1)
|
||||||
if is_selected:
|
if is_selected:
|
||||||
return color | reverse
|
return color | reverse
|
||||||
return color
|
return color
|
||||||
|
@ -186,7 +186,7 @@ class ChatView:
|
||||||
self, is_selected: bool, title: str, user: Optional[str]
|
self, is_selected: bool, title: str, user: Optional[str]
|
||||||
) -> Tuple[int, ...]:
|
) -> Tuple[int, ...]:
|
||||||
attrs = (
|
attrs = (
|
||||||
get_color(cyan, -1),
|
get_color(config.COLOR_TIME, -1),
|
||||||
get_color(get_color_by_str(title), -1),
|
get_color(get_color_by_str(title), -1),
|
||||||
get_color(get_color_by_str(user or ""), -1),
|
get_color(get_color_by_str(user or ""), -1),
|
||||||
self._msg_color(is_selected),
|
self._msg_color(is_selected),
|
||||||
|
@ -204,7 +204,7 @@ class ChatView:
|
||||||
|
|
||||||
self.win.vline(0, width, line, self.h)
|
self.win.vline(0, width, line, self.h)
|
||||||
self.win.addstr(
|
self.win.addstr(
|
||||||
0, 0, title.center(width)[:width], get_color(cyan, -1) | bold
|
0, 0, title.center(width)[:width], get_color(config.COLOR_TITLE, -1) | bold
|
||||||
)
|
)
|
||||||
|
|
||||||
for i, chat in enumerate(chats, 1):
|
for i, chat in enumerate(chats, 1):
|
||||||
|
@ -365,11 +365,12 @@ class MsgView:
|
||||||
|
|
||||||
def _format_reply_msg(
|
def _format_reply_msg(
|
||||||
self, chat_id: int, msg: str, reply_to: int, width_limit: int
|
self, chat_id: int, msg: str, reply_to: int, width_limit: int
|
||||||
) -> str:
|
) -> Tuple[str, bool]:
|
||||||
_msg = self.model.msgs.get_message(chat_id, reply_to)
|
_msg = self.model.msgs.get_message(chat_id, reply_to)
|
||||||
if not _msg:
|
if not _msg:
|
||||||
return msg
|
return msg, False
|
||||||
reply_msg = MsgProxy(_msg)
|
reply_msg = MsgProxy(_msg)
|
||||||
|
is_reply = False
|
||||||
if reply_msg_content := self._parse_msg(reply_msg):
|
if reply_msg_content := self._parse_msg(reply_msg):
|
||||||
reply_sender = self.model.users.get_user_label(reply_msg.sender_id)
|
reply_sender = self.model.users.get_user_label(reply_msg.sender_id)
|
||||||
sender_name = f" {reply_sender}:" if reply_sender else ""
|
sender_name = f" {reply_sender}:" if reply_sender else ""
|
||||||
|
@ -377,37 +378,42 @@ class MsgView:
|
||||||
if len(reply_line) >= width_limit:
|
if len(reply_line) >= width_limit:
|
||||||
reply_line = f"{reply_line[:width_limit - 4]}..."
|
reply_line = f"{reply_line[:width_limit - 4]}..."
|
||||||
msg = f"{reply_line}\n{msg}"
|
msg = f"{reply_line}\n{msg}"
|
||||||
return msg
|
is_reply = True
|
||||||
|
return msg, is_reply
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _format_url(msg_proxy: MsgProxy) -> str:
|
def _format_url(msg_proxy: MsgProxy) -> Tuple[str, bool]:
|
||||||
if not msg_proxy.is_text or "web_page" not in msg_proxy.msg["content"]:
|
if not msg_proxy.is_text or "web_page" not in msg_proxy.msg["content"]:
|
||||||
return ""
|
return "", False
|
||||||
web = msg_proxy.msg["content"]["web_page"]
|
web = msg_proxy.msg["content"]["web_page"]
|
||||||
page_type = web["type"]
|
page_type = web["type"]
|
||||||
if page_type == "photo":
|
if page_type == "photo":
|
||||||
return f"\n | photo: {web['url']}"
|
return f"\n | photo: {web['url']}", True
|
||||||
name = web["site_name"]
|
name = web["site_name"]
|
||||||
title = web["title"]
|
title = web["title"]
|
||||||
description = web["description"]["text"].replace("\n", "")
|
description = web["description"]["text"].replace("\n", "")
|
||||||
url = f"\n | {name}: {title}"
|
url = f"\n | {name}: {title}"
|
||||||
if description:
|
if description:
|
||||||
url += f"\n | {description}"
|
url += f"\n | {description}"
|
||||||
return url
|
return url, True
|
||||||
|
|
||||||
def _format_msg(self, msg_proxy: MsgProxy, width_limit: int) -> str:
|
def _format_msg(self, msg_proxy: MsgProxy, width_limit: int) -> Tuple[str, bool, bool, bool, bool]:
|
||||||
|
is_reply = False
|
||||||
msg = self._parse_msg(msg_proxy)
|
msg = self._parse_msg(msg_proxy)
|
||||||
|
is_media = not msg_proxy.is_text
|
||||||
|
is_me = self.model.is_me(msg_proxy["sender_id"].get("user_id"))
|
||||||
if caption := msg_proxy.caption:
|
if caption := msg_proxy.caption:
|
||||||
msg += "\n" + caption.replace("\n", " ")
|
msg += "\n" + caption.replace("\n", " ")
|
||||||
msg += self._format_url(msg_proxy)
|
msg_fmt, is_url = self._format_url(msg_proxy)
|
||||||
|
msg += msg_fmt
|
||||||
if reply_to := msg_proxy.reply_msg_id:
|
if reply_to := msg_proxy.reply_msg_id:
|
||||||
msg = self._format_reply_msg(
|
msg, is_reply = self._format_reply_msg(
|
||||||
msg_proxy.chat_id, msg, reply_to, width_limit
|
msg_proxy.chat_id, msg, reply_to, width_limit
|
||||||
)
|
)
|
||||||
if reply_markup := self._format_reply_markup(msg_proxy):
|
if reply_markup := self._format_reply_markup(msg_proxy):
|
||||||
msg += reply_markup
|
msg += reply_markup
|
||||||
|
|
||||||
return msg
|
return msg, is_url, is_reply, is_media, is_me
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _format_reply_markup(msg_proxy: MsgProxy) -> str:
|
def _format_reply_markup(msg_proxy: MsgProxy) -> str:
|
||||||
|
@ -434,7 +440,7 @@ class MsgView:
|
||||||
current_msg_idx: int,
|
current_msg_idx: int,
|
||||||
msgs: List[Tuple[int, Dict[str, Any]]],
|
msgs: List[Tuple[int, Dict[str, Any]]],
|
||||||
min_msg_padding: int,
|
min_msg_padding: int,
|
||||||
) -> List[Tuple[Tuple[str, ...], bool, int]]:
|
) -> List[Tuple[Tuple[str, ...], bool, bool, bool, bool, bool, int]]:
|
||||||
"""
|
"""
|
||||||
Tries to collect list of messages that will satisfy `min_msg_padding`
|
Tries to collect list of messages that will satisfy `min_msg_padding`
|
||||||
theshold. Long messages could prevent other messages from displaying on
|
theshold. Long messages could prevent other messages from displaying on
|
||||||
|
@ -444,7 +450,7 @@ class MsgView:
|
||||||
message could be visible on the screen.
|
message could be visible on the screen.
|
||||||
"""
|
"""
|
||||||
selected_item_idx: Optional[int] = None
|
selected_item_idx: Optional[int] = None
|
||||||
collected_items: List[Tuple[Tuple[str, ...], bool, int]] = []
|
collected_items: List[Tuple[Tuple[str, ...], bool, bool, bool, bool, bool, int]] = []
|
||||||
for ignore_before in range(len(msgs)):
|
for ignore_before in range(len(msgs)):
|
||||||
if selected_item_idx is not None:
|
if selected_item_idx is not None:
|
||||||
break
|
break
|
||||||
|
@ -464,7 +470,7 @@ class MsgView:
|
||||||
label_elements = f" {dt} ", user_id, flags
|
label_elements = f" {dt} ", user_id, flags
|
||||||
label_len = sum(string_len_dwc(e) for e in label_elements)
|
label_len = sum(string_len_dwc(e) for e in label_elements)
|
||||||
|
|
||||||
msg = self._format_msg(
|
msg, is_url, is_reply, is_media, is_me = self._format_msg(
|
||||||
msg_proxy, width_limit=self.w - label_len - 1
|
msg_proxy, width_limit=self.w - label_len - 1
|
||||||
)
|
)
|
||||||
elements = *label_elements, f" {msg}"
|
elements = *label_elements, f" {msg}"
|
||||||
|
@ -493,9 +499,9 @@ class MsgView:
|
||||||
"",
|
"",
|
||||||
f" ...{msg[tail_chatacters:]}",
|
f" ...{msg[tail_chatacters:]}",
|
||||||
)
|
)
|
||||||
collected_items.append((elements, is_selected_msg, 0))
|
collected_items.append((elements, is_selected_msg, is_url, is_reply, is_media, is_me, 0))
|
||||||
break
|
break
|
||||||
collected_items.append((elements, is_selected_msg, line_num))
|
collected_items.append((elements, is_selected_msg, is_url, is_reply, is_media, is_me, line_num))
|
||||||
if is_selected_msg:
|
if is_selected_msg:
|
||||||
selected_item_idx = len(collected_items) - 1
|
selected_item_idx = len(collected_items) - 1
|
||||||
if (
|
if (
|
||||||
|
@ -524,11 +530,11 @@ class MsgView:
|
||||||
if not msgs_to_draw:
|
if not msgs_to_draw:
|
||||||
log.error("Can't collect message for drawing!")
|
log.error("Can't collect message for drawing!")
|
||||||
|
|
||||||
for elements, selected, line_num in msgs_to_draw:
|
for elements, selected, is_url, is_reply, is_media, is_me, line_num in msgs_to_draw:
|
||||||
column = 0
|
column = 0
|
||||||
user = elements[1]
|
user = elements[1]
|
||||||
for attr, elem in zip(
|
for attr, elem in zip(
|
||||||
self._msg_attributes(selected, user), elements
|
self._msg_attributes(selected, is_url, is_reply, is_media, is_me, user), elements
|
||||||
):
|
):
|
||||||
if not elem:
|
if not elem:
|
||||||
continue
|
continue
|
||||||
|
@ -553,7 +559,7 @@ class MsgView:
|
||||||
column += string_len_dwc(elem)
|
column += string_len_dwc(elem)
|
||||||
|
|
||||||
self.win.addstr(
|
self.win.addstr(
|
||||||
0, 0, self._msg_title(chat), get_color(cyan, -1) | bold
|
0, 0, self._msg_title(chat), get_color(config.COLOR_TITLE, -1) | bold
|
||||||
)
|
)
|
||||||
|
|
||||||
self._refresh()
|
self._refresh()
|
||||||
|
@ -584,12 +590,27 @@ class MsgView:
|
||||||
|
|
||||||
return f"{chat['title']}: {status}".center(self.w)[: self.w]
|
return f"{chat['title']}: {status}".center(self.w)[: self.w]
|
||||||
|
|
||||||
def _msg_attributes(self, is_selected: bool, user: str) -> Tuple[int, ...]:
|
def _msg_attributes(self, is_selected: bool, is_url: bool, is_reply: bool, is_media: bool, is_me: bool, user: str) -> Tuple[int, ...]:
|
||||||
|
if is_me:
|
||||||
|
bgcolor = config.BGCOLOR_MSG_MINE
|
||||||
|
else:
|
||||||
|
bgcolor = -1
|
||||||
|
if is_me and config.COLOR_MSG_MINE != -1:
|
||||||
|
textcolor = config.COLOR_MSG_MINE
|
||||||
|
elif is_media and config.COLOR_MSG_MEDIA != -1:
|
||||||
|
textcolor = config.COLOR_MSG_MEDIA
|
||||||
|
elif is_url and config.COLOR_MSG_URL != -1:
|
||||||
|
textcolor = config.COLOR_MSG_URL
|
||||||
|
elif is_reply and config.COLOR_MSG_REPLY != -1:
|
||||||
|
textcolor = config.COLOR_MSG_REPLY
|
||||||
|
else:
|
||||||
|
textcolor = config.COLOR_MSG_NORMAL
|
||||||
|
|
||||||
attrs = (
|
attrs = (
|
||||||
get_color(cyan, -1),
|
get_color(config.COLOR_TIME, -1),
|
||||||
get_color(get_color_by_str(user), -1),
|
get_color(get_color_by_str(user), -1),
|
||||||
get_color(yellow, -1),
|
get_color(config.COLOR_FLAGS, -1),
|
||||||
get_color(white, -1),
|
get_color(textcolor, bgcolor),
|
||||||
)
|
)
|
||||||
|
|
||||||
if is_selected:
|
if is_selected:
|
||||||
|
|
Loading…
Reference in a new issue