This is an automated email from the git hooks/post-receive script.

git pushed a commit to branch main
in repository eradio.

View the commit online.

commit 011fc6c24bbc66c98b4fcfe4206bc931d0ec2708
Author: politebot <[email protected]>
AuthorDate: Sat Oct 11 10:54:59 2025 -0500

    Add loading indicator, hide advanced search controls by default
---
 src/appdata.h      |  5 ++++
 src/http.c         | 14 +++++++++-
 src/station_list.c |  2 +-
 src/ui.c           | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++---
 src/ui.h           |  2 ++
 5 files changed, 94 insertions(+), 5 deletions(-)

diff --git a/src/appdata.h b/src/appdata.h
index a14ab2b..9e78507 100644
--- a/src/appdata.h
+++ b/src/appdata.h
@@ -32,12 +32,17 @@ typedef struct _AppData
    Evas_Object *search_btn;
    Evas_Object *load_more_btn;
    Evas_Object *search_bar;
+   Evas_Object *filters_toggle_btn;
+   Evas_Object *filters_box;
+   Evas_Object *progressbar;   // loading indicator
    Evas_Object *sort_hoversel;
    Evas_Object *reverse_check;
    Eina_List *stations;
    Eina_List *api_servers;    // list of strings (hostnames)
    const char *api_selected;  // currently selected server hostname
    Eina_Bool playing;
+   Eina_Bool filters_visible;
+   int loading_requests;       // refcount of in-flight HTTP requests
    Eina_Hash *favorites;
    Eina_List *favorites_stations;
    ViewMode view_mode;
diff --git a/src/http.c b/src/http.c
index 7e533ae..4d0f0b5 100644
--- a/src/http.c
+++ b/src/http.c
@@ -105,6 +105,7 @@ http_search_stations(AppData *ad, const char *search_term, const char *search_ty
    _issue_station_request(&url, d_ctx);
    ecore_con_url_additional_header_add(url, "User-Agent", "eradio/1.0");
    ecore_con_url_data_set(url, d_ctx);
+   ui_loading_start(ad);
    ecore_con_url_get(url);
 }
 
@@ -135,6 +136,7 @@ http_download_icon(AppData *ad, Elm_Object_Item *list_item, const char *url_str)
     icon_ctx->base.ad = ad;
     icon_ctx->list_item = list_item;
     ecore_con_url_data_set(url, icon_ctx);
+    ui_loading_start(ad);
     ecore_con_url_get(url);
 }
 
@@ -382,6 +384,7 @@ _url_complete_cb(void *data, int type, void *event_info)
 {
     Ecore_Con_Event_Url_Complete *ev = event_info;
     Download_Context *ctx = ecore_con_url_data_get(ev->url_con);
+    AppData *ad;
 
     if (!ctx)
       {
@@ -389,13 +392,19 @@ _url_complete_cb(void *data, int type, void *event_info)
          return ECORE_CALLBACK_PASS_ON;
       }
 
+    ad = ctx->ad;
+
     if (ctx->type == DOWNLOAD_TYPE_STATIONS)
       {
          if (_handle_station_list_complete(ev))
            return ECORE_CALLBACK_PASS_ON;
+         ui_loading_stop(ad);
       }
     else if (ctx->type == DOWNLOAD_TYPE_ICON)
-      _handle_icon_complete(ev);
+      {
+         _handle_icon_complete(ev);
+         ui_loading_stop(ad);
+      }
     else if (ctx->type == DOWNLOAD_TYPE_COUNTER)
       {
          if (ev->status != 200)
@@ -408,6 +417,7 @@ _url_complete_cb(void *data, int type, void *event_info)
          Counter_Download_Context *c_ctx = (Counter_Download_Context *)ctx;
          eina_list_free(c_ctx->servers);
          free(c_ctx);
+         ui_loading_stop(ad);
       }
 
     ecore_con_url_free(ev->url_con);
@@ -565,6 +575,7 @@ static void _retry_next_server_station(Ecore_Con_Url *old_url, Station_Download_
       }
       eina_list_free(d_ctx->servers);
       free(d_ctx);
+      ui_loading_stop(((Download_Context *)d_ctx)->ad);
    }
 }
 
@@ -608,5 +619,6 @@ static void _retry_next_server_counter(Ecore_Con_Url *old_url, Counter_Download_
       ecore_con_url_free(old_url);
       eina_list_free(c_ctx->servers);
       free(c_ctx);
+      ui_loading_stop(((Download_Context *)c_ctx)->ad);
    }
 }
diff --git a/src/station_list.c b/src/station_list.c
index b28060c..f93c715 100644
--- a/src/station_list.c
+++ b/src/station_list.c
@@ -73,7 +73,6 @@ station_list_populate(AppData *ad, Eina_List *stations, Eina_Bool new_search)
 
         Elm_Object_Item *li = elm_list_item_append(ad->list, st->name, icon, fav_btn, NULL, NULL);
         elm_object_item_data_set(li, st);
-        evas_object_smart_callback_add(ad->list, "selected", _list_item_selected_cb, ad);
 
         // Attach callback only when a button exists
         if (fav_btn)
@@ -107,6 +106,7 @@ station_list_populate(AppData *ad, Eina_List *stations, Eina_Bool new_search)
                }
           }
     }
+    evas_object_smart_callback_add(ad->list, "selected", _list_item_selected_cb, ad);
     elm_list_go(ad->list);
 }
 
