mirror of
https://github.com/xfgryujk/blivechat.git
synced 2025-01-13 22:00:15 +08:00
GUI插件完成房间窗口
This commit is contained in:
parent
8277c56224
commit
67a935866c
@ -48,7 +48,7 @@
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">RoomFrameBase</property>
|
||||
<property name="pos"></property>
|
||||
<property name="size">750,650</property>
|
||||
<property name="size">800,650</property>
|
||||
<property name="style">wxDEFAULT_FRAME_STYLE</property>
|
||||
<property name="subclass">; ; forward_declare</property>
|
||||
<property name="title">blivechat - 房间 123456</property>
|
||||
@ -58,6 +58,7 @@
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style">wxTAB_TRAVERSAL</property>
|
||||
<property name="xrc_skip_sizer">1</property>
|
||||
<event name="OnClose">_on_close</event>
|
||||
<object class="wxBoxSizer" expanded="true">
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">bSizer1</property>
|
||||
@ -153,6 +154,7 @@
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<event name="OnButtonClick">_on_config_button_click</event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="true">
|
||||
@ -225,6 +227,7 @@
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<event name="OnToggleButton">_on_stay_on_top_button_toggle</event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="true">
|
||||
@ -276,7 +279,7 @@
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label"><<</property>
|
||||
<property name="label">>></property>
|
||||
<property name="margins"></property>
|
||||
<property name="markup">0</property>
|
||||
<property name="max_size"></property>
|
||||
@ -309,6 +312,7 @@
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<event name="OnButtonClick">_on_collapse_console_button_click</event>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
@ -417,7 +421,7 @@
|
||||
<property name="maximum_size"></property>
|
||||
<property name="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="minimum_size">200,-1</property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">console_notebook</property>
|
||||
<property name="pane_border">1</property>
|
||||
@ -674,7 +678,7 @@
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="style">wxLC_REPORT</property>
|
||||
<property name="style">wxLC_REPORT|wxLC_SINGLE_SEL</property>
|
||||
<property name="subclass">; ; forward_declare</property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip"></property>
|
||||
@ -801,7 +805,7 @@
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="style">wxLC_REPORT</property>
|
||||
<property name="style">wxLC_REPORT|wxLC_SINGLE_SEL</property>
|
||||
<property name="subclass">; ; forward_declare</property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip"></property>
|
||||
@ -940,7 +944,7 @@
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="style">wxLC_REPORT</property>
|
||||
<property name="style">wxLC_REPORT|wxLC_SINGLE_SEL</property>
|
||||
<property name="subclass">; ; forward_declare</property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip"></property>
|
||||
|
@ -18,7 +18,7 @@ import wx.html2
|
||||
class RoomFrameBase ( wx.Frame ):
|
||||
|
||||
def __init__( self, parent ):
|
||||
wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = u"blivechat - 房间 123456", pos = wx.DefaultPosition, size = wx.Size( 750,650 ), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL )
|
||||
wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = u"blivechat - 房间 123456", pos = wx.DefaultPosition, size = wx.Size( 800,650 ), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL )
|
||||
|
||||
self.SetSizeHints( wx.DefaultSize, wx.DefaultSize )
|
||||
self.SetForegroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_WINDOW ) )
|
||||
@ -39,7 +39,7 @@ class RoomFrameBase ( wx.Frame ):
|
||||
|
||||
bSizer3.Add( ( 0, 0), 1, wx.EXPAND, 5 )
|
||||
|
||||
self.collapse_console_button = wx.Button( self, wx.ID_ANY, u"<<", wx.DefaultPosition, wx.DefaultSize, 0 )
|
||||
self.collapse_console_button = wx.Button( self, wx.ID_ANY, u">>", wx.DefaultPosition, wx.DefaultSize, 0 )
|
||||
bSizer3.Add( self.collapse_console_button, 0, 0, 5 )
|
||||
|
||||
|
||||
@ -52,6 +52,8 @@ class RoomFrameBase ( wx.Frame ):
|
||||
bSizer1.Add( bSizer2, 1, wx.EXPAND, 5 )
|
||||
|
||||
self.console_notebook = wx.Notebook( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, 0 )
|
||||
self.console_notebook.SetMinSize( wx.Size( 200,-1 ) )
|
||||
|
||||
self.paid_panel = wx.Panel( self.console_notebook, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
|
||||
bSizer4 = wx.BoxSizer( wx.VERTICAL )
|
||||
|
||||
@ -66,7 +68,7 @@ class RoomFrameBase ( wx.Frame ):
|
||||
self.super_chat_panel = wx.Panel( self.console_notebook, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
|
||||
bSizer5 = wx.BoxSizer( wx.VERTICAL )
|
||||
|
||||
self.super_chat_list = wx.ListCtrl( self.super_chat_panel, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LC_REPORT )
|
||||
self.super_chat_list = wx.ListCtrl( self.super_chat_panel, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LC_REPORT|wx.LC_SINGLE_SEL )
|
||||
bSizer5.Add( self.super_chat_list, 1, wx.EXPAND, 5 )
|
||||
|
||||
|
||||
@ -77,7 +79,7 @@ class RoomFrameBase ( wx.Frame ):
|
||||
self.gift_panel = wx.Panel( self.console_notebook, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
|
||||
bSizer6 = wx.BoxSizer( wx.VERTICAL )
|
||||
|
||||
self.gift_list = wx.ListCtrl( self.gift_panel, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LC_REPORT )
|
||||
self.gift_list = wx.ListCtrl( self.gift_panel, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LC_REPORT|wx.LC_SINGLE_SEL )
|
||||
bSizer6.Add( self.gift_list, 1, wx.EXPAND, 5 )
|
||||
|
||||
|
||||
@ -90,7 +92,7 @@ class RoomFrameBase ( wx.Frame ):
|
||||
|
||||
sbSizer1 = wx.StaticBoxSizer( wx.StaticBox( self.statistics_panel, wx.ID_ANY, u"付费用户" ), wx.VERTICAL )
|
||||
|
||||
self.paid_user_list = wx.ListCtrl( sbSizer1.GetStaticBox(), wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LC_REPORT )
|
||||
self.paid_user_list = wx.ListCtrl( sbSizer1.GetStaticBox(), wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LC_REPORT|wx.LC_SINGLE_SEL )
|
||||
sbSizer1.Add( self.paid_user_list, 1, wx.EXPAND, 5 )
|
||||
|
||||
|
||||
@ -115,10 +117,30 @@ class RoomFrameBase ( wx.Frame ):
|
||||
|
||||
self.Centre( wx.BOTH )
|
||||
|
||||
# Connect Events
|
||||
self.Bind( wx.EVT_CLOSE, self._on_close )
|
||||
self.config_button.Bind( wx.EVT_BUTTON, self._on_config_button_click )
|
||||
self.stay_on_top_button.Bind( wx.EVT_TOGGLEBUTTON, self._on_stay_on_top_button_toggle )
|
||||
self.collapse_console_button.Bind( wx.EVT_BUTTON, self._on_collapse_console_button_click )
|
||||
|
||||
def __del__( self ):
|
||||
pass
|
||||
|
||||
|
||||
# Virtual event handlers, override them in your derived class
|
||||
def _on_close( self, event ):
|
||||
event.Skip()
|
||||
|
||||
def _on_config_button_click( self, event ):
|
||||
event.Skip()
|
||||
|
||||
def _on_stay_on_top_button_toggle( self, event ):
|
||||
event.Skip()
|
||||
|
||||
def _on_collapse_console_button_click( self, event ):
|
||||
event.Skip()
|
||||
|
||||
|
||||
###########################################################################
|
||||
## Class RoomConfigDialogBase
|
||||
###########################################################################
|
||||
|
@ -5,6 +5,8 @@ import datetime
|
||||
import logging
|
||||
from typing import *
|
||||
|
||||
import pubsub.pub as pub
|
||||
|
||||
import blcsdk
|
||||
import blcsdk.models as sdk_models
|
||||
|
||||
@ -41,7 +43,7 @@ class MsgHandler(blcsdk.BaseHandler):
|
||||
def _on_open_plugin_admin_ui(
|
||||
self, client: blcsdk.BlcPluginClient, message: sdk_models.OpenPluginAdminUiMsg, extra: sdk_models.ExtraData
|
||||
):
|
||||
pass
|
||||
pub.sendMessage('open_admin_ui')
|
||||
|
||||
def _on_room_init(
|
||||
self, client: blcsdk.BlcPluginClient, message: sdk_models.RoomInitMsg, extra: sdk_models.ExtraData
|
||||
@ -119,6 +121,10 @@ class MsgHandler(blcsdk.BaseHandler):
|
||||
))
|
||||
|
||||
|
||||
def iter_rooms() -> Iterable['Room']:
|
||||
return _key_room_dict.values()
|
||||
|
||||
|
||||
def get_room(room_key: sdk_models.RoomKey):
|
||||
return _key_room_dict.get(room_key, None)
|
||||
|
||||
@ -128,14 +134,15 @@ def _get_or_add_room(room_key: sdk_models.RoomKey, room_id):
|
||||
if room is None:
|
||||
if room_id is None:
|
||||
raise TypeError('room_id is None')
|
||||
room = _key_room_dict[room_id] = Room(room_key, room_id)
|
||||
# TODO 打开房间窗口
|
||||
room = _key_room_dict[room_key] = Room(room_key, room_id)
|
||||
pub.sendMessage('add_room', room_key=room_key)
|
||||
return room
|
||||
|
||||
|
||||
def _del_room(room_key: sdk_models.RoomKey):
|
||||
_key_room_dict.pop(room_key, None)
|
||||
# TODO 关闭房间窗口
|
||||
room = _key_room_dict.pop(room_key, None)
|
||||
if room is not None:
|
||||
pub.sendMessage('del_room', room_key=room_key)
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
@ -177,44 +184,77 @@ class Room:
|
||||
self._interact_uids: Set[str] = set()
|
||||
self._total_paid_price = 0
|
||||
|
||||
@property
|
||||
def room_key(self):
|
||||
return self._room_key
|
||||
|
||||
@property
|
||||
def room_id(self):
|
||||
return self._room_id
|
||||
|
||||
@property
|
||||
def super_chats(self):
|
||||
return self._super_chats
|
||||
|
||||
@property
|
||||
def gifts(self):
|
||||
return self._gifts
|
||||
|
||||
@property
|
||||
def uid_paid_user_dict(self):
|
||||
return self._uid_paid_user_dict
|
||||
|
||||
@property
|
||||
def danmaku_num(self):
|
||||
return self._danmaku_num
|
||||
|
||||
@property
|
||||
def interact_uids(self):
|
||||
return self._interact_uids
|
||||
|
||||
@property
|
||||
def total_paid_price(self):
|
||||
return self._total_paid_price
|
||||
|
||||
def add_danmaku(self, uid):
|
||||
self._danmaku_num += 1
|
||||
pub.sendMessage('room_data_change.danmaku_num', room=self, value=self._danmaku_num)
|
||||
|
||||
self._add_interact_uid(uid)
|
||||
|
||||
def _add_interact_uid(self, uid):
|
||||
if uid in self._interact_uids:
|
||||
return
|
||||
|
||||
self._interact_uids.add(uid)
|
||||
pub.sendMessage(
|
||||
'room_data_change.interact_uids',
|
||||
room=self,
|
||||
value=self._interact_uids,
|
||||
index=uid,
|
||||
is_new=True,
|
||||
)
|
||||
|
||||
def add_super_chat(self, super_chat: SuperChatRecord):
|
||||
self._super_chats.append(super_chat)
|
||||
pub.sendMessage(
|
||||
'room_data_change.super_chats',
|
||||
room=self,
|
||||
value=self._super_chats,
|
||||
index=len(self._super_chats) - 1,
|
||||
is_new=True,
|
||||
)
|
||||
|
||||
self._add_user_paid_price(PaidUserRecord(
|
||||
uid=super_chat.uid,
|
||||
name=super_chat.author_name,
|
||||
price=super_chat.price,
|
||||
))
|
||||
self._danmaku_num += 1
|
||||
self._interact_uids.add(super_chat.uid)
|
||||
|
||||
self._total_paid_price += super_chat.price
|
||||
pub.sendMessage('room_data_change.total_paid_price', room=self, value=self._total_paid_price)
|
||||
|
||||
def add_gift(self, gift: GiftRecord):
|
||||
# 尝试合并
|
||||
is_merged = False
|
||||
min_time_to_merge = gift.time - datetime.timedelta(seconds=10)
|
||||
for old_gift in reversed(self._gifts):
|
||||
if old_gift.time < min_time_to_merge:
|
||||
break
|
||||
if old_gift.uid == gift.uid and old_gift.gift_name == gift.gift_name:
|
||||
old_gift.num += gift.num
|
||||
old_gift.price += gift.price
|
||||
is_merged = True
|
||||
break
|
||||
|
||||
if not is_merged:
|
||||
self._gifts.append(gift)
|
||||
if gift.price > 0.:
|
||||
self._add_user_paid_price(PaidUserRecord(
|
||||
uid=gift.uid,
|
||||
name=gift.author_name,
|
||||
price=gift.price,
|
||||
))
|
||||
self._interact_uids.add(gift.uid)
|
||||
self._total_paid_price += gift.price
|
||||
self.add_danmaku(super_chat.uid)
|
||||
|
||||
def _add_user_paid_price(self, paid_user: PaidUserRecord):
|
||||
old_paid_user = self._uid_paid_user_dict.get(paid_user.uid, None)
|
||||
@ -224,4 +264,53 @@ class Room:
|
||||
name=paid_user.name,
|
||||
price=0,
|
||||
)
|
||||
is_new = True
|
||||
else:
|
||||
is_new = False
|
||||
old_paid_user.price += paid_user.price
|
||||
|
||||
pub.sendMessage(
|
||||
'room_data_change.uid_paid_user_dict',
|
||||
room=self,
|
||||
value=self._uid_paid_user_dict,
|
||||
index=paid_user.uid,
|
||||
is_new=is_new,
|
||||
)
|
||||
|
||||
def add_gift(self, gift: GiftRecord):
|
||||
# 尝试合并
|
||||
is_merged = False
|
||||
min_time_to_merge = gift.time - datetime.timedelta(seconds=10)
|
||||
index = len(self._gifts)
|
||||
for index in range(len(self._gifts) - 1, -1, -1):
|
||||
old_gift = self._gifts[index]
|
||||
|
||||
if old_gift.time < min_time_to_merge:
|
||||
break
|
||||
if old_gift.uid == gift.uid and old_gift.gift_name == gift.gift_name:
|
||||
old_gift.num += gift.num
|
||||
old_gift.price += gift.price
|
||||
is_merged = True
|
||||
break
|
||||
if not is_merged:
|
||||
index = len(self._gifts)
|
||||
self._gifts.append(gift)
|
||||
pub.sendMessage(
|
||||
'room_data_change.gifts',
|
||||
room=self,
|
||||
value=self._gifts,
|
||||
index=index,
|
||||
is_new=not is_merged,
|
||||
)
|
||||
|
||||
if gift.price > 0.:
|
||||
self._add_user_paid_price(PaidUserRecord(
|
||||
uid=gift.uid,
|
||||
name=gift.author_name,
|
||||
price=gift.price,
|
||||
))
|
||||
|
||||
self._add_interact_uid(gift.uid)
|
||||
|
||||
self._total_paid_price += gift.price
|
||||
pub.sendMessage('room_data_change.total_paid_price', room=self, value=self._total_paid_price)
|
||||
|
@ -5,19 +5,16 @@ import logging.handlers
|
||||
import os
|
||||
import signal
|
||||
import sys
|
||||
from typing import *
|
||||
|
||||
import wx
|
||||
import wxasync
|
||||
|
||||
import blcsdk
|
||||
import config
|
||||
import listener
|
||||
import ui.app
|
||||
|
||||
logger = logging.getLogger('native-ui')
|
||||
|
||||
app: Optional[wxasync.WxAsyncApp] = None
|
||||
|
||||
|
||||
async def main():
|
||||
try:
|
||||
@ -37,7 +34,7 @@ async def init():
|
||||
if not blcsdk.is_sdk_version_compatible():
|
||||
raise RuntimeError('SDK version is not compatible')
|
||||
|
||||
init_ui()
|
||||
ui.app.init()
|
||||
await listener.init()
|
||||
|
||||
|
||||
@ -57,6 +54,7 @@ def init_signal_handlers():
|
||||
|
||||
|
||||
def start_shut_down(*_args):
|
||||
app = wx.GetApp()
|
||||
if app is not None:
|
||||
app.ExitMainLoop()
|
||||
else:
|
||||
@ -78,14 +76,9 @@ def init_logging():
|
||||
)
|
||||
|
||||
|
||||
def init_ui():
|
||||
global app
|
||||
app = wxasync.WxAsyncApp(clearSigInt=False)
|
||||
|
||||
|
||||
async def run():
|
||||
logger.info('Running event loop')
|
||||
await app.MainLoop()
|
||||
await wx.GetApp().MainLoop()
|
||||
logger.info('Start to shut down')
|
||||
|
||||
|
||||
|
@ -1,2 +1,3 @@
|
||||
PyPubSub==4.0.3
|
||||
wxasync==0.49
|
||||
wxPython==4.2.1
|
||||
|
53
plugins/native-ui/ui/app.py
Normal file
53
plugins/native-ui/ui/app.py
Normal file
@ -0,0 +1,53 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import logging
|
||||
from typing import *
|
||||
|
||||
import pubsub.pub as pub
|
||||
import wxasync
|
||||
|
||||
import blcsdk.models as sdk_models
|
||||
import listener
|
||||
import ui.room_frame
|
||||
|
||||
logger = logging.getLogger('native-ui.' + __name__)
|
||||
|
||||
_app: Optional['App'] = None
|
||||
|
||||
|
||||
def init():
|
||||
global _app
|
||||
_app = App()
|
||||
|
||||
|
||||
class App(wxasync.WxAsyncApp):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, clearSigInt=False, **kwargs)
|
||||
self.SetExitOnFrameDelete(False)
|
||||
|
||||
self._key_room_frame_dict: Dict[sdk_models.RoomKey, ui.room_frame.RoomFrame] = {}
|
||||
|
||||
def OnInit(self):
|
||||
pub.subscribe(self._on_add_room, 'add_room')
|
||||
pub.subscribe(self._on_del_room, 'del_room')
|
||||
pub.subscribe(self._on_room_frame_close, 'room_frame_close')
|
||||
pub.subscribe(self._on_open_admin_ui, 'open_admin_ui')
|
||||
return True
|
||||
|
||||
def _on_add_room(self, room_key: sdk_models.RoomKey):
|
||||
if room_key in self._key_room_frame_dict:
|
||||
return
|
||||
|
||||
room_frame = self._key_room_frame_dict[room_key] = ui.room_frame.RoomFrame(None, room_key)
|
||||
room_frame.Show()
|
||||
|
||||
def _on_del_room(self, room_key: sdk_models.RoomKey):
|
||||
room_frame = self._key_room_frame_dict.pop(room_key, None)
|
||||
if room_frame is not None:
|
||||
room_frame.Close(True)
|
||||
|
||||
def _on_room_frame_close(self, room_key: sdk_models.RoomKey):
|
||||
self._key_room_frame_dict.pop(room_key, None)
|
||||
|
||||
def _on_open_admin_ui(self):
|
||||
for room in listener.iter_rooms():
|
||||
self._on_add_room(room.room_key)
|
@ -1,10 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import designer.ui_base
|
||||
|
||||
|
||||
class RoomFrame(designer.ui_base.RoomFrameBase):
|
||||
def __init__(self, parent):
|
||||
super().__init__(parent)
|
||||
|
||||
self.chat_web_view.LoadURL('http://localhost:12450/room/test?minGiftPrice=0&showGiftName=true&relayMessagesByServer=true&lang=zh')
|
||||
self.paid_web_view.LoadURL('http://localhost:12450/room/test?showDanmaku=false&showGiftName=true&relayMessagesByServer=true&lang=zh')
|
185
plugins/native-ui/ui/room_frame.py
Normal file
185
plugins/native-ui/ui/room_frame.py
Normal file
@ -0,0 +1,185 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import datetime
|
||||
import logging
|
||||
import urllib.parse
|
||||
from typing import *
|
||||
|
||||
import pubsub.pub as pub
|
||||
import wx
|
||||
|
||||
import blcsdk
|
||||
import blcsdk.models as sdk_models
|
||||
import designer.ui_base
|
||||
import listener
|
||||
|
||||
logger = logging.getLogger('native-ui.' + __name__)
|
||||
|
||||
|
||||
class RoomFrame(designer.ui_base.RoomFrameBase):
|
||||
def __init__(self, parent, room_key: sdk_models.RoomKey):
|
||||
super().__init__(parent)
|
||||
self._room_key = room_key
|
||||
|
||||
room = listener.get_room(self._room_key)
|
||||
room_str = str(room.room_id) if room is not None else str(self._room_key)
|
||||
self.SetTitle(f'blivechat - 房间 {room_str}')
|
||||
|
||||
room_params = {'minGiftPrice': 0, 'showGiftName': 'true'}
|
||||
self.chat_web_view.LoadURL(self._get_room_url(room_params))
|
||||
room_params['showDanmaku'] = 'false'
|
||||
self.paid_web_view.LoadURL(self._get_room_url(room_params))
|
||||
|
||||
self.super_chat_list.AppendColumn('时间', width=50)
|
||||
self.super_chat_list.AppendColumn('用户名', width=120)
|
||||
self.super_chat_list.AppendColumn('金额', width=50)
|
||||
self.super_chat_list.AppendColumn('内容', width=300)
|
||||
for index in range(len(room.super_chats)):
|
||||
self._on_super_chats_change(room, room.super_chats, index, True)
|
||||
|
||||
self.gift_list.AppendColumn('时间', width=50)
|
||||
self.gift_list.AppendColumn('用户名', width=120)
|
||||
self.gift_list.AppendColumn('礼物名', width=100)
|
||||
self.gift_list.AppendColumn('数量', width=50)
|
||||
self.gift_list.AppendColumn('总价', width=50)
|
||||
for index in range(len(room.gifts)):
|
||||
self._on_gifts_change(room, room.gifts, index, True)
|
||||
|
||||
# item_data只能存int,这里做个映射
|
||||
self._uid_to_paid_user_item_data: Dict[str, int] = {}
|
||||
self._next_paid_user_item_data = 1
|
||||
self.paid_user_list.AppendColumn('用户名', width=120)
|
||||
self.paid_user_list.AppendColumn('总付费', width=60)
|
||||
for index in room.uid_paid_user_dict:
|
||||
self._on_uid_paid_user_dict_change(room, room.uid_paid_user_dict, index, True)
|
||||
|
||||
pub.subscribe(self._on_super_chats_change, 'room_data_change.super_chats')
|
||||
pub.subscribe(self._on_gifts_change, 'room_data_change.gifts')
|
||||
pub.subscribe(self._on_uid_paid_user_dict_change, 'room_data_change.uid_paid_user_dict')
|
||||
pub.subscribe(self._on_simple_statistics_change, 'room_data_change.danmaku_num')
|
||||
pub.subscribe(self._on_simple_statistics_change, 'room_data_change.interact_uids')
|
||||
pub.subscribe(self._on_simple_statistics_change, 'room_data_change.total_paid_price')
|
||||
|
||||
def _get_room_url(self, params: dict):
|
||||
params = params.copy()
|
||||
params['roomKeyType'] = self._room_key.type.value
|
||||
params['relayMessagesByServer'] = 'true'
|
||||
|
||||
query = '&'.join(
|
||||
f'{urllib.parse.quote_plus(key)}={urllib.parse.quote_plus(str(value))}'
|
||||
for key, value in params.items()
|
||||
)
|
||||
blc_port = blcsdk.get_blc_port()
|
||||
encoded_room_key_value = urllib.parse.quote_plus(str(self._room_key.value))
|
||||
url = f'http://localhost:{blc_port}/room/{encoded_room_key_value}?{query}'
|
||||
return url
|
||||
|
||||
#
|
||||
# UI事件
|
||||
#
|
||||
|
||||
def _on_close(self, event):
|
||||
pub.sendMessage('room_frame_close', room_key=self._room_key)
|
||||
super()._on_close(event)
|
||||
|
||||
def _on_config_button_click(self, event):
|
||||
# TODO WIP
|
||||
dialog = designer.ui_base.RoomConfigDialogBase(self)
|
||||
dialog.Show()
|
||||
|
||||
def _on_stay_on_top_button_toggle(self, event: wx.CommandEvent):
|
||||
style = self.GetWindowStyle()
|
||||
if event.IsChecked():
|
||||
style |= wx.STAY_ON_TOP
|
||||
else:
|
||||
style &= ~wx.STAY_ON_TOP
|
||||
self.SetWindowStyle(style)
|
||||
|
||||
def _on_collapse_console_button_click(self, event):
|
||||
window_size = self.GetSize()
|
||||
if self.console_notebook.IsShown():
|
||||
window_size.Scale(0.5, 1)
|
||||
self.console_notebook.Hide()
|
||||
self.collapse_console_button.SetLabelText('<<')
|
||||
else:
|
||||
window_size.Scale(2, 1)
|
||||
self.console_notebook.Show()
|
||||
self.collapse_console_button.SetLabelText('>>')
|
||||
self.SetSize(window_size)
|
||||
self.Layout()
|
||||
|
||||
#
|
||||
# 模型事件
|
||||
#
|
||||
|
||||
def _on_super_chats_change(self, room: listener.Room, value: List[listener.SuperChatRecord], index, is_new): # noqa
|
||||
super_chat = value[index]
|
||||
col_texts = [
|
||||
self._format_time(super_chat.time),
|
||||
super_chat.author_name,
|
||||
str(super_chat.price),
|
||||
super_chat.content,
|
||||
]
|
||||
self._update_list_ctrl(self.super_chat_list, index, is_new, col_texts)
|
||||
|
||||
@staticmethod
|
||||
def _format_time(time: datetime.datetime):
|
||||
return time.strftime('%H:%M')
|
||||
|
||||
def _update_list_ctrl(self, list_ctrl: wx.ListCtrl, item_data: int, is_new, col_texts: List[str]):
|
||||
if is_new:
|
||||
row_index = list_ctrl.Append(col_texts)
|
||||
list_ctrl.SetItemData(row_index, item_data)
|
||||
|
||||
self._maybe_scroll_list_ctrl_to_bottom(list_ctrl)
|
||||
return
|
||||
|
||||
for row_index in range(list_ctrl.GetItemCount() - 1, -1, -1):
|
||||
if list_ctrl.GetItemData(row_index) != item_data:
|
||||
continue
|
||||
for col_index, text in enumerate(col_texts):
|
||||
list_ctrl.SetItem(row_index, col_index, text)
|
||||
break
|
||||
|
||||
@staticmethod
|
||||
def _maybe_scroll_list_ctrl_to_bottom(list_ctrl: wx.ListCtrl):
|
||||
"""如果原来就在底端则滚动到底端"""
|
||||
last_row_index = list_ctrl.GetItemCount() - 1
|
||||
if last_row_index < 0:
|
||||
return
|
||||
|
||||
# 没有找到更简单的方法
|
||||
list_height = list_ctrl.GetClientSize().GetHeight() * list_ctrl.GetContentScaleFactor()
|
||||
last_row_rect = list_ctrl.GetItemRect(max(last_row_index, 0))
|
||||
height_to_bottom = last_row_rect.GetBottom() - list_height
|
||||
if height_to_bottom < last_row_rect.GetHeight() * 3:
|
||||
list_ctrl.Focus(last_row_index)
|
||||
|
||||
def _on_gifts_change(self, room: listener.Room, value: List[listener.GiftRecord], index, is_new): # noqa
|
||||
gift = value[index]
|
||||
col_texts = [
|
||||
self._format_time(gift.time),
|
||||
gift.author_name,
|
||||
gift.gift_name,
|
||||
str(gift.num),
|
||||
str(gift.price),
|
||||
]
|
||||
self._update_list_ctrl(self.gift_list, index, is_new, col_texts)
|
||||
|
||||
def _on_uid_paid_user_dict_change(
|
||||
self, room: listener.Room, value: Dict[str, listener.PaidUserRecord], index, is_new # noqa
|
||||
):
|
||||
item_data = self._uid_to_paid_user_item_data.get(index, None)
|
||||
if item_data is None:
|
||||
item_data = self._uid_to_paid_user_item_data[index] = self._next_paid_user_item_data
|
||||
self._next_paid_user_item_data += 1
|
||||
|
||||
paid_user = value[index]
|
||||
col_texts = [
|
||||
paid_user.name,
|
||||
str(paid_user.price),
|
||||
]
|
||||
self._update_list_ctrl(self.paid_user_list, item_data, is_new, col_texts)
|
||||
|
||||
def _on_simple_statistics_change(self, room: listener.Room, value=None, index=None, is_new=None): # noqa
|
||||
text = f'总弹幕数:{room.danmaku_num} 互动用户数:{len(room.interact_uids)} 总付费:{room.total_paid_price} 元'
|
||||
self.statistics_text.SetLabelText(text)
|
Loading…
Reference in New Issue
Block a user