Files
pear-admin-flask/templates/public/index.html
T
bwstudio 4ece453f00 feat(public): 首页卡片/主题菜单/侧栏/移动端多项优化
卡片
- 描述与网址共用一行(.meta-line + grid 同格),默认显示描述、悬停交叉淡出为网址;
  触屏 (hover:none) 直接显示网址,卡片不再被两行文字撑高

主题菜单
- 修复「暗色」项与其他项不一致:主题变量块原用裸属性选择器 [data-theme="dark"],
  会连菜单里的 <li data-theme="dark"> 一起命中导致颜色被局部覆盖;
  全部改为 html[data-theme="…"](8 个主题 + 关于页 dark 特例)
- 每项加统一色块标识 + 选中对勾,宽高与对齐方式一致

左侧菜单栏
- 「我常访问」「热门网址」合并为一个「常用 & 热门」分区(侧栏 + 移动端抽屉),
  标题随数据动态切换;右侧内容区两个 section 保持独立不变
- addSideNavEntry/addDrawerEntry 改为往合并分区插 li,removeEntries 只摘单条,
  避免整块删除把热门入口一起干掉
- 新增 retitleFeatured():JS 补入/移除个人榜后同步标题与图标

PC 侧栏
- 修复滚轮无响应:overscroll-behavior 由 contain 改为 auto(contain 会阻断滚动链接,
  内容未溢出时侧栏上滚轮完全没反应)
- 滚动条加宽到 6px 并使用 --text-soft,加 scrollbar-gutter: stable

移动端顶栏
- 修复 360px 小屏三个控件挤成两行:.topbar-actions 改 flex: 1 1 0 + min-width: 0
  (flex 换行先于收缩,basis auto 会先按固有宽度判定放不下而换行)
- 恢复显示站点名与副标题作为第二行,消除顶部空白
- 手机端隐藏「搜索」按钮,改由左侧放大镜提交,input 加 enterkeyhint
- placeholder 按视口自适应:手机「搜索书签」

抽屉
- 主题菜单在窄屏改为内联展开(280px 抽屉放不下 160px fixed 浮层,
  原逻辑会算出负数 left 飞出屏幕)
- positionThemeMenu 增加边界兜底:两侧都放不下时贴可视区右边缘
- 面板补 width: min(280px,84vw) + overflow-y:auto(原被内容撑成 173px)
2026-09-07 20:38:06 +08:00

120 lines
5.3 KiB
HTML

{% extends 'public/base.html' %}
{# 单张导航卡片:热门 / 个人 / 普通分类共用 #}
{% macro nav_card(item, cls='', mine=None) %}
<a class="card {{ cls }}"
href="{{ item.url }}"
data-nav-id="{{ item.id }}"
{%- if mine is not none %} data-mine="{{ mine }}"{% endif %}
{%- if item.is_external %} target="_blank" rel="noopener noreferrer"{% endif %}>
<div class="icon-wrap">
<span class="nav-letter" style="background:{{ item.color }}">{{ item.letter }}</span>
{% if item.domain %}
{# 图标走本地缓存接口 /site/icon/<domain>,由服务端拉取并落盘到 data/icon/,失败自动生成字母头像 #}
<img class="nav-favicon" alt="" loading="lazy" referrerpolicy="no-referrer"
data-domain="{{ item.domain }}" data-letter="{{ item.letter }}"
style="display:none">
{% endif %}
</div>
<div class="card-body">
<div class="title-row">
<div class="title" title="{{ item.title }}">{{ item.title }}</div>
{% if item.is_external %}
<span class="ext-tag" title="外部链接"><i class="layui-icon layui-icon-link"></i></span>
{% endif %}
</div>
{# 描述与网址共用同一行:默认显示描述,悬停时交叉淡出为网址,避免两行同时占用卡片空间 #}
<div class="meta-line">
<div class="desc">{{ item.description or '暂无描述' }}</div>
<div class="url" title="{{ item.url }}">{{ item.url }}</div>
</div>
<div class="visit-count" data-nav-visit="{{ item.visit_count or 0 }}">
{%- if mine is not none -%}
我点过 {{ item.mine_count or 0 }} 次
{%- else -%}
{%- set vc = item.visit_count or 0 -%}
{%- if vc >= 3 -%}访问 {{ '{:,}'.format(vc) }}
{%- else -%}新
{%- endif -%}
{%- endif -%}
</div>
</div>
<div class="card-arrow"><i class="layui-icon layui-icon-right"></i></div>
</a>
{% endmacro %}
{# 分类目录条:仅平板(601–1024px)可见,桌面走左侧侧栏、手机走抽屉 #}
{% block cat_nav %}
{% if groups or top_navs or my_navs %}
{% set anchors = cat_anchors or {} %}
<nav class="cat-nav" aria-label="分类导航">
<div class="cat-nav-inner" id="cat-nav-inner">
{% if my_navs %}<a href="#cat-mine" class="cat-nav-mine">★ 我常访问</a>{% endif %}
{% if top_navs %}<a href="#cat-top" class="cat-nav-hot">🔥 热门网址</a>{% endif %}
{% for category in groups.keys() %}
<a href="#{{ anchors.get(category) or ('cat-' ~ loop.index) }}">{{ category }}</a>
{% endfor %}
</div>
</nav>
{% endif %}
{% endblock %}
{% block content %}
{% if not groups and not top_navs and not my_navs %}
<div class="empty">
<i class="layui-icon layui-icon-face-surprised" style="font-size:48px;color:#ccc;"></i>
<p>暂无导航数据,请先在后台【系统管理 → 导航管理】添加。</p>
</div>
{% else %}
{# ===== 我常访问:基于匿名 ID + 本机 localStorage 的个人榜 ===== #}
{% if my_navs %}
<section class="section section-mine" id="cat-mine">
<div class="section-header">
<h2><i class="layui-icon layui-icon-star-fill"></i> 我常访问</h2>
<div class="meta">只在这台设备上统计 · <a href="javascript:;" id="clear-mine">清除我的记录</a></div>
</div>
<div class="grid" id="mine-grid">
{% for item in my_navs %}
{{ nav_card(item, 'card-mine', item.mine_score) }}
{% endfor %}
</div>
</section>
{% endif %}
{# ===== 热门网址:跨分类聚合的全站 TOP N ===== #}
{% if top_navs %}
<section class="section section-hot" id="cat-top">
<div class="section-header">
<h2><i class="layui-icon layui-icon-fire"></i> 热门网址</h2>
<div class="meta">全站访客共同热度,前 {{ top_navs|length }} 个</div>
</div>
<div class="grid">
{% for item in top_navs %}
{{ nav_card(item, 'card-top') }}
{% endfor %}
</div>
</section>
{% endif %}
{% for category, items in groups.items() %}
{# 锚点与左侧侧栏、顶部横条、移动端抽屉共用同一套 id #}
{% set cat_id = (cat_anchors or {}).get(category) or ('cat-' ~ loop.index) %}
<section class="section" id="{{ cat_id }}" data-cat="{{ category }}">
<div class="section-header">
<h2>{{ category }}</h2>
<div class="meta">
共 {{ items|length }} 个 ·
<a href="{{ url_for('public_nav.category_detail', name=category) }}">查看全部 →</a>
</div>
</div>
<div class="grid">
{% for item in items %}
{{ nav_card(item) }}
{% endfor %}
</div>
</section>
{% endfor %}
{% endif %}
{% endblock %}