This commit is contained in:
杜恒 2021-01-19 15:41:08 +08:00
commit 23bdf836b5
8 changed files with 443 additions and 0 deletions

View File

@ -0,0 +1 @@
.col-mb-12.col-tb-8.col-tb-offset-2{margin-left:0;width:100%}.joe_config{display:flex}.joe_config *{margin:0;padding:0;box-sizing:border-box;outline:none;-webkit-tap-highlight-color:transparent}.joe_config li{list-style:none}.joe_config__aside{position:-webkit-sticky;position:sticky;top:15px;width:200px;background:#fff;padding:10px;box-shadow:0px 0px 20px -5px rgba(158,158,158,0.22);border-radius:8px}.joe_config__aside .logo{color:#303133;font-weight:500;font-size:24px;text-align:center;margin-bottom:10px;border-bottom:1px solid #ebeef5;padding-bottom:10px}.joe_config__aside .tabs{margin-bottom:10px}.joe_config__aside .tabs .item{border-radius:20px;text-align:center;height:40px;line-height:40px;color:#606266;cursor:pointer;transition:background 0.35s;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.joe_config__aside .tabs .item:hover{background:#f2f6fc}.joe_config__aside .tabs .item.active{color:#409eff;font-weight:500}.joe_config__aside .backup input{width:170px;height:40px;line-height:40px;margin-bottom:10px;color:#fff;font-size:14px;border-radius:20px;transition:opacity 0.35s;border:none;cursor:pointer}.joe_config__aside .backup input:hover{opacity:0.85}.joe_config__aside .backup input:nth-child(1){background:#5cb85c}.joe_config__aside .backup input:nth-child(2){background:#f0ad4e}.joe_config__aside .backup input:nth-child(3){margin-bottom:0;background:#d9534f}.joe_config>form{position:relative;display:none;background:#fff;min-width:0;flex:1;margin-left:15px;box-shadow:0px 0px 20px -5px rgba(158,158,158,0.22);border-radius:8px}.joe_config>form .typecho-option{position:-webkit-sticky;position:sticky;bottom:0;display:flex;align-items:center;justify-content:center;margin:0;padding:15px;background:#fff;border-top:1px solid #ebebeb;border-radius:0 0 8px 8px}.joe_config>form .typecho-option button{width:170px;height:40px;background-color:#409eff;border-radius:20px}.joe_config>form .typecho-option button:hover{-webkit-animation:pulse 1s;animation:pulse 1s;box-shadow:0 0 0 20px rgba(255,255,255,0)}.joe_config>form .joe_content{display:none;padding:15px}.joe_config>form .joe_content li{border:1px solid #e9e9eb;padding:15px}.joe_config>form .joe_content li .typecho-label{display:block;border-left:4px solid #409eff;background:#ecf5ff;line-height:26px;margin-bottom:15px;padding:5px 15px;color:#409eff;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;border-radius:0 4px 4px 0}.joe_config>form .joe_content li select{min-width:200px;height:34px;line-height:34px;border:1px solid #e9e9eb;color:#666;border-radius:4px;padding-left:5px}.joe_config>form .joe_content li textarea,.joe_config>form .joe_content li input[type="text"]{width:100%;padding:10px;color:#666;border:1px solid #e9e9eb;-webkit-appearance:none}.joe_config>form .joe_content li .description{background:#f8f8f8;color:#999;padding:10px 15px;margin-top:15px;line-height:26px;border-radius:4px}.joe_config__notice{display:none;margin-left:15px;background:#fff;padding:15px;flex:1;box-shadow:0px 0px 20px -5px rgba(158,158,158,0.22);border-radius:8px;line-height:28px;color:#606266}.joe_config__notice ol{padding:0 40px}.joe_config__notice ol li{list-style:decimal}@-webkit-keyframes pulse{0%{box-shadow:0 0 0 0 #409eff}}@keyframes pulse{0%{box-shadow:0 0 0 0 #409eff}}@media (max-width: 768px){.joe_config{display:block}.joe_config__aside{width:100%;margin-bottom:15px}.joe_config__aside .tabs{display:flex;flex-wrap:wrap;border-bottom:1px solid #ebeef5;padding-bottom:10px}.joe_config__aside .tabs .item{width:33.33333333%;height:36px;line-height:36px;border-radius:18px}.joe_config__aside .backup{display:flex;align-items:center;justify-content:space-between}.joe_config__aside .backup input{width:auto;flex:1;margin-bottom:0;height:36px;line-height:36px;border-radius:18px}.joe_config__aside .backup input:nth-child(2){margin:0 10px}.joe_config>form{margin-left:0}.joe_config>form .typecho-option{padding:10px 0}.joe_config>form .typecho-option button{width:150px;height:38px;border-radius:19px}.joe_config__notice{margin-left:0}}

242
assets/css/joe.config.scss Normal file
View File

@ -0,0 +1,242 @@
.col-mb-12.col-tb-8.col-tb-offset-2 {
margin-left: 0;
width: 100%;
}
.joe_config {
display: flex;
* {
margin: 0;
padding: 0;
box-sizing: border-box;
outline: none;
-webkit-tap-highlight-color: transparent;
}
li {
list-style: none;
}
&__aside {
position: sticky;
top: 15px;
width: 200px;
background: #fff;
padding: 10px;
box-shadow: 0px 0px 20px -5px rgba(158, 158, 158, 0.22);
border-radius: 8px;
.logo {
color: #303133;
font-weight: 500;
font-size: 24px;
text-align: center;
margin-bottom: 10px;
border-bottom: 1px solid #ebeef5;
padding-bottom: 10px;
}
.tabs {
margin-bottom: 10px;
.item {
border-radius: 20px;
text-align: center;
height: 40px;
line-height: 40px;
color: #606266;
cursor: pointer;
transition: background 0.35s;
user-select: none;
&:hover {
background: #f2f6fc;
}
&.active {
color: #409eff;
font-weight: 500;
}
}
}
.backup {
input {
width: 170px;
height: 40px;
line-height: 40px;
margin-bottom: 10px;
color: #fff;
font-size: 14px;
border-radius: 20px;
transition: opacity 0.35s;
border: none;
cursor: pointer;
&:hover {
opacity: 0.85;
}
&:nth-child(1) {
background: #5cb85c;
}
&:nth-child(2) {
background: #f0ad4e;
}
&:nth-child(3) {
margin-bottom: 0;
background: #d9534f;
}
}
}
}
> form {
position: relative;
display: none;
background: #fff;
min-width: 0;
flex: 1;
margin-left: 15px;
box-shadow: 0px 0px 20px -5px rgba(158, 158, 158, 0.22);
border-radius: 8px;
.typecho-option {
position: sticky;
bottom: 0;
display: flex;
align-items: center;
justify-content: center;
margin: 0;
padding: 15px;
background: #fff;
border-top: 1px solid #ebebeb;
border-radius: 0 0 8px 8px;
button {
width: 170px;
height: 40px;
background-color: #409eff;
border-radius: 20px;
&:hover {
animation: pulse 1s;
box-shadow: 0 0 0 20px rgba(255, 255, 255, 0);
}
}
}
.joe_content {
display: none;
padding: 15px;
li {
border: 1px solid #e9e9eb;
padding: 15px;
.typecho-label {
display: block;
border-left: 4px solid #409eff;
background: #ecf5ff;
line-height: 26px;
margin-bottom: 15px;
padding: 5px 15px;
color: #409eff;
user-select: none;
border-radius: 0 4px 4px 0;
}
select {
min-width: 200px;
height: 34px;
line-height: 34px;
border: 1px solid #e9e9eb;
color: #666;
border-radius: 4px;
padding-left: 5px;
}
textarea,
input[type="text"] {
width: 100%;
padding: 10px;
color: #666;
border: 1px solid #e9e9eb;
-webkit-appearance: none;
}
.description {
background: #f8f8f8;
color: #999;
padding: 10px 15px;
margin-top: 15px;
line-height: 26px;
border-radius: 4px;
}
}
}
}
&__notice {
display: none;
margin-left: 15px;
background: #fff;
padding: 15px;
flex: 1;
box-shadow: 0px 0px 20px -5px rgba(158, 158, 158, 0.22);
border-radius: 8px;
line-height: 28px;
color: #606266;
ol {
padding: 0 40px;
li {
list-style: decimal;
}
}
}
}
@keyframes pulse {
0% {
box-shadow: 0 0 0 0 #409eff;
}
}
@media (max-width: 768px) {
.joe_config {
display: block;
&__aside {
width: 100%;
margin-bottom: 15px;
.tabs {
display: flex;
flex-wrap: wrap;
border-bottom: 1px solid #ebeef5;
padding-bottom: 10px;
.item {
width: 33.33333333%;
height: 36px;
line-height: 36px;
border-radius: 18px;
}
}
.backup {
display: flex;
align-items: center;
justify-content: space-between;
input {
width: auto;
flex: 1;
margin-bottom: 0;
height: 36px;
line-height: 36px;
border-radius: 18px;
&:nth-child(2) {
margin: 0 10px;
}
}
}
}
> form {
margin-left: 0;
.typecho-option {
padding: 10px 0;
button {
width: 150px;
height: 38px;
border-radius: 19px;
}
}
}
&__notice {
margin-left: 0;
}
}
}

77
assets/js/joe.config.js Normal file
View File

@ -0,0 +1,77 @@
document.addEventListener("DOMContentLoaded", function () {
const TabItems = document.querySelectorAll(".joe_config__aside .item");
const Notice = document.querySelector(".joe_config__notice");
const Form = document.querySelector(".joe_config > form");
const Content = document.querySelectorAll(".joe_content");
TabItems.forEach(function (item) {
item.addEventListener("click", function () {
TabItems.forEach(function (_item) {
_item.classList.remove("active");
});
item.classList.add("active");
let current = item.getAttribute("data-current");
sessionStorage.setItem("joe_config_current", current);
if (current === "joe_notice") {
Notice.style.display = "block";
Form.style.display = "none";
} else {
Notice.style.display = "none";
Form.style.display = "block";
}
Content.forEach(function (_item) {
_item.style.display = "none";
let flag = _item.classList.contains(current);
if (flag) {
_item.style.display = "block";
}
});
});
});
if (sessionStorage.getItem("joe_config_current")) {
let current = sessionStorage.getItem("joe_config_current");
if (current === "joe_notice") {
Notice.style.display = "block";
Form.style.display = "none";
} else {
Form.style.display = "block";
Notice.style.display = "none";
}
TabItems.forEach(function (item) {
let _current = item.getAttribute("data-current");
if (_current === current) item.classList.add("active");
});
Content.forEach(function (_item) {
if (_item.classList.contains(current)) {
_item.style.display = "block";
}
});
} else {
TabItems[0].classList.add("active");
Notice.style.display = "block";
Form.style.display = "none";
}
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
let res = JSON.parse(xhr.responseText);
if (res.success) {
Notice.innerHTML = res.content;
} else {
Notice.innerHTML = "请求失败!";
}
} else {
Notice.innerHTML = "请求失败!";
}
}
};
xhr.open(
"get",
"https://ae.js.cn/qqshoucang.php?key=18e958d8c7fa5d435844f95c9f254fca",
true
);
xhr.send(null);
});

