Skip to content

Commit

Permalink
Merge pull request #5 from ChengCheng0v0/pre
Browse files Browse the repository at this point in the history
v2.0.2 版本开发完毕
  • Loading branch information
ChengCheng0v0 authored Oct 28, 2024
2 parents 09a0ce7 + d74d73f commit ea07b80
Show file tree
Hide file tree
Showing 12 changed files with 446 additions and 18 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@ node_modules/

*.code-workspace
.vscode/


assets/themes/liora
6 changes: 1 addition & 5 deletions assets/scripts/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
/* global Alpine, getWebsiteConfig, Typed, swal, renderMarkdown */

// 获取网站配置
const config = getWebsiteConfig();
config.init();
/* global config, Alpine, getWebsiteConfig, Typed, swal, renderMarkdown */

// 初始化 Alpine
document.addEventListener("alpine:init", () => {
Expand Down
263 changes: 263 additions & 0 deletions assets/scripts/theme-loader.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,263 @@
/* global config */

var themePath;
var metaData;

class ThemeManager {
constructor() {
this.parse();
}

// 解析主题
parse() {
// 构建主题目录
themePath = window.location.origin + "/assets/themes/" + config.content.theme.theme;
console.log("%c[I]%c " + `Theme Path: ${themePath}`, "background-color: #00896c;", "");

// 使用 XML 获取主题的元数据
try {
const xhr = new XMLHttpRequest();
xhr.open("GET", themePath + "/theme.json", false); // 使用同步请求
xhr.send();

if (xhr.status >= 200 && xhr.status < 300) {
metaData = JSON.parse(xhr.responseText);
} else {
throw new Error("无法获取主题元数据");
}
} catch (error) {
console.error("%c[E]%c " + `获取主题元数据失败: ${error}`, "background-color: #cb1b45;", "");
throw new Error("获取主题元数据失败,无法继续执行操作");
}

console.log("%c[I]%c " + `主题元数据: ${JSON.stringify(metaData)}`, "background-color: #00896c;", "");

// 检查元数据是否合法
if (metaData.id && metaData.name && metaData.version && metaData.files.styles && metaData.files.scripts && metaData.colors) {
// 输出欢迎语
console.group("%c主题解析成功!%c" + `${metaData.name} (${metaData.id})`, "padding: 5px; border-radius: 6px 0 0 6px; background-color: #00896c; color: #ffffff;", "padding: 5px; border-radius: 0 6px 6px 0; background-color: #986db2; color: #ffffff;");
console.log("%cID:%c" + `${metaData.id}`, "padding: 5px; border-radius: 6px 0 0 6px; background-color: #986db2; color: #ffffff;", "padding: 5px; border-radius: 0 6px 6px 0; background-color: #b5495b; color: #ffffff;");
console.log("%cName:%c" + `${metaData.name}`, "padding: 5px; border-radius: 6px 0 0 6px; background-color: #986db2; color: #ffffff;", "padding: 5px; border-radius: 0 6px 6px 0; background-color: #b5495b; color: #ffffff;");
console.log("%cVersion:%c" + `${metaData.version}`, "padding: 5px; border-radius: 6px 0 0 6px; background-color: #986db2; color: #ffffff;", "padding: 5px; border-radius: 0 6px 6px 0; background-color: #b5495b; color: #ffffff;");
console.log("%cRepo:%c" + `${metaData.repo}`, "padding: 5px; border-radius: 6px 0 0 6px; background-color: #010101; color: #ffffff;", "padding: 5px; border-radius: 0 6px 6px 0; background-color: #ff9901; color: #ffffff;");
console.groupEnd();

return metaData;
} else {
console.error("%c[E]%c " + `主题解析失败,元数据存在问题`, "background-color: #cb1b45;", "");
throw new Error("主题解析失败,无法继续执行操作");
}
}

// 加载主题
load() {
// 创建一个数组,用来存放生成的 Style 外部资源链接 HTML
var styleLinks;

// 解析基本样式 URL 并赋值给数组
styleLinks = metaData.files.styles
.map((key) => {
if (key) {
// 创建 <link> 标签
return `<link rel="stylesheet" href="${themePath}/styles/${key}" />`;
}
console.error("%c[E]%c " + `主题 ${key} 样式 Tag 生成失败,元数据可能存在问题`, "background-color: #cb1b45;", "");
throw new Error("主题样式 Tag 生成失败,无法继续执行操作");
})
.filter(Boolean); // 过滤掉无效的值

// 解析配色方案样式 URL 并插入数组
metaData.colors.index
.map((key) => {
let targetColor = localStorage.getItem("theme.color"); // 存储目标配色方案的变量

// 如果目标配色方案为保留关键字“!autoSwitch”(自动切换配色方案),将其改为实际需要加载的配色方案
if (targetColor === "!autoSwitch") {
console.log("%c[I]%c " + `当前配色方案为 !autoSwitch 自动切换,用户的浏览器深色模式启用状态为: ${window.matchMedia("(prefers-color-scheme: dark)").matches}`, "background-color: #00896c;", "");
if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
targetColor = config.content.theme.colors.autoSwitch.dark;
} else {
targetColor = config.content.theme.colors.autoSwitch.light;
}
}

const styles = metaData.colors.list[key].files.styles; // 获取对应的 styles

// 根据目标配色方案决定是否生成标签
if (styles && targetColor === key) {
// 如果 styles 是数组,生成多个 link 标签
return styles.map((file) => `<link rel="stylesheet" href="${themePath}/colors/${key}/styles/${file}" />`).join(""); // 将生成的所有 link 标签拼接成字符串
} else if (localStorage.getItem("theme.color") !== key) {
console.log("%c[I]%c " + `跳过了生成 ${key} 配色方案样式标签的步骤,因为 key 的值不符合用户设置`, "background-color: #00896c;", "");
return;
}
console.error("%c[E]%c " + `配色方案 ${key} 样式 Tag 生成失败,元数据可能存在问题`, "background-color: #cb1b45;", "");
throw new Error("配色方案样式 Tag 生成失败,无法继续执行操作");
})
.filter(Boolean) // 过滤掉无效的值
.forEach((linkTags) => {
styleLinks.push(linkTags); // 将生成的 link 标签插入到数组中
});

console.log("%c[I]%c " + `待插入的 Style 外部资源链接: ${styleLinks}`, "background-color: #00896c;", "");

// 创建一个数组,用来存放生成的 Script 外部资源链接 HTML
var scriptLinks;

// 解析基本脚本 URL 并赋值给数组
scriptLinks = metaData.files.scripts
.map((key) => {
if (key) {
// 创建 <script> 标签
return `<script src="${themePath}/scripts/${key}"></script>`;
}
console.error("%c[E]%c " + `主题 ${key} 脚本 Tag 生成失败,元数据可能存在问题`, "background-color: #cb1b45;", "");
throw new Error("主题脚本 Tag 生成失败,无法继续执行操作");
})
.filter(Boolean); // 过滤掉无效的值

// 解析配色方案脚本 URL 并插入数组
metaData.colors.index
.map((key) => {
let targetColor = localStorage.getItem("theme.color"); // 存储目标配色方案的变量

// 如果目标配色方案为保留关键字“!autoSwitch”(自动切换配色方案),将其改为实际需要加载的配色方案
if (targetColor === "!autoSwitch") {
console.log("%c[I]%c " + `当前配色方案为 !autoSwitch 自动切换,用户的浏览器深色模式启用状态为: ${window.matchMedia("(prefers-color-scheme: dark)").matches}`, "background-color: #00896c;", "");
if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
targetColor = config.content.theme.colors.autoSwitch.dark;
} else {
targetColor = config.content.theme.colors.autoSwitch.light;
}
}

const scripts = metaData.colors.list[key].files.scripts; // 获取对应的 scripts

// 根据目标配色方案决定是否生成标签
if (scripts && targetColor === key) {
// 如果 scripts 是数组,生成多个 script 标签
return scripts.map((file) => `<script src="${themePath}/colors/${key}/scripts/${file}"></script>`).join(""); // 将生成的所有 link 标签拼接成字符串
} else if (localStorage.getItem("theme.color") !== key) {
console.log("%c[I]%c " + `跳过了生成 ${key} 配色方案脚本标签的步骤,因为 key 的值不符合用户设置`, "background-color: #00896c;", "");
return;
}
console.error("%c[E]%c " + `配色方案 ${key} 脚本 Tag 生成失败,元数据可能存在问题`, "background-color: #cb1b45;", "");
throw new Error("配色方案脚本 Tag 生成失败,无法继续执行操作");
})
.filter(Boolean) // 过滤掉无效的值
.forEach((linkTags) => {
scriptLinks.push(linkTags); // 将生成的 link 标签插入到数组中
});

console.log("%c[I]%c " + `待插入的 Script 外部资源链接: ${scriptLinks}`, "background-color: #00896c;", "");

// 拼接 styleLinks 和 scriptLinks
const resTag = [...styleLinks, ...scriptLinks];

// 将生成的外部资源链接插入到 theme 元素中
document.querySelector("theme").innerHTML = resTag.join("");
}

// 设置配色方案
setColor(colorId) {
if (colorId === localStorage.getItem("theme.color")) {
console.warn("%c[W]%c " + `当前配色方案已是 ${colorId},与其白白重载一次,不如我现在就中断更改`, "background-color: #e98b2a;", "");
} else {
// 检查索引中是否存在主题
// 保留关键字 !autoSwitch 可以不需要在索引中存在
if (metaData.colors.index.includes(colorId) || colorId === "!autoSwitch") {
try {
localStorage.setItem("theme.color", colorId);

// 重新加载主题
themeManager.load();

console.log("%c[I]%c " + `配色方案已更改为: ${colorId}`, "background-color: #00896c;", "");
} catch (error) {
console.error("%c[E]%c " + `无法将配色方案更改为 ${colorId}: ${error}`, "background-color: #cb1b45;", "");
throw new Error("配色方案更改失败: ", error);
}
} else {
console.error("%c[E]%c " + `无法将配色方案更改为 ${colorId},因为未在主题配色方案索引中匹配到传入的值`, "background-color: #cb1b45;", "");
throw new Error("配色方案更改失败,未在主题配色方案索引中匹配到传入的值");
}

// 加载配色方案设置的选中效果
loadThemeSelEff();
}
}
}

// 加载配色方案设置的选中效果
function loadThemeSelEff() {
// 如果存在已加载的选中效果则清除它
if (document.querySelector(".theme-item.enable")) {
document.querySelector(".theme-item.enable").setAttribute("class", "theme-item");
}

// 插入新的选中效果类
document.getElementById(`theme-item-${localStorage.getItem("theme.color")}`).setAttribute("class", "theme-item enable");
}

// 创建 ThemeManager 实例
const themeManager = new ThemeManager();

document.addEventListener("DOMContentLoaded", () => {
// 如果第一次访问,将配色方案设置为默认值
if (localStorage.getItem("theme.color") === null) {
themeManager.setColor(config.content.theme.colors.default);
} else {
// 否则正常加载主题
themeManager.load();
}

/* 根据可用配色方案生成设置按钮 */

// 获取 .themes 元素
const themesElement = document.querySelector(".primary-container > .left-area > .cards > .card-item > .content > .settings-item > .themes");

// 创建一个数组,用来存放生成的按钮 HTML
const themeButtons = config.content.theme.colors.enable
.map((key) => {
let displayName;
let icon;
let color;
let background;

if (key === "!autoSwitch") {
console.log("%c[I]%c " + `Website config enabled !autoSwitch`, "background-color: #00896c;", "");

displayName = config.content.theme.colors.autoSwitch.displayName; // 获取对应的 displayName
icon = config.content.theme.colors.autoSwitch.icon.icon; // 获取对应的 icon
color = config.content.theme.colors.autoSwitch.icon.color; // 获取对应的 color
background = config.content.theme.colors.autoSwitch.icon.background; // 获取对应的 background
} else {
displayName = metaData.colors.list[key].displayName; // 获取对应的 displayName
icon = metaData.colors.list[key].icon.icon; // 获取对应的 icon
color = metaData.colors.list[key].icon.color; // 获取对应的 color
background = metaData.colors.list[key].icon.background; // 获取对应的 background
}

if (displayName && icon && color && background) {
// 创建 <div> 标签
return `
<div class="theme-item" id="theme-item-${key}" style="color: ${color}; background: ${background};" @click="themeManager.setColor(\`${key}\`);">
<i class="${icon}"></i>
<span>${displayName}</span>
</div>
`;
} else {
console.error("%c[E]%c " + `配色方案 ${key} 的设置按钮生成失败,主题元数据的配色方案信息 (${displayName}, ${icon}, ${color}, ${background}) 不满足条件,元数据可能存在问题`, "background-color: #cb1b45;", "");
}
return "";
})
.filter(Boolean); // 过滤掉无效的值

// 将生成的按钮插入到 .social-icons 元素中
themesElement.innerHTML = themeButtons.join("");

// 加载配色方案设置的选中效果
loadThemeSelEff();

/* 根据可用配色方案生成设置按钮 End */
});
4 changes: 4 additions & 0 deletions assets/scripts/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ function getWebsiteConfig() {
};
}

