From: Jaroslav Kysela Date: Sat, 26 Mar 2016 14:10:38 +0000 (+0100) Subject: WEBUI: Add theme support (blue,gray,access) X-Git-Tag: v4.2.1~811 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ccae289acdc4a48d2da874731a76784545faff51;p=thirdparty%2Ftvheadend.git WEBUI: Add theme support (blue,gray,access) --- diff --git a/Makefile.webui b/Makefile.webui index 5505979d6..6aeacc295 100644 --- a/Makefile.webui +++ b/Makefile.webui @@ -47,7 +47,11 @@ endif JAVASCRIPT = JAVASCRIPT2 = JAVASCRIPT_TV = -CSS = +CSS_INIT = +CSS_DONE = +CSS_BLUE = +CSS_GREY = +CSS_ACCESS = CSS_TV = # @@ -61,13 +65,16 @@ JAVASCRIPT += $(EXTJSPATH)/ext-all$(DEBUG).js # CSS # -CSS += $(EXTJSPATH)/resources/css/ext-all-notheme.css -CSS += $(EXTJSPATH)/resources/css/xtheme-blue.css -CSS += $(ROOTPATH)/livegrid/resources/css/ext-ux-livegrid.css -CSS += $(EXTJSPATH)/examples/ux/gridfilters/css/GridFilters.css -CSS += $(EXTJSPATH)/examples/ux/gridfilters/css/RangeMenu.css -CSS += static/xcheckbox/xcheckbox.css -CSS += static/app/ext.css +CSS_INIT += $(EXTJSPATH)/resources/css/ext-all-notheme.css +CSS_DONE += $(ROOTPATH)/livegrid/resources/css/ext-ux-livegrid.css +CSS_DONE += $(EXTJSPATH)/examples/ux/gridfilters/css/GridFilters.css +CSS_DONE += $(EXTJSPATH)/examples/ux/gridfilters/css/RangeMenu.css +CSS_DONE += static/xcheckbox/xcheckbox.css +CSS_DONE += static/app/ext.css + +CSS_BLUE += $(EXTJSPATH)/resources/css/xtheme-blue.css +CSS_GREY += $(EXTJSPATH)/resources/css/xtheme-grey.css +CSS_ACCESS += $(EXTJSPATH)/resources/css/xtheme-access.css # # extjs extensions @@ -147,9 +154,13 @@ JAVASCRIPT_TV += $(ROOTPATH)/tv.js # JAVASCRIPT_SRC = $(foreach f,$(JAVASCRIPT),$(WEBDIR)/$(f)) -CSS_SRC = $(foreach f,$(CSS),$(WEBDIR)/$(f)) +CSS_BLUE_SRC = $(foreach f,$(CSS_INIT) $(CSS_BLUE) $(CSS_DONE),$(WEBDIR)/$(f)) +CSS_GRAY_SRC = $(foreach f,$(CSS_INIT) $(CSS_GRAY) $(CSS_DONE),$(WEBDIR)/$(f)) +CSS_ACCESS_SRC = $(foreach f,$(CSS_INIT) $(CSS_ACCESS) $(CSS_DONE),$(WEBDIR)/$(f)) +CSS_SRC = $(CSS_BLUE_SRC) $(CSS_GRAY_SRC) $(CSS_ACCESS_SRC) + JAVASCRIPT_TV_SRC = $(foreach f,$(JAVASCRIPT_TV),$(WEBDIR)/$(f)) -CSS_TV_SRC = $(foreach f,$(CSS_TV),$(WEBDIR)/$(f)) +CSS_TV_SRC = $(foreach f,$(CSS_TV),$(WEBDIR)/$(f)) # # Internationalization @@ -209,12 +220,14 @@ all: $(MAKE) -f $(IAM) WEBUI=debug compile-debug $(WEBDIR)/extjs-std.c: $(JAVASCRIPT_SRC) $(CSS_SRC) - $(VV)printf 'extjs_lcss(hq, "static/tvh.css.gz");\n' > $@ + $(VV)printf 'extjs_lcss(hq, "redir/theme.css");\n' > $@ $(VV)printf 'extjs_load(hq, "redir/locale.js");\n' >> $@ $(VV)printf 'extjs_load(hq, "static/tvh.js.gz");\n' >> $@ $(WEBDIR)/extjs-debug.c: $(JAVASCRIPT_SRC) $(CSS_SRC) - $(VV)printf '$(foreach f,$(CSS),extjs_lcss(hq, "$(f)");\n)' > $@ + $(VV)printf '$(foreach f,$(CSS_INIT),extjs_lcss(hq, "$(f)");\n)' > $@ + $(VV)printf 'extjs_lcss(hq, "redir/theme.debug.css");\n' >> $@ + $(VV)printf '$(foreach f,$(CSS_DONE),extjs_lcss(hq, "$(f)");\n)' >> $@ $(VV)printf 'extjs_load(hq, "redir/locale.js");\n' >> $@ $(VV)printf '$(foreach f,$(JAVASCRIPT),extjs_load(hq, "$(f)");\n)' >> $@ @@ -231,7 +244,13 @@ $(WEBDIR)/extjs-tv-debug.c: $(JAVASCRIPT_TV_SRC) $(CSS_TV_SRC) $(WEBDIR)/$(ROOTPATH)/tvh.js.gz: $(JAVASCRIPT_SRC) $(call GO_JS) -$(WEBDIR)/$(ROOTPATH)/tvh.css.gz: $(CSS_SRC) +$(WEBDIR)/$(ROOTPATH)/tvh.blue.css.gz: $(CSS_BLUE_SRC) + $(call GO_CSS) + +$(WEBDIR)/$(ROOTPATH)/tvh.gray.css.gz: $(CSS_GRAY_SRC) + $(call GO_CSS) + +$(WEBDIR)/$(ROOTPATH)/tvh.access.css.gz: $(CSS_ACCESS_SRC) $(call GO_CSS) $(WEBDIR)/$(ROOTPATH)/tvh-tv.js.gz: $(JAVASCRIPT_TV_SRC) @@ -241,7 +260,8 @@ $(WEBDIR)/$(ROOTPATH)/tvh-tv.css.gz: $(CSS_TV_SRC) $(call GO_CSS) .PHONY: compile-std -compile-std: $(WEBDIR)/$(ROOTPATH)/tvh.js.gz $(WEBDIR)/$(ROOTPATH)/tvh.css.gz \ +compile-std: $(WEBDIR)/$(ROOTPATH)/tvh.js.gz $(WEBDIR)/$(ROOTPATH)/tvh.blue.css.gz \ + $(WEBDIR)/$(ROOTPATH)/tvh.gray.css.gz $(WEBDIR)/$(ROOTPATH)/tvh.access.css.gz \ $(WEBDIR)/$(ROOTPATH)/tvh-tv.js.gz $(WEBDIR)/$(ROOTPATH)/tvh-tv.css.gz \ $(WEBDIR)/extjs-std.c $(WEBDIR)/extjs-tv-std.c $(JSI-FILES) @echo "WEBUI std finished" diff --git a/src/access.c b/src/access.c index 3e1134fd4..5ccb553c5 100644 --- a/src/access.c +++ b/src/access.c @@ -209,6 +209,8 @@ access_copy(access_t *src) dst->aa_lang = strdup(src->aa_lang); if (src->aa_lang_ui) dst->aa_lang_ui = strdup(src->aa_lang_ui); + if (src->aa_theme) + dst->aa_theme = strdup(src->aa_theme); if (src->aa_profiles) dst->aa_profiles = htsmsg_copy(src->aa_profiles); if (src->aa_dvrcfgs) @@ -241,6 +243,20 @@ access_get_lang(access_t *a, const char *lang) } } +/** + * + */ +const char * +access_get_theme(access_t *a) +{ + if (a->aa_theme == NULL || a->aa_theme[0] == '\0') { + if (config.theme_ui == NULL || config.theme_ui[0] == '\0') + return "blue"; + return config.theme_ui; + } + return a->aa_theme; +} + /** * */ @@ -253,6 +269,7 @@ access_destroy(access_t *a) free(a->aa_representative); free(a->aa_lang); free(a->aa_lang_ui); + free(a->aa_theme); htsmsg_destroy(a->aa_profiles); htsmsg_destroy(a->aa_dvrcfgs); htsmsg_destroy(a->aa_chtags); @@ -600,6 +617,9 @@ access_update(access_t *a, access_entry_t *ae) a->aa_lang_ui = lang_code_user(s); } + if ((!a->aa_theme || a->aa_theme[0] == '\0') && ae->ae_theme && ae->ae_theme[0]) + a->aa_theme = strdup(a->aa_theme); + a->aa_rights |= ae->ae_rights; } @@ -1402,6 +1422,17 @@ uilevel_nochange_get_list ( void *o, const char *lang ) return strtab2htsmsg(tab, 1, lang); } +htsmsg_t * +theme_get_ui_list ( void *p, const char *lang ) +{ + static struct strtab_str tab[] = { + { N_("Blue"), "blue" }, + { N_("Gray"), "gray" }, + { N_("Access"), "access" }, + }; + return strtab2htsmsg_str(tab, 1, lang); +} + const idclass_t access_entry_class = { .ic_class = "access", .ic_caption = N_("Access"), @@ -1474,11 +1505,19 @@ const idclass_t access_entry_class = { .type = PT_STR, .id = "langui", .name = N_("Web interface language"), - .desc = N_("Default web interface language."), + .desc = N_("Web interface language."), .list = language_get_ui_list, .off = offsetof(access_entry_t, ae_lang_ui), .opts = PO_ADVANCED, }, + { + .type = PT_STR, + .id = "themeui", + .name = N_("Web theme"), + .desc = N_("Web interface theme."), + .list = theme_get_ui_list, + .off = offsetof(access_entry_t, ae_theme), + }, { .type = PT_BOOL, .id = "streaming", diff --git a/src/access.h b/src/access.h index 5bd7dc17d..a742232fc 100644 --- a/src/access.h +++ b/src/access.h @@ -98,6 +98,7 @@ typedef struct access_entry { char *ae_comment; char *ae_lang; char *ae_lang_ui; + char *ae_theme; int ae_index; int ae_wizard; @@ -159,6 +160,7 @@ typedef struct access { uint32_t aa_conn_dvr; int aa_uilevel; int aa_uilevel_nochange; + char *aa_theme; } access_t; TAILQ_HEAD(access_ticket_queue, access_ticket); @@ -225,6 +227,12 @@ access_t *access_copy(access_t *src); char * access_get_lang(access_t *a, const char *lang); +/** + * + */ +const char * +access_get_theme(access_t *a); + /** * Verifies that the given user in combination with the source ip * complies with the requested mask @@ -313,6 +321,7 @@ void access_done(void); */ htsmsg_t *language_get_list ( void *obj, const char *lang ); htsmsg_t *language_get_ui_list ( void *obj, const char *lang ); +htsmsg_t *theme_get_ui_list ( void *obj, const char *lang ); htsmsg_t *user_get_userlist ( void *obj, const char *lang ); #endif /* ACCESS_H_ */ diff --git a/src/config.c b/src/config.c index 8c04dbccd..f130d9c74 100644 --- a/src/config.c +++ b/src/config.c @@ -1637,6 +1637,7 @@ config_boot ( const char *path, gid_t gid, uid_t uid ) config.descrambler_buffer = 9000; config.epg_compress = 1; config_scanfile_ok = 0; + config.theme_ui = strdup("blue"); /* Generate default */ if (!path) { @@ -1747,6 +1748,7 @@ void config_done ( void ) free(config.server_name); free(config.language); free(config.language_ui); + free(config.theme_ui); free(config.info_area); free(config.muxconf_path); free(config.chicon_path); @@ -2164,6 +2166,16 @@ const idclass_t config_class = { .off = offsetof(config_t, language_ui), .group = 3 }, + { + .type = PT_STR, + .id = "theme_ui", + .name = N_("Theme"), + .desc = N_("The default theme for web interface to use if the user " + " theme isn't set in the Access Entries tab."), + .list = theme_get_ui_list, + .off = offsetof(config_t, theme_ui), + .group = 3 + }, { .type = PT_STR, .id = "muxconfpath", diff --git a/src/config.h b/src/config.h index 1df2d7bd9..e841e9867 100644 --- a/src/config.h +++ b/src/config.h @@ -39,6 +39,7 @@ typedef struct config { char *language; char *info_area; char *language_ui; + char *theme_ui; char *muxconf_path; int prefer_picon; char *chicon_path; diff --git a/src/webui/comet.c b/src/webui/comet.c index 03a3633f4..dfd115925 100644 --- a/src/webui/comet.c +++ b/src/webui/comet.c @@ -169,6 +169,7 @@ comet_access_update(http_connection_t *hc, comet_mailbox_t *cmb) if (config.uilevel_nochange) htsmsg_add_u32(m, "uilevel_nochange", config.uilevel_nochange); } + htsmsg_add_str(m, "theme", access_get_theme(hc->hc_access)); htsmsg_add_u32(m, "quicktips", config.ui_quicktips); if (!access_noacl) htsmsg_add_str(m, "username", username); diff --git a/src/webui/static/app/acleditor.js b/src/webui/static/app/acleditor.js index de97e6c80..812de3404 100644 --- a/src/webui/static/app/acleditor.js +++ b/src/webui/static/app/acleditor.js @@ -13,7 +13,7 @@ tvheadend.acleditor = function(panel, index) 'channel_tag_exclude,channel_tag,comment'; var list2 = 'enabled,username,password,prefix,' + - 'lang,webui,langui,uilevel,uilevel_nochange,admin,' + + 'lang,webui,themeui,langui,uilevel,uilevel_nochange,admin,' + 'streaming,adv_streaming,htsp_streaming,' + 'profile,conn_limit_type,conn_limit,' + 'dvr,htsp_dvr,all_dvr,all_rw_dvr,' + diff --git a/src/webui/static/app/config.js b/src/webui/static/app/config.js index cad57de5e..8f06c58c4 100644 --- a/src/webui/static/app/config.js +++ b/src/webui/static/app/config.js @@ -41,6 +41,9 @@ tvheadend.baseconf = function(panel, index) { if (l !== tvheadend.uilevel) reload = 1; } + var n = data['theme']; + if (n !== tvheadend.theme) + reload = 1; var n = data['uilevel_nochange'] ? true : false; if (n !== tvheadend.uilevel_nochange) reload = 1; diff --git a/src/webui/static/app/tvheadend.js b/src/webui/static/app/tvheadend.js index 9cb4db8a4..154a7ea8d 100644 --- a/src/webui/static/app/tvheadend.js +++ b/src/webui/static/app/tvheadend.js @@ -442,6 +442,9 @@ function accessUpdate(o) { if (o.uilevel) tvheadend.uilevel = o.uilevel; + if (o.theme) + tvheadend.theme = o.theme; + tvheadend.quicktips = o.quicktips ? true : false; if (o.uilevel_nochange) diff --git a/src/webui/webui.c b/src/webui/webui.c index 5c2d3ed80..689f29dbe 100644 --- a/src/webui/webui.c +++ b/src/webui/webui.c @@ -1759,7 +1759,7 @@ static int http_file_test(const char *path) static int http_redir(http_connection_t *hc, const char *remain, void *opaque) { - const char *lang; + const char *lang, *theme; char *components[3]; char buf[256]; int nc; @@ -1788,6 +1788,30 @@ http_redir(http_connection_t *hc, const char *remain, void *opaque) pthread_mutex_unlock(&hc->hc_fd_lock); return 0; } + if (!strcmp(components[0], "theme.css")) { + theme = access_get_theme(hc->hc_access); + if (theme) { + snprintf(buf, sizeof(buf), "src/webui/static/tvh.%s.css.gz", theme); + if (!http_file_test(buf)) { + snprintf(buf, sizeof(buf), "/static/tvh.%s.css.gz", theme); + http_redirect(hc, buf, NULL, 0); + return 0; + } + } + return 0; + } + if (!strcmp(components[0], "theme.debug.css")) { + theme = access_get_theme(hc->hc_access); + if (theme) { + snprintf(buf, sizeof(buf), "src/webui/static/extjs/resources/css/xtheme-%s.css", theme); + if (!http_file_test(buf)) { + snprintf(buf, sizeof(buf), "/static/extjs/resources/css/xtheme-%s.css", theme); + http_redirect(hc, buf, NULL, 0); + return 0; + } + } + return 0; + } } if (nc >= 2) {