diff --git a/src/css/lang/zh-Hant/setting/index.css b/src/css/lang/zh-Hant/setting/index.css index 239a64b..94c7940 100644 --- a/src/css/lang/zh-Hant/setting/index.css +++ b/src/css/lang/zh-Hant/setting/index.css @@ -12,3 +12,147 @@ body { --background-hsl: 0deg 0% 13%; --background-variant-hsl: 0deg 0% 16%; } + +.wave-container { + display: block !important; + position: relative; + overflow: hidden; +} + +.wave-unverified::after { + content: ""; + position: absolute; + top: 0; + left: -100%; + width: 200%; + height: 100%; + background: repeating-linear-gradient( + 90deg, + transparent 0%, + transparent 35%, + rgba(255, 0, 0, 0.2) 50%, + transparent 65%, + transparent 100% + ); + animation: slide 2s linear infinite, fadeIn 0.5s ease-in; + pointer-events: none; +} + +.wave-unloaded::after { + content: ""; + position: absolute; + top: 0; + left: -100%; + width: 200%; + height: 100%; + background: repeating-linear-gradient( + 90deg, + transparent 0%, + transparent 35%, + rgba(255, 215, 0, 0.2) 50%, + transparent 65%, + transparent 100% + ); + animation: slide 2s linear infinite, fadeIn 0.5s ease-in; + pointer-events: none; +} + +@keyframes slide { + 0% { + transform: translateX(0); + } + 100% { + transform: translateX(100%); + } +} + +.switch { + position: relative; + display: inline-block; +} + +.switch input { + opacity: 0; + width: 0; + height: 0; +} + +.slider { + position: absolute; + cursor: pointer; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: #ccc; + transition: 0.4s ease-in-out; +} + +.slider:before { + position: absolute; + content: ""; + height: 18px; + width: 18px; + left: 3px; + bottom: 3px; + background-color: white; + transition: 0.4s ease-in-out; +} + +.slider.round { + border-radius: 24px; +} + +.slider.round:before { + border-radius: 50%; +} + +input:checked + .slider:before { + transform: translateX(26px); +} + +input:checked + .slider { + background-color: #2196f3; +} + +input[data-verified="false"]:checked + .slider { + background-color: #ff4444; +} + +input[data-loaded="false"]:checked + .slider { + background-color: #ffd700; +} + +@keyframes slide { + 0% { + transform: translateX(0); + } + 100% { + transform: translateX(66.66%); + } +} + +.unverified-badge, +.unloaded-badge, +.loaded-badge { + display: inline-block; + padding: 2px 6px; + border-radius: 4px; + font-size: 12px; + margin-left: 8px; +} + +.unverified-badge { + background-color: #ff4444; + color: white; +} + +.loaded-badge { + background-color: #4caf50; + color: white; +} + +.unloaded-badge { + background-color: #ffd700; + color: black; +} diff --git a/src/js/setting/plugin_list.js b/src/js/setting/plugin_list.js index c8a0e34..b3bef1e 100644 --- a/src/js/setting/plugin_list.js +++ b/src/js/setting/plugin_list.js @@ -1,10 +1,10 @@ -const { ipcRenderer } = require('electron'); +const manager = require('../core/manager'); class PluginList { constructor() { - this.pluginManagerStore = require('../core/manager'); this.enablePluginList = JSON.parse(localStorage.getItem('enabled-plugins')) || []; this.pluginList = JSON.parse(localStorage.getItem('plugin-list')) || []; + this.loadedPlugins = JSON.parse(localStorage.getItem('loaded-plugins')) || []; this.extendedInfo = document.querySelector('.extended-info'); this.extendedConfirmWrapper = document.querySelector('.confirm-wrapper'); this.ConfirmSure = this.extendedConfirmWrapper.querySelector('.confirm-sure'); @@ -31,6 +31,13 @@ class PluginList { }); } + getPluginLoadStatus(pluginName) { + if (Array.isArray(this.loadedPlugins)) { + return this.loadedPlugins.map((_) => _.name).includes(pluginName); + } + return this.loadedPlugins[pluginName] !== undefined; + } + renderElements() { if (!this.pluginList.length) { return; @@ -40,32 +47,52 @@ class PluginList { return; } const isEnabled = this.enablePluginList.includes(item.name); + const isLoaded = this.getPluginLoadStatus(item.name); + + const waveClassName = isEnabled + ? (!isLoaded + ? 'wave-unloaded' + : !item.verified + ? 'wave-unverified' + : '') + : ''; + return ` -