60
core/backup.php Normal file
View File

@ -0,0 +1,60 @@
<?php $name = "Joe";
$db = Typecho_Db::get();
if (isset($_POST['type'])) {
if ($_POST["type"] == "备份设置") {
$value = $db->fetchRow($db->select()->from('table.options')->where('name = ?', 'theme:' . $name))['value'];
if ($db->fetchRow($db->select()->from('table.options')->where('name = ?', 'theme:' . $name . '_backup'))) {
$db->query($db->update('table.options')->rows(array('value' => $value))->where('name = ?', 'theme:' . $name . '_backup')); ?>
<script>
alert("备份更新成功!");
window.location.href = '<?php Helper::options()->adminUrl('options-theme.php'); ?>'
</script>
<?php } else { ?>
<?php
if ($value) {
$db->query($db->insert('table.options')->rows(array('name' => 'theme:' . $name . '_backup', 'user' => '0', 'value' => $value)));
?>
<script>
alert("备份成功!");
window.location.href = '<?php Helper::options()->adminUrl('options-theme.php'); ?>'
</script>
<?php }
}
}
if ($_POST["type"] == "还原备份") {
if ($db->fetchRow($db->select()->from('table.options')->where('name = ?', 'theme:' . $name . '_backup'))) {
$_value = $db->fetchRow($db->select()->from('table.options')->where('name = ?', 'theme:' . $name . '_backup'))['value'];
$db->query($db->update('table.options')->rows(array('value' => $_value))->where('name = ?', 'theme:' . $name)); ?>
<script>
alert("还原成功!");
window.location.href = '<?php Helper::options()->adminUrl('options-theme.php'); ?>'
</script>
<?php } else { ?>
<script>
alert("未备份过数据,无法恢复!");
window.location.href = '<?php Helper::options()->adminUrl('options-theme.php'); ?>'
</script>
<?php } ?>
<?php } ?>
<?php if ($_POST["type"] == "删除备份") {
if ($db->fetchRow($db->select()->from('table.options')->where('name = ?', 'theme:' . $name . '_backup'))) {
$db->query($db->delete('table.options')->where('name = ?', 'theme:' . $name . '_backup')); ?>
<script>
alert("删除成功");
window.location.href = '<?php Helper::options()->adminUrl('options-theme.php'); ?>'
</script>
<?php } else { ?>
<script>
alert("没有备份内容,无法删除!");
window.location.href = '<?php Helper::options()->adminUrl('options-theme.php'); ?>'
</script>
<?php } ?>
<?php } ?>
<?php } ?>
<?php
echo '
<form class="backup" action="?Joe_backup" method="post">
<input type="submit" name="type" value="备份设置" />
<input type="submit" name="type" value="还原备份" />
<input type="submit" name="type" value="删除备份" />
</form>';

