前言

星度主题的瞬间插件适配已经等了很久了,但是最近买了Cursor Pro,那就让AI帮我折腾一下吧

效果

演示:瞬间 - 星尘客栈

并且增添了一些配置

操作

比较累不想写太详细的教程,如果哪里跟不上可以询问AI

首先你的博客是星度主题且安装了瞬间插件

接下来获取你的主题文件,如果方便可以直接修改,当然如果你不方便或者不会可以通过下载备份的手段获取主题文件

打开主题目录

首先编辑setting.yaml文件,在最后面添加如下代码

    - group: moments
      label: 瞬间设置
      formSchema:
        - $formkit: text
          name: moments_title
          label: 瞬间页面标题
          value: "瞬间"
          validation: required
        - $formkit: text
          name: moments_description
          label: 瞬间页面描述
          value: "记录生活的美好瞬间,分享内心的感动。"
          validation: required
        - $formkit: number
          name: moments_per_page
          label: 每页显示数量
          value: 10
          min: 5
          max: 50
          help: 设置瞬间列表每页显示的瞬间数量。
          validation: required
        - $formkit: radio
          name: moments_show_stats
          label: 显示统计信息
          value: true
          options:
            - label: 显示
              value: true
            - label: 隐藏
              value: false
        - $formkit: radio
          name: moments_show_tags
          label: 显示标签筛选
          value: true
          options:
            - label: 显示
              value: true
            - label: 隐藏
              value: false

保存后在templates 目录新建文件moment.html 代码如下

<!DOCTYPE html>
<html xmlns:th="https://www.thymeleaf.org"
  th:replace="~{modules/layout :: layout(_title = '瞬间详情',menu_site_title = '正在阅读:瞬间详情',_content = ~{::content},
  _head = ~{::head},page_js = ~{::page_js}, body_class = 'page-template page-template-moment page wide-page')}">
<th:block th:fragment="head">
  <th:block th:replace="~{modules/page-css}" />
  <link rel="stylesheet" th:href="@{/assets/css/moments.css?v={version}(version=${theme.spec.version})}" type="text/css" media="all">
</th:block>
<th:block th:fragment="content">
  <main id="main" class="site-main" role="main">
    <header class="page-header">
      <div class="breadcrumb fade-before">
        <a th:href="@{/moments}">瞬间</a>
        <span class="separator">/</span>
        <span>详情</span>
      </div>
    </header>
    
    <article class="moment-detail">
      <div class="moment-item fade-before">
        <div class="moment-header">
          <div class="moment-author">
            <img th:if="${moment.owner != null && not #strings.isEmpty(moment.owner.avatar)}" 
                 th:src="${moment.owner.avatar}" 
                 th:alt="${moment.owner.displayName}"
                 class="author-avatar">
            <div class="author-info">
              <span class="author-name" th:text="${moment.owner != null ? moment.owner.displayName : '未知作者'}">作者</span>
              <time class="moment-time" th:datetime="${moment.spec.releaseTime}" 
                    th:text="${moment.spec.releaseTime != null ? #dates.format(moment.spec.releaseTime, 'yyyy年MM月dd日 HH:mm') : '未知时间'}">时间</time>
            </div>
          </div>
          <div class="moment-stats" th:if="${theme.config.moments.moments_show_stats}">
            <span class="stat-item" th:if="${moment.stats != null && moment.stats.upvote > 0}">
              <i class="thyuu-iconfont thyuu-icon-like"></i>
              <span th:text="${moment.stats.upvote}">0</span>
            </span>
            <span class="stat-item" th:if="${moment.stats != null && moment.stats.totalComment > 0}">
              <i class="thyuu-iconfont thyuu-icon-pinglun"></i>
              <span th:text="${moment.stats.totalComment}">0</span>
            </span>
          </div>
        </div>
        
        <!-- 瞬间内容 -->
        <div class="moment-content" th:if="${moment.spec != null && moment.spec.content != null && not #strings.isEmpty(moment.spec.content.html)}">
          <div class="moment-text" th:utext="${moment.spec.content.html}"></div>
        </div>
        
        <!-- 媒体内容 -->
        <div class="moment-media" th:if="${moment.spec != null && moment.spec.content != null && not #lists.isEmpty(moment.spec.content.medium)}">
          <div class="media-grid" th:if="${#lists.size(moment.spec.content.medium) == 1}">
            <div class="media-item single" th:each="media : ${moment.spec.content.medium}">
              <img th:if="${media.type.toString() == 'PHOTO' or media.type.toString() == 'photo' or media.type.name() == 'PHOTO'}" 
                   th:src="${media.url.startsWith('http') ? media.url : (media.url.startsWith('/upload') ? media.url : ('/upload' + media.url))}" 
                   th:alt="瞬间图片"
                   class="media-image"
                   data-fancybox="moment-detail">
              <video th:if="${media.type.toString() == 'VIDEO' or media.type.toString() == 'video' or media.type.name() == 'VIDEO'}" 
                     th:src="${media.url.startsWith('http') ? media.url : (media.url.startsWith('/upload') ? media.url : ('/upload' + media.url))}" 
                     controls 
                     preload="metadata"
                     class="media-video">
                <p>您的浏览器不支持视频播放。</p>
              </video>
              <audio th:if="${media.type.toString() == 'AUDIO' or media.type.toString() == 'audio' or media.type.name() == 'AUDIO'}" 
                     th:src="${media.url.startsWith('http') ? media.url : (media.url.startsWith('/upload') ? media.url : ('/upload' + media.url))}" 
                     controls 
                     preload="metadata"
                     class="media-audio">
                <p>您的浏览器不支持音频播放。</p>
              </audio>
            </div>
          </div>
          <div class="media-grid multiple" th:if="${#lists.size(moment.spec.content.medium) > 1}">
            <div class="media-item" th:each="media : ${moment.spec.content.medium}">
              <img th:if="${media.type.toString() == 'PHOTO' or media.type.toString() == 'photo' or media.type.name() == 'PHOTO'}" 
                   th:src="${media.url.startsWith('http') ? media.url : (media.url.startsWith('/upload') ? media.url : ('/upload' + media.url))}" 
                   th:alt="瞬间图片"
                   class="media-image"
                   data-fancybox="moment-detail">
              <video th:if="${media.type.toString() == 'VIDEO' or media.type.toString() == 'video' or media.type.name() == 'VIDEO'}" 
                     th:src="${media.url.startsWith('http') ? media.url : (media.url.startsWith('/upload') ? media.url : ('/upload' + media.url))}" 
                     controls 
                     preload="metadata"
                     class="media-video">
                <p>您的浏览器不支持视频播放。</p>
              </video>
              <audio th:if="${media.type.toString() == 'AUDIO' or media.type.toString() == 'audio' or media.type.name() == 'AUDIO'}" 
                     th:src="${media.url.startsWith('http') ? media.url : (media.url.startsWith('/upload') ? media.url : ('/upload' + media.url))}" 
                     controls 
                     preload="metadata"
                     class="media-audio">
                <p>您的浏览器不支持音频播放。</p>
              </audio>
            </div>
          </div>
        </div>
        
        <!-- 标签 -->
        <div class="moment-tags" th:if="${moment.spec != null && not #lists.isEmpty(moment.spec.tags)}">
          <span class="tag" th:each="tag : ${moment.spec.tags}">
            <a th:href="|/moments?tag=${tag}|" th:text="${tag}">标签</a>
          </span>
        </div>
        
        <!-- 互动按钮和操作按钮 -->
        <div class="moment-actions">
          <div class="interaction-buttons">
            <button class="interaction-btn like-btn" th:data-moment-id="${moment.metadata.name}">
              <span class="like-icon">❤️</span>
              <span class="like-count" th:text="${moment.stats != null ? moment.stats.upvote : 0}">0</span>
            </button>
            <button class="interaction-btn share-btn" th:data-moment-id="${moment.metadata.name}">
              <span class="share-icon">📤</span>
              <span>分享</span>
            </button>
          </div>
          
          <a th:href="@{/moments}" class="action-link back-btn">
            <i class="thyuu-iconfont thyuu-icon-back"></i>
            <span>返回瞬间</span>
          </a>
        </div>
      </div>
      
      <!-- 评论区域 -->
      <div class="moment-comments fade-before">
        <h3 class="comments-title">评论</h3>
        <div class="comments-container">
          <!-- 集成Halo评论插件 -->
          <th:block th:replace="~{modules/widgets/comment :: comment(post_name=${moment.metadata.name},kind='Moment',group='moment.halo.run')}"></th:block>
        </div>
      </div>
    </article>
  </main>