diff --git a/src/ui.c b/src/ui.c
index 4efacec..1d90a15 100644
--- a/src/ui.c
+++ b/src/ui.c
@@ -10,6 +10,7 @@ static void _hoversel_item_selected_cb(void *data, Evas_Object *obj, void *event
 static void _tb_favorites_clicked_cb(void *data, Evas_Object *obj, void *event_info);
 static void _tb_search_clicked_cb(void *data, Evas_Object *obj, void *event_info);
 static void _server_item_selected_cb(void *data, Evas_Object *obj, void *event_info);
+static void _filters_toggle_btn_clicked_cb(void *data, Evas_Object *obj, void *event_info);
 
 // Forward declarations for callbacks
 void _play_pause_btn_clicked_cb(void *data, Evas_Object *obj, void *event_info);
@@ -97,11 +98,27 @@ ui_create(AppData *ad)
    evas_object_show(ad->search_entry);
    elm_object_focus_set(ad->search_entry, EINA_TRUE);
 
-   // Search options in a separate box
+   // Filters toggle button
+   ad->filters_toggle_btn = elm_button_add(ad->win);
+   elm_object_text_set(ad->filters_toggle_btn, "Filters ▾");
+   elm_box_pack_end(ad->search_bar, ad->filters_toggle_btn);
+   evas_object_show(ad->filters_toggle_btn);
+   evas_object_smart_callback_add(ad->filters_toggle_btn, "clicked", _filters_toggle_btn_clicked_cb, ad);
+
+   // Collapsible filters box (hidden by default)
+   ad->filters_box = elm_box_add(ad->win);
+   elm_box_padding_set(ad->filters_box, 10, 10);
+   evas_object_size_hint_weight_set(ad->filters_box, EVAS_HINT_EXPAND, 0);
+   evas_object_size_hint_align_set(ad->filters_box, EVAS_HINT_FILL, 0);
+   elm_box_pack_end(ad->search_bar, ad->filters_box);
+   evas_object_hide(ad->filters_box);
+   ad->filters_visible = EINA_FALSE;
+
+   // Search options inside the filters box
    Evas_Object *search_options_box = elm_box_add(ad->win);
    elm_box_horizontal_set(search_options_box, EINA_TRUE);
    elm_box_padding_set(search_options_box, 10, 0);
-   elm_box_pack_end(ad->search_bar, search_options_box);
+   elm_box_pack_end(ad->filters_box, search_options_box);
    evas_object_show(search_options_box);
 
    Evas_Object *lbl;
@@ -158,7 +175,7 @@ ui_create(AppData *ad)
    ad->server_hoversel = elm_hoversel_add(ad->win);
    elm_hoversel_hover_parent_set(ad->server_hoversel, ad->win);
    elm_object_text_set(ad->server_hoversel, "server");
-   elm_box_pack_end(ad->search_bar, ad->server_hoversel);
+   elm_box_pack_end(ad->filters_box, ad->server_hoversel);
    evas_object_show(ad->server_hoversel);
 
    ad->search_btn = elm_button_add(ad->win);
@@ -166,6 +183,16 @@ ui_create(AppData *ad)
    elm_box_pack_end(ad->search_bar, ad->search_btn);
    evas_object_show(ad->search_btn);
 
+   // Loading indicator (spinner)
+   ad->progressbar = elm_progressbar_add(ad->win);
+   elm_object_style_set(ad->progressbar, "wheel");
+   elm_progressbar_pulse_set(ad->progressbar, EINA_TRUE);
+   evas_object_size_hint_weight_set(ad->progressbar, 0.0, 0.0);
+   evas_object_size_hint_align_set(ad->progressbar, 0.5, 0.5);
+   elm_box_pack_end(ad->search_bar, ad->progressbar);
+   evas_object_hide(ad->progressbar);
+   ad->loading_requests = 0;
+
    /* Separator */
    Evas_Object *sep = elm_separator_add(ad->win);
    elm_separator_horizontal_set(sep, EINA_TRUE);
@@ -238,6 +265,49 @@ ui_create(AppData *ad)
    evas_object_show(ad->win);
 }
 
+static void
+_filters_toggle_btn_clicked_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+   AppData *ad = data;
+   if (!ad) return;
+   ad->filters_visible = !ad->filters_visible;
+   if (ad->filters_visible)
+   {
+      elm_object_text_set(ad->filters_toggle_btn, "Filters ▴");
+      evas_object_show(ad->filters_box);
+   }
+   else
+   {
+      elm_object_text_set(ad->filters_toggle_btn, "Filters ▾");
+      evas_object_hide(ad->filters_box);
+   }
+}
+
+void ui_loading_start(AppData *ad)
+{
+   if (!ad || !ad->progressbar) return;
+   ad->loading_requests++;
+   if (ad->loading_requests == 1)
+   {
+      evas_object_show(ad->progressbar);
+      elm_progressbar_pulse(ad->progressbar, EINA_TRUE);
+      elm_object_text_set(ad->statusbar, "Loading...");
+   }
+}
+
+void ui_loading_stop(AppData *ad)
+{
+   if (!ad || !ad->progressbar) return;
+   if (ad->loading_requests > 0)
+     ad->loading_requests--;
+   if (ad->loading_requests == 0)
+   {
+      elm_progressbar_pulse(ad->progressbar, EINA_FALSE);
+      evas_object_hide(ad->progressbar);
+      elm_object_text_set(ad->statusbar, "");
+   }
+}
+
 void ui_update_server_list(AppData *ad)
 {
    if (!ad || !ad->server_hoversel) return;
diff --git a/src/ui.h b/src/ui.h
index c1765c0..3575c8b 100644
--- a/src/ui.h
+++ b/src/ui.h
@@ -7,3 +7,5 @@ typedef struct _AppData AppData;
 void ui_create(AppData *ad);
 void ui_update_server_list(AppData *ad);
 void ui_set_load_more_button_visibility(AppData *ad, Eina_Bool visible);
+void ui_loading_start(AppData *ad);
+void ui_loading_stop(AppData *ad);

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.

Reply via email to