This commit is contained in:
杜恒 2021-01-20 14:15:32 +08:00
parent 1fadaa1073
commit 4e31dbdf81
8 changed files with 420 additions and 8 deletions

File diff suppressed because one or more lines are too long

View File

@ -257,6 +257,33 @@
position: sticky;
margin-bottom: 0;
}
&-title {
display: flex;
align-items: center;
border-bottom: 1px solid var(--classC);
font-size: 16px;
font-weight: 500;
height: 45px;
line-height: 45px;
padding: 0 15px;
color: var(--main);
.icon {
width: 18px;
height: 18px;
margin-right: 8px;
fill: var(--main);
}
.line {
width: 10px;
height: 1px;
background: #54b5db;
margin-left: 12px;
}
}
&-contain {
position: relative;
padding: 15px;
}
&.author {
background: var(--background);
padding: 45px 15px 15px;
@ -295,6 +322,182 @@
object-fit: cover;
z-index: 1;
}
.user {
position: relative;
z-index: 4;
display: flex;
flex-direction: column;
align-items: center;
padding-bottom: 15px;
.avatar {
width: 75px;
height: 75px;
border-radius: 50%;
overflow: hidden;
margin-bottom: 10px;
object-fit: cover;
transition: transform 0.75s;
background: var(--background);
padding: 5px;
&:hover {
transform: rotate(360deg);
}
}
.link {
color: var(--theme);
margin-bottom: 10px;
font-size: 16px;
font-weight: 500;
&:hover {
text-decoration: underline;
}
}
.motto {
color: var(--main);
text-align: center;
}
}
.count {
width: 100%;
padding-bottom: 15px;
display: flex;
align-items: center;
border-bottom: 1px solid var(--classC);
.item {
min-width: 0;
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
color: var(--routine);
font-size: 12px;
&:first-child {
border-right: 1px solid var(--classC);
}
.num {
max-width: 70px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
font-weight: 500;
font-size: 22px;
color: var(--main);
margin-bottom: 3px;
text-shadow: var(--text_shadow);
}
}
}
.list {
padding-top: 15px;
.item {
display: flex;
align-items: center;
justify-content: space-between;
line-height: 30px;
.link {
position: relative;
color: var(--routine);
max-width: 85%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
&::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
width: 0;
height: 1px;
background: var(--theme);
transition: all 0.35s;
}
&:hover {
color: var(--theme);
&::after {
width: 100%;
}
}
}
.icon {
fill: var(--routine);
}
}
}
}
&.timelife {
background: var(--background);
.item {
margin-bottom: 15px;
&:last-child {
margin-bottom: 0;
}
.title {
font-size: 12px;
color: var(--minor);
margin-bottom: 5px;
display: flex;
align-items: center;
.text {
color: var(--theme);
font-weight: 500;
font-size: 14px;
margin: 0 5px;
}
}
.progress {
display: flex;
align-items: center;
&-bar {
height: 10px;
border-radius: 5px;
overflow: hidden;
background: var(--classC);
width: 0;
min-width: 0;
flex: 1;
margin-right: 5px;
&-inner {
width: 0;
height: 100%;
border-radius: 5px;
transition: width 0.35s;
animation: progress 750ms linear infinite;
&-0 {
background: #bde6ff;
background-image: linear-gradient(135deg, #50bfff 25%, transparent 25%, transparent 50%, #50bfff 50%, #50bfff 75%, transparent 75%, transparent 100%);
background-size: 30px 30px;
}
&-1 {
background: #ffd980;
background-image: linear-gradient(135deg, #f7ba2a 25%, transparent 25%, transparent 50%, #f7ba2a 50%, #f7ba2a 75%, transparent 75%, transparent 100%);
background-size: 30px 30px;
}
&-2 {
background: #ffa9a9;
background-image: linear-gradient(135deg, #ff4949 25%, transparent 25%, transparent 50%, #ff4949 50%, #ff4949 75%, transparent 75%, transparent 100%);
background-size: 30px 30px;
}
&-3 {
background: #67c23a;
background-image: linear-gradient(135deg, #4f9e28 25%, transparent 25%, transparent 50%, #4f9e28 50%, #4f9e28 75%, transparent 75%, transparent 100%);
background-size: 30px 30px;
}
}
}
&-percentage {
color: var(--minor);
}
}
}
}
}
}
@keyframes progress {
0% {
background-position: 0 0;
}
100% {
background-position: 30px 0;
}
}

View File

@ -26,6 +26,65 @@ window.Joe = function () {
}
});
}
/* Timelife */
{
let timelife = [
{ title: '今日已经过去', endTitle: '小时', num: 0, percent: '0%' },
{ title: '这周已经过去', endTitle: '天', num: 0, percent: '0%' },
{ title: '本月已经过去', endTitle: '天', num: 0, percent: '0%' },
{ title: '今年已经过去', endTitle: '个月', num: 0, percent: '0%' }
];
{
let nowDate = +new Date();
let todayStartDate = new Date(new Date().toLocaleDateString()).getTime();
let todayPassHours = (nowDate - todayStartDate) / 1000 / 60 / 60;
let todayPassHoursPercent = (todayPassHours / 24) * 100;
timelife[0].num = parseInt(todayPassHours);
timelife[0].percent = parseInt(todayPassHoursPercent) + '%';
}
{
let weeks = { 0: 7, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6 };
let weekDay = weeks[new Date().getDay()];
let weekDayPassPercent = (weekDay / 7) * 100;
timelife[1].num = parseInt(weekDay);
timelife[1].percent = parseInt(weekDayPassPercent) + '%';
}
{
let year = new Date().getFullYear();
let date = new Date().getDate();
let month = new Date().getMonth() + 1;
let monthAll = new Date(year, month, 0).getDate();
let monthPassPercent = (date / monthAll) * 100;
timelife[2].num = date;
timelife[2].percent = parseInt(monthPassPercent) + '%';
}
{
let month = new Date().getMonth() + 1;
let yearPass = (month / 12) * 100;
timelife[3].num = month;
timelife[3].percent = parseInt(yearPass) + '%';
}
let htmlStr = '';
timelife.forEach((item, index) => {
htmlStr += `
<div class="item">
<div class="title">
${item.title}
<span class="text">${item.num}</span>
${item.endTitle}
</div>
<div class="progress">
<div class="progress-bar">
<div class="progress-bar-inner progress-bar-inner-${index}" style="width: ${item.percent}"></div>
</div>
<div class="progress-percentage">${item.percent}</div>
</div>
</div>
`;
});
$('.joe_aside__item-contain').html(htmlStr);
}
};
document.addEventListener('DOMContentLoaded', () => Joe());