</th:block>

<th:block th:fragment="page_js">
<script>
// 瞬间详情页面 - 最后执行的脚本(避免冲突)
console.log('🚀 瞬间详情页面脚本开始执行!');
console.log('当前时间:', new Date().toISOString());
console.log('页面URL:', window.location.href);
console.log('文档状态:', document.readyState);

// 优化:只等待DOM就绪,不等待所有资源
function waitForDOMReady() {
  return new Promise((resolve) => {
    if (document.readyState === 'interactive' || document.readyState === 'complete') {
      resolve();
    } else {
      document.addEventListener('DOMContentLoaded', resolve);
    }
  });
}

// 主要的按钮功能
function initMomentButtons() {
  console.log('🔍 开始初始化瞬间按钮...');
  
  const likeBtn = document.querySelector('.like-btn');
  const shareBtn = document.querySelector('.share-btn');
  
  console.log('点赞按钮:', likeBtn ? '✅ 找到' : '❌ 未找到');
  console.log('分享按钮:', shareBtn ? '✅ 找到' : '❌ 未找到');
  
  if (likeBtn) {
    // 移除可能存在的旧事件监听器
    const newLikeBtn = likeBtn.cloneNode(true);
    likeBtn.parentNode.replaceChild(newLikeBtn, likeBtn);
    
    newLikeBtn.addEventListener('click', function(e) {
      e.preventDefault();
      e.stopPropagation();
      console.log('🎯 点赞按钮被点击!');
      
      const momentId = this.getAttribute('data-moment-id');
      const likeCount = this.querySelector('.like-count');
      const likeIcon = this.querySelector('.like-icon');
      
      if (likeCount && likeIcon && momentId) {
        // 检查是否已经点赞过
        const wasLiked = this.classList.contains('liked');
        
        if (wasLiked) {
          console.log('❌ 已经点赞过了,不能重复点赞');
          return; // 已经点赞过,直接返回
        }
        
        // 更新UI状态(只支持点赞,不支持取消)
        this.classList.add('liked');
        let currentCount = parseInt(likeCount.textContent) || 0;
        likeCount.textContent = currentCount + 1;
        likeIcon.textContent = '💖';
        
        console.log(`点赞成功!数量: ${likeCount.textContent}`);
        
        // 保存点赞状态到localStorage
        saveLikeStatus(momentId, true);
        
        // 尝试提交到后端
        submitLikeToBackend(momentId);
        
        // 显示反馈
        showLikeFeedback(true);
        
        // 禁用按钮,防止重复点击
        this.style.pointerEvents = 'none';
        this.style.opacity = '0.7';
        console.log('✅ 点赞按钮已禁用,防止重复点赞');
      }
    });
    
    console.log('✅ 点赞按钮事件已绑定');
  }
  
  if (shareBtn) {
    // 移除可能存在的旧事件监听器
    const newShareBtn = shareBtn.cloneNode(true);
    shareBtn.parentNode.replaceChild(newShareBtn, shareBtn);
    
    newShareBtn.addEventListener('click', function(e) {
      e.preventDefault();
      e.stopPropagation();
      console.log('🎯 分享按钮被点击!');
      
      // 简单的分享功能
      const url = window.location.href;
      const title = document.title;
      
      if (navigator.share) {
        navigator.share({
          title: title,
          url: url
        }).then(() => {
          console.log('分享成功');
        }).catch((error) => {
          console.log('分享失败:', error);
          fallbackShare(url, title);
        });
      } else {
        fallbackShare(url, title);
      }
    });
    
    console.log('✅ 分享按钮事件已绑定');
  }
}

// 备用分享功能
function fallbackShare(url, title) {
  if (navigator.clipboard) {
    navigator.clipboard.writeText(url).then(() => {
      console.log('链接已复制到剪贴板');
      alert('链接已复制到剪贴板');
    });
  } else {
    const input = document.createElement('input');
    input.value = url;
    document.body.appendChild(input);
    input.select();
    document.execCommand('copy');
    document.body.removeChild(input);
    console.log('链接已复制到剪贴板(备用方法)');
    alert('链接已复制到剪贴板');
  }
}

// 点赞相关功能
function saveLikeStatus(momentId, isLiked) {
  try {
    const likes = JSON.parse(localStorage.getItem('moment-likes') || '{}');
    likes[momentId] = isLiked;
    localStorage.setItem('moment-likes', JSON.stringify(likes));
    console.log(`✅ 点赞状态已保存到localStorage: ${momentId} = ${isLiked}`);
  } catch (error) {
    console.error('❌ 保存点赞状态失败:', error);
  }
}

function getLikeStatus(momentId) {
  try {
    const likes = JSON.parse(localStorage.getItem('moment-likes') || '{}');
    return likes[momentId] || false;
  } catch (error) {
    console.error('❌ 获取点赞状态失败:', error);
    return false;
  }
}

