@@ -8,6 +8,8 @@ var notification_manager := load("res://core/global/notification_manager.tres")
88var sections_label_scene := load ("res://core/ui/components/section_label.tscn" ) as PackedScene
99var button_scene := load ("res://core/ui/components/card_button_setting.tscn" ) as PackedScene
1010var toggle_scene := load ("res://core/ui/components/toggle.tscn" ) as PackedScene
11+ var dropdown_scene := load ("res://core/ui/components/dropdown.tscn" ) as PackedScene
12+ var general_settings_state := load ("res://assets/state/states/settings_general.tres" ) as State
1113
1214var update_available := false
1315var update_installed := false
@@ -160,7 +162,113 @@ func _add_updater(root: Node) -> void:
160162 # Configure update button
161163 update_button .button_up .connect (_on_update .bind (update_button , check_update_button ))
162164
163- # TODO: Add branch selector
165+ # Get the currently selected branch
166+ var current_branch := _get_current_branch ()
167+ if current_branch .is_empty ():
168+ logger .warn ("Unable to detect current branch" )
169+ return
170+
171+ # Add branch selector
172+ var branches_dropdown := dropdown_scene .instantiate () as Dropdown
173+ branches_dropdown .title = "Branch"
174+ branches_dropdown .description = "Channel used for updates"
175+ branches_dropdown .clear ()
176+ branches_dropdown .add_item (current_branch )
177+ branches_dropdown .select (0 )
178+ container .add_child (branches_dropdown )
179+ container .move_child (branches_dropdown , 4 )
180+
181+ # Set the current branch when an item is selected
182+ var on_item_selected := func (idx : int ):
183+ var branch := branches_dropdown .option_button .get_item_text (idx )
184+ _set_branch (branch )
185+ branches_dropdown .item_selected .connect (on_item_selected )
186+
187+ # Query for available branches whenever the menu state is entered
188+ var on_state_entered := func (_from : State ):
189+ _populate_branches (branches_dropdown )
190+ general_settings_state .state_entered .connect (on_state_entered )
191+
192+
193+ # Set the current branch to the given branch
194+ func _set_branch (branch : String ) -> int :
195+ if branch .is_empty ():
196+ return ERR_DOES_NOT_EXIST
197+ var current_branch := _get_current_branch ()
198+ if branch == current_branch :
199+ return OK
200+
201+ var cmd := Command .create (UPDATER_CMD , ["set-branch" , branch ])
202+ var result := cmd .execute ()
203+ if result != OK :
204+ logger .warn ("Unable to set branch" )
205+ return result
206+ var exit_code := await cmd .finished as int
207+ if exit_code != OK :
208+ logger .warn ("Failed to set branch:" , cmd .stdout , cmd .stderr )
209+ return exit_code
210+
211+ return OK
212+
213+ # Populate the given dropdown with the current branches
214+ func _populate_branches (dropdown : Dropdown ) -> void :
215+ # Get the currently selected branch
216+ var current_branch := _get_current_branch ()
217+ if current_branch .is_empty ():
218+ logger .warn ("Unable to detect current branch" )
219+ return
220+
221+ # Fetch the available branches
222+ var cmd := Command .create (UPDATER_CMD , ["list-branches" ])
223+ if cmd .execute () != OK :
224+ logger .warn ("Unable to check for branches" )
225+ return
226+ if await cmd .finished != OK :
227+ logger .warn ("Failed to check for branches:" , cmd .stdout , cmd .stderr )
228+ return
229+ var lines := cmd .stdout .split ("\n " , false )
230+
231+ # Populate the dropdown
232+ var selected := dropdown .selected
233+ dropdown .clear ()
234+ dropdown .add_item (current_branch )
235+ for line in lines :
236+ dropdown .add_item (line )
237+
238+
239+ # Gets the currently selected OS branch
240+ func _get_current_branch () -> String :
241+ var config := FileAccess .open ("/etc/nixos/flake.nix" , FileAccess .READ )
242+ if not config :
243+ logger .warn ("Unable to open config `/etc/nixos/flake.nix` to discover branch" )
244+ return ""
245+ var data := config .get_as_text ()
246+ var lines := data .split ("\n " )
247+
248+ var input_line := ""
249+ for line in lines :
250+ if not line .contains ("shadowblip.url" ):
251+ continue
252+ input_line = line
253+ break
254+
255+ if input_line .is_empty ():
256+ logger .warn ("Unable to find input URL in `/etc/nixos/flake.nix` to discover branch" )
257+ return ""
258+
259+ # shadowblip.url = "gitlab:shadowapex/os-flake?ref=main";
260+ var parts := input_line .split ('"' , false )
261+ if parts .size () < 2 :
262+ logger .warn ("Unable to parse branch line to discover branch" )
263+ return ""
264+
265+ var url := parts [1 ]
266+ if not "ref" in url :
267+ logger .warn ("Unable to find '?ref=<branch>' pattern in config to discover branch" )
268+ return ""
269+ var branch := url .split ("=" , false )[- 1 ]
270+
271+ return branch
164272
165273
166274# Invoked whenever the updater timer times out
0 commit comments