feat(install): 实现游戏安装页面功能

- 添加安装路径选择逻辑- 实现调用 Rust 后端进行安装的功能
- 增加安装过程日志显示与自动滚动
- 添加视频背景组件替换原有首页内容
- 引入 sass-embedded 依赖支持 SCSS 样式编写
- 更新 Header 组件增加 backdrop-blur 效果
This commit is contained in:
Chaos
2025-11-11 17:18:53 +08:00
parent a09f4a7e6e
commit d9b786e935
6 changed files with 1049 additions and 87 deletions

View File

@@ -10,7 +10,7 @@
</script>
<header class="h-8 w-full bg-base absolute top-0 window-controls flex gap-10 px-3 items-center" data-tauri-drag-region>
<header class="h-8 w-full backdrop-blur absolute top-0 window-controls flex gap-10 px-3 items-center" data-tauri-drag-region>
<div class="flex-1" data-tauri-drag-region></div>

View File

@@ -1,92 +1,14 @@
<script lang="ts">
import { invoke } from '@tauri-apps/api/core';
import { open } from '@tauri-apps/plugin-dialog';
let installPath = '未选择安装路径';
let isInstalling = false;
// 1. 打开目录选择对话框
async function selectInstallDir() {
// 默认打开 C:/Program Files仅限 Windows
const defaultPath = 'C:\\Program Files';
const selected = await open({
directory: true, // 必须选择目录
multiple: false, // 只能选择一个
title: '请选择游戏的安装目录',
defaultPath: defaultPath, // 初始打开的路径
});
if (typeof selected === 'string') {
installPath = selected;
}
}
// 2. 调用 Rust 后端命令开始安装
async function startInstallation() {
if (installPath === '未选择安装路径') {
alert('请先选择安装路径!');
return;
}
isInstalling = true;
try {
// 调用我们在 Rust 中定义的 `install_game` 命令
// Tauri 会自动处理前端和后端的数据传输
const result: string = await invoke('install_game', {
targetDir: installPath
});
alert(`安装完成!\n${result}`);
} catch (error) {
console.error('安装失败:', error);
alert(`安装失败:${error}`);
} finally {
isInstalling = false;
}
}
import video from '$lib/assets/video/c9df6498_517c_4fee_a39d_72b43f3425fd.mp4';
</script>
<main class="h-screen flex flex-col bg-base ">
<div class="app-wallpaper" >
<video class="absolute h-screen object-cover -z-10" autoplay muted loop playsinline>
<source src="{video}" type="video/mp4">
</video>
</div>
<div class="flex-1 pt-10 px-4">
<h1 class="text-3xl font-bold">游戏安装程序</h1>
</div>
<style lang="scss">
<div class="h-32 shrink-0 p-4 border-base ">
<div class="flex items-center">
<input class="input flex-1" value={installPath} />
<button class="btn " on:click={selectInstallDir} disabled={isInstalling}>
选择安装目录
</button>
</div>
<div class="pt-4 text-center btn-primary">
<button class="btn btn-block" on:click={startInstallation} disabled={isInstalling}>
{isInstalling ? '正在安装...' : '开始安装'}
</button>
</div>
</div>
</main>
<!-- <h1>游戏安装程序</h1>-->
<!-- <div class="path-display">-->
<!-- <p>目标安装路径: <strong>{installPath}</strong></p>-->
<!-- <button on:click={selectInstallDir} disabled={isInstalling}>-->
<!-- 选择安装目录-->
<!-- </button>-->
<!-- </div>-->
<!-- <button class="btn">Default</button>-->
<!-- <button-->
<!-- on:click={startInstallation}-->
<!-- disabled={isInstalling || installPath === '未选择安装路径'}>-->
<!-- {isInstalling ? '正在安装...' : '开始安装'}-->
<!-- </button>-->
<style>
/* 基础样式 */
</style>
</style>

View File