function submitLikeToBackend(momentId) {
  // 只支持点赞,不支持取消点赞
  const apiEndpoints = [
    `/apis/api.halo.run/v1alpha1/trackers/upvote`
  ];
  
  const payload = {
    group: "moment.halo.run",
    plural: "moments", 
    name: momentId
  };
  
  // 尝试每个端点
  apiEndpoints.forEach((endpoint, index) => {
    setTimeout(() => {
      // 只使用POST方法进行点赞
      fetch(endpoint, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'Accept': 'application/json',
          'X-Requested-With': 'XMLHttpRequest'
        },
        body: JSON.stringify(payload)
      })
      .then(response => {
        if (response.ok) {
          console.log(`✅ 点赞数据已提交到后端: ${endpoint}`);
          return response.json();
        } else {
          console.log(`⚠️ API端点不可用: ${endpoint} (${response.status})`);
          throw new Error(`HTTP ${response.status}`);
        }
      })
      .then(data => {
        console.log('📊 后端响应:', data);
        // 如果后端返回了新的点赞数,更新UI
        if (data && typeof data.upvote !== 'undefined') {
          const likeCount = document.querySelector('.like-count');
          if (likeCount) {
            likeCount.textContent = data.upvote;
            console.log(`🔄 从后端更新点赞数: ${data.upvote}`);
          }
        }
      })
      .catch(error => {
        console.log(`❌ API请求失败: ${endpoint}`, error.message);
      });
    }, index * 100); // 每个请求间隔100ms
  });
}

function showLikeFeedback(isLiked) {
  // 创建反馈提示
  const feedback = document.createElement('div');
  feedback.style.cssText = `
    position: fixed;
    top: 20px;
    right: 20px;
    background: ${isLiked ? '#4CAF50' : '#f44336'};
    color: white;
    padding: 12px 20px;
    border-radius: 8px;
    font-size: 14px;
    z-index: 10000;
    box-shadow: 0 4px 12px rgba(0,0,0,0.15);
    animation: slideIn 0.3s ease-out;
  `;
  
  feedback.textContent = isLiked ? '💖 已点赞' : '💔 已取消点赞';
  
  // 添加动画样式
  const style = document.createElement('style');
  style.textContent = `
    @keyframes slideIn {
      from { transform: translateX(100%); opacity: 0; }
      to { transform: translateX(0); opacity: 1; }
    }
  `;
  document.head.appendChild(style);
  
  document.body.appendChild(feedback);
  
  // 3秒后自动移除
  setTimeout(() => {
    feedback.style.animation = 'slideIn 0.3s ease-out reverse';
    setTimeout(() => {
      if (feedback.parentNode) {
        feedback.parentNode.removeChild(feedback);
      }
      if (style.parentNode) {
        style.parentNode.removeChild(style);
      }
    }, 300);
  }, 3000);
}

// 优化:从后端获取点赞数,HTML中已有初始值
function loadLikeCountFromBackend(momentId) {
  const endpoint = '/apis/api.halo.run/v1alpha1/trackers/upvote';
  const likeCount = document.querySelector('.like-count');
  
  // HTML中已经有初始值,直接异步获取最新数据
  fetch(endpoint, {
    method: 'GET',
    headers: {
      'Content-Type': 'application/json',
      'X-Requested-With': 'XMLHttpRequest'
    }
  })
  .then(response => {
    if (response.ok) {
      return response.json();
    } else {
      console.log(`⚠️ 获取点赞数失败: ${response.status}`);
      throw new Error(`HTTP ${response.status}`);
    }
  })
  .then(data => {
    console.log('📊 获取到的点赞数据:', data);
    
    // 查找当前瞬间的点赞数
    if (data && data.items) {
      const currentMomentTracker = data.items.find(item => 
        item.spec && 
        item.spec.group === 'moment.halo.run' && 
        item.spec.plural === 'moments' && 
        item.spec.name === momentId
      );
      
      if (currentMomentTracker && currentMomentTracker.spec.upvote !== undefined) {
        if (likeCount) {
          const currentValue = parseInt(likeCount.textContent) || 0;
          const newValue = currentMomentTracker.spec.upvote;
          
          // 只在数值不同时更新,避免不必要的DOM操作
          if (currentValue !== newValue) {
            likeCount.textContent = newValue;
            console.log(`✅ 更新点赞数: ${currentValue} → ${newValue}`);
          } else {
            console.log(`ℹ️ 点赞数无变化: ${newValue}`);
          }
        }
      } else {
        console.log('ℹ️ 未找到当前瞬间的点赞数据,保持HTML初始值');
      }
    }
  })
  .catch(error => {
    console.log(`❌ 获取点赞数失败:`, error.message);
    // 保持HTML中的初始值
  });
}

function loadLikeStatus(momentId) {
  const isLiked = getLikeStatus(momentId);
  const likeBtn = document.querySelector('.like-btn');
  
  if (likeBtn && isLiked) {
    likeBtn.classList.add('liked');
    const likeIcon = likeBtn.querySelector('.like-icon');
    if (likeIcon) {
      likeIcon.textContent = '💖';
    }
    
    // 禁用按钮,防止重复点赞
    likeBtn.style.pointerEvents = 'none';
    likeBtn.style.opacity = '0.7';
    
    console.log(`🔄 已加载点赞状态: ${momentId} = ${isLiked},按钮已禁用`);
  }
}

// 调试功能已移除

// 优化:主初始化函数,移除重复执行和调试开销
async function initMomentPage() {
  console.log('=== 开始初始化瞬间详情页面 ===');
  
  // 只等待DOM就绪,不等待所有资源
  await waitForDOMReady();
  console.log('✅ DOM已就绪');
  
  // 获取瞬间ID
  const momentId = document.querySelector('.like-btn')?.getAttribute('data-moment-id');
  console.log('瞬间ID:', momentId);
  
  // 初始化按钮
  initMomentButtons();
  
  // 加载保存的点赞状态和点赞数
  if (momentId) {
    loadLikeStatus(momentId);
    // 优化:立即显示初始值,异步获取最新数据
    loadLikeCountFromBackend(momentId);
  }
  
  // 延迟初始化(减少初始加载开销)
  setTimeout(() => {
    // 调试功能已移除
  }, 500);
  
  // 优化:使用事件委托处理图片错误,减少内存开销
  document.addEventListener('error', function(e) {
    if (e.target.classList.contains('media-image')) {
      console.warn('图片加载失败:', e.target.src);
      e.target.style.display = 'none';
      
      const placeholder = document.createElement('div');
      placeholder.className = 'image-placeholder';
      placeholder.innerHTML = `
        <div style="display: flex; flex-direction: column; align-items: center; justify-content: center; 
                    height: 200px; background: #f5f5f5; border-radius: 8px; color: #666;">
          <i class="thyuu-iconfont thyuu-icon-image" style="font-size: 2rem; margin-bottom: 0.5rem;"></i>
          <span>图片加载失败</span>
        </div>
      `;
      e.target.parentNode.insertBefore(placeholder, e.target);
    }
  }, true);
  
  // 延迟初始化Fancybox(非关键功能)
  setTimeout(() => {
    if (typeof Fancybox !== 'undefined') {
      Fancybox.bind("[data-fancybox]", {
        Image: {
          zoom: true,
          click: "toggleZoom",
          wheel: "zoom",
          doubleClick: "zoom"
        }
      });
      console.log('✅ Fancybox已初始化');
    } else {
      console.warn('⚠️ Fancybox未加载');
    }
  }, 200);
  
  console.log('✅ 瞬间详情页面初始化完成');
}

