mirror of
https://github.com/paul-nameless/tg
synced 2024-11-25 21:30:22 +00:00
Merge pull request #166 from paul-nameless/fix-glitch
Fix drawing glitch with chat vertical separator
This commit is contained in:
commit
5cf8ed016f
2 changed files with 46 additions and 21 deletions
23
tg/utils.py
23
tg/utils.py
|
@ -12,6 +12,7 @@ import shlex
|
||||||
import struct
|
import struct
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
import unicodedata
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from functools import lru_cache
|
from functools import lru_cache
|
||||||
from logging.handlers import RotatingFileHandler
|
from logging.handlers import RotatingFileHandler
|
||||||
|
@ -180,9 +181,25 @@ def notify(
|
||||||
subprocess.Popen(notify_cmd, shell=True)
|
subprocess.Popen(notify_cmd, shell=True)
|
||||||
|
|
||||||
|
|
||||||
def truncate_to_len(s: str, target_len: int) -> str:
|
def string_len_dwc(string: str) -> int:
|
||||||
target_len -= sum(map(bool, map(emoji_pattern.findall, s[:target_len])))
|
"""Returns string len including count for double width characters"""
|
||||||
return s[: max(1, target_len - 1)]
|
return sum(1 + (unicodedata.east_asian_width(c) in "WF") for c in string)
|
||||||
|
|
||||||
|
|
||||||
|
def truncate_to_len(string: str, width: int) -> str:
|
||||||
|
real_len = string_len_dwc(string)
|
||||||
|
if real_len <= width:
|
||||||
|
return string
|
||||||
|
|
||||||
|
cur_len = 0
|
||||||
|
out_string = ""
|
||||||
|
|
||||||
|
for char in string:
|
||||||
|
cur_len += 2 if unicodedata.east_asian_width(char) in "WF" else 1
|
||||||
|
out_string += char
|
||||||
|
if cur_len >= width:
|
||||||
|
break
|
||||||
|
return out_string
|
||||||
|
|
||||||
|
|
||||||
def copy_to_clipboard(text: str) -> None:
|
def copy_to_clipboard(text: str) -> None:
|
||||||
|
|
44
tg/views.py
44
tg/views.py
|
@ -10,7 +10,13 @@ from tg.colors import bold, cyan, get_color, magenta, reverse, white, yellow
|
||||||
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
|
||||||
from tg.utils import emoji_pattern, get_color_by_str, num, truncate_to_len
|
from tg.utils import (
|
||||||
|
emoji_pattern,
|
||||||
|
get_color_by_str,
|
||||||
|
num,
|
||||||
|
string_len_dwc,
|
||||||
|
truncate_to_len,
|
||||||
|
)
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -173,6 +179,7 @@ class ChatView:
|
||||||
self.win.erase()
|
self.win.erase()
|
||||||
line = curses.ACS_VLINE # type: ignore
|
line = curses.ACS_VLINE # type: ignore
|
||||||
width = self.w - 1
|
width = self.w - 1
|
||||||
|
|
||||||
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(cyan, -1) | bold
|
||||||
|
@ -186,6 +193,17 @@ class ChatView:
|
||||||
|
|
||||||
last_msg_sender, last_msg = self._get_last_msg_data(chat)
|
last_msg_sender, last_msg = self._get_last_msg_data(chat)
|
||||||
sender_label = f" {last_msg_sender}" if last_msg_sender else ""
|
sender_label = f" {last_msg_sender}" if last_msg_sender else ""
|
||||||
|
flags = self._get_flags(chat)
|
||||||
|
flags_len = string_len_dwc(flags)
|
||||||
|
|
||||||
|
if flags:
|
||||||
|
self.win.addstr(
|
||||||
|
i,
|
||||||
|
max(0, width - flags_len),
|
||||||
|
truncate_to_len(flags, width)[-width:],
|
||||||
|
# flags[-width:],
|
||||||
|
self._unread_color(is_selected),
|
||||||
|
)
|
||||||
|
|
||||||
for attr, elem in zip(
|
for attr, elem in zip(
|
||||||
self._chat_attributes(is_selected, title, last_msg_sender),
|
self._chat_attributes(is_selected, title, last_msg_sender),
|
||||||
|
@ -193,23 +211,12 @@ class ChatView:
|
||||||
):
|
):
|
||||||
if not elem:
|
if not elem:
|
||||||
continue
|
continue
|
||||||
item = truncate_to_len(elem, max(0, width - offset))
|
item = truncate_to_len(
|
||||||
|
elem, max(0, width - offset - flags_len)
|
||||||
|
)
|
||||||
if len(item) > 1:
|
if len(item) > 1:
|
||||||
self.win.addstr(i, offset, item, attr)
|
self.win.addstr(i, offset, item, attr)
|
||||||
offset += len(elem) + sum(
|
offset += string_len_dwc(elem)
|
||||||
map(len, emoji_pattern.findall(elem))
|
|
||||||
)
|
|
||||||
|
|
||||||
if flags := self._get_flags(chat):
|
|
||||||
flags_len = len(flags) + sum(
|
|
||||||
map(len, emoji_pattern.findall(flags))
|
|
||||||
)
|
|
||||||
self.win.addstr(
|
|
||||||
i,
|
|
||||||
max(0, width - flags_len),
|
|
||||||
flags[-width:],
|
|
||||||
self._unread_color(is_selected),
|
|
||||||
)
|
|
||||||
|
|
||||||
self._refresh()
|
self._refresh()
|
||||||
|
|
||||||
|
@ -463,7 +470,7 @@ class MsgView:
|
||||||
):
|
):
|
||||||
if not elem:
|
if not elem:
|
||||||
continue
|
continue
|
||||||
lines = (column + len(elem)) // self.w
|
lines = (column + string_len_dwc(elem)) // self.w
|
||||||
last_line = self.h == line_num + lines
|
last_line = self.h == line_num + lines
|
||||||
# work around agaist curses behaviour, when you cant write
|
# work around agaist curses behaviour, when you cant write
|
||||||
# char to the lower right coner of the window
|
# char to the lower right coner of the window
|
||||||
|
@ -481,11 +488,12 @@ class MsgView:
|
||||||
start, stop = stop, stop + self.w
|
start, stop = stop, stop + self.w
|
||||||
else:
|
else:
|
||||||
self.win.addstr(line_num, column, elem, attr)
|
self.win.addstr(line_num, column, elem, attr)
|
||||||
column += len(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(cyan, -1) | bold
|
||||||
)
|
)
|
||||||
|
|
||||||
self._refresh()
|
self._refresh()
|
||||||
|
|
||||||
def _msg_title(self, chat: Dict[str, Any]) -> str:
|
def _msg_title(self, chat: Dict[str, Any]) -> str:
|
||||||
|
|
Loading…
Reference in a new issue