View File

@ -1,10 +1,83 @@
<?php
function _getVersion()
{
return "1.0.0";
};
timerStart();
function timerStart()
{
global $timeStart;
$mTime = explode(' ', microtime());
$timeStart = $mTime[1] + $mTime[0];
return true;
}
function timerStop($precision = 3)
{
global $timeStart, $timeEnd;
$mTime = explode(' ', microtime());
$timeEnd = $mTime[1] + $mTime[0];
$timeTotal = number_format($timeEnd - $timeStart, $precision);
echo $timeTotal < 1 ? $timeTotal * 1000 . "ms" : $timeTotal . "s";
}
function _getAvatarByMail($mail)
{
$gravatarsUrl = 'https://gravatar.helingqi.com/wavatar/';
$mailLower = strtolower($mail);
$md5MailLower = md5($mailLower);
$qqMail = str_replace('@qq.com', '', $mailLower);
if (strstr($mailLower, "qq.com") && is_numeric($qqMail) && strlen($qqMail) < 11 && strlen($qqMail) > 4) {
echo 'https://thirdqq.qlogo.cn/g?b=qq&nk=' . $qqMail . '&s=100';
} else {
echo $gravatarsUrl . $md5MailLower . '?d=mm';
}
};
function _getAsideAuthorMotto()
{
$JMottoRandom = explode("\r\n", Helper::options()->JAside_Author_Motto);
echo $JMottoRandom[array_rand($JMottoRandom, 1)];
}
function _getAsideAuthorNav()
{
if (Helper::options()->JAside_Author_Nav !== "off") {
$db = Typecho_Db::get();
$adapterName = $db->getAdapterName();
if ($adapterName == 'pgsql' || $adapterName == 'Pdo_Pgsql' || $adapterName == 'Pdo_SQLite' || $adapterName == 'SQLite') {
$order_by = 'RANDOM()';
} else {
$order_by = 'RAND()';
}
$result = $db->fetchAll(
$db->select()
->from('table.contents')
->where('status = ?', 'publish')
->where('type = ?', 'post')
->where('password IS NULL')
->limit(Helper::options()->JAside_Author_Nav)
->order($order_by)
);
foreach ($result as $item) {
$obj = Typecho_Widget::widget('Widget_Abstract_Contents');
$item = $obj->push($item);
$title = htmlspecialchars($item['title']);
$permalink = $item['permalink'];
echo "
<li class='item'>
<a class='link' href='{$permalink}' title='{$title}'>{$title}</a>
<svg class='icon' viewBox='0 0 1024 1024' version='1.1' xmlns='http://www.w3.org/2000/svg' width='16' height='16'>
<path d='M448.12 320.331a30.118 30.118 0 0 1-42.616-42.586L552.568 130.68a213.685 213.685 0 0 1 302.2 0l38.552 38.551a213.685 213.685 0 0 1 0 302.2L746.255 618.497a30.118 30.118 0 0 1-42.586-42.616l147.034-147.035a153.45 153.45 0 0 0 0-217.028l-38.55-38.55a153.45 153.45 0 0 0-216.998 0L448.12 320.33zM575.88 703.67a30.118 30.118 0 0 1 42.616 42.586L471.432 893.32a213.685 213.685 0 0 1-302.2 0l-38.552-38.551a213.685 213.685 0 0 1 0-302.2l147.065-147.065a30.118 30.118 0 0 1 42.586 42.616L173.297 595.125a153.45 153.45 0 0 0 0 217.027l38.55 38.551a153.45 153.45 0 0 0 216.998 0L575.88 703.64z m-234.256-63.88L639.79 341.624a30.118 30.118 0 0 1 42.587 42.587L384.21 682.376a30.118 30.118 0 0 1-42.587-42.587z' p-id='7351'></path>
</svg>
</li>
";
}
}
}
function themeFields($layout)
{
$aside = new Typecho_Widget_Helper_Form_Element_Radio(

View File

@ -39,7 +39,7 @@ function themeConfig($form)
'JFavicon',
NULL,
'https://cdn.jsdelivr.net/gh/HaoOuBa/Joe@master/favicon.ico',
'网站 Favicon 设置(非必填)',
'网站 Favicon 设置',
'介绍:用于设置网站 Favicon一个好的 Favicon 可以给用户一种很专业的观感 <br />
格式:图片 URL地址 Base64 地址 <br />
其他:免费转换 Favicon 网站 <a target="_blank" href="//tool.lu/favicon">tool.lu/favicon</a>'
@ -51,7 +51,7 @@ function themeConfig($form)
'JLogo',
NULL,
'https://cdn.jsdelivr.net/gh/HaoOuBa/Joe@master/assets/img/logo.png',
'网站 Logo 设置(非必填)',
'网站 Logo 设置',
'介绍:用于设置网站 Logo一个好的 Logo 能为网站带来有效的流量 <br />
格式:图片 URL地址 Base64 地址 <br />
其他:免费制作 logo 网站 <a target="_blank" href="//www.uugai.com">www.uugai.com</a>'
@ -79,9 +79,10 @@ function themeConfig($form)
'JAside',
array(
'author' => '作者栏',
'timelife' => '计时栏',
),
null,
'选择首页需要显示的侧边栏栏目(非必选)',
'选择首页需要显示的侧边栏栏目',
'介绍:用于控制首页侧边栏的栏目显示规则 <br>
注意:如果全部未选,则表示不开启侧边栏'
);
@ -92,11 +93,52 @@ function themeConfig($form)
'JAside_Author_Image',
NULL,
"https://cdn.jsdelivr.net/gh/HaoOuBa/Joe@master/assets/img/aside_author_image.jpg",
'作者栏 —— 背景(非必填)',
'作者栏 —— 背景',
'介绍:用于修改作者栏的背景图片 <br/>
格式:图片地址 <br />
注意:不填写时,则显示默认背景'
);
$JAside_Author_Image->setAttribute('class', 'joe_content joe_aside');
$form->addInput($JAside_Author_Image);
$JAside_Author_Link = new Typecho_Widget_Helper_Form_Element_Textarea(
'JAside_Author_Link',
NULL,
"https://ae.js.cn",
'作者栏 —— 跳转链接',
'介绍:用于修改作者栏的跳转链接'
);
$JAside_Author_Link->setAttribute('class', 'joe_content joe_aside');
$form->addInput($JAside_Author_Link);
$JAside_Author_Motto = new Typecho_Widget_Helper_Form_Element_Textarea(
'JAside_Author_Motto',
NULL,
"有钱终成眷属,没钱亲眼目睹",
'作者栏 —— 座右铭',
'介绍:用于显示在侧边栏作者信息的座右铭。<br />
格式:可以填写多行也可以填写一行,填写多行时,每次随机显示其中的某一条'
);
$JAside_Author_Motto->setAttribute('class', 'joe_content joe_aside');
$form->addInput($JAside_Author_Motto);
$JAside_Author_Nav = new Typecho_Widget_Helper_Form_Element_Select(
'JAside_Author_Nav',
array(
'off' => '关闭(默认)',
'3' => '开启并显示3条最新文章',
'4' => '开启并显示4条最新文章',
'5' => '开启并显示5条最新文章',
'6' => '开启并显示6条最新文章',
'7' => '开启并显示7条最新文章',
'8' => '开启并显示8条最新文章',
'9' => '开启并显示9条最新文章',
'10' => '开启并显示10条最新文章'
),
'off',
'作者栏 —— 随机文章数目',
'介绍:用于控制作者栏的随机文章条数'
);
$JAside_Author_Nav->setAttribute('class', 'joe_content joe_aside');
$form->addInput($JAside_Author_Nav->multiMode());
} ?>