// 测试评论API连接
function testCommentAPI() {
  const momentId = document.querySelector('.like-btn')?.getAttribute('data-moment-id');
  if (!momentId) {
    console.log('❌ 无法获取瞬间ID');
    return;
  }
  
  const commentAPI = `/apis/api.halo.run/v1alpha1/comments?kind=Moment&group=moment.halo.run&name=${momentId}`;
  console.log('🔍 测试评论API:', commentAPI);
  
  fetch(commentAPI, {
    method: 'GET',
    headers: {
      'Content-Type': 'application/json',
      'X-Requested-With': 'XMLHttpRequest'
    }
  })
  .then(response => {
    if (response.ok) {
      return response.json();
    } else {
      console.log(`⚠️ 评论API请求失败: ${response.status}`);
      throw new Error(`HTTP ${response.status}`);
    }
  })
  .then(data => {
    console.log('📊 评论API响应:', data);
    const commentCount = data.total || 0;
    console.log(`✅ 评论API连接正常,当前评论数: ${commentCount}`);
  })
  .catch(error => {
    console.log(`❌ 评论API连接失败:`, error.message);
  });
}

// 优化:只执行一次初始化
initMomentPage();

console.log('✅ 瞬间详情页面脚本加载完成');
</script>
</th:block>

</html>

在同样目录下新建文件moments.html ,代码如下

<!DOCTYPE html>
<html xmlns:th="https://www.thymeleaf.org"
  th:replace="~{modules/layout :: layout(_title = '瞬间',menu_site_title = '正在阅读:瞬间',_content = ~{::content},
  _head = ~{::head},page_js = null, body_class = 'page-template page-template-moments page wide-page')}">
<th:block th:fragment="head">
  <th:block th:replace="~{modules/page-css}" />
  <link rel="stylesheet" th:href="@{/assets/css/moments.css?v={version}(version=${theme.spec.version})}" type="text/css" media="all">
</th:block>
<th:block th:fragment="content">
  <main id="main" class="site-main" role="main">
    <header class="page-header">
      <h1 class="page-title fade-before">
        <span th:text="${theme.config.moments.moments_title}">瞬间</span>
        <em class="num" th:utext="${moments.total + ' 条'}"></em>
      </h1>
      <div class="taxonomy-des fade-before">
        <p th:text="${theme.config.moments.moments_description}">记录生活的美好瞬间,分享内心的感动。</p>
      </div>
      <!-- 标签筛选 -->
      <nav class="taxonomy-nav fade-before" th:if="${not #lists.isEmpty(tags) && theme.config.moments.moments_show_tags}">
        <ul class="taxonomy-sub no-scrollbar">
          <li>
            <a th:href="@{/moments}" th:classappend="${#strings.isEmpty(param.tag)} ? 'active' : ''">全部</a>
          </li>
          <li th:each="tag : ${tags}">
            <a th:href="|/moments?tag=${tag.name}|" 
               th:classappend="${#strings.equals(param.tag, tag.name)} ? 'active' : ''"
               th:text="${tag.name}">标签</a>
          </li>
        </ul>
      </nav>
    </header>
    
    <article class="moments-container page type-page hentry">
      <!-- 瞬间列表 -->
      <div class="moments-list" th:if="${moments != null && not #lists.isEmpty(moments.items)}">
        <div class="moment-item fade-before" th:each="moment : ${moments.items}">
          <div class="moment-header">
            <div class="moment-author">
              <img th:if="${not #strings.isEmpty(moment.owner.avatar)}" 
                   th:src="${moment.owner.avatar}" 
                   th:alt="${moment.owner.displayName}"
                   class="author-avatar">
              <div class="author-info">
                <span class="author-name" th:text="${moment.owner.displayName}">作者</span>
                <time class="moment-time" th:datetime="${moment.spec.releaseTime}" 
                      th:text="${#dates.format(moment.spec.releaseTime, 'yyyy年MM月dd日 HH:mm')}">时间</time>
              </div>
            </div>
            </div>
          
          <!-- 瞬间内容 -->
          <div class="moment-content" th:if="${not #strings.isEmpty(moment.spec.content.html)}">
            <div class="moment-text-wrapper" th:classappend="${#strings.length(moment.spec.content.html) > 200 ? 'collapsed' : ''}">
              <div class="moment-text" th:utext="${moment.spec.content.html}"></div>
              <div class="content-hint" th:if="${#strings.length(moment.spec.content.html) > 200}">
                <span class="hint-text">内容过长,点击详情查看</span>
              </div>
            </div>
          </div>
          
          <!-- 媒体内容 -->
          
          <div class="moment-media" th:if="${moment.spec.content.medium != null and not #lists.isEmpty(moment.spec.content.medium)}">
            <div class="media-grid" th:if="${#lists.size(moment.spec.content.medium) == 1}">
              <div class="media-item single" th:each="media : ${moment.spec.content.medium}">
                <img th:if="${media.type.toString() == 'PHOTO' or media.type.toString() == 'photo' or media.type.name() == 'PHOTO'}" 
                     th:src="${media.url.startsWith('http') ? media.url : (media.url.startsWith('/upload') ? media.url : ('/upload' + media.url))}" 
                     th:alt="瞬间图片"
                     class="media-image"
                     data-fancybox="moment-[[${moment.metadata.name}]]">
                <video th:if="${media.type.toString() == 'VIDEO' or media.type.toString() == 'video' or media.type.name() == 'VIDEO'}" 
                       th:src="${media.url.startsWith('http') ? media.url : (media.url.startsWith('/upload') ? media.url : ('/upload' + media.url))}" 
                       controls 
                       preload="none"
                       class="media-video">
                  <p>您的浏览器不支持视频播放。</p>
                </video>
                <audio th:if="${media.type.toString() == 'AUDIO' or media.type.toString() == 'audio' or media.type.name() == 'AUDIO'}" 
                       th:src="${media.url.startsWith('http') ? media.url : (media.url.startsWith('/upload') ? media.url : ('/upload' + media.url))}" 
                       controls 
                       preload="none"
                       class="media-audio">
                  <p>您的浏览器不支持音频播放。</p>
                </audio>
              </div>
            </div>
            <div class="media-grid multiple" th:if="${#lists.size(moment.spec.content.medium) > 1}">
              <div class="media-item" th:each="media : ${moment.spec.content.medium}">
                <img th:if="${media.type.toString() == 'PHOTO' or media.type.toString() == 'photo' or media.type.name() == 'PHOTO'}" 
                     th:src="${media.url.startsWith('http') ? media.url : (media.url.startsWith('/upload') ? media.url : ('/upload' + media.url))}" 
                     th:alt="瞬间图片"
                     class="media-image"
                     data-fancybox="moment-[[${moment.metadata.name}]]">
                <video th:if="${media.type.toString() == 'VIDEO' or media.type.toString() == 'video' or media.type.name() == 'VIDEO'}" 
                       th:src="${media.url.startsWith('http') ? media.url : (media.url.startsWith('/upload') ? media.url : ('/upload' + media.url))}" 
                       controls 
                       preload="none"
                       class="media-video">
                  <p>您的浏览器不支持视频播放。</p>
                </video>
                <audio th:if="${media.type.toString() == 'AUDIO' or media.type.toString() == 'audio' or media.type.name() == 'AUDIO'}" 
                       th:src="${media.url.startsWith('http') ? media.url : (media.url.startsWith('/upload') ? media.url : ('/upload' + media.url))}" 
                       controls 
                       preload="none"
                       class="media-audio">
                  <p>您的浏览器不支持音频播放。</p>
                </audio>
              </div>
            </div>
          </div>
          
          <!-- 标签 -->
          <div class="moment-tags" th:if="${not #lists.isEmpty(moment.spec.tags)}">
            <span class="tag" th:each="tag : ${moment.spec.tags}">
              <a th:href="|/moments?tag=${tag}|" th:text="${tag}">标签</a>
            </span>
          </div>
          
          <!-- 底部信息栏 -->
          <div class="moment-footer">
            <!-- 统计信息和按钮并列 -->
            <div class="moment-footer-content">
              <!-- 统计信息 -->
              <div class="moment-stats" th:if="${theme.config.moments.moments_show_stats}">
                <span class="stat-item" th:if="${moment.stats != null && moment.stats.upvote > 0}">
                  <span class="stat-number" th:text="${moment.stats.upvote}">0</span>
                  <span class="stat-label">人赞了</span>
                </span>
                <span class="stat-item" th:if="${moment.stats != null && moment.stats.totalComment > 0}">
                  <span class="stat-number" th:text="${moment.stats.totalComment}">0</span>
                  <span class="stat-label">人评论</span>
                </span>
              </div>
              
              <!-- 详情按钮 -->
              <div class="moment-actions">
                <a th:href="@{/moments/{name}(name=${moment.metadata.name})}" class="action-link">
                  <i class="thyuu-iconfont thyuu-icon-link"></i>
                  <span>详情</span>
                </a>
              </div>
            </div>
          </div>
        </div>
      </div>
      
      <!-- 空状态 -->
      <div class="moments-empty fade-before" th:if="${moments == null || #lists.isEmpty(moments.items)}">
        <div class="empty-content">
          <i class="thyuu-iconfont thyuu-icon-moment empty-icon"></i>
          <h3>暂无瞬间</h3>
          <p>还没有发布任何瞬间,快去发布第一条吧!</p>
        </div>
      </div>
    </article>
    
    <!-- 分页 -->
    <th:block th:if="${moments != null}" th:replace="~{modules/widgets/pagination :: page('/moments',${moments})}"></th:block>
  </main>
</th:block>

<script>
// 移动端触摸增强
document.addEventListener('DOMContentLoaded', function() {
  // 检测是否为触摸设备
  const isTouchDevice = 'ontouchstart' in window || navigator.maxTouchPoints > 0;
  
  if (isTouchDevice) {
    const cards = document.querySelectorAll('.moment-item');
    
    cards.forEach(card => {
      let touchStartTime = 0;
      
      card.addEventListener('touchstart', function(e) {
        touchStartTime = Date.now();
        this.classList.add('touch-active');
      });
      
      card.addEventListener('touchend', function(e) {
        const touchDuration = Date.now() - touchStartTime;
        
        // 如果触摸时间超过200ms,显示按钮
        if (touchDuration > 200) {
          this.classList.add('touch-active');
          
          // 3秒后自动隐藏
          setTimeout(() => {
            this.classList.remove('touch-active');
          }, 3000);
        } else {
          this.classList.remove('touch-active');
        }
      });
      
      card.addEventListener('touchcancel', function(e) {
        this.classList.remove('touch-active');
      });
    });
  }
  
  // 处理图片加载错误
  const images = document.querySelectorAll('.media-image');
  images.forEach(img => {
    img.addEventListener('error', function() {
      console.warn('图片加载失败:', this.src);
      this.style.display = 'none';
      
      // 创建错误提示元素
      const errorDiv = document.createElement('div');
      errorDiv.className = 'image-error';
      errorDiv.style.cssText = `
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        color: hsl(var(--thyuu--color-font) / 0.6);
        font-size: 0.875rem;
        text-align: center;
        padding: 1rem;
        background: hsl(var(--thyuu--color-font) / 0.05);
        border-radius: var(--thyuu--size-radius);
        border: 1px dashed hsl(var(--thyuu--color-font) / 0.2);
      `;
      errorDiv.textContent = '图片加载失败';
      
      // 插入到父容器中
      const parent = this.parentElement;
      if (parent) {
        parent.style.position = 'relative';
        parent.appendChild(errorDiv);
      }
    });
    
    img.addEventListener('load', function() {
      console.log('图片加载成功:', this.src);
    });
  });
  
  // 初始化Fancybox
  if (typeof Fancybox !== 'undefined') {
    Fancybox.bind("[data-fancybox]", {
      // 图片组配置
      groupAll: false,
      // 工具栏配置
      Toolbar: {
        display: {
          left: ["infobar"],
          middle: ["zoomIn", "zoomOut", "toggle1to1", "rotateCCW", "rotateCW", "flipX", "flipY"],
          right: ["slideshow", "thumbs", "close"]
        }
      },
      // 缩略图配置
      Thumbs: {
        autoStart: false
      },
      // 图片配置
      Image: {
        zoom: true,
        click: "toggleZoom",
        wheel: "zoom",
        doubleClick: "zoom"
      }
    });
  } else {
    console.warn('Fancybox未加载,图片预览功能可能不可用');
  }
});
</script>


</html>

主题目录\templates\assets\css 下创建文件moments.css ,内容如下

@charset "utf-8";

/* =瞬间页面样式
-------------------------------------------------------------- */

/* 瞬间列表容器 */
.moments-container {
  max-width: 95% !important;
  width: 95% !important;
  margin: 0 auto;
  padding: 0 1rem;
}

/* 覆盖主题的内容宽度限制 */
.page-template-moments .moments-container {
  max-width: 95% !important;
  width: 95% !important;
}

/* 确保瞬间页面不受内容宽度限制 */
.page-template-moments .site-main > .moments-container {
  max-width: 95% !important;
  width: 95% !important;
}

/* 强制覆盖所有可能的内容宽度限制 */
.page-template-moments .moments-container,
.page-template-moments .site-main .moments-container,
body.page-template-moments .moments-container {
  max-width: 95% !important;
  width: 95% !important;
  margin-left: auto !important;
  margin-right: auto !important;
}

