2026-03-08 13:25:35 -05:00
|
|
|
extends PanelContainer
|
|
|
|
|
class_name UserEntry
|
|
|
|
|
|
|
|
|
|
var chatter: Chatter
|
|
|
|
|
|
|
|
|
|
var tw_hidden: Tween
|
|
|
|
|
var is_expanded: bool = false
|
2026-03-08 19:27:39 -05:00
|
|
|
|
2026-03-08 13:25:35 -05:00
|
|
|
var is_profile_picture_loaded: bool = false
|
2026-03-12 01:32:34 -05:00
|
|
|
const SHOUTOUT_ALERT_SCENE := preload("res://UI/Shoutouts/shoutout.tscn")
|
2026-03-08 13:25:35 -05:00
|
|
|
|
|
|
|
|
signal user_selected(chatter: Chatter)
|
|
|
|
|
|
|
|
|
|
# Called when the node enters the scene tree for the first time.
|
|
|
|
|
func _ready() -> void:
|
|
|
|
|
update()
|
|
|
|
|
toggle_buttons(false)
|
|
|
|
|
Globals.live_streamers_updated.connect(func(): %LiveStatus.visible = chatter.twitch_id in Globals.live_streamers.keys())
|
|
|
|
|
await get_tree().process_frame
|
|
|
|
|
check_update_profile_picture()
|
2026-03-08 16:24:55 -05:00
|
|
|
%ScreenNotifer.rect = get_rect()
|
|
|
|
|
%ScreenNotifer.screen_entered.connect(check_update_profile_picture)
|
2026-03-08 13:25:35 -05:00
|
|
|
%User.pressed.connect(user_selected.emit.bind(chatter))
|
2026-03-12 01:32:34 -05:00
|
|
|
%Shoutout.pressed.connect(_handle_shoutout) #func(): Globals.twitcher.shoutout(chatter.user))
|
2026-03-08 13:25:35 -05:00
|
|
|
%Promote.pressed.connect(func(): Globals.twitcher.send_message(chatter.promo_msg))
|
2026-03-09 03:08:01 -05:00
|
|
|
%ButtonMenu.pressed.connect(func(): toggle_buttons(!is_expanded))
|
|
|
|
|
_update_tooltips()
|
|
|
|
|
|
2026-03-12 01:32:34 -05:00
|
|
|
func _handle_shoutout() -> void:
|
|
|
|
|
Globals.twitcher.shoutout(chatter.user)
|
|
|
|
|
Globals.twitcher.send_message(Globals.settings.shoutout_message.format(chatter.user))
|
|
|
|
|
var alrt = SHOUTOUT_ALERT_SCENE.instantiate()
|
|
|
|
|
alrt.chatter = chatter
|
|
|
|
|
EventManager.add_alert(alrt)
|
|
|
|
|
|
2026-03-09 03:08:01 -05:00
|
|
|
func _update_tooltips() -> void:
|
|
|
|
|
for node: Control in [%Shoutout, %Promote, %Refresh, %Raid, %Delete]:
|
|
|
|
|
node.tooltip_text = node.tooltip_text % chatter.user.display_name
|
2026-03-08 13:25:35 -05:00
|
|
|
|
|
|
|
|
func update() -> void:
|
|
|
|
|
if not chatter:
|
|
|
|
|
push_error("No user for button!")
|
|
|
|
|
return
|
|
|
|
|
if not chatter.user:
|
|
|
|
|
chatter.user = await Globals.twitcher.get_user_by_id(chatter.twitch_id)
|
|
|
|
|
%User.text = chatter.user.display_name
|
|
|
|
|
%Shoutout.disabled = !chatter.is_streamer
|
|
|
|
|
%Promote.disabled = chatter.promo_msg == ""
|
|
|
|
|
%LiveStatus.visible = chatter.twitch_id in Globals.live_streamers.keys()
|
|
|
|
|
%Raid.disabled = not chatter.twitch_id in Globals.live_streamers.keys()
|
|
|
|
|
|
|
|
|
|
func update_profile_picture() -> void:
|
|
|
|
|
if not chatter.user.profile_image_url: return
|
|
|
|
|
%LoadingSimple.show()
|
|
|
|
|
%AvatarImg.texture = await Globals.twitcher.media.load_profile_image(chatter.user)
|
|
|
|
|
%LoadingSimple.hide()
|
|
|
|
|
|
|
|
|
|
func reload_twitch_user() -> void:
|
|
|
|
|
var t_user: TwitchUser = await Globals.twitcher.get_user_by_id(chatter.twitch_id)
|
|
|
|
|
if not t_user:
|
|
|
|
|
return
|
|
|
|
|
chatter.user = t_user
|
|
|
|
|
chatter.save()
|
|
|
|
|
update()
|
|
|
|
|
update_profile_picture()
|
|
|
|
|
|
|
|
|
|
func check_update_profile_picture() -> void:
|
|
|
|
|
if is_profile_picture_loaded: return
|
|
|
|
|
if not chatter: return
|
|
|
|
|
await get_tree().process_frame
|
2026-03-08 16:24:55 -05:00
|
|
|
if not %ScreenNotifer.is_on_screen(): return
|
2026-03-08 13:25:35 -05:00
|
|
|
is_profile_picture_loaded = true
|
|
|
|
|
await update_profile_picture()
|
|
|
|
|
if not %AvatarImg.texture: is_profile_picture_loaded = false
|
|
|
|
|
|
|
|
|
|
func toggle_buttons(vis: bool) -> void:
|
|
|
|
|
const ANIM_SPEED = 0.2
|
|
|
|
|
const MIN_SIZE = Vector2(32,32)
|
|
|
|
|
if tw_hidden:
|
|
|
|
|
tw_hidden.kill()
|
|
|
|
|
tw_hidden = create_tween()
|
|
|
|
|
tw_hidden.set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_CUBIC)
|
|
|
|
|
|
|
|
|
|
var min_size: Vector2 = MIN_SIZE if vis else Vector2.ZERO
|
|
|
|
|
var cover_btn_alpha: float = float(!vis)
|
|
|
|
|
var btns_alpha: float = float(vis)
|
|
|
|
|
for btn: Button in %Menu.get_children():
|
|
|
|
|
tw_hidden.parallel().tween_property(
|
|
|
|
|
btn,
|
|
|
|
|
^"custom_minimum_size",
|
|
|
|
|
min_size,
|
|
|
|
|
ANIM_SPEED
|
|
|
|
|
)
|
|
|
|
|
tw_hidden.parallel().tween_property(
|
|
|
|
|
btn,
|
|
|
|
|
^"modulate:a",
|
|
|
|
|
btns_alpha,
|
|
|
|
|
ANIM_SPEED
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
%ButtonMenu.show()
|
|
|
|
|
tw_hidden.tween_property(%ButtonMenu, ^"modulate:a", cover_btn_alpha, ANIM_SPEED)
|
|
|
|
|
if vis:
|
|
|
|
|
tw_hidden.tween_property(%ButtonMenu, ^"visible", false, ANIM_SPEED)
|
|
|
|
|
is_expanded = true
|
|
|
|
|
set_process(true)
|
|
|
|
|
|
|
|
|
|
func _process(_delta: float) -> void:
|
|
|
|
|
if !is_expanded:
|
|
|
|
|
set_process(false)
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
var m_pos: Vector2 = get_global_mouse_position()
|
|
|
|
|
var is_inside: bool = %Toggle.get_global_rect().has_point(m_pos)
|
|
|
|
|
if is_inside:
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
toggle_buttons(false)
|
|
|
|
|
is_expanded = false
|
|
|
|
|
set_process(false)
|