| … | … | @@ -25,11 +25,86 @@ unique_name_in_owner = true |
| 25 | 25 | layout_mode = 2 |
| 26 | 26 | tooltip_text = "Clustering algorithm" |
| 27 | 27 | |
| 28 | [node name="SyncBtn" type="Button" parent="VBox/Header"] | |
| 29 | unique_name_in_owner = true | |
| 30 | layout_mode = 2 | |
| 31 | tooltip_text = "Sync MetadataBase with another device" | |
| 32 | text = "Sync" | |
| 33 | ||
| 28 | 34 | [node name="RefreshBtn" type="Button" parent="VBox/Header"] |
| 29 | 35 | unique_name_in_owner = true |
| 30 | 36 | layout_mode = 2 |
| 31 | 37 | text = "Refresh" |
| 32 | 38 | |
| 39 | [node name="SyncDialog" type="Window" parent="."] | |
| 40 | unique_name_in_owner = true | |
| 41 | title = "MetadataBase Sync" | |
| 42 | initial_position = 2 | |
| 43 | size = Vector2i(480, 220) | |
| 44 | visible = false | |
| 45 | wrap_controls = true | |
| 46 | transient = true | |
| 47 | exclusive = true | |
| 48 | ||
| 49 | [node name="Margin" type="MarginContainer" parent="SyncDialog"] | |
| 50 | anchors_preset = 15 | |
| 51 | anchor_right = 1.0 | |
| 52 | anchor_bottom = 1.0 | |
| 53 | offset_left = 12.0 | |
| 54 | offset_top = 12.0 | |
| 55 | offset_right = -12.0 | |
| 56 | offset_bottom = -12.0 | |
| 57 | ||
| 58 | [node name="VBox" type="VBoxContainer" parent="SyncDialog/Margin"] | |
| 59 | layout_mode = 2 | |
| 60 | theme_override_constants/separation = 8 | |
| 61 | ||
| 62 | [node name="KeyLabel" type="Label" parent="SyncDialog/Margin/VBox"] | |
| 63 | layout_mode = 2 | |
| 64 | text = "Your MetadataBase key:" | |
| 65 | ||
| 66 | [node name="KeyRow" type="HBoxContainer" parent="SyncDialog/Margin/VBox"] | |
| 67 | layout_mode = 2 | |
| 68 | ||
| 69 | [node name="KeyField" type="LineEdit" parent="SyncDialog/Margin/VBox/KeyRow"] | |
| 70 | unique_name_in_owner = true | |
| 71 | layout_mode = 2 | |
| 72 | size_flags_horizontal = 3 | |
| 73 | editable = false | |
| 74 | placeholder_text = "Loading..." | |
| 75 | ||
| 76 | [node name="CopyBtn" type="Button" parent="SyncDialog/Margin/VBox/KeyRow"] | |
| 77 | unique_name_in_owner = true | |
| 78 | layout_mode = 2 | |
| 79 | text = "Copy" | |
| 80 | ||
| 81 | [node name="Sep" type="HSeparator" parent="SyncDialog/Margin/VBox"] | |
| 82 | layout_mode = 2 | |
| 83 | ||
| 84 | [node name="JoinLabel" type="Label" parent="SyncDialog/Margin/VBox"] | |
| 85 | layout_mode = 2 | |
| 86 | text = "Join remote MetadataBase:" | |
| 87 | ||
| 88 | [node name="JoinRow" type="HBoxContainer" parent="SyncDialog/Margin/VBox"] | |
| 89 | layout_mode = 2 | |
| 90 | ||
| 91 | [node name="JoinField" type="LineEdit" parent="SyncDialog/Margin/VBox/JoinRow"] | |
| 92 | unique_name_in_owner = true | |
| 93 | layout_mode = 2 | |
| 94 | size_flags_horizontal = 3 | |
| 95 | placeholder_text = "Paste key from other device..." | |
| 96 | ||
| 97 | [node name="JoinBtn" type="Button" parent="SyncDialog/Margin/VBox/JoinRow"] | |
| 98 | unique_name_in_owner = true | |
| 99 | layout_mode = 2 | |
| 100 | text = "Join" | |
| 101 | ||
| 102 | [node name="StatusLabel" type="Label" parent="SyncDialog/Margin/VBox"] | |
| 103 | unique_name_in_owner = true | |
| 104 | layout_mode = 2 | |
| 105 | text = "" | |
| 106 | horizontal_alignment = 1 | |
| 107 | ||
| 33 | 108 | [node name="GraphCanvas" type="Control" parent="VBox"] |
| 34 | 109 | unique_name_in_owner = true |
| 35 | 110 | layout_mode = 2 |
| … | … | @@ -5,8 +5,15 @@ extends PanelContainer |
| 5 | 5 | |
| 6 | 6 | @onready var title_label: Label = %Title |
| 7 | 7 | @onready var algo_btn: OptionButton = %AlgoBtn |
| 8 | @onready var sync_btn: Button = %SyncBtn | |
| 8 | 9 | @onready var refresh_btn: Button = %RefreshBtn |
| 9 | 10 | @onready var graph_canvas: Control = %GraphCanvas |
| 11 | @onready var sync_dialog: Window = %SyncDialog | |
| 12 | @onready var key_field: LineEdit = %KeyField | |
| 13 | @onready var copy_btn: Button = %CopyBtn | |
| 14 | @onready var join_field: LineEdit = %JoinField | |
| 15 | @onready var join_btn: Button = %JoinBtn | |
| 16 | @onready var status_label: Label = %StatusLabel | |
| 10 | 17 | |
| 11 | 18 | const ALGO_PRESETS: Array[Dictionary] = [ |
| 12 | 19 | # Simple slices |
| … | … | @@ -39,6 +46,12 @@ func _ready() -> void: |
| 39 | 46 | refresh_btn.pressed.connect(_on_refresh) |
| 40 | 47 | graph_canvas.room_clicked.connect(_on_room_clicked) |
| 41 | 48 | |
| 49 | # Sync dialog | |
| 50 | sync_btn.pressed.connect(_on_sync_pressed) | |
| 51 | copy_btn.pressed.connect(_on_copy_key) | |
| 52 | join_btn.pressed.connect(_on_join_meta) | |
| 53 | sync_dialog.close_requested.connect(func(): sync_dialog.hide()) | |
| 54 | ||
| 42 | 55 | # Populate algo selector |
| 43 | 56 | algo_btn.add_item("Default", 0) |
| 44 | 57 | for i: int in ALGO_PRESETS.size(): |
| … | … | @@ -172,3 +185,49 @@ func _on_room_clicked(room_id: String) -> void: |
| 172 | 185 | title = r["title"] |
| 173 | 186 | break |
| 174 | 187 | KeetService.select_room(room_id) |
| 188 | ||
| 189 | ||
| 190 | # --- MetadataBase Sync --- | |
| 191 | ||
| 192 | func _on_sync_pressed() -> void: | |
| 193 | status_label.text = "" | |
| 194 | key_field.text = "Loading..." | |
| 195 | join_field.text = "" | |
| 196 | sync_dialog.popup_centered() | |
| 197 | # Fetch our MetadataBase key | |
| 198 | KeetService.graph_mgr.client.call_rpc("meta.key", {}, func(result, err): | |
| 199 | if err != null: | |
| 200 | key_field.text = "Error: %s" % str(err) | |
| 201 | return | |
| 202 | if result is Dictionary: | |
| 203 | key_field.text = str(result.get("key", "")) | |
| 204 | else: | |
| 205 | key_field.text = str(result) | |
| 206 | ) | |
| 207 | ||
| 208 | ||
| 209 | func _on_copy_key() -> void: | |
| 210 | if key_field.text != "" and key_field.text != "Loading...": | |
| 211 | DisplayServer.clipboard_set(key_field.text) | |
| 212 | status_label.text = "Key copied to clipboard" | |
| 213 | ||
| 214 | ||
| 215 | func _on_join_meta() -> void: | |
| 216 | var key: String = join_field.text.strip_edges() | |
| 217 | if key == "": | |
| 218 | status_label.text = "Paste a key first" | |
| 219 | return | |
| 220 | if key.length() < 32: | |
| 221 | status_label.text = "Invalid key (too short)" | |
| 222 | return | |
| 223 | status_label.text = "Joining..." | |
| 224 | join_btn.disabled = true | |
| 225 | KeetService.graph_mgr.client.call_rpc("meta.join", {"key": key}, func(result, err): | |
| 226 | join_btn.disabled = false | |
| 227 | if err != null: | |
| 228 | status_label.text = "Error: %s" % str(err) | |
| 229 | else: | |
| 230 | status_label.text = "Joined! Metadata will sync shortly." | |
| 231 | # Refresh graph after joining | |
| 232 | _fetch_all() | |
| 233 | ) |