/* about.js - Robust Core with i18n & 3D Cloud */ $(document).ready(function() { new AppManager(); }); class AppManager { constructor() { this.i18n = new I18nManager(); this.theme = new ThemeManager(); this.data = new DataFetcher(); this.ui = new UIManager(); } } /* =========================== 1. Internationalization =========================== */ class I18nManager { constructor() { this.lang = localStorage.getItem('lang') || (navigator.language.startsWith('zh') ? 'zh' : 'en'); this.dict = { zh: { "nav.home": "首页", "nav.about": "关于", "nav.blog": "博客", "profile.status": "在线", "profile.name": "Honesty", "profile.role": "Java 后端 & AI 探索者", "profile.location": "上海", "bio.title": "关于我", "bio.desc": "我是一名充满热情的Java后端开发工程师,专注于AI技术的探索与应用。来自湖南,现在上海工作,享受在这座充满活力的城市中追求技术梦想。", "bio.quote": "我追求技术的深度理解而非广度堆砌,每一项技术的学习都源于解决实际问题的内在驱动。", "stats.exp": "编程年限", "stats.repos": "开源项目", "stats.followers": "关注者", "mbti.type": "提倡者", "mbti.desc": "善于深度思考,注重细节,通过代码创造有意义的产品。", "mbti.tag1": "理想主义", "mbti.tag2": "深度洞察", "mbti.tag3": "利他精神", "tech.title": "技术栈宇宙", "interest.title": "个人兴趣", "interest.cycling": "骑行", "interest.cycling_desc": "用车轮丈量城市边界", "interest.reading": "阅读", "interest.reading_desc": "记录思考的轨迹", "interest.opensource": "开源", "interest.opensource_desc": "用代码连接世界", "github.title": "开源贡献", "blog.title": "最新文章", "blog.more": "查看全部", "comment.title": "留言板", "modal.wechat_title": "关注公众号", "modal.wechat_desc": "扫码获取技术干货" }, en: { "nav.home": "Home", "nav.about": "About", "nav.blog": "Blog", "profile.status": "Available", "profile.name": "Honesty", "profile.role": "Java Backend & AI Dev", "profile.location": "Shanghai", "bio.title": "About Me", "bio.desc": "I am a passionate Java Backend Engineer focused on AI exploration. Based in Shanghai, originally from Hunan, enjoying the pursuit of technical dreams in this vibrant city.", "bio.quote": "I seek deep understanding over broad stacking. Every skill I learn is driven by the need to solve real problems.", "stats.exp": "Years Exp", "stats.repos": "Projects", "stats.followers": "Followers", "mbti.type": "Advocate", "mbti.desc": "Deep thinker, detail-oriented, creating meaningful products through code.", "mbti.tag1": "Idealism", "mbti.tag2": "Insight", "mbti.tag3": "Altruism", "tech.title": "Tech Universe", "interest.title": "Interests", "interest.cycling": "Cycling", "interest.cycling_desc": "Measuring the world on wheels", "interest.reading": "Reading", "interest.reading_desc": "Recording thoughts via text", "interest.opensource": "Open Source", "interest.opensource_desc": "Connecting world with code", "github.title": "Open Source", "blog.title": "Latest Posts", "blog.more": "View All", "comment.title": "Message Board", "modal.wechat_title": "Official Account", "modal.wechat_desc": "Scan for tech insights" } }; this.init(); } init() { this.render(); $('#lang-toggle').on('click', () => { this.lang = this.lang === 'zh' ? 'en' : 'zh'; localStorage.setItem('lang', this.lang); this.render(); }); } render() { const t = this.dict[this.lang]; $('[data-i18n]').each(function() { const key = $(this).data('i18n'); if(t[key]) $(this).text(t[key]); }); $('.lang-text').text(this.lang === 'zh' ? 'EN' : '中'); } } /* =========================== 2. Theme Manager =========================== */ class ThemeManager { constructor() { this.init(); } init() { const saved = localStorage.getItem('theme') || 'day'; if (saved === 'night') document.documentElement.setAttribute('data-theme', 'night'); $('#theme-toggle').on('click', () => { const current = document.documentElement.getAttribute('data-theme'); const next = current === 'night' ? 'day' : 'night'; if (next === 'night') document.documentElement.setAttribute('data-theme', 'night'); else document.documentElement.removeAttribute('data-theme'); localStorage.setItem('theme', next); }); } } /* =========================== 3. Data & API (Robust) =========================== */ class DataFetcher { constructor() { this.fallbackRepos = [ { name: "yunxiao-LLM-reviewer", description: "AI Code Reviewer based on LLM", stargazers_count: 9, html_url: "#" }, { name: "hexo-theme-stellar", description: "A beautiful Hexo theme", stargazers_count: 5, html_url: "#" }, { name: "Universal-IoT-Java", description: "IoT Platform implementation", stargazers_count: 2, html_url: "#" } ]; this.fallbackPosts = [ { title: "Vector Database Guide", pubDate: "2025-01-02", category: "Tech", link: "#" }, { title: "Spring Boot 3.0 Features", pubDate: "2024-12-30", category: "Java", link: "#" }, { title: "Microservices Patterns", pubDate: "2024-12-28", category: "Arch", link: "#" } ]; this.init(); } init() { this.fetchGitHub(); this.fetchBlog(); } fetchGitHub() { const user = (window.SiteConfig && window.SiteConfig.github) ? window.SiteConfig.github.username : 'listener-He'; // 1. User Stats $.ajax({ url: `https://api.github.com/users/${user}`, timeout: 5000 }).done(data => { const years = new Date().getFullYear() - new Date(data.created_at).getFullYear(); $('#coding-years').text(years + "+"); $('#github-repos').text(data.public_repos); $('#github-followers').text(data.followers); }).fail(() => { console.warn("GH API fail, using default stats"); }); // 2. Repos $.ajax({ url: `https://api.github.com/users/${user}/repos?sort=stars&per_page=6`, timeout: 5000 }).done(data => this.renderRepos(data)) .fail(() => this.renderRepos(this.fallbackRepos)); } renderRepos(list) { let html = ''; list.slice(0, 5).forEach(repo => { // Fix: handle API field naming differences const stars = repo.stargazers_count !== undefined ? repo.stargazers_count : (repo.stars || 0); const desc = repo.description || 'No description provided.'; html += `