diff --git a/Emby.CustomCssJS/CustomCssJS.js b/Emby.CustomCssJS/CustomCssJS.js new file mode 100644 index 0000000..996c32b --- /dev/null +++ b/Emby.CustomCssJS/CustomCssJS.js @@ -0,0 +1,133 @@ +define([ + "events", + "connectionManager", +], function ( + events, + connectionManager, + ) { + "use strict"; + + return function () { + + function loadCss(name, content, source) { + try { + let s = document.createElement("style"); + s.type = "text/css"; + s.innerHTML = content; + document.head.appendChild(s); + console.warn(`load CustomCss from ${source}: ${name}`); + } catch (e) { + console.error(`load CustomCss from ${source} ${name} error: ${e}`); + } + } + + function loadJS(name, content, source) { + try { + // let s = document.createElement("script"); + // s.type = "text/javascript"; + // s.innerHTML = content; + // document.body.appendChild(s); + new Function(content)(); + console.warn(`load CustomJS from ${source}: ${name}`); + } catch (e) { + console.error(`load CustomJS from ${source} ${name} error: ${e}`); + } + } + + function loadCode(custom, type, source) { + if (type === "css") { + custom.forEach(item => loadCss(item.name, item.content, source)); + } else if (type === "js") { + custom.forEach(item => loadJS(item.name, item.content, source)); + } + } + + function getCustom(type, config) { + // get Config for Server + let serverId = ApiClient.serverId(); + let customServerConfig = localStorage.getItem(`custom${type}ServerConfig_${serverId}`); + if (!customServerConfig) { + customServerConfig = []; + localStorage.setItem(`custom${type}ServerConfig_${serverId}`, JSON.stringify(customServerConfig)); + } else { + customServerConfig = JSON.parse(customServerConfig); + } + // get custom in Server + let customServer = config[`custom${type}`].filter(item => (item.state === "on" && customServerConfig.includes(item.name)) || item.state === "forced_on" ); + + // get Config for Local + let customLocalConfig = localStorage.getItem(`custom${type}LocalConfig`); + if (!customLocalConfig) { + customLocalConfig = []; + localStorage.setItem(`custom${type}LocalConfig`, JSON.stringify(customLocalConfig)); + } else { + customLocalConfig = JSON.parse(customLocalConfig); + } + // get custom in Local + let customLocal = localStorage.getItem(`custom${type}Local`); + if (!customLocal) { + customLocal = []; + localStorage.setItem(`custom${type}Local`, JSON.stringify(customLocal)); + } else { + customLocal = JSON.parse(customLocal).filter(item => customLocalConfig.includes(item.name)); + } + + return [customServer, customLocal]; + } + + function loadConfiguration() { + ApiClient.getJSON(ApiClient.getUrl("CustomCssJS/Scripts", {})).then((config) => { + if (!window.isCustomCssJSLoad) { + window.isCustomCssJSLoad = true; + let [customjsServer, customjsLocal] = getCustom("js", config); + let [customcssServer, customcssLocal] = getCustom("css", config); + loadCode(customcssServer, "css", "Server"); + loadCode(customcssLocal, "css", "Local"); + loadCode(customjsServer, "js", "Server"); + loadCode(customjsLocal, "js", "Local"); + } + }, () => { + if (window.isCustomCssJSLoad) { + reload(); + } + }); + } + + function reload() { + if (typeof MainActivity === "undefined") { + let href = window.location.href; + if (href.match(/autostart=false/i)) { + window.location.href = `index.html?autostart=false`; + } else if (href.match(/autostart=true/i)) { + window.location.href = `index.html?autostart=true`; + } else { + window.location.href = "index.html"; + } + } else { + if (document.getElementById("Carnival")) { + window.location.href = "index.html"; + } else { + MainActivity.exitApp(); + setTimeout(function () { + window.open("emby://items", "_blank") + }, 150); + } + } + } + + function loadCustomCssJS() { + return function () { + let serverId = ApiClient.serverId(); + if (window.serverId && window.serverId !== serverId && window.isCustomCssJSLoad) { + reload(); + } else { + window.serverId = serverId; + loadConfiguration(); + } + } + } + + events.on(connectionManager, "localusersignedin", loadCustomCssJS()); + + } +}); \ No newline at end of file diff --git a/Emby.CustomCssJS/CustomCssJSPluginEntryPoint.cs b/Emby.CustomCssJS/CustomCssJSPluginEntryPoint.cs index 8abdd1b..b28115c 100644 --- a/Emby.CustomCssJS/CustomCssJSPluginEntryPoint.cs +++ b/Emby.CustomCssJS/CustomCssJSPluginEntryPoint.cs @@ -1,32 +1,69 @@ -using MediaBrowser.Common.Configuration; -using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.Library; +using System; +using System.IO; +using MediaBrowser.Controller; using MediaBrowser.Controller.Plugins; -using MediaBrowser.Model.IO; using MediaBrowser.Model.Logging; -using MediaBrowser.Model.Services; -using MediaBrowser.Model.Tasks; namespace Emby.CustomCssJS { public class CustomCssJSPluginEntryPoint : IServerEntryPoint { public static CustomCssJSPluginEntryPoint Instance { get; private set; } - - public CustomCssJSPluginEntryPoint() + private readonly string _uiPath; + private readonly ILogger _logger; + + public CustomCssJSPluginEntryPoint(IServerApplicationPaths p, ILogManager lm) { - + _uiPath = Path.Combine(p.ApplicationResourcesPath, "dashboard-ui"); + _logger = lm.GetLogger("CustomCssJs"); } public void Run() { - + CreateJs(); + Inject(); } - public void Dispose() + /// + /// 检测 modules/CustomCssJS.js 是否存在, 不存在时创建. + /// + private void CreateJs() + { + var jsPath = Path.Combine(_uiPath, "modules", "CustomCssJS.js"); + _logger.Info("CustomCssJS.js path: " + jsPath); + + if (File.Exists(jsPath)) return; + using (var src = GetType().Assembly.GetManifestResourceStream(GetType().Namespace + ".CustomCssJS.js")) + using (var target = new FileStream(jsPath, FileMode.Create, FileAccess.Write)) + { + src?.CopyTo(target); + } + _logger.Info("Create CustomCssJS.js successfully"); + } + + /// + /// 向 app.js 注入加载 CustomCssJS.js 的代码. + /// + private void Inject() { + var jsPath = Path.Combine(_uiPath, "app.js"); + _logger.Info("app.js path: " + jsPath); + + const string search = "Promise.all(list.map(loadPlugin))"; + const string inject = "list.push(\"./modules/CustomCssJS.js\"),"; + + var content = File.ReadAllText(jsPath); + if (content.IndexOf(inject + search, StringComparison.Ordinal) != -1) return; + + var index = content.IndexOf(search, StringComparison.Ordinal); + if (index == -1) return; + content = content.Insert(index, inject); + File.WriteAllText(jsPath, content); + _logger.Info("Inject app.js successfully"); } - + public void Dispose() + { + } } -} +} \ No newline at end of file diff --git a/Emby.CustomCssJS/Emby.CustomCssJS.csproj b/Emby.CustomCssJS/Emby.CustomCssJS.csproj index 616a4be..78e22eb 100644 --- a/Emby.CustomCssJS/Emby.CustomCssJS.csproj +++ b/Emby.CustomCssJS/Emby.CustomCssJS.csproj @@ -22,6 +22,7 @@ + @@ -38,10 +39,12 @@ + + diff --git a/src/Emby.CustomCssJS.dll b/src/Emby.CustomCssJS.dll index 137ee99..7849a81 100644 Binary files a/src/Emby.CustomCssJS.dll and b/src/Emby.CustomCssJS.dll differ