]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
WEBUI: Add theme support (blue,gray,access)
authorJaroslav Kysela <perex@perex.cz>
Sat, 26 Mar 2016 14:10:38 +0000 (15:10 +0100)
committerJaroslav Kysela <perex@perex.cz>
Sat, 26 Mar 2016 14:10:38 +0000 (15:10 +0100)
Makefile.webui
src/access.c
src/access.h
src/config.c
src/config.h
src/webui/comet.c
src/webui/static/app/acleditor.js
src/webui/static/app/config.js
src/webui/static/app/tvheadend.js
src/webui/webui.c

index 5505979d64e893fcaaa7f346aa7877d44cbbeabd..6aeacc29556ab47e9609940c1fab2853ae689bfe 100644 (file)
@@ -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"
index 3e1134fd41c34b99e1c8b19859d2f61534db6a1b..5ccb553c53098d627c9e954629457cd5f1286674 100644 (file)
@@ -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",
index 5bd7dc17de27d4d63d86c0675d7affcb9a757b17..a742232fc4494e307a86810f0f61de4f452a1c9b 100644 (file)
@@ -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_ */
index 8c04dbccdb695774ae39746efb8053a2edd01833..f130d9c74f755bc83afc0ea2288781b774c1eb39 100644 (file)
@@ -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",
index 1df2d7bd9ee1224d832216cb65e2b0c0b1c52002..e841e9867dfa538c651e6181beafda3c75a16cf4 100644 (file)
@@ -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;
index 03a3633f4cc2d96205db9f5bb57ca5df4f9c1bd0..dfd115925f0c2582241a54b6b9445896a5d7f66d 100644 (file)
@@ -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);
index de97e6c807e6c781a53bd1669d4947b57055c6b7..812de3404f0e0bdbe97441d1e4c71d5d36d2b5b0 100644 (file)
@@ -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,' +
index cad57de5e0d3dc679bf661bab122654e34f201a7..8f06c58c48d669277a5a0244c82034a43ccf9fe6 100644 (file)
@@ -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;
index 9cb4db8a4238fef5b106b070fcb19d8cdee761bd..154a7ea8d4d50d29bebaddf0c1e63f8625bd42ab 100644 (file)
@@ -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)
index 5c2d3ed80e5a57a98b8d4ddb5d27569936bbfb20..689f29dbe9df6017c61338347aead9d31b08858e 100644 (file)
@@ -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) {