diff --git a/assets/css/joe.global.scss b/assets/css/joe.global.scss index ed25886..df745f6 100644 --- a/assets/css/joe.global.scss +++ b/assets/css/joe.global.scss @@ -709,6 +709,10 @@ } } +.joe_list { + +} + @keyframes progress { 0% { background-position: 0 0; diff --git a/assets/css/joe.index.css b/assets/css/joe.index.css index 36bafd0..2960ad4 100644 --- a/assets/css/joe.index.css +++ b/assets/css/joe.index.css @@ -1 +1 @@ -.joe_index{border-radius:8px;padding:0 15px;background:var(--background);box-shadow:var(--box-shadow);margin-bottom:15px}.joe_index__banner{padding-top:15px;display:flex}.joe_index__banner-recommend{width:270px;margin-left:15px;display:flex;flex-direction:column}.joe_index__banner-recommend.noswiper{width:100%;flex-direction:row;margin-left:0}.joe_index__banner-recommend.noswiper .item:first-child{margin-bottom:0;margin-right:7.5px}.joe_index__banner-recommend.noswiper .item:last-child{margin-left:7.5px}.joe_index__banner-recommend .item{position:relative;width:100%;height:160px;margin-bottom:15px;border-radius:5px;overflow:hidden}.joe_index__banner-recommend .item:last-child{margin-bottom:0}.joe_index__banner-recommend .item .thumbnail{display:block;width:100%;height:100%;transition:opacity 0.35s}.joe_index__banner-recommend .item .thumbnail img{width:100%;height:100%;-o-object-fit:cover;object-fit:cover}.joe_index__banner-recommend .item .thumbnail:hover{opacity:0.85}.joe_index__banner-recommend .item .information{display:flex;align-items:center;position:absolute;z-index:1;bottom:0;left:0;right:0;padding:8px;background:linear-gradient(to bottom, rgba(0,0,0,0), rgba(0,0,0,0.5));color:#fff;line-height:20px}.joe_index__banner-recommend .item .information_type{background-image:linear-gradient(to right, #fc712a, #f84c39);background-color:#f84c39;padding:0 5px;height:20px;border-radius:2px;margin-right:5px;font-size:12px}.joe_index__banner-recommend .item .information_title{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex:1;font-size:14px}.swiper-container{min-width:0;flex:1;height:335px;--swiper-theme-color: #fff;border-radius:5px}.swiper-container .item{display:block;height:335px;border-radius:5px}.swiper-container .item .thumbnail{width:100%;height:100%;-o-object-fit:cover;object-fit:cover;transition:opacity 0.35s}.swiper-container .item .thumbnail:hover{opacity:0.85}.swiper-container .item .title{position:absolute;z-index:1;left:0;right:0;bottom:0;text-align:center;background:linear-gradient(to bottom, rgba(0,0,0,0), rgba(0,0,0,0.45));white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:#fff;font-size:15px;padding:10px;font-weight:normal}.swiper-container .item .icon{position:absolute;z-index:1;top:10px;left:10px;width:18px;height:18px;fill:#fff;opacity:0.5}.swiper-container.swiper-container-horizontal .swiper-pagination-bullets{bottom:unset;left:unset;width:auto;right:10px;top:10px} +.joe_index{border-radius:8px;padding:0 15px;background:var(--background);box-shadow:var(--box-shadow);margin-bottom:15px}.joe_index__banner{padding-top:15px;display:flex}.joe_index__banner-recommend{width:270px;margin-left:15px;display:flex;flex-direction:column}.joe_index__banner-recommend.noswiper{width:100%;flex-direction:row;margin-left:0}.joe_index__banner-recommend.noswiper .item:first-child{margin-bottom:0;margin-right:7.5px}.joe_index__banner-recommend.noswiper .item:last-child{margin-left:7.5px}.joe_index__banner-recommend .item{position:relative;width:100%;height:160px;margin-bottom:15px;border-radius:5px;overflow:hidden}.joe_index__banner-recommend .item:last-child{margin-bottom:0}.joe_index__banner-recommend .item .thumbnail{display:block;width:100%;height:100%;transition:opacity 0.35s}.joe_index__banner-recommend .item .thumbnail img{width:100%;height:100%;-o-object-fit:cover;object-fit:cover}.joe_index__banner-recommend .item .thumbnail:hover{opacity:0.85}.joe_index__banner-recommend .item .information{display:flex;align-items:center;position:absolute;z-index:1;bottom:0;left:0;right:0;padding:8px;background:linear-gradient(to bottom, rgba(0,0,0,0), rgba(0,0,0,0.5));color:#fff;line-height:20px}.joe_index__banner-recommend .item .information_type{background-image:linear-gradient(to right, #fc712a, #f84c39);background-color:#f84c39;padding:0 5px;height:20px;border-radius:2px;margin-right:5px;font-size:12px}.joe_index__banner-recommend .item .information_title{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex:1;font-size:14px}.joe_index__hot{padding-top:15px}.joe_index__hot-list{display:flex;margin:0 -5px}.joe_index__hot-list .item{width:25%;padding:0 5px}.joe_index__hot-list .item .link{display:block}.joe_index__hot-list .item .link .inner{position:relative;cursor:pointer}.joe_index__hot-list .item .link .inner:hover .image{opacity:0.85}.joe_index__hot-list .item .link .inner:hover .title{background:var(--classC)}.joe_index__hot-list .item .link .inner .image{width:100%;height:125px;-o-object-fit:cover;object-fit:cover;border-radius:5px 5px 0 0;transition:opacity 0.35s}.joe_index__hot-list .item .link .inner .title{font-size:13px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-align:center;padding:0 8px;line-height:32px;color:var(--minor);background:var(--classD);border-radius:0 0 5px 5px;transition:background 0.35s}.joe_index__hot-list .item .link .inner .views{display:flex;align-items:center;position:absolute;z-index:1;top:5px;right:5px;background-image:linear-gradient(270deg, #986fee, #8695e6, #68b7dd, #18d7d3);color:#fff;font-size:12px;height:18px;padding:0 8px;border-radius:2px;white-space:nowrap}.joe_index__title{display:flex;align-items:center;border-bottom:1px solid var(--classC)}.joe_index__title-title{position:relative;display:flex;align-items:center;color:var(--routine);font-weight:500;height:40px;line-height:40px}.joe_index__title-title .item{cursor:pointer;margin-right:20px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;transition:color 0.35s}.joe_index__title-title .item.active{color:var(--theme)}.joe_index__title-title .line{position:absolute;bottom:-1px;left:0;height:2px;border-radius:1px;background:var(--theme);transition:left 0.35s, width 0.35s}.swiper-container{min-width:0;flex:1;height:335px;--swiper-theme-color: #fff;border-radius:5px}.swiper-container .item{display:block;height:335px;border-radius:5px}.swiper-container .item .thumbnail{width:100%;height:100%;-o-object-fit:cover;object-fit:cover;transition:opacity 0.35s}.swiper-container .item .thumbnail:hover{opacity:0.85}.swiper-container .item .title{position:absolute;z-index:1;left:0;right:0;bottom:0;text-align:center;background:linear-gradient(to bottom, rgba(0,0,0,0), rgba(0,0,0,0.45));white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:#fff;font-size:15px;padding:10px;font-weight:normal}.swiper-container .item .icon{position:absolute;z-index:1;top:10px;left:10px;width:18px;height:18px;fill:#fff;opacity:0.5}.swiper-container.swiper-container-horizontal .swiper-pagination-bullets{bottom:unset;left:unset;width:auto;right:10px;top:10px} diff --git a/assets/css/joe.index.scss b/assets/css/joe.index.scss index 4922b1a..3a85939 100644 --- a/assets/css/joe.index.scss +++ b/assets/css/joe.index.scss @@ -80,6 +80,99 @@ } } } + &__hot { + padding-top: 15px; + &-list { + display: flex; + margin: 0 -5px; + .item { + width: 25%; + padding: 0 5px; + .link { + display: block; + .inner { + position: relative; + cursor: pointer; + &:hover { + .image { + opacity: 0.85; + } + .title { + background: var(--classC); + } + } + .image { + width: 100%; + height: 125px; + object-fit: cover; + border-radius: 5px 5px 0 0; + transition: opacity 0.35s; + } + .title { + font-size: 13px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + text-align: center; + padding: 0 8px; + line-height: 32px; + color: var(--minor); + background: var(--classD); + border-radius: 0 0 5px 5px; + transition: background 0.35s; + } + .views { + display: flex; + align-items: center; + position: absolute; + z-index: 1; + top: 5px; + right: 5px; + background-image: linear-gradient(270deg, #986fee, #8695e6, #68b7dd, #18d7d3); + color: #fff; + font-size: 12px; + height: 18px; + padding: 0 8px; + border-radius: 2px; + white-space: nowrap; + } + } + } + } + } + } + &__title { + display: flex; + align-items: center; + border-bottom: 1px solid var(--classC); + &-title { + position: relative; + display: flex; + align-items: center; + color: var(--routine); + font-weight: 500; + height: 40px; + line-height: 40px; + .item { + cursor: pointer; + margin-right: 20px; + user-select: none; + transition: color 0.35s; + &.active { + color: var(--theme); + } + } + .line { + position: absolute; + bottom: -1px; + left: 0; + height: 2px; + border-radius: 1px; + background: var(--theme); + transition: left 0.35s, width 0.35s; + } + } + } } .swiper-container { diff --git a/assets/js/joe.global.js b/assets/js/joe.global.js index e187b1b..4c960da 100644 --- a/assets/js/joe.global.js +++ b/assets/js/joe.global.js @@ -1,4 +1,6 @@ window.Joe = function () { + const BASE_API = '/index.php/joe/api'; + let IsMobile = false; if (/windows phone|iphone|android/gi.test(window.navigator.userAgent)) { IsMobile = true; @@ -103,7 +105,11 @@ window.Joe = function () { /* Ranking */ if ($('.joe_aside__item.ranking').length !== 0) { $.ajax({ - url: '/index.php/action/ranking', + url: BASE_API, + type: 'POST', + data: { + routeType: 'ranking' + }, success(res) { $('.joe_aside__item.ranking .joe_aside__item-title .text').html(res.title); let htmlStr = ''; @@ -131,6 +137,54 @@ window.Joe = function () { new Swiper('.swiper-container', { direction, loop: true, autoplay: true, mousewheel: true, pagination: { el: '.swiper-pagination' } }); } + /* Index Title */ + if ($('.joe_index__list').length > 0) { + let queryData = { page: 1, pageSize: 10, type: 'created' }; + const initDom = () => { + $('.joe_index__list').html(''); + const activeItem = $(`.joe_index__title-title .item[data-type="${queryData.type}"]`); + const activeLine = $('.joe_index__title-title .line'); + activeItem.addClass('active').siblings().removeClass('active'); + activeLine.css({ left: activeItem.position().left, width: activeItem.width() }); + }; + const pushDom = () => { + $.ajax({ + url: BASE_API, + type: 'POST', + data: { + routeType: 'list', + page: queryData.page, + pageSize: queryData.pageSize, + type: queryData.type + }, + success(res) { + res.data.forEach(_ => { + $('.joe_index__list').append(` +
  • +
    + + + + + + + + +
  • + `); + }); + } + }); + }; + initDom(); + pushDom(); + $('.joe_index__title-title .item').on('click', function () { + queryData = { page: 1, pageSize: 10, type: $(this).attr('data-type') }; + initDom(); + pushDom(); + }); + } + new LazyLoad('.lazyload'); }; diff --git a/core/core.php b/core/core.php index a7c5f0d..0e8a65e 100644 --- a/core/core.php +++ b/core/core.php @@ -1,35 +1,19 @@ request->getPathinfo(); - switch ($path_info) { - case '/action/ranking': - _getRanking($self); - break; - }; -} - -function _getRanking($self) -{ - header("HTTP/1.1 200 OK"); - $ranking_txt = Helper::options()->JAside_Ranking; - $ranking_arr = explode("$", $ranking_txt); - $arrContextOptions = ['ssl' => ['verify_peer' => false, 'verify_peer_name' => false,]]; - $json = file_get_contents("https://the.top/v1/{$ranking_arr[1]}/1/9", false, stream_context_create($arrContextOptions)); - $res = json_decode($json, TRUE); - if ($res['code'] === 0) { - $self->response->throwJson([ - "code" => 1, - "title" => $ranking_arr[0], - "data" => $res["data"] - ]); - } else { - $self->response->throwJson([ - "code" => 0, - "title" => $ranking_arr[0], - "data" => null - ]); + if ($path_info === "/joe/api") { + switch ($self->request->routeType) { + case 'ranking': + _getRanking($self); + break; + case 'list': + _getPost($self); + break; + }; } } @@ -76,7 +60,22 @@ function _getAsideAuthorMotto() echo $JMottoRandom[array_rand($JMottoRandom, 1)]; } -function _getThumbnail($item) +function _getAbstract($item, $type = true) +{ + $abstract = ""; + if ($item->fields->abstract) { + $abstract = $item->fields->abstract; + } else { + $abstract = $item->excerpt; + } + if ($type) { + echo $abstract; + } else { + return $abstract; + } +} + +function _getThumbnail($item, $type = true) { $randomThumb = 'https://cdn.jsdelivr.net/npm/typecho_joe_theme@4.3.5/assets/img/random/' . rand(1, 25) . '.webp'; $custom_thumbnail = Helper::options()->JThumbnail; @@ -96,7 +95,11 @@ function _getThumbnail($item) } elseif (preg_match_all($patternMDfoot, $item->content, $thumbUrl)) { $randomThumb = $thumbUrl[1][0]; } - echo $randomThumb; + if ($type) { + echo $randomThumb; + } else { + return $randomThumb; + } } function _getViews($item) @@ -209,6 +212,16 @@ function themeFields($layout) 3、若文章无图片,并且外观设置里填写了·自定义缩略图·选项,则取自定义缩略图图片' ); $layout->addItem($thumb); + + $abstract = new Typecho_Widget_Helper_Form_Element_Textarea( + 'abstract', + NULL, + NULL, + '自定义文章摘要', + '填写时:将会显示填写的摘要
    + 不填写时:默认取文章里的内容' + ); + $layout->addItem($abstract); } class Widget_Contents_Hot extends Widget_Abstract_Contents @@ -228,3 +241,22 @@ class Widget_Contents_Hot extends Widget_Abstract_Contents ); } } + +class Widget_Contents_Sort extends Widget_Abstract_Contents +{ + public function execute() + { + $this->parameter->setDefault(array('page' => 1, 'pageSize' => 10, 'type' => 'created')); + $offset = $this->parameter->pageSize * ($this->parameter->page - 1); + $this->db->fetchAll( + $this->select() + ->from('table.contents') + ->where('table.contents.type = ?', 'post') + ->where('table.contents.status = ?', 'publish') + ->limit($this->parameter->pageSize) + ->offset($offset) + ->order($this->parameter->type, Typecho_Db::SORT_DESC), + array($this, 'push') + ); + } +} diff --git a/core/route.php b/core/route.php new file mode 100644 index 0000000..b1043ef --- /dev/null +++ b/core/route.php @@ -0,0 +1,48 @@ +JAside_Ranking; + $ranking_arr = explode("$", $ranking_txt); + $arrContextOptions = ['ssl' => ['verify_peer' => false, 'verify_peer_name' => false,]]; + $json = file_get_contents("https://the.top/v1/{$ranking_arr[1]}/1/9", false, stream_context_create($arrContextOptions)); + $res = json_decode($json, TRUE); + if ($res['code'] === 0) { + $self->response->throwJson([ + "code" => 1, + "title" => $ranking_arr[0], + "data" => $res["data"] + ]); + } else { + $self->response->throwJson([ + "code" => 0, + "title" => $ranking_arr[0], + "data" => null + ]); + } +} + +function _getPost($self) +{ + header("HTTP/1.1 200 OK"); + $page = $self->request->page; + $pageSize = $self->request->pageSize; + $type = $self->request->type; + $result = []; + $self->widget('Widget_Contents_Sort', 'page=' . $page . '&pageSize=' . $pageSize . '&type=' . $type)->to($item); + while ($item->next()) { + $result[] = array( + "image" => _getThumbnail($item, false), + "time" => date('Y-m-d', $item->created), + "created" => date('Y年m月d日', $item->created), + "title" => $item->title, + "abstract" => _getAbstract($item, false), + "category" => $item->categories, + "views" => number_format($item->views), + "commentsNum" => number_format($item->commentsNum), + "agree" => number_format($item->agree), + "permalink" => $item->permalink, + ); + }; + $self->response->throwJson(array("data" => $result)); +} diff --git a/functions.php b/functions.php index 5ffec88..8ff7251 100644 --- a/functions.php +++ b/functions.php @@ -6,8 +6,8 @@ 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('views', $_db->fetchRow($_db->select()->from('table.contents')->page(1, 1)))) { + $_db->query('ALTER TABLE `' . $_prefix . 'contents` ADD `views` 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;'); @@ -337,4 +337,14 @@ function themeConfig($form) ); $JIndex_Recommend->setAttribute('class', 'joe_content joe_index'); $form->addInput($JIndex_Recommend); + + $JIndex_Hot = new Typecho_Widget_Helper_Form_Element_Radio( + 'JIndex_Hot', + array('off' => '关闭(默认)', 'on' => '开启'), + 'off', + '是否开启首页热门文章', + '介绍:开启后,网站首页将会显示浏览量最多的4篇热门文章' + ); + $JIndex_Hot->setAttribute('class', 'joe_content joe_index'); + $form->addInput($JIndex_Hot->multiMode()); } ?> \ No newline at end of file diff --git a/index.php b/index.php index 7ded42e..6e72616 100644 --- a/index.php +++ b/index.php @@ -24,7 +24,6 @@
    - widget('Widget_Archive', 'pageSize=1&type=post', 'cid=' . $cid)->to($item); ?>
    - <?php $item->title() ?> + <?php $item->title() ?>
    推荐 @@ -86,7 +85,34 @@
    - + options->JIndex_Hot === "on") : ?> + widget('Widget_Contents_Hot@Index', 'pageSize=4')->to($item); ?> +
    + +
    + +
    +
      +
    • 最新文章
    • +
    • 评论最多
    • +
    • 点赞最多
    • +
    • 浏览最多
    • +
    • +
    +
    +
    need('public/aside.php'); ?> diff --git a/public/aside.php b/public/aside.php index b9763f8..df70966 100644 --- a/public/aside.php +++ b/public/aside.php @@ -51,7 +51,7 @@ 热门文章 - widget('Widget_Contents_Hot', 'pageSize=' . $this->options->JAside_Hot_Num)->to($item); ?> + widget('Widget_Contents_Hot@Aside', 'pageSize=' . $this->options->JAside_Hot_Num)->to($item); ?>
      have()) : ?>