diff options
| -rw-r--r-- | src/Main.c | 1 | ||||
| -rw-r--r-- | src/Routes/Home.c | 5 | ||||
| -rw-r--r-- | src/Routes/Images.c | 17 | ||||
| -rw-r--r-- | src/Routes/Settings.c | 32 | ||||
| -rw-r--r-- | src/Utility/Utility.c | 116 | ||||
| -rw-r--r-- | src/Utility/Utility.h | 7 | ||||
| -rw-r--r-- | static/main.css | 23 | ||||
| -rw-r--r-- | static/themes/dark.css (renamed from static/theme-dark.css) | 0 | ||||
| -rw-r--r-- | static/themes/light.css (renamed from static/theme-light.css) | 0 | ||||
| -rw-r--r-- | static/themes/system.css | 22 | ||||
| -rw-r--r-- | templates/home.html | 3 | ||||
| -rw-r--r-- | templates/images.html | 3 | ||||
| -rw-r--r-- | templates/results.html | 3 | ||||
| -rw-r--r-- | templates/settings.html | 9 |
14 files changed, 176 insertions, 65 deletions
@@ -88,6 +88,7 @@ int main() { } set_default_locale(cfg.default_locale); + init_themes("static"); global_config = cfg; diff --git a/src/Routes/Home.c b/src/Routes/Home.c index 0534517..bf85fe1 100644 --- a/src/Routes/Home.c +++ b/src/Routes/Home.c @@ -2,12 +2,17 @@ #include "../Utility/Utility.h" #include <beaker.h> #include <stdlib.h> +#include <string.h> int home_handler(UrlParams *params) { (void)params; char *theme = get_theme(""); char *locale = get_locale(NULL); + char **themes = NULL; + int themes_count = 0; + get_available_themes(&themes, &themes_count); + TemplateContext ctx = new_context(); context_set(&ctx, "theme", theme); context_set(&ctx, "version", VERSION); diff --git a/src/Routes/Images.c b/src/Routes/Images.c index dda329c..40ab88f 100644 --- a/src/Routes/Images.c +++ b/src/Routes/Images.c @@ -6,6 +6,8 @@ #include "../Utility/Utility.h" #include "Config.h" #include <beaker.h> +#include <stdlib.h> +#include <string.h> static char *build_images_request_cache_key(const char *query, int page, const char *client_key) { @@ -67,15 +69,18 @@ int images_handler(UrlParams *params) { beaker_set_locale(&ctx, locale); const char *rate_limit_msg = beaker_get_locale_value(locale, "rate_limit"); - if (!rate_limit_msg) rate_limit_msg = "Slow down! Too many image searches from you!"; - const char *error_images_msg = beaker_get_locale_value(locale, "error_images"); - if (!error_images_msg) error_images_msg = "Error fetching images"; + if (!rate_limit_msg) + rate_limit_msg = "Slow down! Too many image searches from you!"; + const char *error_images_msg = + beaker_get_locale_value(locale, "error_images"); + if (!error_images_msg) + error_images_msg = "Error fetching images"; char ***pager_matrix = NULL; int *pager_inner_counts = NULL; - int pager_count = build_pagination(page, images_href_builder, - (void *)raw_query, &pager_matrix, - &pager_inner_counts); + int pager_count = + build_pagination(page, images_href_builder, (void *)raw_query, + &pager_matrix, &pager_inner_counts); if (pager_count > 0) { context_set_array_of_arrays(&ctx, "pagination_links", pager_matrix, pager_count, pager_inner_counts); diff --git a/src/Routes/Settings.c b/src/Routes/Settings.c index b21dd6f..eb3072b 100644 --- a/src/Routes/Settings.c +++ b/src/Routes/Settings.c @@ -32,7 +32,8 @@ int settings_handler(UrlParams *params) { char **user_engines = NULL; int user_engine_count = 0; - int has_user_pref = (get_user_engines(&user_engines, &user_engine_count) == 0); + int has_user_pref = + (get_user_engines(&user_engines, &user_engine_count) == 0); int enabled_count = 0; for (int i = 0; i < ENGINE_COUNT; i++) { @@ -77,7 +78,34 @@ int settings_handler(UrlParams *params) { context_set(&ctx, "query", query); context_set(&ctx, "theme", theme); context_set(&ctx, "locale", locale); - context_set_array_of_arrays(&ctx, "locales", locale_data, locale_count, inner_counts); + context_set_array_of_arrays(&ctx, "locales", locale_data, locale_count, + inner_counts); + + char **themes = NULL; + int themes_count = 0; + get_available_themes(&themes, &themes_count); + + if (themes_count > 0) { + char ***theme_ptrs = malloc(sizeof(char **) * themes_count); + int *theme_inner = malloc(sizeof(int) * themes_count); + for (int i = 0; i < themes_count; i++) { + theme_ptrs[i] = malloc(sizeof(char *) * 2); + theme_ptrs[i][0] = themes[i]; + theme_ptrs[i][1] = strdup(themes[i]); + if (theme_ptrs[i][1][0] >= 'a' && theme_ptrs[i][1][0] <= 'z') { + theme_ptrs[i][1][0] = theme_ptrs[i][1][0] - 'a' + 'A'; + } + theme_inner[i] = 2; + } + context_set_array_of_arrays(&ctx, "themes", theme_ptrs, themes_count, + theme_inner); + for (int i = 0; i < themes_count; i++) { + free(theme_ptrs[i][1]); + free(theme_ptrs[i]); + } + free(theme_ptrs); + free(theme_inner); + } if (enabled_count > 0) { context_set_array_of_arrays(&ctx, "enabled_engines", engine_data, diff --git a/src/Utility/Utility.c b/src/Utility/Utility.c index 8bcb748..1428722 100644 --- a/src/Utility/Utility.c +++ b/src/Utility/Utility.c @@ -1,11 +1,80 @@ #include "Utility.h" #include "../Scraping/Scraping.h" #include <beaker.h> +#include <dirent.h> #include <stdio.h> #include <stdlib.h> #include <string.h> static char global_default_locale[32] = "en_gb"; +static char **themes_list = NULL; +static int themes_count = 0; +static int themes_initialized = 0; + +void init_themes(const char *static_path) { + if (themes_initialized) + return; + themes_initialized = 1; + + char themes_dir[512]; + snprintf(themes_dir, sizeof(themes_dir), "%s/themes", static_path); + + DIR *dir = opendir(themes_dir); + if (!dir) + return; + + struct dirent *entry; + int capacity = 4; + themes_list = malloc(sizeof(char *) * capacity); + themes_count = 0; + + while ((entry = readdir(dir)) != NULL) { + size_t len = strlen(entry->d_name); + if (len > 4 && strcmp(entry->d_name + len - 4, ".css") == 0) { + if (themes_count >= capacity) { + capacity *= 2; + themes_list = realloc(themes_list, sizeof(char *) * capacity); + } + themes_list[themes_count] = strndup(entry->d_name, len - 4); + themes_count++; + } + } + closedir(dir); + + for (int i = 0; i < themes_count; i++) { + for (int j = i + 1; j < themes_count; j++) { + int priority_i = 0, priority_j = 0; + if (strcmp(themes_list[i], "system") == 0) + priority_i = 0; + else if (strcmp(themes_list[i], "light") == 0) + priority_i = 1; + else if (strcmp(themes_list[i], "dark") == 0) + priority_i = 2; + else + priority_i = 3; + if (strcmp(themes_list[j], "system") == 0) + priority_j = 0; + else if (strcmp(themes_list[j], "light") == 0) + priority_j = 1; + else if (strcmp(themes_list[j], "dark") == 0) + priority_j = 2; + else + priority_j = 3; + if (priority_i > priority_j || + (priority_i == priority_j && + strcmp(themes_list[i], themes_list[j]) > 0)) { + char *tmp = themes_list[i]; + themes_list[i] = themes_list[j]; + themes_list[j] = tmp; + } + } + } +} + +void get_available_themes(char ***out_themes, int *out_count) { + *out_themes = themes_list; + *out_count = themes_count; +} void set_default_locale(const char *locale) { if (locale && strlen(locale) > 0) { @@ -26,13 +95,16 @@ int hex_to_int(char c) { char *get_theme(const char *default_theme) { char *cookie = get_cookie("theme"); - if (cookie && - (strcmp(cookie, "light") == 0 || - strcmp(cookie, "dark") == 0)) { - return cookie; + if (cookie && strlen(cookie) > 0) { + for (int i = 0; i < themes_count; i++) { + if (strcmp(cookie, themes_list[i]) == 0) { + return cookie; + } + } } free(cookie); - return strdup(default_theme); + return strdup(default_theme && strlen(default_theme) > 0 ? default_theme + : "system"); } char *get_locale(const char *default_locale) { @@ -41,7 +113,8 @@ char *get_locale(const char *default_locale) { return cookie; } free(cookie); - const char *fallback = default_locale ? default_locale : global_default_locale; + const char *fallback = + default_locale ? default_locale : global_default_locale; return strdup(fallback); } @@ -49,9 +122,12 @@ static int engine_id_casecmp(const char *a, const char *b) { while (*a && *b) { char la = *a; char lb = *b; - if (la >= 'A' && la <= 'Z') la = la - 'A' + 'a'; - if (lb >= 'A' && lb <= 'Z') lb = lb - 'A' + 'a'; - if (la != lb) return 0; + if (la >= 'A' && la <= 'Z') + la = la - 'A' + 'a'; + if (lb >= 'A' && lb <= 'Z') + lb = lb - 'A' + 'a'; + if (la != lb) + return 0; a++; b++; } @@ -59,7 +135,8 @@ static int engine_id_casecmp(const char *a, const char *b) { } int is_engine_id_enabled(const char *engine_id) { - if (!engine_id) return 0; + if (!engine_id) + return 0; for (int i = 0; i < ENGINE_COUNT; i++) { if (ENGINE_REGISTRY[i].enabled && engine_id_casecmp(ENGINE_REGISTRY[i].id, engine_id)) { @@ -120,7 +197,8 @@ int get_user_engines(char ***out_ids, int *out_count) { } int user_engines_contains(const char *engine_id, char **ids, int count) { - if (!engine_id || !ids) return 0; + if (!engine_id || !ids) + return 0; for (int i = 0; i < count; i++) { if (engine_id_casecmp(ids[i], engine_id)) return 1; @@ -135,8 +213,7 @@ int add_link_to_collection(const char *href, const char *label, int *old_inner_counts = *inner_counts; char ***new_collection = (char ***)malloc(sizeof(char **) * (current_count + 1)); - int *new_inner_counts = - (int *)malloc(sizeof(int) * (current_count + 1)); + int *new_inner_counts = (int *)malloc(sizeof(int) * (current_count + 1)); if (!new_collection || !new_inner_counts) { free(new_collection); @@ -188,9 +265,8 @@ int add_link_to_collection(const char *href, const char *label, return current_count + 1; } -int build_pagination(int page, - char *(*href_builder)(int page, void *data), void *data, - char ****out_matrix, int **out_inner_counts) { +int build_pagination(int page, char *(*href_builder)(int page, void *data), + void *data, char ****out_matrix, int **out_inner_counts) { enum { PAGER_WINDOW_SIZE = 5 }; *out_matrix = NULL; @@ -202,8 +278,8 @@ int build_pagination(int page, if (page > 1) { char *href = href_builder(page - 1, data); - count = add_link_to_collection(href, "←", "pagination-btn prev", - out_matrix, out_inner_counts, count); + count = add_link_to_collection(href, "←", "pagination-btn prev", out_matrix, + out_inner_counts, count); free(href); } @@ -219,8 +295,8 @@ int build_pagination(int page, } char *href = href_builder(page + 1, data); - count = add_link_to_collection(href, "→", "pagination-btn next", - out_matrix, out_inner_counts, count); + count = add_link_to_collection(href, "→", "pagination-btn next", out_matrix, + out_inner_counts, count); free(href); return count; diff --git a/src/Utility/Utility.h b/src/Utility/Utility.h index bd48295..1e1de09 100644 --- a/src/Utility/Utility.h +++ b/src/Utility/Utility.h @@ -15,6 +15,8 @@ int hex_to_int(char c); char *get_theme(const char *default_theme); +void init_themes(const char *static_path); +void get_available_themes(char ***out_themes, int *out_count); void set_default_locale(const char *locale); char *get_locale(const char *default_locale); @@ -26,8 +28,7 @@ int add_link_to_collection(const char *href, const char *label, const char *class_name, char ****collection, int **inner_counts, int current_count); -int build_pagination(int page, - char *(*href_builder)(int page, void *data), void *data, - char ****out_matrix, int **out_inner_counts); +int build_pagination(int page, char *(*href_builder)(int page, void *data), + void *data, char ****out_matrix, int **out_inner_counts); #endif diff --git a/static/main.css b/static/main.css index d07ecfa..4039888 100644 --- a/static/main.css +++ b/static/main.css @@ -1,26 +1,3 @@ -:root { - --bg-main: #ffffff; - --bg-card: #f8f9fa; - --border: #e0e0e0; - --text-primary: #1a1a1a; - --text-secondary: #5f6368; - --text-muted: #757575; - --accent: #202124; - --accent-glow: rgba(0,0,0,0.05); -} -@media (prefers-color-scheme: dark) { - :root { - --bg-main: #121212; - --bg-card: #1e1e1e; - --border: #333333; - --text-primary: #ffffff; - --text-secondary: #a0a0a0; - --text-muted: #d1d1d1; - --accent: #e2e2e2; - --accent-glow: rgba(255,255,255,0.1); - } -} - *, *::before, *::after { box-sizing: border-box; font-family: sans-serif; diff --git a/static/theme-dark.css b/static/themes/dark.css index 246aabe..246aabe 100644 --- a/static/theme-dark.css +++ b/static/themes/dark.css diff --git a/static/theme-light.css b/static/themes/light.css index 1c69377..1c69377 100644 --- a/static/theme-light.css +++ b/static/themes/light.css diff --git a/static/themes/system.css b/static/themes/system.css new file mode 100644 index 0000000..f9c52cf --- /dev/null +++ b/static/themes/system.css @@ -0,0 +1,22 @@ +:root { + --bg-main: #ffffff; + --bg-card: #f8f9fa; + --border: #e0e0e0; + --text-primary: #1a1a1a; + --text-secondary: #5f6368; + --text-muted: #757575; + --accent: #202124; + --accent-glow: rgba(0,0,0,0.05); +} +@media (prefers-color-scheme: dark) { + :root { + --bg-main: #121212; + --bg-card: #1e1e1e; + --border: #333333; + --text-primary: #ffffff; + --text-secondary: #a0a0a0; + --text-muted: #d1d1d1; + --accent: #e2e2e2; + --accent-glow: rgba(255,255,255,0.1); + } +}
\ No newline at end of file diff --git a/templates/home.html b/templates/home.html index 65280cf..9c546ca 100644 --- a/templates/home.html +++ b/templates/home.html @@ -8,8 +8,7 @@ OmniSearch </title> <link rel="stylesheet" href="static/main.css"> - {{if theme == "light"}}<link rel="preload" href="static/theme-light.css" as="style"><link rel="stylesheet" href="static/theme-light.css">{{endif}} - {{if theme == "dark"}}<link rel="preload" href="static/theme-dark.css" as="style"><link rel="stylesheet" href="static/theme-dark.css">{{endif}} + <link rel="stylesheet" href="static/themes/{{theme}}.css"> <link rel="icon" type="image/x-icon" href="/static/favicon.ico"> <link rel="search" type="application/opensearchdescription+xml" diff --git a/templates/images.html b/templates/images.html index d7397b5..4674bee 100644 --- a/templates/images.html +++ b/templates/images.html @@ -9,8 +9,7 @@ </title> <link rel="icon" type="image/x-icon" href="/static/favicon.ico"> <link rel="stylesheet" href="static/main.css"> - {{if theme == "light"}}<link rel="preload" href="static/theme-light.css" as="style"><link rel="stylesheet" href="static/theme-light.css">{{endif}} - {{if theme == "dark"}}<link rel="preload" href="static/theme-dark.css" as="style"><link rel="stylesheet" href="static/theme-dark.css">{{endif}} + <link rel="stylesheet" href="static/themes/{{theme}}.css"> </head> <body class="images-view"> diff --git a/templates/results.html b/templates/results.html index f97a096..bea337f 100644 --- a/templates/results.html +++ b/templates/results.html @@ -8,8 +8,7 @@ OmniSearch - {{query}} </title> <link rel="stylesheet" href="static/main.css"> - {{if theme == "light"}}<link rel="preload" href="static/theme-light.css" as="style"><link rel="stylesheet" href="static/theme-light.css">{{endif}} - {{if theme == "dark"}}<link rel="preload" href="static/theme-dark.css" as="style"><link rel="stylesheet" href="static/theme-dark.css">{{endif}} + <link rel="stylesheet" href="static/themes/{{theme}}.css"> <link rel="icon" type="image/x-icon" href="/static/favicon.ico"> <link rel="search" type="application/opensearchdescription+xml" diff --git a/templates/settings.html b/templates/settings.html index d353d24..2f4ecb6 100644 --- a/templates/settings.html +++ b/templates/settings.html @@ -8,8 +8,7 @@ OmniSearch - {{l("settings_title")}} </title> <link rel="stylesheet" href="static/main.css"> - {{if theme == "light"}}<link rel="preload" href="static/theme-light.css" as="style"><link rel="stylesheet" href="static/theme-light.css">{{endif}} - {{if theme == "dark"}}<link rel="preload" href="static/theme-dark.css" as="style"><link rel="stylesheet" href="static/theme-dark.css">{{endif}} + <link rel="stylesheet" href="static/themes/{{theme}}.css"> <link rel="icon" type="image/x-icon" href="/static/favicon.ico"> <link rel="search" type="application/opensearchdescription+xml" @@ -58,9 +57,9 @@ <div class="settings-field"> <label class="settings-label" for="theme">{{l("theme_label")}}</label> <select id="theme" name="theme" class="settings-select"> - <option value="system" {{if theme == "system"}}selected{{endif}}>{{l("theme_system")}}</option> - <option value="light" {{if theme == "light"}}selected{{endif}}>{{l("theme_light")}}</option> - <option value="dark" {{if theme == "dark"}}selected{{endif}}>{{l("theme_dark")}}</option> + {{for t in themes}} + <option value="{{t[0]}}" {{if theme == t[0]}}selected{{endif}}>{{t[1]}}</option> + {{endfor}} </select> </div> </section> |
