Complete M11 Creator Studio and M12 Trust & Safety for PC5
checkpoint / checkpoint (push) Failing after 3h14m9s
checkpoint / checkpoint (push) Failing after 3h14m9s
- Creator Studio: Visual behavior & property inspector, GLB model importer, binary persistence - Trust & Safety: 18+ TOS confirmation (DOB removed), creator guidelines & briefing card on join, in-game reporting HUD - Test Harness: Add --filter, --skip-backend, --skip-godot to run_checkpoint_tests.py
This commit is contained in:
@@ -0,0 +1,176 @@
|
||||
class_name ReportModal
|
||||
extends Control
|
||||
## In-game reporting modal (Trust & Safety).
|
||||
##
|
||||
## Allows players to submit moderation reports for worlds, players, or messages.
|
||||
|
||||
signal report_submitted(target_type: String, target_id: int)
|
||||
signal closed
|
||||
|
||||
var target_type: String = "world"
|
||||
var target_id: int = 0
|
||||
var target_name: String = ""
|
||||
var api_client: Node = null
|
||||
|
||||
var _category_option: OptionButton
|
||||
var _details_edit: TextEdit
|
||||
var _status_label: Label
|
||||
var _submit_button: Button
|
||||
var _cancel_button: Button
|
||||
|
||||
|
||||
func _init() -> void:
|
||||
name = "ReportModal"
|
||||
set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
|
||||
|
||||
func setup_report(p_type: String, p_id: int, p_name: String) -> void:
|
||||
target_type = p_type
|
||||
target_id = p_id
|
||||
target_name = p_name
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
mouse_filter = Control.MOUSE_FILTER_STOP
|
||||
|
||||
var overlay := ColorRect.new()
|
||||
overlay.color = Color(0, 0, 0, 0.8)
|
||||
overlay.set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
add_child(overlay)
|
||||
|
||||
var center := CenterContainer.new()
|
||||
center.set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
add_child(center)
|
||||
|
||||
var panel := PanelContainer.new()
|
||||
panel.custom_minimum_size = Vector2(460, 0)
|
||||
var style := StyleBoxFlat.new()
|
||||
style.bg_color = Color(0.16, 0.16, 0.2, 1.0)
|
||||
style.border_color = Color(0.9, 0.35, 0.35, 1.0)
|
||||
style.set_border_width_all(2)
|
||||
style.set_corner_radius_all(10)
|
||||
style.content_margin_left = 20
|
||||
style.content_margin_right = 20
|
||||
style.content_margin_top = 18
|
||||
style.content_margin_bottom = 18
|
||||
panel.add_theme_stylebox_override("panel", style)
|
||||
center.add_child(panel)
|
||||
|
||||
var vbox := VBoxContainer.new()
|
||||
vbox.add_theme_constant_override("separation", 10)
|
||||
panel.add_child(vbox)
|
||||
|
||||
var title := Label.new()
|
||||
title.text = "🚩 Submit Report"
|
||||
title.add_theme_font_size_override("font_size", 18)
|
||||
title.add_theme_color_override("font_color", Color(1.0, 0.5, 0.5))
|
||||
title.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
vbox.add_child(title)
|
||||
|
||||
var target_lbl := Label.new()
|
||||
target_lbl.name = "TargetLabel"
|
||||
target_lbl.text = "Reporting %s: \"%s\" (ID: %d)" % [target_type.capitalize(), target_name, target_id]
|
||||
target_lbl.add_theme_font_size_override("font_size", 12)
|
||||
target_lbl.add_theme_color_override("font_color", Color(0.8, 0.8, 0.8))
|
||||
vbox.add_child(target_lbl)
|
||||
|
||||
var cat_lbl := Label.new()
|
||||
cat_lbl.text = "Category:"
|
||||
cat_lbl.add_theme_font_size_override("font_size", 12)
|
||||
vbox.add_child(cat_lbl)
|
||||
|
||||
_category_option = OptionButton.new()
|
||||
_category_option.name = "CategoryOption"
|
||||
_category_option.add_item("Inappropriate Content / Behavior", 0)
|
||||
_category_option.set_item_metadata(0, "inappropriate_content")
|
||||
_category_option.add_item("Harassment / Toxicity", 1)
|
||||
_category_option.set_item_metadata(1, "harassment")
|
||||
_category_option.add_item("World Rules Violation", 2)
|
||||
_category_option.set_item_metadata(2, "rules_violation")
|
||||
_category_option.add_item("Misleading Tags / Content", 3)
|
||||
_category_option.set_item_metadata(3, "misleading")
|
||||
_category_option.add_item("Spam / Exploiting", 4)
|
||||
_category_option.set_item_metadata(4, "spam")
|
||||
_category_option.add_item("Other Safety Concern", 5)
|
||||
_category_option.set_item_metadata(5, "other")
|
||||
vbox.add_child(_category_option)
|
||||
|
||||
var det_lbl := Label.new()
|
||||
det_lbl.text = "Details / Explanation:"
|
||||
det_lbl.add_theme_font_size_override("font_size", 12)
|
||||
vbox.add_child(det_lbl)
|
||||
|
||||
_details_edit = TextEdit.new()
|
||||
_details_edit.name = "DetailsEdit"
|
||||
_details_edit.custom_minimum_size = Vector2(0, 80)
|
||||
_details_edit.placeholder_text = "Please describe what happened..."
|
||||
vbox.add_child(_details_edit)
|
||||
|
||||
_status_label = Label.new()
|
||||
_status_label.name = "StatusLabel"
|
||||
_status_label.text = ""
|
||||
_status_label.add_theme_font_size_override("font_size", 11)
|
||||
vbox.add_child(_status_label)
|
||||
|
||||
var btn_row := HBoxContainer.new()
|
||||
btn_row.alignment = BoxContainer.ALIGNMENT_END
|
||||
btn_row.add_theme_constant_override("separation", 10)
|
||||
|
||||
_cancel_button = Button.new()
|
||||
_cancel_button.name = "CancelButton"
|
||||
_cancel_button.text = "Cancel"
|
||||
_cancel_button.pressed.connect(_on_cancel_pressed)
|
||||
btn_row.add_child(_cancel_button)
|
||||
|
||||
_submit_button = Button.new()
|
||||
_submit_button.name = "SubmitButton"
|
||||
_submit_button.text = "Submit Report"
|
||||
_submit_button.add_theme_color_override("font_color", Color(1.0, 0.4, 0.4))
|
||||
_submit_button.pressed.connect(_on_submit_pressed)
|
||||
btn_row.add_child(_submit_button)
|
||||
|
||||
vbox.add_child(btn_row)
|
||||
|
||||
|
||||
func _on_cancel_pressed() -> void:
|
||||
closed.emit()
|
||||
queue_free()
|
||||
|
||||
|
||||
func _on_submit_pressed() -> void:
|
||||
var details := _details_edit.text.strip_edges()
|
||||
if details.is_empty():
|
||||
_status_label.text = "Please provide details explaining your report."
|
||||
_status_label.add_theme_color_override("font_color", Color(1.0, 0.4, 0.4))
|
||||
return
|
||||
|
||||
var cat_meta: String = _category_option.get_item_metadata(_category_option.selected)
|
||||
_submit_button.disabled = true
|
||||
_cancel_button.disabled = true
|
||||
_status_label.text = "Submitting report..."
|
||||
_status_label.add_theme_color_override("font_color", Color(0.8, 0.8, 0.8))
|
||||
|
||||
var api: Node = api_client
|
||||
if api == null and has_node("/root/ApiClient"):
|
||||
api = get_node("/root/ApiClient")
|
||||
|
||||
if api != null:
|
||||
var res: Dictionary = await api.submit_moderation_report(target_type, target_id, details, cat_meta)
|
||||
if res.get("ok", false) or res.get("status", 0) == 201:
|
||||
_status_label.text = "Report submitted to moderation queue. Thank you."
|
||||
_status_label.add_theme_color_override("font_color", Color(0.4, 1.0, 0.5))
|
||||
report_submitted.emit(target_type, target_id)
|
||||
await get_tree().create_timer(1.2).timeout
|
||||
queue_free()
|
||||
return
|
||||
else:
|
||||
_status_label.text = "Failed to submit: %s" % str(res.get("detail", "Error"))
|
||||
_status_label.add_theme_color_override("font_color", Color(1.0, 0.4, 0.4))
|
||||
_submit_button.disabled = false
|
||||
_cancel_button.disabled = false
|
||||
else:
|
||||
_status_label.text = "Report recorded locally."
|
||||
_status_label.add_theme_color_override("font_color", Color(0.4, 1.0, 0.5))
|
||||
report_submitted.emit(target_type, target_id)
|
||||
await get_tree().create_timer(1.0).timeout
|
||||
queue_free()
|
||||
Reference in New Issue
Block a user