/* 网格布局优化 */
.moments-list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 1.5rem;
  align-items: start;
  justify-items: stretch;
  margin-bottom: 2rem;
}

/* 瞬间项目 */
.moment-item {
  background: var(--thyuu--color-back-white);
  border-radius: var(--thyuu--size-radius);
  box-shadow: var(--thyuu--shadow-white);
  padding: 1.5rem;
  transition: all 0.3s ease;
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  height: fit-content;
  min-height: 200px;
}

.moment-item:hover {
  box-shadow: var(--thyuu--shadow-normal);
  /* 删除hover动画,避免鼠标卡住 */
}


/* 瞬间头部 */
.moment-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: 1rem;
}

.moment-author {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.author-avatar {
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 50%;
  object-fit: cover;
  border: 2px solid hsl(var(--thyuu--main-color) / 0.1);
  transition: all 0.3s ease;
}

.moment-item:hover .author-avatar {
  border-color: hsl(var(--thyuu--main-color) / 0.3);
  /* 简化头像动画,避免鼠标卡住 */
  transform: none;
}

.author-info {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.author-name {
  font-weight: 600;
  color: hsl(var(--thyuu--color-font));
  font-size: 0.95rem;
}

.moment-time {
  font-size: 0.8rem;
  color: hsl(var(--thyuu--color-font) / 0.6);
}

/* 底部信息栏布局 */
.moment-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding-top: 1rem;
  margin-top: auto;
  border-top: 1px solid hsl(var(--thyuu--color-border));
}

/* 底部信息栏布局 */
.moment-footer-content {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
}

/* 统计信息 - 新格式 */
.moment-stats {
  display: flex;
  gap: 1rem;
  align-items: center;
}

.stat-item {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  font-size: 0.85rem;
}

.stat-number {
  font-weight: 600;
  color: hsl(var(--thyuu--main-color));
  font-size: 0.9rem;
}

.stat-label {
  color: hsl(var(--thyuu--color-font) / 0.6);
  font-weight: 400;
}

/* 瞬间内容 */
.moment-content {
  margin-bottom: 1rem;
}

.moment-text {
  line-height: 1.6;
  color: hsl(var(--thyuu--color-font));
  word-break: break-word;
}

.moment-text p {
  margin: 0 0 0.5rem 0;
}

.moment-text p:last-child {
  margin-bottom: 0;
}

/* 文本省略效果 - 优化版本 */
.moment-text-wrapper {
  position: relative;
}

.moment-text-wrapper.collapsed .moment-text {
  max-height: 4.5em; /* 约3行文字的高度 */
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  -webkit-box-orient: vertical;
  word-break: break-word;
  line-height: 1.5;
  position: relative;
}

/* 渐变遮罩效果 */
.moment-text-wrapper.collapsed .moment-text::after {
  content: '';
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  height: 1.5em;
  background: linear-gradient(transparent, hsl(var(--thyuu--color-back-white)));
  pointer-events: none;
}

/* 内容提示样式 */
.content-hint {
  margin-top: 0.5rem;
  text-align: center;
}

.hint-text {
  display: inline-block;
  padding: 0.3rem 0.8rem;
  background: hsl(var(--thyuu--color-bg) / 0.8);
  color: hsl(var(--thyuu--color-text) / 0.7);
  border: 1px solid hsl(var(--thyuu--color-border));
  border-radius: 0.5rem;
  font-size: 0.75rem;
  font-weight: 400;
  backdrop-filter: blur(4px);
  transition: all 0.2s ease;
}

.hint-text:hover {
  background: hsl(var(--thyuu--color-bg) / 0.9);
  color: hsl(var(--thyuu--color-text) / 0.8);
  border-color: hsl(var(--thyuu--main-color) / 0.3);
}

/* 媒体内容 */
.moment-media {
  margin-bottom: 1rem;
}

.media-grid {
  display: grid;
  gap: 0.5rem;
  border-radius: var(--thyuu--size-radius);
  overflow: hidden;
}

.media-grid.single {
  grid-template-columns: 1fr;
}

.media-grid.multiple {
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}

.media-item {
  position: relative;
  overflow: hidden;
  border-radius: var(--thyuu--size-radius);
  background: hsl(var(--thyuu--color-font) / 0.05);
}

.media-item.single {
  max-height: 500px;
}

.media-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.3s ease;
  cursor: pointer;
  display: block;
  background: hsl(var(--thyuu--color-font) / 0.05);
}

/* 图片加载失败时的样式 */
.media-image:not([src]),
.media-image[src=""],
.media-image[src*="undefined"],
.media-image[src*="null"] {
  background: hsl(var(--thyuu--color-font) / 0.1);
  position: relative;
}

.media-image:not([src]):after,
.media-image[src=""]:after,
.media-image[src*="undefined"]:after,
.media-image[src*="null"]:after {
  content: "图片加载失败";
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  color: hsl(var(--thyuu--color-font) / 0.6);
  font-size: 0.875rem;
  text-align: center;
}


.media-video {
  width: 100%;
  height: auto;
  max-height: 400px;
  border-radius: var(--thyuu--size-radius);
}

.media-audio {
  width: 100%;
  height: 40px;
  border-radius: var(--thyuu--size-radius);
}

/* 标签 */
.moment-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 1rem;
}

.tag {
  display: inline-block;
}

.tag a {
  display: inline-block;
  padding: 0.25rem 0.75rem;
  background: hsl(var(--thyuu--main-color) / 0.1);
  color: hsl(var(--thyuu--main-color));
  border-radius: 1rem;
  font-size: 0.8rem;
  text-decoration: none;
  transition: all 0.3s ease;
}

.tag a:hover {
  background: hsl(var(--thyuu--main-color) / 0.2);
  /* 简化标签动画,避免鼠标卡住 */
  transform: none;
}

/* 操作按钮 - 紧凑设计 */
.moment-actions {
  display: flex;
  align-items: center;
}

/* 互动按钮组 */
.interaction-buttons {
  display: flex;
  gap: 0.75rem;
  align-items: center;
}

/* 返回按钮样式调整 */
.back-btn {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 1rem;
  background: hsl(var(--thyuu--main-color) / 0.1);
  border-radius: var(--thyuu--size-radius);
  text-decoration: none;
  color: hsl(var(--thyuu--color-font));
  transition: all 0.3s ease;
  font-size: 0.9rem;
  overflow: hidden;
}

.back-btn::before {
  content: '';
  position: absolute;
  top: 0;
  left: -100%;
  width: 100%;
  height: 100%;
  background: linear-gradient(90deg, 
    transparent, 
    hsl(var(--thyuu--main-color) / 0.2), 
    transparent);
  transition: left 0.8s ease-in-out;
}

.back-btn:hover::before {
  left: 100%;
}

.back-btn:hover {
  background: hsl(var(--thyuu--main-color) / 0.2);
  transform: translateY(-1px);
}


