feat: 优化界面与功能
- 移除过时代码,迁移 ESLint 到 v9 新配置格式 - 修复已废弃的 overflow: overlay CSS 属性 - 新增 LZMA 压缩选项,提升压缩率 - 更新弹窗布局:两列显示,适配小窗口 - 优化更新功能:用户可选择便携版或安装版 - 调整界面间距与样式,提升视觉效果
This commit is contained in:
1 parent
9e8cb8ba0e
commit
ac4d93b172
8 files changed
+99
-64
No files matched your search
+7
-1
@@ -25,7 +25,13 @@ export default [
|
||||
indent: ['error', 4],
|
||||
quotes: ['error', 'single', { avoidEscape: true }],
|
||||
semi: ['error', 'never'],
|
||||
'no-unused-vars': ['warn', { argsIgnorePattern: '^_' }],
|
||||
'no-unused-vars': [
|
||||
'warn',
|
||||
{
|
||||
argsIgnorePattern: '^_',
|
||||
varsIgnorePattern: '^currentUpdateInfo_$',
|
||||
},
|
||||
],
|
||||
'no-constant-condition': ['warn', { checkLoops: false }],
|
||||
'no-console': 'off',
|
||||
},
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "UPX-Tools",
|
||||
"version": "1.3.0",
|
||||
"version": "1.4.5",
|
||||
"type": "module",
|
||||
"description": "UPX 可视化加壳/脱壳工具",
|
||||
"scripts": {
|
||||
|
||||
Generated
+1
-1
@@ -4,7 +4,7 @@ version = 4
|
||||
|
||||
[[package]]
|
||||
name = "UPX-Tools"
|
||||
version = "1.3.0"
|
||||
version = "1.4.5"
|
||||
dependencies = [
|
||||
"encoding_rs",
|
||||
"reqwest",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "UPX-Tools"
|
||||
version = "1.3.0"
|
||||
version = "1.4.5"
|
||||
description = "UPX 可视化加壳脱壳工具"
|
||||
authors = ["ASLant"]
|
||||
edition = "2021"
|
||||
|
||||
+11
-9
@@ -559,8 +559,7 @@ struct UpdateInfo {
|
||||
release_name: String,
|
||||
release_notes: String,
|
||||
published_at: String,
|
||||
download_url: Option<String>,
|
||||
download_size: Option<u64>,
|
||||
assets: Vec<GitHubAsset>,
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
@@ -605,13 +604,17 @@ async fn check_update() -> Result<UpdateInfo, String> {
|
||||
|
||||
let has_update = version_compare(latest, current);
|
||||
|
||||
// 查找便携版或安装包下载链接
|
||||
let (download_url, download_size) = release
|
||||
// 过滤出 Windows 相关的下载资源
|
||||
let assets: Vec<GitHubAsset> = release
|
||||
.assets
|
||||
.iter()
|
||||
.find(|a| a.name.ends_with("-portable.exe") || a.name.ends_with("-setup.exe"))
|
||||
.map(|a| (Some(a.browser_download_url.clone()), Some(a.size)))
|
||||
.unwrap_or((None, None));
|
||||
.filter(|a| {
|
||||
a.name.ends_with("-portable.exe")
|
||||
|| a.name.ends_with("-setup.exe")
|
||||
|| a.name.ends_with(".msi")
|
||||
})
|
||||
.cloned()
|
||||
.collect();
|
||||
|
||||
Ok(UpdateInfo {
|
||||
has_update,
|
||||
@@ -621,8 +624,7 @@ async fn check_update() -> Result<UpdateInfo, String> {
|
||||
release_name: release.name,
|
||||
release_notes: release.body.unwrap_or_default(),
|
||||
published_at: release.published_at,
|
||||
download_url,
|
||||
download_size,
|
||||
assets,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://schema.tauri.app/config/2",
|
||||
"productName": "UPX-Tools",
|
||||
"version": "1.3.0",
|
||||
"version": "1.4.5",
|
||||
"identifier": "top.aslant.upxgui",
|
||||
"build": {
|
||||
"beforeDevCommand": "",
|
||||
|
||||
+14
-12
@@ -390,7 +390,7 @@
|
||||
class="hidden fixed inset-0 bg-foreground/80 flex items-center justify-center z-50 backdrop-blur-sm modal-backdrop"
|
||||
>
|
||||
<div class="card p-6 w-full mx-4 modal-content" style="max-width: 480px">
|
||||
<div class="flex items-center gap-3 mb-4">
|
||||
<div class="flex items-center gap-3 mb-5">
|
||||
<div
|
||||
class="w-10 h-10 rounded-full bg-green-500/10 flex items-center justify-center"
|
||||
>
|
||||
@@ -414,15 +414,23 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center justify-between mb-2">
|
||||
<div class="flex items-center justify-between mb-3">
|
||||
<h3 class="text-sm font-medium text-foreground">更新内容</h3>
|
||||
<span id="update-date" class="text-xs text-muted-foreground"></span>
|
||||
</div>
|
||||
<div class="bg-muted p-4 rounded-md max-h-32 overflow-y-auto">
|
||||
<div class="bg-muted p-4 rounded-md max-h-32 overflow-y-auto mb-5">
|
||||
<div id="update-notes" class="text-sm text-muted-foreground space-y-1"></div>
|
||||
</div>
|
||||
|
||||
<div id="update-progress" class="hidden mt-6">
|
||||
<!-- 下载选项 -->
|
||||
<div class="space-y-3 mb-5">
|
||||
<h4 class="text-sm font-medium text-foreground">选择下载版本</h4>
|
||||
<div id="download-options" class="grid grid-cols-2 gap-4">
|
||||
<!-- 动态填充下载选项 -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="update-progress" class="hidden">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="flex-1 h-2 bg-border rounded-full overflow-hidden">
|
||||
<div
|
||||
@@ -437,19 +445,13 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-3 mt-6">
|
||||
<div class="flex mt-6">
|
||||
<button
|
||||
id="update-later-btn"
|
||||
class="btn btn-ghost flex-1 py-2.5 px-6 text-sm rounded-sm"
|
||||
class="btn btn-outline w-full py-2.5 px-6 text-sm rounded-sm"
|
||||
>
|
||||
稍后更新
|
||||
</button>
|
||||
<button
|
||||
id="update-now-btn"
|
||||
class="btn btn-primary flex-1 py-2.5 px-6 text-sm rounded-sm"
|
||||
>
|
||||
立即更新
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+63
-38
@@ -600,10 +600,10 @@ let updateModal,
|
||||
updateProgressText,
|
||||
updateProgressBar,
|
||||
updateLaterBtn,
|
||||
updateNowBtn
|
||||
downloadOptions
|
||||
|
||||
// 当前更新信息缓存
|
||||
let currentUpdateInfo = null
|
||||
let currentUpdateInfo_ = null
|
||||
|
||||
// 初始化更新弹窗元素和事件
|
||||
function initUpdateModal() {
|
||||
@@ -615,10 +615,9 @@ function initUpdateModal() {
|
||||
updateProgressText = $('update-progress-text')
|
||||
updateProgressBar = $('update-progress-bar')
|
||||
updateLaterBtn = $('update-later-btn')
|
||||
updateNowBtn = $('update-now-btn')
|
||||
downloadOptions = $('download-options')
|
||||
|
||||
updateLaterBtn?.addEventListener('click', hideUpdateModal)
|
||||
updateNowBtn?.addEventListener('click', handleDownloadUpdate)
|
||||
updateModal?.addEventListener('click', (e) => {
|
||||
if (e.target === updateModal) hideUpdateModal()
|
||||
})
|
||||
@@ -634,7 +633,7 @@ async function handleCheckUpdate() {
|
||||
|
||||
if (updateInfo.has_update) {
|
||||
addLog(`发现新版本: ${updateInfo.latest_version}`, 'success', true)
|
||||
currentUpdateInfo = updateInfo
|
||||
currentUpdateInfo_ = updateInfo
|
||||
showUpdateModal(updateInfo)
|
||||
} else {
|
||||
addLog(`当前已是最新版本 (${updateInfo.current_version})`, 'success')
|
||||
@@ -712,43 +711,70 @@ function showUpdateModal(info) {
|
||||
updateDate.textContent = `发布于 ${formatDate(info.published_at)}`
|
||||
updateNotes.innerHTML = renderMarkdown(info.release_notes)
|
||||
|
||||
// 重置进度条和按钮状态
|
||||
// 重置进度条状态
|
||||
updateProgress.classList.add('hidden')
|
||||
updateProgressBar.style.width = '0%'
|
||||
updateProgressText.textContent = '0%'
|
||||
updateNowBtn.disabled = false
|
||||
updateNowBtn.textContent = info.download_url ? '立即更新' : '前往下载'
|
||||
updateLaterBtn.disabled = false
|
||||
|
||||
// 渲染下载选项
|
||||
renderDownloadOptions(info.assets)
|
||||
|
||||
showModal(updateModal)
|
||||
}
|
||||
|
||||
const hideUpdateModal = () => hideModal(updateModal)
|
||||
// 渲染下载选项
|
||||
function renderDownloadOptions(assets) {
|
||||
if (!downloadOptions) return
|
||||
|
||||
// 下载并安装更新
|
||||
async function handleDownloadUpdate() {
|
||||
if (!currentUpdateInfo) return
|
||||
|
||||
// 如果没有直接下载链接,打开浏览器
|
||||
if (!currentUpdateInfo.download_url) {
|
||||
try {
|
||||
const { open } = window.__TAURI__.shell
|
||||
await open(currentUpdateInfo.release_url)
|
||||
addLog('已在浏览器中打开下载页面', 'success')
|
||||
hideUpdateModal()
|
||||
} catch (e) {
|
||||
addLog(`打开链接失败: ${e}`, 'error')
|
||||
}
|
||||
return
|
||||
const optionLabels = {
|
||||
'portable.exe': '便携版',
|
||||
'setup.exe': '安装版',
|
||||
}
|
||||
|
||||
downloadOptions.innerHTML = assets
|
||||
.filter((asset) => {
|
||||
// 只显示便携版和安装版
|
||||
return asset.name.includes('portable.exe') || asset.name.includes('setup.exe')
|
||||
})
|
||||
.map((asset) => {
|
||||
const label =
|
||||
Object.entries(optionLabels).find(([key]) => asset.name.includes(key))?.[1] ||
|
||||
asset.name
|
||||
|
||||
return `
|
||||
<button
|
||||
class="download-option-btn btn btn-outline py-2.5 px-4 text-sm rounded-sm"
|
||||
data-url="${asset.browser_download_url}"
|
||||
data-filename="${asset.name}"
|
||||
>
|
||||
${label}
|
||||
</button>
|
||||
`
|
||||
})
|
||||
.join('')
|
||||
|
||||
// 绑定点击事件
|
||||
downloadOptions.querySelectorAll('.download-option-btn').forEach((btn) => {
|
||||
btn.addEventListener('click', handleDownloadOption)
|
||||
})
|
||||
}
|
||||
|
||||
// 下载选中的版本
|
||||
async function handleDownloadOption(e) {
|
||||
const url = e.target.dataset.url
|
||||
const filename = e.target.dataset.filename
|
||||
|
||||
if (!url) return
|
||||
|
||||
try {
|
||||
updateNowBtn.disabled = true
|
||||
updateLaterBtn.disabled = true
|
||||
updateNowBtn.textContent = '下载中...'
|
||||
// 禁用所有下载按钮
|
||||
downloadOptions
|
||||
.querySelectorAll('.download-option-btn')
|
||||
.forEach((btn) => (btn.disabled = true))
|
||||
|
||||
updateProgress.classList.remove('hidden')
|
||||
|
||||
// 模拟进度(因为无法获取真实进度)
|
||||
// 模拟进度
|
||||
let progress = 0
|
||||
const progressInterval = setInterval(() => {
|
||||
progress += Math.random() * 15
|
||||
@@ -757,13 +783,10 @@ async function handleDownloadUpdate() {
|
||||
updateProgressText.textContent = `${Math.round(progress)}%`
|
||||
}, 200)
|
||||
|
||||
// 从 URL 提取文件名
|
||||
const filename = currentUpdateInfo.download_url.split('/').pop() || 'UPX-Tools-setup.exe'
|
||||
|
||||
addLog(`正在下载: ${filename}`, 'info')
|
||||
const filePath = await invoke('download_and_install', {
|
||||
url: currentUpdateInfo.download_url,
|
||||
filename: filename,
|
||||
url,
|
||||
filename,
|
||||
})
|
||||
|
||||
clearInterval(progressInterval)
|
||||
@@ -773,19 +796,21 @@ async function handleDownloadUpdate() {
|
||||
addLog(`下载完成: ${filePath}`, 'success')
|
||||
addLog('正在启动安装程序...', 'info')
|
||||
|
||||
// 短暂延迟后关闭弹窗
|
||||
setTimeout(() => {
|
||||
hideUpdateModal()
|
||||
addLog('安装程序已启动,请按提示完成安装', 'success', true)
|
||||
}, 1000)
|
||||
} catch (error) {
|
||||
addLog(`下载失败: ${error}`, 'error')
|
||||
updateNowBtn.disabled = false
|
||||
updateLaterBtn.disabled = false
|
||||
updateNowBtn.textContent = '重试'
|
||||
// 恢复按钮状态
|
||||
downloadOptions
|
||||
.querySelectorAll('.download-option-btn')
|
||||
.forEach((btn) => (btn.disabled = false))
|
||||
}
|
||||
}
|
||||
|
||||
const hideUpdateModal = () => hideModal(updateModal)
|
||||
|
||||
// 格式化日期
|
||||
function formatDate(isoString) {
|
||||
try {
|
||||
|
||||
Reference in new issue
Block a user