Merge pull request #166 from paul-nameless/fix-glitch

Fix drawing glitch with chat vertical separator
This commit is contained in:
Nameless 2020-07-27 20:05:58 +08:00 committed by GitHub
commit 5cf8ed016f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 46 additions and 21 deletions

View file

@ -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:

View file

@ -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: