- Added option to show voice connection status

- Added option to show channel title
- Added option to not hide voice overlay on disconnect (debug)
- Added font picker for voice title
- Added new translations to base pot
- Update discord connector to chase forcibly moved user
This commit is contained in:
trigg 2022-07-09 21:14:30 +01:00
parent 8b507a5323
commit 8672f87613
4 changed files with 298 additions and 33 deletions

View file

@ -57,7 +57,6 @@ class DiscordConnector:
self.current_text = "0"
self.list_altered = False
self.text_altered = False
self.last_connection = ""
self.text = []
self.authed = False
@ -288,6 +287,8 @@ class DiscordConnector:
self.set_in_room(j["data"]["user"]["id"], False)
if j["data"]["user"]["id"] == self.user["id"]:
self.in_room = []
self.find_user()
# User might have been forcibly moved room
elif j["evt"] == "SPEAKING_START":
self.list_altered = True
# It's only possible to get alerts for the room you're in
@ -306,8 +307,7 @@ class DiscordConnector:
elif j["evt"] == "VOICE_CHANNEL_SELECT":
self.set_channel(j["data"]["channel_id"])
elif j["evt"] == "VOICE_CONNECTION_STATUS":
# VOICE_CONNECTED > CONNECTING > AWAITING_ENDPOINT > DISCONNECTED
self.last_connection = j["data"]["state"]
self.discover.voice_overlay.set_connection_status(j["data"])
elif j["evt"] == "MESSAGE_CREATE":
if self.current_text == j["data"]["channel_id"]:
self.add_text(j["data"]["message"])
@ -374,6 +374,7 @@ class DiscordConnector:
elif j["cmd"] == "GET_SELECTED_VOICE_CHANNEL":
if 'data' in j and j['data'] and 'id' in j['data']:
self.set_channel(j['data']['id'])
self.discover.voice_overlay.set_channel_title(j["data"]["name"])
self.list_altered = True
self.in_room = []
for u in j['data']['voice_states']:
@ -701,7 +702,6 @@ class DiscordConnector:
for userid in self.in_room:
newlist.append(self.userlist[userid])
self.discover.voice_overlay.set_user_list(newlist, self.list_altered)
self.discover.voice_overlay.set_connection(self.last_connection)
self.list_altered = False
# Update text list
if self.discover.text_overlay.popup_style:

View file

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-05-29 23:27+0000\n"
"POT-Creation-Date: 2022-07-09 21:08+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -89,6 +89,9 @@ msgstr ""
msgid "Settings"
msgstr ""
msgid "Toggle Hidden"
msgstr ""
msgid "Close"
msgstr ""
@ -221,6 +224,39 @@ msgstr ""
msgid "Line limit"
msgstr ""
msgid "DISCONNECTED"
msgstr ""
msgid "NO_ROUTE"
msgstr ""
msgid "VOICE_DISCONNECTED"
msgstr ""
msgid "ICE_CHECKING"
msgstr ""
msgid "AWAITING_ENDPOINT"
msgstr ""
msgid "AUTHENTICATING"
msgstr ""
msgid "CONNECTING"
msgstr ""
msgid "CONNECTED"
msgstr ""
msgid "VOICE_CONNECTING"
msgstr ""
msgid "VOICE_CONNECTED"
msgstr ""
msgid "Title Font"
msgstr ""
msgid "Label"
msgstr ""
@ -293,5 +329,14 @@ msgstr ""
msgid "Shrink"
msgstr ""
msgid "Show Title"
msgstr ""
msgid "Show Connection Status"
msgstr ""
msgid "Show while disconnected"
msgstr ""
msgid "Dummy count"
msgstr ""

View file

@ -11,10 +11,12 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
"""Overlay window for voice"""
import gettext
import logging
import math
import cairo
import sys
import pkg_resources
from .overlay import OverlayWindow
from .image_getter import get_surface, draw_img_to_rect
# pylint: disable=wrong-import-order
@ -27,6 +29,10 @@ import random
log = logging.getLogger(__name__)
t = gettext.translation(
'default', pkg_resources.resource_filename('discover_overlay', 'locales'), fallback=True)
_ = t.gettext
class VoiceOverlayWindow(OverlayWindow):
"""Overlay window for voice"""
@ -58,6 +64,7 @@ class VoiceOverlayWindow(OverlayWindow):
self.avatar_size = 48
self.text_pad = 6
self.text_font = None
self.title_font = None
self.text_size = 13
self.text_baseline_adj = 0
self.icon_spacing = 8
@ -70,6 +77,10 @@ class VoiceOverlayWindow(OverlayWindow):
self.overflow = None
self.use_dummy = False
self.dummy_count = 10
self.show_title = True
self.show_connection = True
self.show_disconnected = True
self.channel_title=""
self.round_avatar = True
self.icon_only = True
@ -82,7 +93,7 @@ class VoiceOverlayWindow(OverlayWindow):
self.hili_col = [0.0, 0.0, 0.0, 0.9]
self.border_col = [0.0, 0.0, 0.0, 0.0]
self.userlist = []
self.connected = False
self.connection_status = "DISCONNECTED"
self.horizontal = False
self.guild_ids = tuple()
self.force_location()
@ -95,6 +106,22 @@ class VoiceOverlayWindow(OverlayWindow):
def set_blank(self):
self.userlist=[]
self.needsredraw=True
def set_title_font(self, font):
self.title_font = font
self.needsredraw = True
def set_show_connection(self, show_connection):
self.show_connection = show_connection
self.needsredraw = True
def set_show_title(self, show_title):
self.show_title = show_title
self.needsredraw = True
def set_show_disconnected(self, show_disconnected):
self.show_disconnected = show_disconnected
self.needsredraw = True
def set_show_dummy(self, show_dummy):
"""
@ -274,6 +301,12 @@ class VoiceOverlayWindow(OverlayWindow):
"""
self.col(self.mute_col, alpha)
def set_channel_title(self, channel_title):
"""
Set title above voice list
"""
self.channel_title = channel_title
def set_user_list(self, userlist, alt):
"""
Set the users in list to draw
@ -288,13 +321,12 @@ class VoiceOverlayWindow(OverlayWindow):
if alt:
self.needsredraw = True
def set_connection(self, connection):
def set_connection_status(self, connection):
"""
Set if discord has a clean connection to server
"""
is_connected = connection == "VOICE_CONNECTED"
if self.connected != is_connected:
self.connected = is_connected
if self.connection_status != connection['state']:
self.connection_status = connection['state']
self.needsredraw = True
def sort_list(self, in_list):
@ -336,7 +368,7 @@ class VoiceOverlayWindow(OverlayWindow):
context.clip()
context.set_operator(cairo.OPERATOR_OVER)
if not self.connected and not self.use_dummy:
if not self.show_disconnected and self.connection_status == "DISCONNECTED" and not self.use_dummy:
return
connection = self.discover.connection
@ -412,7 +444,16 @@ class VoiceOverlayWindow(OverlayWindow):
current_y+=offset_y
else:
# Calculate height needed to show overlay
needed_height = (len(users_to_draw) * self.avatar_size) + \
doTitle = False
doConnection = False
if self.show_connection:
users_to_draw.insert(0, None)
doConnection = True
if self.show_title:
users_to_draw.insert(0, None)
doTitle = True
needed_height = ((len(users_to_draw)+0) * self.avatar_size) + \
(len(users_to_draw) + 1) * self.icon_spacing
if needed_height > height:
@ -453,9 +494,24 @@ class VoiceOverlayWindow(OverlayWindow):
current_y = height - needed_height - self.vert_edge_padding
largest_text_width = 0
for user in col:
text_width = self.draw_avatar(context, user, current_x, current_y, avatar_size)
largest_text_width = max(text_width, largest_text_width)
current_y += avatar_size + self.icon_spacing
if not user:
if doTitle:
# Draw header
text_width = self.draw_title(context, current_x, current_y, avatar_size)
largest_text_width = max(text_width, largest_text_width)
current_y += avatar_size + self.icon_spacing
doTitle = False
elif doConnection:
# Draw header
text_width = self.draw_connection(context, current_x, current_y, avatar_size)
largest_text_width = max(text_width, largest_text_width)
current_y += avatar_size + self.icon_spacing
doConnection = False
else:
text_width = self.draw_avatar(context, user, current_x, current_y, avatar_size)
largest_text_width = max(text_width, largest_text_width)
current_y += avatar_size + self.icon_spacing
if largest_text_width > 0:
largest_text_width += self.text_pad
else:
@ -482,6 +538,52 @@ class VoiceOverlayWindow(OverlayWindow):
if identifier in self.avatars:
del self.avatars[identifier]
def draw_title(self,context, pos_x, pos_y, avatar_size):
"""
Draw title at given Y position. Includes both text and image based on settings
"""
title = self.channel_title
if self.use_dummy:
title="Dummy Title"
tw = self.draw_text(
context, title,
pos_x,
pos_y,
self.text_col,
self.norm_col,
avatar_size,
self.title_font
)
return tw
def unused_fn_needed_translations(self):
_("DISCONNECTED")
_("NO_ROUTE")
_("VOICE_DISCONNECTED")
_("ICE_CHECKING")
_("AWAITING_ENDPOINT")
_("AUTHENTICATING")
_("CONNECTING")
_("CONNECTED")
_("VOICE_CONNECTING")
_("VOICE_CONNECTED")
def draw_connection(self,context, pos_x, pos_y, avatar_size):
"""
Draw title at given Y position. Includes both text and image based on settings
"""
tw = self.draw_text(
context, _(self.connection_status),
pos_x,
pos_y,
self.text_col,
self.norm_col,
avatar_size,
self.text_font
)
self.draw_connection_icon(context, pos_x, pos_y, avatar_size)
return tw
def draw_avatar(self, context, user, pos_x, pos_y, avatar_size):
"""
Draw avatar at given Y position. Includes both text and image based on settings
@ -527,7 +629,8 @@ class VoiceOverlayWindow(OverlayWindow):
pos_y,
fg_col,
bg_col,
avatar_size
avatar_size,
self.text_font
)
self.draw_avatar_pix(context, pix,pos_x,pos_y,colour, avatar_size)
if deaf:
@ -536,7 +639,7 @@ class VoiceOverlayWindow(OverlayWindow):
self.draw_mute(context, pos_x, pos_y, avatar_size)
return tw
def draw_text(self, context, string, pos_x, pos_y, tx_col, bg_col, avatar_size):
def draw_text(self, context, string, pos_x, pos_y, tx_col, bg_col, avatar_size, font):
"""
Draw username & background at given position
"""
@ -546,9 +649,8 @@ class VoiceOverlayWindow(OverlayWindow):
layout.set_width(Pango.SCALE * self.width)
layout.set_spacing(Pango.SCALE * 3)
font = None
if self.text_font:
font = Pango.FontDescription(self.text_font)
if font:
font = Pango.FontDescription(font)
layout.set_font_description(font)
(_ink_rect, logical_rect) = layout.get_pixel_extents()
text_height = logical_rect.height
@ -741,3 +843,39 @@ class VoiceOverlayWindow(OverlayWindow):
context.fill()
context.restore()
def draw_connection_icon(self, context, pos_x, pos_y, avatar_size):
context.save()
context.translate(pos_x, pos_y)
context.scale(avatar_size, avatar_size)
bars = 0
s = self.connection_status
if s == "DISCONNECTED" or s == "NO_ROUTE" or s == "VOICE_DISCONNECTED":
bars = 0
self.col([1.0,0.0,0.0,1.0])
elif s == "ICE_CHECKING" or s == "AWAITING_ENDPOINT" or s == "AUTHENTICATING":
bars = 1
self.col([1.0,0.0,0.0,1.0])
elif s == "CONNECTING" or s == "CONNECTED" or s == "VOICE_CONNECTING":
bars = 2
self.col([1.0,1.0,0.0,1.0])
elif s == "VOICE_CONNECTED":
bars = 3
self.col([0.0,1.0,0.0,1.0])
context.set_line_width(0.1)
if bars >= 1:
context.move_to(0.3, 0.8)
context.line_to(0.3, 0.7)
context.stroke()
if bars >= 2:
context.move_to(0.5, 0.8)
context.line_to(0.5, 0.5)
context.stroke()
if bars == 3:
context.move_to(0.7, 0.8)
context.line_to(0.7, 0.2)
context.stroke()
context.restore()

View file

@ -65,6 +65,7 @@ class VoiceSettingsWindow(SettingsWindow):
self.text_padding = None
self.text_baseline_adj = None
self.font = None
self.title_font = None
self.square_avatar = None
self.only_speaking = None
self.highlight_self = None
@ -77,11 +78,14 @@ class VoiceSettingsWindow(SettingsWindow):
self.horizontal = None
self.guild_ids = None
self.overflow = None
self.init_config()
self.guild_filter_string = ""
self.warned = False
self.show_dummy = False
self.dummy_count = 10
self.show_connection = None
self.show_title = None
self.show_disconnected = None
self.init_config()
self.create_gui()
@ -129,6 +133,7 @@ class VoiceSettingsWindow(SettingsWindow):
self.text_baseline_adj = config.getint(
"main", "text_baseline_adj", fallback=0)
self.font = config.get("main", "font", fallback=None)
self.title_font = config.get("main", "title_font", fallback=None)
self.square_avatar = config.getboolean(
"main", "square_avatar", fallback=True)
self.only_speaking = config.getboolean(
@ -154,6 +159,9 @@ class VoiceSettingsWindow(SettingsWindow):
self.guild_ids = parse_guild_ids(
config.get("main", "guild_ids", fallback=""))
self.overflow = config.getint("main", "overflow", fallback = 0)
self.show_connection = config.getboolean("main", "show_connection", fallback=False)
self.show_title = config.getboolean("main", "show_title", fallback=False)
self.show_disconnected = config.getboolean("main", "show_disconnected", fallback=False)
# Pass all of our config over to the overlay
self.overlay.set_align_x(self.align_x)
@ -183,12 +191,17 @@ class VoiceSettingsWindow(SettingsWindow):
self.overlay.set_guild_ids(self.guild_ids)
self.overlay.set_overflow(self.overflow)
self.overlay.set_enabled(True)
self.overlay.set_show_connection(self.show_connection)
self.overlay.set_show_title(self.show_title)
self.overlay.set_show_disconnected(self.show_disconnected)
self.overlay.set_floating(
self.floating, self.floating_x, self.floating_y, self.floating_w, self.floating_h)
if self.font:
self.overlay.set_font(self.font)
if self.title_font:
self.overlay.set_title_font(self.title_font)
def save_config(self):
"""
@ -216,6 +229,8 @@ class VoiceSettingsWindow(SettingsWindow):
(self.text_baseline_adj))
if self.font:
config.set("main", "font", self.font)
if self.title_font:
config.set("main", "title_font", self.title_font)
config.set("main", "square_avatar", "%d" % (int(self.square_avatar)))
config.set("main", "only_speaking", "%d" % (int(self.only_speaking)))
config.set("main", "highlight_self", "%d" % (int(self.highlight_self)))
@ -235,6 +250,9 @@ class VoiceSettingsWindow(SettingsWindow):
config.set("main", "guild_ids", "%s" %
guild_ids_to_string(self.guild_ids))
config.set("main", "overflow", "%s" % (int(self.overflow)))
config.set("main", "show_connection", "%d" % (int(self.show_connection)))
config.set("main", "show_title", "%d" % (int(self.show_title)))
config.set("main", "show_disconnected", "%d" % (int(self.show_disconnected)))
with open(self.config_file, 'w') as file:
config.write(file)
@ -280,6 +298,15 @@ class VoiceSettingsWindow(SettingsWindow):
alignment_box.attach(font_label, 0, 0, 1, 1)
alignment_box.attach(font, 1, 0, 1, 1)
# Title Font chooser
title_font_label = Gtk.Label.new(_("Title Font"))
title_font = Gtk.FontButton()
if self.title_font:
title_font.set_font(self.title_font)
title_font.connect("font-set", self.change_title_font)
alignment_box.attach(title_font_label, 0, 1, 1, 1)
alignment_box.attach(title_font, 1, 1, 1, 1)
# Colours
bg_col = Gtk.ColorButton.new_with_rgba(
Gdk.RGBA(self.bg_col[0], self.bg_col[1], self.bg_col[2], self.bg_col[3]))
@ -487,8 +514,8 @@ class VoiceSettingsWindow(SettingsWindow):
icon_spacing = Gtk.SpinButton.new(icon_spacing_adjustment, 0, 0)
icon_spacing.connect("value-changed", self.change_icon_spacing)
alignment_box.attach(icon_spacing_label, 0, 1, 1, 1)
alignment_box.attach(icon_spacing, 1, 1, 1, 1)
alignment_box.attach(icon_spacing_label, 0, 2, 1, 1)
alignment_box.attach(icon_spacing, 1, 2, 1, 1)
# Text padding
text_padding_label = Gtk.Label.new(_("Text Padding"))
@ -498,8 +525,8 @@ class VoiceSettingsWindow(SettingsWindow):
text_padding = Gtk.SpinButton.new(text_padding_adjustment, 0, 0)
text_padding.connect("value-changed", self.change_text_padding)
alignment_box.attach(text_padding_label, 0, 2, 1, 1)
alignment_box.attach(text_padding, 1, 2, 1, 1)
alignment_box.attach(text_padding_label, 0, 3, 1, 1)
alignment_box.attach(text_padding, 1, 3, 1, 1)
# Text Baseline Adjustment
text_baseline_label = Gtk.Label.new(_("Text Vertical Offset"))
@ -509,8 +536,8 @@ class VoiceSettingsWindow(SettingsWindow):
text_baseline = Gtk.SpinButton.new(text_baseline_adjustment, 0, 0)
text_baseline.connect("value-changed", self.change_text_baseline)
alignment_box.attach(text_baseline_label, 0, 3, 1, 1)
alignment_box.attach(text_baseline, 1, 3, 1, 1)
alignment_box.attach(text_baseline_label, 0, 4, 1, 1)
alignment_box.attach(text_baseline, 1, 4, 1, 1)
# Edge padding
vert_edge_padding_label = Gtk.Label.new(_("Vertical Edge Padding"))
@ -522,8 +549,8 @@ class VoiceSettingsWindow(SettingsWindow):
vert_edge_padding.connect(
"value-changed", self.change_vert_edge_padding)
alignment_box.attach(vert_edge_padding_label, 0, 4, 1, 1)
alignment_box.attach(vert_edge_padding, 1, 4, 1, 1)
alignment_box.attach(vert_edge_padding_label, 0, 5, 1, 1)
alignment_box.attach(vert_edge_padding, 1, 5, 1, 1)
horz_edge_padding_label = Gtk.Label.new(_("Horizontal Edge Padding"))
horz_edge_padding_adjustment = Gtk.Adjustment.new(
@ -533,8 +560,8 @@ class VoiceSettingsWindow(SettingsWindow):
horz_edge_padding.connect(
"value-changed", self.change_horz_edge_padding)
alignment_box.attach(horz_edge_padding_label, 0, 5, 1, 1)
alignment_box.attach(horz_edge_padding, 1, 5, 1, 1)
alignment_box.attach(horz_edge_padding_label, 0, 6, 1, 1)
alignment_box.attach(horz_edge_padding, 1, 6, 1, 1)
# Display icon horizontally
horizontal_label = Gtk.Label.new(_("Display Horizontally"))
@ -543,8 +570,8 @@ class VoiceSettingsWindow(SettingsWindow):
horizontal.set_active(self.horizontal)
horizontal.connect("toggled", self.change_horizontal)
alignment_box.attach(horizontal_label, 0, 6, 1, 1)
alignment_box.attach(horizontal, 1, 6, 1, 1)
alignment_box.attach(horizontal_label, 0, 7, 1, 1)
alignment_box.attach(horizontal, 1, 7, 1, 1)
# Overflow
overflow_label = Gtk.Label.new(_("Overflow style"))
@ -563,6 +590,36 @@ class VoiceSettingsWindow(SettingsWindow):
avatar_box.attach(overflow_label, 0, 6, 1, 1)
avatar_box.attach(overflow, 1, 6, 1, 1)
# Show Title
show_title_label = Gtk.Label.new(_("Show Title"))
show_title_label.set_xalign(0)
show_title = Gtk.CheckButton.new()
show_title.set_active(self.show_title)
show_title.connect("toggled", self.change_show_title)
avatar_box.attach(show_title_label, 0, 7, 1,1)
avatar_box.attach(show_title, 1, 7, 1,1)
# Show Connection
show_connection_label = Gtk.Label.new(_("Show Connection Status"))
show_connection_label.set_xalign(0)
show_connection = Gtk.CheckButton.new()
show_connection.set_active(self.show_connection)
show_connection.connect("toggled", self.change_show_connection)
avatar_box.attach(show_connection_label, 0, 8, 1,1)
avatar_box.attach(show_connection, 1, 8, 1,1)
# Show Disconnected
show_disconnected_label = Gtk.Label.new(_("Show while disconnected"))
show_disconnected_label.set_xalign(0)
show_disconnected = Gtk.CheckButton.new()
show_disconnected.set_active(self.show_disconnected)
show_disconnected.connect("toggled", self.change_show_disconnected)
avatar_box.attach(show_disconnected_label, 0, 9, 1,1)
avatar_box.attach(show_disconnected, 1, 9, 1,1)
# use dummy
dummy_label = Gtk.Label.new(_("Show test content"))
dummy_label.set_xalign(0)
@ -600,6 +657,16 @@ class VoiceSettingsWindow(SettingsWindow):
self.font = font
self.save_config()
def change_title_font(self, button):
"""
Font settings changed
"""
title_font = button.get_font()
self.overlay.set_title_font(title_font)
self.title_font = title_font
self.save_config()
def change_bg(self, button):
"""
Background colour changed
@ -802,6 +869,21 @@ class VoiceSettingsWindow(SettingsWindow):
self.overflow = button.get_active()
self.save_config()
def change_show_title(self, button):
self.overlay.set_show_title(button.get_active())
self.show_title = button.get_active()
self.save_config()
def change_show_connection(self, button):
self.overlay.set_show_connection(button.get_active())
self.show_connection = button.get_active()
self.save_config()
def change_show_disconnected(self, button):
self.overlay.set_show_disconnected(button.get_active())
self.show_disconnected = button.get_active()
self.save_config()
def on_guild_selection_changed(self, tree, number, selection):
model, treeiter = tree.get_selection().get_selected()
if treeiter is not None: