OverviewFilesCommitsIssuesDocsReleasesPeers

godot-keet commits / 74f773e

Add MetadataBase sync UI — share key + join remote
Sync button in graph panel header opens dialog showing: - Your MetadataBase key (with copy button) - Join field to paste a key from another device Calls meta.key and meta.join RPC under the hood. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
74f773e262f75ad04138426bfd1b9a5513052659
by plankatron <fleeky@gmail.com> · 2026-02-23T03:40:15.000Z

Changed files (2) +134 -0

scenes/graph_panel.tscn +75 -0
……@@ -25,11 +25,86 @@ unique_name_in_owner = true
2525layout_mode = 2
2626tooltip_text = "Clustering algorithm"
2727
28[node name="SyncBtn" type="Button" parent="VBox/Header"]
29unique_name_in_owner = true
30layout_mode = 2
31tooltip_text = "Sync MetadataBase with another device"
32text = "Sync"
33
2834[node name="RefreshBtn" type="Button" parent="VBox/Header"]
2935unique_name_in_owner = true
3036layout_mode = 2
3137text = "Refresh"
3238
39[node name="SyncDialog" type="Window" parent="."]
40unique_name_in_owner = true
41title = "MetadataBase Sync"
42initial_position = 2
43size = Vector2i(480, 220)
44visible = false
45wrap_controls = true
46transient = true
47exclusive = true
48
49[node name="Margin" type="MarginContainer" parent="SyncDialog"]
50anchors_preset = 15
51anchor_right = 1.0
52anchor_bottom = 1.0
53offset_left = 12.0
54offset_top = 12.0
55offset_right = -12.0
56offset_bottom = -12.0
57
58[node name="VBox" type="VBoxContainer" parent="SyncDialog/Margin"]
59layout_mode = 2
60theme_override_constants/separation = 8
61
62[node name="KeyLabel" type="Label" parent="SyncDialog/Margin/VBox"]
63layout_mode = 2
64text = "Your MetadataBase key:"
65
66[node name="KeyRow" type="HBoxContainer" parent="SyncDialog/Margin/VBox"]
67layout_mode = 2
68
69[node name="KeyField" type="LineEdit" parent="SyncDialog/Margin/VBox/KeyRow"]
70unique_name_in_owner = true
71layout_mode = 2
72size_flags_horizontal = 3
73editable = false
74placeholder_text = "Loading..."
75
76[node name="CopyBtn" type="Button" parent="SyncDialog/Margin/VBox/KeyRow"]
77unique_name_in_owner = true
78layout_mode = 2
79text = "Copy"
80
81[node name="Sep" type="HSeparator" parent="SyncDialog/Margin/VBox"]
82layout_mode = 2
83
84[node name="JoinLabel" type="Label" parent="SyncDialog/Margin/VBox"]
85layout_mode = 2
86text = "Join remote MetadataBase:"
87
88[node name="JoinRow" type="HBoxContainer" parent="SyncDialog/Margin/VBox"]
89layout_mode = 2
90
91[node name="JoinField" type="LineEdit" parent="SyncDialog/Margin/VBox/JoinRow"]
92unique_name_in_owner = true
93layout_mode = 2
94size_flags_horizontal = 3
95placeholder_text = "Paste key from other device..."
96
97[node name="JoinBtn" type="Button" parent="SyncDialog/Margin/VBox/JoinRow"]
98unique_name_in_owner = true
99layout_mode = 2
100text = "Join"
101
102[node name="StatusLabel" type="Label" parent="SyncDialog/Margin/VBox"]
103unique_name_in_owner = true
104layout_mode = 2
105text = ""
106horizontal_alignment = 1
107
33108[node name="GraphCanvas" type="Control" parent="VBox"]
34109unique_name_in_owner = true
35110layout_mode = 2
scripts/graph_panel.gd +59 -0
……@@ -5,8 +5,15 @@ extends PanelContainer
55
66@onready var title_label: Label = %Title
77@onready var algo_btn: OptionButton = %AlgoBtn
8@onready var sync_btn: Button = %SyncBtn
89@onready var refresh_btn: Button = %RefreshBtn
910@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
1017
1118const ALGO_PRESETS: Array[Dictionary] = [
1219 # Simple slices
……@@ -39,6 +46,12 @@ func _ready() -> void:
3946 refresh_btn.pressed.connect(_on_refresh)
4047 graph_canvas.room_clicked.connect(_on_room_clicked)
4148
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
4255 # Populate algo selector
4356 algo_btn.add_item("Default", 0)
4457 for i: int in ALGO_PRESETS.size():
……@@ -172,3 +185,49 @@ func _on_room_clicked(room_id: String) -> void:
172185 title = r["title"]
173186 break
174187 KeetService.select_room(room_id)
188
189
190# --- MetadataBase Sync ---
191
192func _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
209func _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
215func _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 )