View File

@ -21,7 +21,7 @@
<?php $this->need('public/header.php'); ?>
<div class="joe_container">
<div class="joe_main">
1
<?php timerStop() ?>
</div>
<?php $this->need('public/aside.php'); ?>
</div>

View File

@ -2,7 +2,42 @@
<aside class="joe_aside">
<?php if (in_array('author', $this->options->JAside)) : ?>
<section class="joe_aside__item author">
<img class="image" src="" alt="<?php $this->author->screenName(); ?>" />
<img class="image" src="<?php $this->options->JAside_Author_Image() ?>" alt="<?php $this->author->screenName(); ?>" />
<div class="user">
<img class="avatar" src="<?php _getAvatarByMail($this->author->mail) ?>" alt="<?php $this->author->screenName(); ?>" />
<a class="link" href="<?php $this->options->JAside_Author_Link() ?>" target="_blank" rel="noopener noreferrer nofollow"><?php $this->author->screenName(); ?></a>
<p class="motto"><?php _getAsideAuthorMotto() ?></p>
</div>
<?php Typecho_Widget::widget('Widget_Stat')->to($item); ?>
<div class="count">
<div class="item" title="累计文章数">
<span class="num"><?php echo number_format($item->publishedPostsNum); ?></span>
<span>文章数</span>
</div>
<div class="item" title="累计评论数">
<span class="num"><?php echo number_format($item->publishedCommentsNum); ?></span>
<span>评论量</span>
</div>
</div>
<?php if ($this->options->JAside_Author_Nav !== "off") : ?>
<ul class="list">
<?php _getAsideAuthorNav() ?>
</ul>
<?php endif; ?>
</section>
<?php endif; ?>
<?php if (in_array('timelife', $this->options->JAside)) : ?>
<section class="joe_aside__item timelife">
<h3 class="joe_aside__item-title">
<svg class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" width="18" height="18">
<path d="M864.801 895.471h-33.56v-96.859c0-126.081-73.017-235.093-179.062-287.102 106.046-52.01 179.062-161.022 179.062-287.102v-96.859h33.56c17.301 0 31.325-14.327 31.325-32 0-17.673-14.024-32-31.325-32H159.018c-17.3 0-31.325 14.327-31.325 32 0 17.673 14.025 32 31.325 32h33.02v96.859c0 126.08 73.016 235.092 179.061 287.102-106.046 52.009-179.062 161.02-179.062 287.101v96.859h-33.02c-17.3 0-31.325 14.326-31.325 32s14.025 32 31.325 32H864.8c17.301 0 31.325-14.326 31.325-32s-14.023-31.999-31.324-31.999zM256.05 222.427v-94.878h513.046v94.878c0 141.674-114.85 256.522-256.523 256.522-141.674 0-256.523-114.848-256.523-256.522z m513.046 673.044H256.05v-94.879c0-141.674 114.849-256.521 256.523-256.521 141.673 0 256.523 114.848 256.523 256.521v94.879z" p-id="29837"></path>
<path d="M544.141 384c0-17.69-14.341-32.031-32.031-32.031-71.694 0-127.854-56.161-127.854-127.855 0-17.69-14.341-32.032-32.031-32.032s-32.032 14.341-32.032 32.032c0 107.617 84.3 191.918 191.917 191.918 17.69 0 32.031-14.342 32.031-32.032z" p-id="29838"></path>
</svg>
<span class="text">人生倒计时</span>
<span class="line"></span>
</h3>
<div class="joe_aside__item-contain"></div>
</section>
<?php endif; ?>
</aside>

View File

@ -57,7 +57,7 @@
<nav class="joe_dropdown__menu">
<?php foreach ($children as $mid) : ?>
<?php $child = $item->getCategory($mid); ?>
<a class="<?php echo $this->is('category', $$child['slug']) ? 'active' : '' ?>" href="<?php echo $child['permalink'] ?>" title="<?php echo $child['name']; ?>"><?php echo $child['name']; ?></a>
<a class="<?php echo $this->is('category', $child['slug']) ? 'active' : '' ?>" href="<?php echo $child['permalink'] ?>" title="<?php echo $child['name']; ?>"><?php echo $child['name']; ?></a>
<?php endforeach; ?>
</nav>
</div>