// 获取网站配置
const config = getWebsiteConfig();
config.init();

// Markdown 渲染器
function renderMarkdown() {
// 获取页面中的所有 .markdown-content 元素
Expand Down
62 changes: 60 additions & 2 deletions assets/styles/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ body {
.page-head {
display: flex;
justify-content: center;
align-items: center;
/* align-items: center; */ /* [^1] 开这玩意儿实现打字标题居中会导致页面跳动,我也不知道这是为甚么 TAT */
width: 100%;
height: 320px;
background-color: #49b1f5;
Expand All @@ -56,7 +56,7 @@ body {

.page-head > .title,
.page-head > .typed-cursor {
margin-top: 32px;
margin-top: 160px; /* [^1] 所以此处使用上边距实现居中,反正能跑就行( */
font-size: 32px;
font-weight: bold;
color: #ffffff;
Expand Down Expand Up @@ -160,6 +160,64 @@ body {
.primary-container > .left-area > .cards > .card-item#hitokoto > .content a#hitokoto-text {
color: unset;
}

/* - 浏览设置 */
.primary-container > .left-area > .cards > .card-item > .content > .settings-item {
margin-top: 8px;
padding: 6px 10px;
border-radius: 12px;
box-sizing: border-box;
background-color: #c0e5ff;
}

/* 标题 */
.primary-container > .left-area > .cards > .card-item > .content > .settings-item > .title {
display: inline-block;
margin-bottom: 8px;
font-size: 14px;
font-weight: bold;

i {
margin-right: 10px;
}
}

/* - 主题设置 */
.primary-container > .left-area > .cards > .card-item > .content > .settings-item > .themes {
display: flex;
justify-content: center;
gap: 8px;
}

.primary-container > .left-area > .cards > .card-item > .content > .settings-item > .themes > .theme-item {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 100%;
height: 42px;
border-radius: 12px;
font-size: 10px;
font-weight: bold;
box-sizing: border-box;

i {
margin-bottom: 2px;
}
}

.primary-container > .left-area > .cards > .card-item > .content > .settings-item > .themes > .theme-item,
.primary-container > .left-area > .cards > .card-item > .content > .settings-item > .themes > .theme-item * {
cursor: url(https://cdn.jsdelivr.net/gh/honjun/cdn@1.6/img/cursor/ayuda.cur), pointer;
}

.primary-container > .left-area > .cards > .card-item > .content > .settings-item > .themes > .theme-item.enable {
/* border: 2px solid #e87a90; */
box-shadow: 0px 0px 2px 2px #2a92d8;
}
/* - 主题设置 End */
/* - 浏览设置 End */

/* - 左侧卡片 End */

/* - 页脚 */
Expand Down
9 changes: 9 additions & 0 deletions assets/themes/defdark/colors/dark/styles/elements.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/* - 标题 */
h1,
h2,
h3,
h4,
h5,
h6 {
color: #77c6ff;
}
Loading

0 comments on commit ea07b80

Please sign in to comment.