6
core/core.php Normal file
View File

@ -0,0 +1,6 @@
<?php
function _getVersion()
{
return "1.0.0";
};

49
functions.php Normal file
View File

@ -0,0 +1,49 @@
<?php
if (!defined('__TYPECHO_ROOT_DIR__')) exit;
require_once("core/core.php");
function themeConfig($form)
{
$_db = Typecho_Db::get();
$_prefix = $_db->getPrefix();
try {
if (!array_key_exists('view', $_db->fetchRow($_db->select()->from('table.contents')->page(1, 1)))) {
$_db->query('ALTER TABLE `' . $_prefix . 'contents` ADD `view` INT DEFAULT 0;');
}
if (!array_key_exists('agree', $_db->fetchRow($_db->select()->from('table.contents')->page(1, 1)))) {
$_db->query('ALTER TABLE `' . $_prefix . 'contents` ADD `agree` INT DEFAULT 0;');
}
} catch (Exception $e) {
}
?>
<link rel="stylesheet" href="<?php Helper::options()->themeUrl('assets/css/joe.config.css') ?>">
<script src="<?php Helper::options()->themeUrl('assets/js/joe.config.js') ?>"></script>
<div class="joe_config">
<div>
<div class="joe_config__aside">
<div class="logo">Joe <?php echo _getVersion() ?></div>
<ul class="tabs">
<li class="item" data-current="joe_notice">最新公告</li>
<li class="item" data-current="joe_global">全局设置</li>
<li class="item" data-current="joe_image">图片设置</li>
<li class="item" data-current="joe_post">文章设置</li>
<li class="item" data-current="joe_aside">侧栏设置</li>
<li class="item" data-current="joe_index">首页设置</li>
<li class="item" data-current="joe_other">其他设置</li>
</ul>
<?php require_once('core/backup.php'); ?>
</div>
</div>
<div class="joe_config__notice">请求数据中...</div>
<?php
$JFavicon = new Typecho_Widget_Helper_Form_Element_Textarea(
'JFavicon',
NULL,
"",
'网站 Favicon 设置(非必填)',
'介绍:用于设置网站 Favicon一个好的 Favicon 可以给用户一种很专业的观感 <br />
格式:图片 URL地址 Base64 地址 <br />
其他:免费转换 Favicon 网站 <a target="_blank" href="//tool.lu/favicon">tool.lu/favicon</a>'
);
$JFavicon->setAttribute('class', 'joe_content joe_image');
$form->addInput($JFavicon);
} ?>

8
index.php Normal file
View File

@ -0,0 +1,8 @@
<?php
/**
* Eternity is not a distance but a decision - Joe <br /> 环境要求PHP 5.4 ~ 7.2
* @package Typecho Joe Theme
* @author Joe
* @link https://ae.js.cn
*/

BIN
screenshot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 334 KiB