Add CCS study tools and case reporting

This commit is contained in:
hz
2026-07-15 10:43:03 -05:00
parent 7256f93002
commit 9f379cda5c
13 changed files with 542 additions and 56 deletions
+61 -1
View File
@@ -8,8 +8,14 @@ signal attempt_changed
signal orders_changed
signal history_changed
signal prediction_changed
signal report_submitted(report_id: String)
signal report_failed(message: String)
signal request_failed(message: String)
const TEXT_SCALE_MIN := 0.85
const TEXT_SCALE_MAX := 1.35
const TEXT_SCALE_STEP := 0.1
var api_url := DEFAULT_API_URL
var request: HTTPRequest
var cases: Array = []
@@ -20,6 +26,8 @@ var prediction := {}
var is_loading := false
var pending_action := ""
var queue: Array = []
var text_scale := 1.0
var highlights := {}
func _ready() -> void:
@@ -27,6 +35,7 @@ func _ready() -> void:
request = HTTPRequest.new()
request.request_completed.connect(_on_request_completed)
add_child(request)
AuthState.auth_changed.connect(_on_auth_changed)
func load_cases() -> void:
@@ -69,6 +78,44 @@ func load_prediction() -> void:
_send("prediction", HTTPClient.METHOD_GET, "/prediction")
func submit_report(attempt_id: String, category: String, details: String) -> void:
_send("report", HTTPClient.METHOD_POST, "/reports", {"attemptId": attempt_id, "category": category, "details": details})
func adjust_text_scale(delta: float) -> void:
text_scale = clampf(text_scale + delta, TEXT_SCALE_MIN, TEXT_SCALE_MAX)
func toggle_highlight(attempt_id: String, region_id: String, start: int, end: int) -> void:
var key := "%s:%s" % [attempt_id, region_id]
var ranges: Array = highlights.get(key, [])
var removed := false
for index in range(ranges.size() - 1, -1, -1):
var item: Dictionary = ranges[index]
if start < int(item.get("end", 0)) and end > int(item.get("start", 0)):
ranges.remove_at(index); removed = true
if not removed: ranges.append({"start": start, "end": end})
highlights[key] = ranges
func clear_highlights(attempt_id: String) -> void:
for key in highlights.keys():
if str(key).begins_with("%s:" % attempt_id): highlights.erase(key)
func highlighted_text(attempt_id: String, region_id: String, plain_text: String) -> String:
var ranges: Array = highlights.get("%s:%s" % [attempt_id, region_id], []).duplicate()
ranges.sort_custom(func(a: Dictionary, b: Dictionary): return int(a.get("start", 0)) < int(b.get("start", 0)))
var result := ""; var cursor := 0
for item in ranges:
var start := clampi(int(item.get("start", 0)), cursor, plain_text.length())
var end := clampi(int(item.get("end", 0)), start, plain_text.length())
result += _escape_bbcode(plain_text.substr(cursor, start - cursor))
result += "[bgcolor=yellow][color=black]%s[/color][/bgcolor]" % _escape_bbcode(plain_text.substr(start, end - start))
cursor = end
return result + _escape_bbcode(plain_text.substr(cursor))
func abandon() -> void:
if attempt.is_empty():
return
@@ -107,7 +154,9 @@ func _on_request_completed(result: int, response_code: int, _headers: PackedStri
call_deferred("_process_queue")
if result != HTTPRequest.RESULT_SUCCESS or response_code < 200 or response_code >= 300:
var detail := body.get_string_from_utf8().strip_edges().left(240)
request_failed.emit("CCS request failed (%d). %s" % [response_code, detail])
var message := "CCS request failed (%d). %s" % [response_code, detail]
if action == "report": report_failed.emit(message)
else: request_failed.emit(message)
return
if response_code == 204:
attempt = {}
@@ -125,6 +174,7 @@ func _on_request_completed(result: int, response_code: int, _headers: PackedStri
"orders": orders = parsed; orders_changed.emit()
"history": history = parsed; history_changed.emit()
"prediction": prediction = parsed; prediction_changed.emit()
"report": report_submitted.emit(str(parsed.get("id", "")))
_:
attempt = parsed
attempt_changed.emit()
@@ -136,3 +186,13 @@ func _process_queue() -> void:
var queued: Dictionary = queue.pop_front()
var suffix := str(queued.get("url", "")).trim_prefix(api_url.rstrip("/"))
_send(str(queued.get("action", "")), int(queued.get("method", HTTPClient.METHOD_GET)), suffix, queued.get("payload", {}))
func _escape_bbcode(value: String) -> String:
return value.replace("[", "[lb]").replace("]", "[rb]")
func _on_auth_changed() -> void:
if not AuthState.is_logged_in:
highlights.clear()
text_scale = 1.0