/* 操作按钮脉冲效果 */
.action-link {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.4rem 0.8rem;
  background: linear-gradient(135deg, 
    hsl(var(--thyuu--main-color) / 0.1) 0%, 
    hsl(var(--thyuu--main-color) / 0.15) 100%);
  color: hsl(var(--thyuu--main-color));
  border: 1px solid hsl(var(--thyuu--main-color) / 0.2);
  border-radius: 0.5rem;
  text-decoration: none;
  font-size: 0.8rem;
  font-weight: 500;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  backdrop-filter: blur(10px);
  overflow: hidden;
}

.action-link::before {
  content: '';
  position: absolute;
  top: 0;
  left: -100%;
  width: 100%;
  height: 100%;
  background: linear-gradient(90deg, 
    transparent, 
    hsl(var(--thyuu--main-color) / 0.3), 
    transparent);
  transition: left 0.6s ease-in-out;
}

.action-link:hover::before {
  left: 100%;
}

.action-link:hover {
  background: linear-gradient(135deg, 
    hsl(var(--thyuu--main-color) / 0.2) 0%, 
    hsl(var(--thyuu--main-color) / 0.3) 100%);
  border-color: hsl(var(--thyuu--main-color) / 0.4);
  box-shadow: 
    0 2px 8px hsl(var(--thyuu--main-color) / 0.15),
    0 1px 4px hsl(var(--thyuu--main-color) / 0.1);
  transform: translateY(-1px);
}

.action-link i {
  font-size: 0.85rem;
  transition: transform 0.3s ease;
  position: relative;
  z-index: 1;
}

.action-link:hover i {
  transform: scale(1.1);
}

/* 按钮文字渐变效果 */
.action-link span {
  background: linear-gradient(135deg, 
    hsl(var(--thyuu--main-color)) 0%, 
    hsl(var(--thyuu--main-color) / 0.8) 100%);
  background-clip: text;
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  transition: all 0.3s ease;
}

.action-link:hover span {
  background: linear-gradient(135deg, 
    hsl(var(--thyuu--main-color)) 0%, 
    hsl(var(--thyuu--main-color)) 100%);
  background-clip: text;
  -webkit-background-clip: text;
}

/* 简洁的焦点样式 - 轮廓线在按钮内部 */
.action-link:focus {
  outline: 2px solid hsl(var(--thyuu--main-color));
  outline-offset: -2px;
}

.action-link:focus-visible {
  outline: 2px solid hsl(var(--thyuu--main-color));
  outline-offset: -2px;
}

/* 空状态 */
.moments-empty {
  text-align: center;
  padding: 4rem 2rem;
}

.empty-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1rem;
}

.empty-icon {
  font-size: 4rem;
  color: hsl(var(--thyuu--color-font) / 0.3);
}

.empty-content h3 {
  font-size: 1.5rem;
  color: hsl(var(--thyuu--color-font) / 0.7);
  margin: 0;
}

.empty-content p {
  color: hsl(var(--thyuu--color-font) / 0.5);
  margin: 0;
}

/* 瞬间详情页 */
.moment-detail {
  max-width: 1000px;
  width: 1000px;
  margin: 0 auto;
  padding: 0 1rem;
}

.moment-detail .moment-item {
  margin-bottom: 2rem;
  width: 100%;
  min-width: 1000px;
}

/* 评论区域样式 - 统一版本 */
.moment-comments {
  margin-top: 2rem;
  padding-top: 2rem;
  border-top: 1px solid hsl(var(--thyuu--color-font) / 0.1);
  display: block !important;
  visibility: visible !important;
  opacity: 1 !important;
}

