diff --git a/UI/Controls/user_entry.gd b/UI/Controls/user_entry.gd new file mode 100644 index 00000000..9619de88 --- /dev/null +++ b/UI/Controls/user_entry.gd @@ -0,0 +1,112 @@ +extends PanelContainer +class_name UserEntry + +var chatter: Chatter + +var tw_hidden: Tween +var is_expanded: bool = false + +var scroll: ScrollContainer +var is_visible_in_scroll: bool: + get: + if not scroll: return false + return scroll.get_global_rect().intersects(get_global_rect()) +var is_profile_picture_loaded: bool = false + +signal user_selected(chatter: Chatter) + +# Called when the node enters the scene tree for the first time. +func _ready() -> void: + scroll = get_parent().get_parent() + scroll.get_v_scroll_bar().scrolling.connect(check_update_profile_picture) + visibility_changed.connect(check_update_profile_picture) + 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() + %User.pressed.connect(user_selected.emit.bind(chatter)) + %Shoutout.pressed.connect(func(): Globals.twitcher.shoutout(chatter.user)) + %Promote.pressed.connect(func(): Globals.twitcher.send_message(chatter.promo_msg)) + +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 + if not is_visible_in_scroll: return + 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) diff --git a/UI/Controls/user_entry.gd.uid b/UI/Controls/user_entry.gd.uid new file mode 100644 index 00000000..a46cfbf3 --- /dev/null +++ b/UI/Controls/user_entry.gd.uid @@ -0,0 +1 @@ +uid://ldua0xcjjws4 diff --git a/UI/Controls/user_entry.tscn b/UI/Controls/user_entry.tscn new file mode 100644 index 00000000..7805b1f1 --- /dev/null +++ b/UI/Controls/user_entry.tscn @@ -0,0 +1,136 @@ +[gd_scene format=3 uid="uid://c3hb5od24tfr3"] + +[ext_resource type="Texture2D" uid="uid://bu2juj2beyws7" path="res://UI/assets/twitch_user_profile_pic.png" id="1_8xi1h"] +[ext_resource type="Theme" uid="uid://dh11pgqmtpeig" path="res://UI/assets/main_theme.tres" id="1_r4556"] +[ext_resource type="Script" uid="uid://ldua0xcjjws4" path="res://UI/Controls/user_entry.gd" id="1_xsfty"] +[ext_resource type="PackedScene" uid="uid://cbr5aed24dvty" path="res://UI/Controls/loading_simple.tscn" id="3_mi6bx"] +[ext_resource type="Texture2D" uid="uid://ed2yvxs0b8sv" path="res://UI/assets/bootstrap/megaphone-fill.png" id="3_sck47"] +[ext_resource type="Texture2D" uid="uid://eybcntflwjpx" path="res://UI/assets/bootstrap/megaphone.svg" id="4_0jtnn"] +[ext_resource type="Texture2D" uid="uid://bb2asei1pibev" path="res://UI/assets/bootstrap/arrow-repeat.png" id="5_xsfty"] +[ext_resource type="Texture2D" uid="uid://b3372gsnwqsyn" path="res://UI/assets/bootstrap/twitch.svg" id="6_mi6bx"] +[ext_resource type="Texture2D" uid="uid://d1qh7e8vpfm1p" path="res://UI/assets/font_awesome/ellipsis.svg" id="7_k1oax"] +[ext_resource type="Texture2D" uid="uid://echc7jyluqi0" path="res://UI/assets/bootstrap/trash.png" id="9_k1oax"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_ddi2y"] +content_margin_left = 4.0 +content_margin_top = 4.0 +content_margin_right = 4.0 +content_margin_bottom = 4.0 +bg_color = Color(0.101960786, 0.101960786, 0.101960786, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 +corner_detail = 5 + +[node name="UserEntry" type="PanelContainer" unique_id=1215925059] +offset_right = 40.0 +offset_bottom = 40.0 +script = ExtResource("1_xsfty") + +[node name="HBoxContainer" type="HBoxContainer" parent="." unique_id=582266053] +layout_mode = 2 + +[node name="AvatarImg" type="TextureRect" parent="HBoxContainer" unique_id=1364124968] +unique_name_in_owner = true +custom_minimum_size = Vector2(48, 48) +layout_mode = 2 +texture = ExtResource("1_8xi1h") +expand_mode = 1 +stretch_mode = 5 + +[node name="LoadingSimple" parent="HBoxContainer/AvatarImg" unique_id=814067408 instance=ExtResource("3_mi6bx")] +unique_name_in_owner = true +visible = false +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="OpenSteram" type="Button" parent="HBoxContainer/AvatarImg" unique_id=118186600] +unique_name_in_owner = true +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +theme = ExtResource("1_r4556") +theme_type_variation = &"BlankButton" + +[node name="User" type="Button" parent="HBoxContainer" unique_id=565524419] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 3 +text = "Falinere" + +[node name="LiveStatus" type="ColorRect" parent="HBoxContainer/User" unique_id=1459190091] +unique_name_in_owner = true +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 +color = Color(0.3647059, 1, 0.44313726, 0.3764706) + +[node name="Shoutout" type="Button" parent="HBoxContainer" unique_id=85236405] +unique_name_in_owner = true +custom_minimum_size = Vector2(32, 32) +layout_mode = 2 +icon = ExtResource("3_sck47") +icon_alignment = 1 +expand_icon = true + +[node name="Toggle" type="PanelContainer" parent="HBoxContainer" unique_id=174111778] +unique_name_in_owner = true +layout_mode = 2 + +[node name="Menu" type="HBoxContainer" parent="HBoxContainer/Toggle" unique_id=1481656507] +unique_name_in_owner = true +layout_mode = 2 + +[node name="Promote" type="Button" parent="HBoxContainer/Toggle/Menu" unique_id=2137206096] +unique_name_in_owner = true +custom_minimum_size = Vector2(32, 32) +layout_mode = 2 +icon = ExtResource("4_0jtnn") +icon_alignment = 1 +expand_icon = true + +[node name="Refresh" type="Button" parent="HBoxContainer/Toggle/Menu" unique_id=1938170984] +unique_name_in_owner = true +custom_minimum_size = Vector2(32, 32) +layout_mode = 2 +icon = ExtResource("5_xsfty") +icon_alignment = 1 +expand_icon = true + +[node name="Raid" type="Button" parent="HBoxContainer/Toggle/Menu" unique_id=527951722] +unique_name_in_owner = true +modulate = Color(0.6392157, 0.38431373, 0.84313726, 1) +custom_minimum_size = Vector2(32, 32) +layout_mode = 2 +icon = ExtResource("6_mi6bx") +icon_alignment = 1 +expand_icon = true + +[node name="Delete" type="Button" parent="HBoxContainer/Toggle/Menu" unique_id=596657869] +unique_name_in_owner = true +modulate = Color(1, 0, 0, 1) +custom_minimum_size = Vector2(32, 32) +layout_mode = 2 +icon = ExtResource("9_k1oax") +icon_alignment = 1 +expand_icon = true + +[node name="ButtonMenu" type="Button" parent="HBoxContainer/Toggle" unique_id=887606573] +unique_name_in_owner = true +layout_mode = 2 +theme_override_styles/normal = SubResource("StyleBoxFlat_ddi2y") +icon = ExtResource("7_k1oax") +icon_alignment = 1 +expand_icon = true