Add synced question bookmarks
This commit is contained in:
@@ -0,0 +1,246 @@
|
||||
extends VBoxContainer
|
||||
|
||||
const Brand := preload("res://scripts/ui/medmind_style.gd")
|
||||
|
||||
var main
|
||||
var search_input: LineEdit
|
||||
var system_filter: OptionButton
|
||||
var discipline_filter: OptionButton
|
||||
var sort_filter: OptionButton
|
||||
var status_label: Label
|
||||
var retry_button: Button
|
||||
var list_container: VBoxContainer
|
||||
var load_more_button: Button
|
||||
var debounce_timer: Timer
|
||||
var list_scroll: ScrollContainer
|
||||
var saved_scroll_position := 0
|
||||
var pending_open_question_id := ""
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
size_flags_vertical = Control.SIZE_EXPAND_FILL
|
||||
add_theme_constant_override("separation", 16)
|
||||
_build_header()
|
||||
_build_filters()
|
||||
status_label = Label.new()
|
||||
status_label.add_theme_font_override("font", Brand.font)
|
||||
status_label.add_theme_color_override("font_color", Brand.muted_color(UIThemeService.is_dark_mode()))
|
||||
add_child(status_label)
|
||||
retry_button = Button.new()
|
||||
retry_button.text = "Retry"
|
||||
retry_button.visible = false
|
||||
retry_button.custom_minimum_size = Vector2(100, 42)
|
||||
retry_button.size_flags_horizontal = Control.SIZE_SHRINK_BEGIN
|
||||
retry_button.pressed.connect(_retry)
|
||||
add_child(retry_button)
|
||||
list_scroll = ScrollContainer.new()
|
||||
list_scroll.size_flags_vertical = Control.SIZE_EXPAND_FILL
|
||||
add_child(list_scroll)
|
||||
list_container = VBoxContainer.new()
|
||||
list_container.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
list_container.add_theme_constant_override("separation", 10)
|
||||
list_scroll.add_child(list_container)
|
||||
load_more_button = Button.new()
|
||||
load_more_button.text = "Load more"
|
||||
load_more_button.custom_minimum_size = Vector2(0, 44)
|
||||
load_more_button.pressed.connect(func(): BookmarkService.load_bookmarks(false))
|
||||
list_container.add_child(load_more_button)
|
||||
debounce_timer = Timer.new()
|
||||
debounce_timer.one_shot = true
|
||||
debounce_timer.wait_time = 0.35
|
||||
debounce_timer.timeout.connect(_reload)
|
||||
add_child(debounce_timer)
|
||||
BookmarkService.list_changed.connect(_render)
|
||||
BookmarkService.list_failed.connect(_on_list_failed)
|
||||
BookmarkService.question_loaded.connect(_on_question_loaded)
|
||||
BookmarkService.question_failed.connect(_on_question_load_failed)
|
||||
UIThemeService.theme_changed.connect(func(_dark: bool): _render())
|
||||
|
||||
|
||||
func _build_header() -> void:
|
||||
var eyebrow := Label.new()
|
||||
eyebrow.text = "STUDY TOOLS"
|
||||
eyebrow.add_theme_font_override("font", Brand.font)
|
||||
eyebrow.add_theme_font_size_override("font_size", 13)
|
||||
eyebrow.add_theme_color_override("font_color", Brand.SKY_BLUE)
|
||||
add_child(eyebrow)
|
||||
var title := Label.new()
|
||||
title.text = "Bookmarks"
|
||||
title.add_theme_font_override("font", Brand.font)
|
||||
title.add_theme_font_size_override("font_size", 32)
|
||||
add_child(title)
|
||||
var subtitle := Label.new()
|
||||
subtitle.text = "Review saved questions without changing your rating or progression."
|
||||
subtitle.add_theme_font_override("font", Brand.font)
|
||||
subtitle.add_theme_color_override("font_color", Brand.muted_color(UIThemeService.is_dark_mode()))
|
||||
add_child(subtitle)
|
||||
|
||||
|
||||
func _build_filters() -> void:
|
||||
var row := HFlowContainer.new()
|
||||
row.add_theme_constant_override("separation", 10)
|
||||
add_child(row)
|
||||
search_input = LineEdit.new()
|
||||
search_input.placeholder_text = "Search saved questions"
|
||||
search_input.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
search_input.custom_minimum_size = Vector2(260, 44)
|
||||
search_input.text_changed.connect(func(_value: String): debounce_timer.start())
|
||||
row.add_child(search_input)
|
||||
system_filter = _add_filter(row, "All systems")
|
||||
discipline_filter = _add_filter(row, "All disciplines")
|
||||
sort_filter = _add_filter(row, "Newest", ["Oldest"])
|
||||
|
||||
|
||||
func _add_filter(parent: Container, first: String, extras: Array = []) -> OptionButton:
|
||||
var control := OptionButton.new()
|
||||
control.add_item(first)
|
||||
for text in extras:
|
||||
control.add_item(str(text))
|
||||
control.custom_minimum_size = Vector2(150, 44)
|
||||
control.item_selected.connect(func(_index: int): _reload())
|
||||
parent.add_child(control)
|
||||
return control
|
||||
|
||||
|
||||
func on_show(_payload: Variant = null) -> void:
|
||||
_populate_categories()
|
||||
if not BookmarkService.remote_list_loaded:
|
||||
BookmarkService.load_bookmarks(true, _filters())
|
||||
_render()
|
||||
|
||||
|
||||
func on_hide() -> void:
|
||||
if list_scroll != null:
|
||||
saved_scroll_position = int(list_scroll.scroll_vertical)
|
||||
|
||||
|
||||
func _populate_categories() -> void:
|
||||
_populate_filter(system_filter, "All systems", BookmarkService.available_systems)
|
||||
_populate_filter(discipline_filter, "All disciplines", BookmarkService.available_disciplines)
|
||||
|
||||
|
||||
func _populate_filter(control: OptionButton, first: String, values: Array) -> void:
|
||||
var selected_text := control.get_item_text(control.selected) if control.item_count > 0 else first
|
||||
control.clear()
|
||||
control.add_item(first)
|
||||
for value in values:
|
||||
if str(value) != "" and str(value) != "All Systems":
|
||||
control.add_item(str(value))
|
||||
for index in range(control.item_count):
|
||||
if control.get_item_text(index) == selected_text:
|
||||
control.select(index)
|
||||
break
|
||||
|
||||
|
||||
func _filters() -> Dictionary:
|
||||
return {
|
||||
"query": search_input.text,
|
||||
"system": "" if system_filter.selected == 0 else system_filter.get_item_text(system_filter.selected),
|
||||
"discipline": "" if discipline_filter.selected == 0 else discipline_filter.get_item_text(discipline_filter.selected),
|
||||
"sort": "oldest" if sort_filter.selected == 1 else "newest"
|
||||
}
|
||||
|
||||
|
||||
func _reload() -> void:
|
||||
BookmarkService.load_bookmarks(true, _filters())
|
||||
_render()
|
||||
|
||||
|
||||
func _render() -> void:
|
||||
if list_container == null:
|
||||
return
|
||||
if not visible:
|
||||
return
|
||||
_populate_categories()
|
||||
for child in list_container.get_children():
|
||||
if child != load_more_button:
|
||||
child.queue_free()
|
||||
status_label.text = "Loading bookmarks..." if BookmarkService.list_loading else BookmarkService.list_error
|
||||
retry_button.visible = BookmarkService.list_error != ""
|
||||
if not BookmarkService.list_loading and BookmarkService.items.is_empty() and BookmarkService.list_error == "":
|
||||
status_label.text = "No saved questions match these filters."
|
||||
var insert_index := 0
|
||||
for item in BookmarkService.items:
|
||||
var card := _bookmark_card(item)
|
||||
list_container.add_child(card)
|
||||
list_container.move_child(card, insert_index)
|
||||
insert_index += 1
|
||||
load_more_button.visible = BookmarkService.has_more
|
||||
load_more_button.disabled = BookmarkService.list_loading
|
||||
if list_scroll != null:
|
||||
list_scroll.set_deferred("scroll_vertical", saved_scroll_position)
|
||||
|
||||
|
||||
func _bookmark_card(item: Dictionary) -> Control:
|
||||
var dark := UIThemeService.is_dark_mode()
|
||||
var card := PanelContainer.new()
|
||||
card.add_theme_stylebox_override("panel", Brand.content_card_box(dark, false, Brand.TEAL))
|
||||
var row := HFlowContainer.new()
|
||||
row.add_theme_constant_override("separation", 14)
|
||||
card.add_child(row)
|
||||
var content := VBoxContainer.new()
|
||||
content.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
row.add_child(content)
|
||||
var stem := Label.new()
|
||||
stem.text = str(item.get("stem", ""))
|
||||
stem.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
||||
stem.add_theme_font_override("font", Brand.font)
|
||||
stem.add_theme_font_size_override("font_size", 16)
|
||||
content.add_child(stem)
|
||||
var metadata := Label.new()
|
||||
metadata.text = "%s | %s | Difficulty %d%s" % [
|
||||
str(item.get("system", "")), str(item.get("discipline", "")),
|
||||
int(item.get("difficulty", 1)), " | Image" if bool(item.get("has_media", false)) else ""]
|
||||
metadata.add_theme_font_override("font", Brand.font)
|
||||
metadata.add_theme_font_size_override("font_size", 13)
|
||||
metadata.add_theme_color_override("font_color", Brand.muted_color(dark))
|
||||
content.add_child(metadata)
|
||||
var open := Button.new()
|
||||
open.text = "Practice"
|
||||
open.custom_minimum_size = Vector2(105, 42)
|
||||
open.pressed.connect(_open_question.bind(str(item.get("question_id", ""))))
|
||||
row.add_child(open)
|
||||
var remove := Button.new()
|
||||
remove.icon = preload("res://assets/icons/lucide/bookmark.svg")
|
||||
remove.tooltip_text = "Remove bookmark"
|
||||
remove.custom_minimum_size = Vector2(44, 42)
|
||||
remove.pressed.connect(BookmarkService.set_bookmarked.bind(str(item.get("question_id", "")), false))
|
||||
row.add_child(remove)
|
||||
return card
|
||||
|
||||
|
||||
func _open_question(question_id: String) -> void:
|
||||
pending_open_question_id = question_id
|
||||
status_label.text = "Loading question..."
|
||||
retry_button.visible = false
|
||||
BookmarkService.begin_practice(question_id)
|
||||
|
||||
|
||||
func _on_question_loaded(question: Dictionary) -> void:
|
||||
if not visible:
|
||||
return
|
||||
pending_open_question_id = ""
|
||||
if BlockSessionService.start_bookmark_question(question):
|
||||
main.show_screen("player")
|
||||
|
||||
|
||||
func _on_list_failed(message: String) -> void:
|
||||
status_label.text = message
|
||||
retry_button.visible = true
|
||||
|
||||
|
||||
func _on_question_load_failed(message: String) -> void:
|
||||
if not visible:
|
||||
return
|
||||
status_label.text = message
|
||||
retry_button.visible = true
|
||||
|
||||
|
||||
func _retry() -> void:
|
||||
retry_button.visible = false
|
||||
if pending_open_question_id != "":
|
||||
status_label.text = "Loading question..."
|
||||
BookmarkService.begin_practice(pending_open_question_id)
|
||||
else:
|
||||
_reload()
|
||||
@@ -0,0 +1 @@
|
||||
uid://k7ycreyxpntj
|
||||
+7
-1
@@ -289,6 +289,11 @@ func _build_ui() -> void:
|
||||
notes.main = self
|
||||
screens_container.add_child(notes)
|
||||
screens["notes"] = notes
|
||||
var bookmarks := preload("res://scripts/ui/bookmarks_screen.gd").new()
|
||||
bookmarks.name = "BookmarksScreen"
|
||||
bookmarks.main = self
|
||||
screens_container.add_child(bookmarks)
|
||||
screens["bookmarks"] = bookmarks
|
||||
|
||||
feedback_dialog = preload("res://scripts/ui/app_feedback_dialog.gd").new()
|
||||
feedback_dialog.name = "AppFeedbackDialog"
|
||||
@@ -357,7 +362,7 @@ func _populate_navigation(container: VBoxContainer, include_brand: bool) -> void
|
||||
_add_nav_button(container, "performance", "Performance", "chart-no-axes-column-increasing", true)
|
||||
_add_nav_button(container, "flashcards", "Flashcards", "copy", false)
|
||||
_add_nav_button(container, "study_plan", "Study Plan", "calendar-days", true)
|
||||
_add_nav_button(container, "bookmarks", "Bookmarks", "bookmark", false)
|
||||
_add_nav_button(container, "bookmarks", "Bookmarks", "bookmark", true)
|
||||
_add_nav_button(container, "notes", "Notes", "notebook-pen", true)
|
||||
|
||||
var spacer := Control.new()
|
||||
@@ -402,6 +407,7 @@ func _on_navigation_pressed(key: String) -> void:
|
||||
"study_plan": show_screen("map")
|
||||
"settings": show_screen("settings")
|
||||
"notes": show_screen("notes")
|
||||
"bookmarks": show_screen("bookmarks")
|
||||
"logout": _logout()
|
||||
|
||||
|
||||
|
||||
@@ -19,4 +19,6 @@ static func key_for_screen(screen_name: String, payload: Variant = null) -> Stri
|
||||
key = "settings"
|
||||
elif screen_name == "notes":
|
||||
key = "notes"
|
||||
elif screen_name == "bookmarks":
|
||||
key = "bookmarks"
|
||||
return key
|
||||
|
||||
+102
-13
@@ -84,6 +84,7 @@ var clear_highlight_button: Button
|
||||
var flag_button: Button
|
||||
var report_button: Button
|
||||
var notes_button: Button
|
||||
var bookmark_button: Button
|
||||
var app_feedback_button: Button
|
||||
var theme_button: Button
|
||||
var question_toolbar: HFlowContainer
|
||||
@@ -161,6 +162,12 @@ func _ready() -> void:
|
||||
ExamSimulationService.state_changed.connect(_on_simulation_state_changed)
|
||||
if not ExamSimulationService.request_failed.is_connected(_on_simulation_request_failed):
|
||||
ExamSimulationService.request_failed.connect(_on_simulation_request_failed)
|
||||
if not BookmarkService.status_changed.is_connected(_on_bookmark_status_changed):
|
||||
BookmarkService.status_changed.connect(_on_bookmark_status_changed)
|
||||
if not BookmarkService.question_loaded.is_connected(_on_bookmark_question_loaded):
|
||||
BookmarkService.question_loaded.connect(_on_bookmark_question_loaded)
|
||||
if not BookmarkService.question_failed.is_connected(_on_bookmark_question_failed):
|
||||
BookmarkService.question_failed.connect(_on_bookmark_question_failed)
|
||||
|
||||
question_card = PanelContainer.new()
|
||||
question_card.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
@@ -267,6 +274,18 @@ func _ready() -> void:
|
||||
)
|
||||
question_toolbar.add_child(flag_button)
|
||||
|
||||
bookmark_button = Button.new()
|
||||
bookmark_button.tooltip_text = "Save question"
|
||||
bookmark_button.icon = preload("res://assets/icons/lucide/bookmark.svg")
|
||||
bookmark_button.custom_minimum_size = Vector2(44, 44)
|
||||
bookmark_button.add_theme_constant_override("icon_max_width", 22)
|
||||
bookmark_button.alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
bookmark_button.icon_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
bookmark_button.focus_mode = Control.FOCUS_NONE
|
||||
UISoundService.set_button_sound(bookmark_button, "toggle")
|
||||
bookmark_button.pressed.connect(_toggle_bookmark_current_question)
|
||||
question_toolbar.add_child(bookmark_button)
|
||||
|
||||
report_button = Button.new()
|
||||
report_button.tooltip_text = "Report question"
|
||||
report_button.custom_minimum_size = Vector2(44, 44)
|
||||
@@ -840,10 +859,10 @@ func _apply_question_theme() -> void:
|
||||
var navigator_heading := navigator_popup.find_child("NavigatorHeading", true, false) as Label
|
||||
if navigator_heading != null:
|
||||
navigator_heading.add_theme_color_override("font_color", Brand.text_color(dark))
|
||||
for control in [text_smaller_button, text_larger_button, flag_button, notes_button, app_feedback_button]:
|
||||
for control in [text_smaller_button, text_larger_button, flag_button, bookmark_button, notes_button, app_feedback_button]:
|
||||
if control == null:
|
||||
continue
|
||||
var active: bool = control == flag_button and flagged
|
||||
var active: bool = (control == flag_button and flagged) or (control == bookmark_button and BookmarkService.is_bookmarked(str(BlockSessionService.get_current_question().get("id", ""))))
|
||||
control.add_theme_stylebox_override("normal", _toolbar_box(dark, active))
|
||||
control.add_theme_stylebox_override("hover", _toolbar_box(dark, true))
|
||||
control.add_theme_stylebox_override("pressed", _toolbar_box(dark, true))
|
||||
@@ -1018,15 +1037,17 @@ func _load_question() -> void:
|
||||
next_button.disabled = true
|
||||
skip_button.disabled = false
|
||||
skip_button.visible = true
|
||||
skip_button.text = "Skip"
|
||||
report_button.visible = BlockSessionService.session_kind != "simulation"
|
||||
|
||||
var question := BlockSessionService.get_current_question()
|
||||
if question.is_empty():
|
||||
main.show_screen("selection", "exam" if BlockSessionService.session_kind == "core" else "step3")
|
||||
main.show_screen("bookmarks" if BlockSessionService.session_kind == "bookmark" else "selection", "exam" if BlockSessionService.session_kind == "core" else "step3")
|
||||
return
|
||||
BookmarkService.observe_question(question)
|
||||
progress_button.text = _question_progress_text()
|
||||
progress_button.disabled = BlockSessionService.session_kind == "core"
|
||||
progress_button.tooltip_text = "" if BlockSessionService.session_kind == "core" else "Open question navigator"
|
||||
progress_button.disabled = BlockSessionService.session_kind in ["core", "bookmark"]
|
||||
progress_button.tooltip_text = "" if BlockSessionService.session_kind in ["core", "bookmark"] else "Open question navigator"
|
||||
var show_timer := _is_session_timer_visible()
|
||||
timer_label.visible = show_timer
|
||||
timer_bar.visible = show_timer
|
||||
@@ -1150,6 +1171,16 @@ func _should_clear_selection_from_click(mouse_event: InputEventMouseButton) -> b
|
||||
|
||||
|
||||
func _skip_current_question() -> void:
|
||||
if BlockSessionService.session_kind == "bookmark":
|
||||
if not current_answer.is_empty():
|
||||
_finish()
|
||||
return
|
||||
current_answer = BlockSessionService.skip_bookmark_question(eliminated, flagged)
|
||||
if current_answer.is_empty():
|
||||
return
|
||||
selected_choice = ""
|
||||
_show_answer_review()
|
||||
return
|
||||
if pending_correct_advance or (not current_answer.is_empty() and BlockSessionService.session_kind != "simulation"):
|
||||
return
|
||||
if BlockSessionService.session_kind != "core":
|
||||
@@ -1260,15 +1291,16 @@ func _submit_or_next() -> void:
|
||||
if selected_choice == "":
|
||||
return
|
||||
var question_id_for_attempt := str(BlockSessionService.get_current_question().get("id", ""))
|
||||
if BlockSessionService.session_kind == "core":
|
||||
if BlockSessionService.session_kind in ["core", "bookmark"]:
|
||||
_collapse_resolved_followups()
|
||||
var attempted_choice := selected_choice
|
||||
QuestionBankService.record_first_attempt(
|
||||
question_id_for_attempt,
|
||||
attempted_choice,
|
||||
_presented_choice_ids()
|
||||
)
|
||||
var result := BlockSessionService.submit_core_attempt(selected_choice, eliminated, flagged)
|
||||
if BlockSessionService.session_kind == "core":
|
||||
QuestionBankService.record_first_attempt(
|
||||
question_id_for_attempt,
|
||||
attempted_choice,
|
||||
_presented_choice_ids()
|
||||
)
|
||||
var result := BlockSessionService.submit_core_attempt(selected_choice, eliminated, flagged) if BlockSessionService.session_kind == "core" else BlockSessionService.submit_bookmark_attempt(selected_choice, eliminated, flagged)
|
||||
if result.is_empty():
|
||||
return
|
||||
var answer: Dictionary = result.get("answer", {})
|
||||
@@ -1297,6 +1329,14 @@ func _submit_or_next() -> void:
|
||||
else:
|
||||
if BlockSessionService.session_kind == "core":
|
||||
_request_next_core_question()
|
||||
elif BlockSessionService.session_kind == "bookmark":
|
||||
if BookmarkService.has_next_practice():
|
||||
awaiting_next_question = true
|
||||
next_button.text = "Loading..."
|
||||
next_button.disabled = true
|
||||
BookmarkService.next_practice()
|
||||
else:
|
||||
_finish()
|
||||
else:
|
||||
_advance_or_finish()
|
||||
|
||||
@@ -1345,9 +1385,14 @@ func _show_answer_review() -> void:
|
||||
_set_answer_review_timer_visibility()
|
||||
next_button.text = "Next"
|
||||
next_button.disabled = false
|
||||
if BlockSessionService.session_kind == "bookmark" and not BookmarkService.has_next_practice():
|
||||
next_button.text = "End of list"
|
||||
next_button.disabled = true
|
||||
if skip_button != null:
|
||||
skip_button.disabled = true
|
||||
skip_button.visible = false
|
||||
skip_button.visible = BlockSessionService.session_kind == "bookmark"
|
||||
skip_button.text = "Back to Bookmarks" if BlockSessionService.session_kind == "bookmark" else "Skip"
|
||||
skip_button.disabled = false if BlockSessionService.session_kind == "bookmark" else true
|
||||
if question_scroll != null:
|
||||
question_scroll.call_deferred("ensure_control_visible", explanation_label)
|
||||
|
||||
@@ -1653,6 +1698,10 @@ func _advance_or_finish() -> void:
|
||||
|
||||
|
||||
func _finish() -> void:
|
||||
if BlockSessionService.session_kind == "bookmark":
|
||||
BlockSessionService.finish_block()
|
||||
main.show_screen("bookmarks")
|
||||
return
|
||||
if BlockSessionService.session_kind == "core":
|
||||
BlockSessionService.finish_block()
|
||||
main.show_screen("selection", "exam")
|
||||
@@ -1662,6 +1711,10 @@ func _finish() -> void:
|
||||
|
||||
|
||||
func _exit_run() -> void:
|
||||
if BlockSessionService.session_kind == "bookmark":
|
||||
BlockSessionService.finish_block()
|
||||
main.show_screen("bookmarks")
|
||||
return
|
||||
var was_core_run := BlockSessionService.session_kind == "core"
|
||||
BlockSessionService.resume_current_question_timer()
|
||||
BlockSessionService.finish_block()
|
||||
@@ -1879,9 +1932,45 @@ func _refresh_toolbar_state() -> void:
|
||||
report_button.tooltip_text = "Report submitted; report another issue" if reported_question_ids.has(question_id) else "Report question"
|
||||
if notes_button != null:
|
||||
notes_button.visible = BlockSessionService.session_kind != "simulation"
|
||||
if bookmark_button != null:
|
||||
bookmark_button.visible = BlockSessionService.session_kind != "simulation"
|
||||
var bookmark_question_id := str(BlockSessionService.get_current_question().get("id", ""))
|
||||
var bookmark_value := BookmarkService.is_bookmarked(bookmark_question_id)
|
||||
var bookmark_pending := BookmarkService.is_pending(bookmark_question_id)
|
||||
bookmark_button.tooltip_text = ("Saved; waiting to sync" if bookmark_pending else "Remove bookmark") if bookmark_value else ("Removal waiting to sync" if bookmark_pending else "Save question")
|
||||
_apply_question_theme()
|
||||
|
||||
|
||||
func _toggle_bookmark_current_question() -> void:
|
||||
var question := BlockSessionService.get_current_question()
|
||||
if not question.is_empty():
|
||||
BookmarkService.toggle_question(question)
|
||||
|
||||
|
||||
func _on_bookmark_status_changed(question_id: String, value: bool, pending: bool) -> void:
|
||||
if question_id != str(BlockSessionService.get_current_question().get("id", "")) or bookmark_button == null:
|
||||
return
|
||||
bookmark_button.tooltip_text = ("Saved; waiting to sync" if pending else "Remove bookmark") if value else ("Removal waiting to sync" if pending else "Save question")
|
||||
_apply_question_theme()
|
||||
|
||||
|
||||
func _on_bookmark_question_loaded(question: Dictionary) -> void:
|
||||
if not visible or BlockSessionService.session_kind != "bookmark" or not awaiting_next_question:
|
||||
return
|
||||
awaiting_next_question = false
|
||||
if BlockSessionService.replace_bookmark_question(question):
|
||||
_load_question()
|
||||
|
||||
|
||||
func _on_bookmark_question_failed(message: String) -> void:
|
||||
if not visible or BlockSessionService.session_kind != "bookmark":
|
||||
return
|
||||
awaiting_next_question = false
|
||||
next_button.text = "Retry"
|
||||
next_button.disabled = false
|
||||
next_button.tooltip_text = message
|
||||
|
||||
|
||||
func refresh_theme_controls() -> void:
|
||||
if media_viewer_background != null:
|
||||
media_viewer_background.color = Style.BACKGROUND
|
||||
|
||||
Reference in New Issue
Block a user