.comments-title {
  font-size: 1.25rem;
  font-weight: 600;
  color: hsl(var(--thyuu--color-font));
  margin-bottom: 1.5rem;
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.comments-title::before {
  content: "💬";
  font-size: 1.1rem;
}

.comments-container {
  background: hsl(var(--thyuu--color-back-white));
  border-radius: var(--thyuu--size-radius);
  padding: 1.5rem;
  box-shadow: var(--thyuu--shadow-white);
  display: block !important;
  visibility: visible !important;
  opacity: 1 !important;
}

/* 面包屑导航 */
.breadcrumb {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 2rem;
  font-size: 0.9rem;
}

.breadcrumb a {
  color: hsl(var(--thyuu--main-color));
  text-decoration: none;
  transition: color 0.3s ease;
}

.breadcrumb a:hover {
  color: hsl(var(--thyuu--main-color) / 0.8);
}

.breadcrumb .separator {
  color: hsl(var(--thyuu--color-font) / 0.4);
}


.comments-placeholder {
  text-align: center;
  padding: 2rem;
  color: hsl(var(--thyuu--color-font) / 0.5);
}

/* 响应式设计 */
@media (min-width: 1600px) {
  .moments-container,
  .page-template-moments .moments-container,
  .page-template-moments .site-main > .moments-container {
    max-width: 98% !important;
    width: 98% !important;
  }
  
  .moment-detail {
    max-width: 1200px;
    width: 1200px;
  }
  
  .moment-detail .moment-item {
    min-width: 1200px;
  }
  
  .moments-list {
    grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  }
}

@media (max-width: 1400px) {
  .moments-container,
  .page-template-moments .moments-container,
  .page-template-moments .site-main > .moments-container {
    max-width: 98% !important;
    width: 98% !important;
  }
  
  .moment-detail {
    max-width: 1000px;
    width: 1000px;
  }
  
  .moment-detail .moment-item {
    min-width: 1000px;
  }
  
  .moments-list {
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  }
}

@media (max-width: 1200px) {
  .moments-container,
  .page-template-moments .moments-container,
  .page-template-moments .site-main > .moments-container {
    max-width: 98% !important;
    width: 98% !important;
  }
  
  .moment-detail {
    max-width: 900px;
    width: 900px;
  }
  
  .moment-detail .moment-item {
    min-width: 900px;
  }
  
  .moments-list {
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  }
}

@media (max-width: 768px) {
  .moments-container,
  .page-template-moments .moments-container,
  .page-template-moments .site-main > .moments-container {
    max-width: 100% !important;
    width: 100% !important;
    padding: 0 0.5rem;
  }
  
  .moment-detail {
    max-width: 100%;
    width: 100%;
    padding: 0 0.5rem;
  }
  
  .moment-detail .moment-item {
    min-width: auto;
    width: 100%;
  }
  
  .moments-list {
    grid-template-columns: 1fr;
    gap: 1rem;
  }
  
  .moment-item {
    padding: 1rem;
  }
  
  .moment-header {
    flex-direction: column;
    gap: 0.5rem;
  }
  
  .moment-footer-content {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.75rem;
  }
  
  .moment-stats {
    align-self: flex-start;
  }
  
  .media-grid.multiple {
    grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  }
  
  .moment-footer {
    flex-direction: column;
    gap: 0.75rem;
    align-items: stretch;
  }
  
  .moment-stats {
    justify-content: center;
    text-align: center;
  }
  
  .moment-actions {
    justify-content: center;
    padding-top: 0;
    opacity: 1 !important;
    transform: translateY(0);
    display: flex !important;
    visibility: visible !important;
  }
  
  .interaction-buttons {
    display: flex !important;
    gap: 0.5rem;
    opacity: 1 !important;
    visibility: visible !important;
  }
  
  .back-btn {
    padding: 0.5rem 1rem;
    font-size: 0.85rem;
    opacity: 1 !important;
    visibility: visible !important;
  }
  
  .action-link {
    padding: 0.4rem 0.8rem;
    font-size: 0.8rem;
    gap: 0.4rem;
  }
  
  .action-link i {
    font-size: 0.8rem;
  }
  
  /* 移动端:按钮始终显示 */
  .moment-item:active .moment-actions,
  .moment-item.touch-active .moment-actions {
    opacity: 1 !important;
    transform: translateY(0);
  }
}

@media (max-width: 1024px) {
  .moments-list {
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  }
}

@media (max-width: 480px) {
  .media-grid.multiple {
    grid-template-columns: 1fr 1fr;
  }
  
  .moment-tags {
    justify-content: center;
  }
  
  .empty-content h3 {
    font-size: 1.2rem;
  }
  
  .empty-icon {
    font-size: 3rem;
  }
  
  /* 移动端按钮优化 */
  .action-link {
    padding: 0.4rem 0.8rem;
    font-size: 0.8rem;
    gap: 0.4rem;
  }
  
  .action-link i {
    font-size: 0.8rem;
  }
  
  /* 移动端简洁焦点样式 - 轮廓线在按钮内部 */
  .action-link:focus {
    outline-offset: -1px;
  }
  
  .action-link:focus-visible {
    outline-offset: -1px;
  }
  
  /* 移动端文本省略适配 */
  .moment-text-wrapper.collapsed .moment-text {
    max-height: 3.2em; /* 移动端显示更少行数 */
    -webkit-line-clamp: 2;
    line-clamp: 2;
  }
  
  .moment-text-wrapper.collapsed .moment-text::after {
    height: 1em;
  }
  
  /* 移动端提示样式适配 */
  .hint-text {
    padding: 0.25rem 0.6rem;
    font-size: 0.7rem;
  }
}

/* 动画效果 - 优化版本 */
/* fadeInUp动画已删除 - 避免鼠标卡住问题 */

/* 动画效果已删除 - 避免鼠标卡住问题 */

/* 为偏好减少动画的用户提供即时显示 */
@media (prefers-reduced-motion: reduce) {
  .moments-container .fade-before,
  .moments-container .moment-item.fade-before {
    animation: none !important;
    opacity: 1 !important;
    transform: none !important;
  }
}

/* 移动端优化 */
@media (max-width: 768px) {
  .moments-container .fade-before,
  .moments-container .moment-item.fade-before {
    animation-duration: 0.2s;
  }
}

/* 标签导航激活状态 */
.taxonomy-nav .taxonomy-sub li a.active {
  background: hsl(var(--thyuu--main-color));
  color: white;
}


.comments-placeholder {
  text-align: center;
  padding: 2rem;
  color: var(--text-secondary);
}

.comments-placeholder p {
  margin: 0;
  font-size: 0.9rem;
}

/* 互动按钮 */
.moment-interactions {
  display: flex;
  gap: 1rem;
  margin: 1.5rem 0;
  padding: 1rem 0;
  border-top: 1px solid var(--border-color);
  border-bottom: 1px solid var(--border-color);
}

.interaction-btn {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.75rem 1.5rem;
  background: var(--card-bg);
  border: 1px solid var(--border-color);
  border-radius: 8px;
  color: var(--text-color);
  font-size: 0.9rem;
  cursor: pointer;
  transition: all 0.2s ease;
  text-decoration: none;
}

.interaction-btn:hover {
  background: var(--bg-color);
  border-color: hsl(var(--thyuu--main-color));
  color: hsl(var(--thyuu--main-color));
  /* 删除hover动画,避免鼠标卡住 */
}

.interaction-btn i,
.interaction-btn .like-icon,
.interaction-btn .share-icon,
.interaction-btn .bookmark-icon {
  font-size: 1rem;
}

.like-btn.liked {
  background: hsl(var(--thyuu--main-color));
  color: white;
  border-color: hsl(var(--thyuu--main-color));
}

.like-btn.liked:hover {
  background: hsl(var(--thyuu--main-color) / 0.8);
}

.like-count {
  font-weight: 600;
}

/* 移动端互动按钮优化 */
@media (max-width: 768px) {
  .moment-interactions {
    gap: 0.75rem;
    margin: 1rem 0;
    padding: 0.75rem 0;
    display: flex !important;
    justify-content: center;
    align-items: center;
    opacity: 1 !important;
    visibility: visible !important;
  }
  
  .interaction-btn {
    padding: 0.75rem 1.25rem;
    font-size: 0.9rem;
    min-width: 60px;
    min-height: 44px;
    display: flex !important;
    align-items: center;
    justify-content: center;
    flex-direction: column;
    gap: 0.25rem;
    opacity: 1 !important;
    visibility: visible !important;
  }
  
  .interaction-btn span {
    display: block !important;
    font-size: 0.75rem;
  }
  
  .interaction-btn i,
  .interaction-btn .like-icon,
  .interaction-btn .share-icon,
  .interaction-btn .bookmark-icon {
    font-size: 1.2rem;
    display: block !important;
  }
}

/* 安卓设备特殊优化 */
@media (max-width: 480px) {
  .moment-interactions {
    gap: 1rem;
    padding: 1rem 0;
    display: flex !important;
    opacity: 1 !important;
    visibility: visible !important;
  }
  
  .interaction-btn {
    padding: 1rem 1.5rem;
    min-width: 70px;
    min-height: 50px;
    font-size: 1rem;
    display: flex !important;
    opacity: 1 !important;
    visibility: visible !important;
  }
  
  .interaction-btn i,
  .interaction-btn .like-icon,
  .interaction-btn .share-icon,
  .interaction-btn .bookmark-icon {
    font-size: 1.3rem;
    display: block !important;
  }
  
  .interaction-btn span {
    font-size: 0.8rem;
    display: block !important;
  }
}

.taxonomy-nav .taxonomy-sub li a {
  padding: 0.5rem 1rem;
  border-radius: var(--thyuu--size-radius);
  text-decoration: none;
  color: hsl(var(--thyuu--color-font) / 0.7);
  transition: all 0.3s ease;
}

.taxonomy-nav .taxonomy-sub li a:hover {
  background: hsl(var(--thyuu--main-color) / 0.1);
  color: hsl(var(--thyuu--main-color));
}

然后修改完后保存,压缩回zip上传备份

/moments 页面你就可以看到瞬间页面了

成功了记得留个评论,然后订阅我的文章QAQ