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.