@@ -0,0 +1,148 @@
<script lang="ts">
import { invoke } from '@tauri-apps/api/core';
import { open } from '@tauri-apps/plugin-dialog';
let installPath = '未选择安装路径';
let isInstalling = false;
let logContent = '';
let logOutputElement: HTMLPreElement;
// 1. 打开目录选择对话框
async function selectInstallDir() {
// 默认打开 C:/Program Files仅限 Windows
const defaultPath = 'C:\\Program Files';
if (installPath !== '未选择安装路径'){
log("重新选择安装目录");
}
const selected = await open({
directory: true, // 必须选择目录
multiple: false, // 只能选择一个
title: '请选择游戏的安装目录',
defaultPath: defaultPath, // 初始打开的路径
});
if (typeof selected === 'string') {
installPath = selected;
log('已选择安装目录:'+selected+",点击开始安装即可开始自动安装");
}else if (selected === null) {
log("取消选择安装目录");
}else{
log("选择安装目录失败");
}
}
// 2. 调用 Rust 后端命令开始安装
async function startInstallation() {
if (installPath === '未选择安装路径') {
alert('请先选择安装路径!');
return;
}
isInstalling = true;
try {
// 调用我们在 Rust 中定义的 `install_game` 命令
// Tauri 会自动处理前端和后端的数据传输
const result: string = await invoke('install_game', {
targetDir: installPath
});
alert(`安装完成!\n${result}`);
} catch (error) {
console.error('安装失败:', error);
alert(`安装失败:${error}`);
} finally {
isInstalling = false;
}
}
/**
* Svelte 版本的日志函数
* 它只更新 logContent 变量Svelte 会自动更新 DOM
*/
const log = (message: string) => {
const timestamp = new Date().toLocaleTimeString('zh-CN', { hour12: false });
// 更新变量,而不是直接操作 DOM
logContent += `[${timestamp}] ${message}\n`;
}
/**
* 2. Svelte 响应式语句 (自动滚动)
* * 这行代码 ( $: ... ) 意味着:
* "每当它依赖的变量(这里是 logContent发生变化
* Svelte 更新 DOM 之后,就执行这里的代码。"
*/
$: if (logOutputElement && logContent) {
// 自动滚动到底部
logOutputElement.scrollTop = logOutputElement.scrollHeight;
}
</script>
<main class="h-screen flex flex-col bg-base ">
<div class="flex-1 pt-10 px-4 overflow-hidden">
<h1 class="textarea-xl">选择安装目录</h1>
<pre
class="overflow-y-auto h-full whitespace-pre-wrap wrap-break-word text-start"
bind:this={logOutputElement}
>
{logContent}
</pre>
</div>
<div class="h-32 shrink-0 p-4 border-base ">
<div class="flex items-center">
<input class="input flex-1" value={installPath} />
<button class="btn " on:click={selectInstallDir} disabled={isInstalling}>
选择安装目录
</button>
</div>
<div class="pt-4 text-center btn-primary">
<button class="btn btn-block" on:click={startInstallation} disabled={isInstalling}>
{isInstalling ? '正在安装...' : '开始安装'}
</button>
</div>
</div>
</main>
<!-- <h1>游戏安装程序</h1>-->
<!-- <div class="path-display">-->
<!-- <p>目标安装路径: <strong>{installPath}</strong></p>-->
<!-- <button on:click={selectInstallDir} disabled={isInstalling}>-->
<!-- 选择安装目录-->
<!-- </button>-->
<!-- </div>-->
<!-- <button class="btn">Default</button>-->
<!-- <button-->
<!-- on:click={startInstallation}-->
<!-- disabled={isInstalling || installPath === '未选择安装路径'}>-->
<!-- {isInstalling ? '正在安装...' : '开始安装'}-->
<!-- </button>-->
<style>
::-webkit-scrollbar {
/*滚动条整体样式*/
width:5px;
/*高宽分别对应横竖滚动条的尺寸*/
height:5px;
}
::-webkit-scrollbar-thumb {
/*滚动条里面小方块*/
background:#000000e0;
}
::-webkit-scrollbar-track {
/*滚动条里面轨道*/
background:#e8ecf3;
}
</style>