| | |
| | (function() { |
| | const style = document.createElement('style'); |
| | style.textContent = ` |
| | @keyframes pulse { |
| | 0%, 100% { |
| | opacity: 1; |
| | } |
| | 50% { |
| | opacity: 0.6; |
| | } |
| | } |
| | .animate-pulse { |
| | animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite; |
| | } |
| | `; |
| | document.head.appendChild(style); |
| | })(); |
| |
|
| | |
| | async function fetchVersion(url, errorMessage, options = {}) { |
| | const response = await fetch(url, options); |
| | if (!response.ok) { |
| | throw new Error(errorMessage); |
| | } |
| | return await response.text(); |
| | } |
| |
|
| | |
| | async function checkForUpdates() { |
| | try { |
| | |
| | const currentVersion = await fetchVersion('/VERSION.txt', '获取当前版本失败', { |
| | cache: 'no-store' |
| | }); |
| | |
| | |
| | let latestVersion; |
| | const VERSION_URL = { |
| | PROXY: 'https://ghfast.top/raw.githubusercontent.com/LibreSpark/LibreTV/main/VERSION.txt', |
| | DIRECT: 'https://raw.githubusercontent.com/LibreSpark/LibreTV/main/VERSION.txt' |
| | }; |
| | const FETCH_TIMEOUT = 1500; |
| | |
| | try { |
| | |
| | const proxyPromise = fetchVersion(VERSION_URL.PROXY, '代理请求失败'); |
| | const timeoutPromise = new Promise((_, reject) => |
| | setTimeout(() => reject(new Error('代理请求超时')), FETCH_TIMEOUT) |
| | ); |
| | |
| | latestVersion = await Promise.race([proxyPromise, timeoutPromise]); |
| | console.log('通过代理服务器获取版本成功'); |
| | } catch (error) { |
| | console.log('代理请求失败,尝试直接请求:', error.message); |
| | try { |
| | |
| | latestVersion = await fetchVersion(VERSION_URL.DIRECT, '获取最新版本失败'); |
| | console.log('直接请求获取版本成功'); |
| | } catch (directError) { |
| | console.error('所有版本检查请求均失败:', directError); |
| | throw new Error('无法获取最新版本信息'); |
| | } |
| | } |
| | |
| | console.log('当前版本:', currentVersion); |
| | console.log('最新版本:', latestVersion); |
| | |
| | |
| | const cleanCurrentVersion = currentVersion.trim(); |
| | const cleanLatestVersion = latestVersion.trim(); |
| | |
| | |
| | return { |
| | current: cleanCurrentVersion, |
| | latest: cleanLatestVersion, |
| | hasUpdate: parseInt(cleanLatestVersion) > parseInt(cleanCurrentVersion), |
| | currentFormatted: formatVersion(cleanCurrentVersion), |
| | latestFormatted: formatVersion(cleanLatestVersion) |
| | }; |
| | } catch (error) { |
| | console.error('版本检测出错:', error); |
| | throw error; |
| | } |
| | } |
| |
|
| | |
| | function formatVersion(versionString) { |
| | |
| | if (!versionString) { |
| | return '未知版本'; |
| | } |
| | |
| | |
| | const cleanedString = versionString.trim(); |
| | |
| | |
| | if (cleanedString.length === 12) { |
| | const year = cleanedString.substring(0, 4); |
| | const month = cleanedString.substring(4, 6); |
| | const day = cleanedString.substring(6, 8); |
| | const hour = cleanedString.substring(8, 10); |
| | const minute = cleanedString.substring(10, 12); |
| | |
| | return `${year}-${month}-${day} ${hour}:${minute}`; |
| | } |
| | |
| | return cleanedString; |
| | } |
| |
|
| | |
| | function createErrorVersionElement(errorMessage) { |
| | const errorElement = document.createElement('p'); |
| | errorElement.className = 'text-gray-500 text-sm mt-1 text-center md:text-left'; |
| | errorElement.innerHTML = `版本: <span class="text-amber-500">检测失败</span>`; |
| | errorElement.title = errorMessage; |
| | return errorElement; |
| | } |
| |
|
| | |
| | function addVersionInfoToFooter() { |
| | checkForUpdates().then(result => { |
| | if (!result) { |
| | |
| | const versionElement = createErrorVersionElement(); |
| | |
| | displayVersionElement(versionElement); |
| | return; |
| | } |
| | |
| | |
| | const versionElement = document.createElement('p'); |
| | versionElement.className = 'text-gray-500 text-sm mt-1 text-center md:text-left'; |
| | |
| | |
| | versionElement.innerHTML = `版本: ${result.currentFormatted}`; |
| | |
| | |
| | if (result.hasUpdate) { |
| | versionElement.innerHTML += ` <span class="inline-flex items-center bg-red-600 text-white text-xs px-2 py-0.5 rounded-md ml-1 cursor-pointer animate-pulse font-medium"> |
| | <svg xmlns="http://www.w3.org/2000/svg" class="h-3 w-3 mr-1" fill="none" viewBox="0 0 24 24" stroke="currentColor"> |
| | <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z" /> |
| | </svg> |
| | 发现新版 |
| | </span>`; |
| | |
| | setTimeout(() => { |
| | const updateBtn = versionElement.querySelector('span'); |
| | if (updateBtn) { |
| | updateBtn.addEventListener('click', () => { |
| | window.open('https://github.com/LibreSpark/LibreTV', '_blank'); |
| | }); |
| | } |
| | }, 100); |
| | } else { |
| | |
| | versionElement.innerHTML = `版本: ${result.currentFormatted} <span class="text-green-500">(最新版本)</span>`; |
| | } |
| | |
| | |
| | displayVersionElement(versionElement); |
| | }).catch(error => { |
| | console.error('版本检测出错:', error); |
| | |
| | const errorElement = createErrorVersionElement(`错误信息: ${error.message}`); |
| | displayVersionElement(errorElement); |
| | }); |
| | } |
| |
|
| | |
| | function displayVersionElement(element) { |
| | |
| | const footerElement = document.querySelector('.footer p.text-gray-500.text-sm'); |
| | if (footerElement) { |
| | |
| | footerElement.insertAdjacentElement('afterend', element); |
| | } else { |
| | |
| | const footer = document.querySelector('.footer .container'); |
| | if (footer) { |
| | footer.querySelector('div').appendChild(element); |
| | } |
| | } |
| | } |
| |
|
| | |
| | document.addEventListener('DOMContentLoaded', addVersionInfoToFooter); |
| |
|