Skip to content

Commit 524ecc4

Browse files
committed
推送版本号到0.4.0,添加OOBE界面,完善界面样式,修复逻辑问题,完善tauri权限获取,完善画笔样式
1 parent d1263a2 commit 524ecc4

File tree

14 files changed

+1604
-42
lines changed

14 files changed

+1604
-42
lines changed

src-tauri/Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src-tauri/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "viewstage"
3-
version = "0.3.0"
3+
version = "0.4.0"
44
description = "An application for video presentation and document annotation"
55
authors = ["ospneam"]
66
edition = "2021"

src-tauri/capabilities/default.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"$schema": "../gen/schemas/desktop-schema.json",
33
"identifier": "default",
44
"description": "Capability for the main window",
5-
"windows": ["main", "settings"],
5+
"windows": ["main", "settings", "oobe"],
66
"permissions": [
77
"core:default",
88
"opener:default",

src-tauri/src/lib.rs

Lines changed: 115 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -722,6 +722,7 @@ use std::sync::atomic::{AtomicBool, Ordering};
722722

723723
static MIRROR_STATE: AtomicBool = AtomicBool::new(false);
724724
static ENHANCE_STATE: AtomicBool = AtomicBool::new(false);
725+
static OOBE_ACTIVE: AtomicBool = AtomicBool::new(false);
725726

726727
// ==================== 设置窗口 ====================
727728
// 打开设置窗口、状态同步
@@ -1025,6 +1026,60 @@ async fn get_available_resolutions(app: tauri::AppHandle) -> Result<Vec<(u32, u3
10251026
Ok(resolutions)
10261027
}
10271028

1029+
#[tauri::command]
1030+
async fn close_splashscreen(app: tauri::AppHandle) -> Result<(), String> {
1031+
if let Some(splashscreen) = app.get_webview_window("splashscreen") {
1032+
let _ = splashscreen.close();
1033+
}
1034+
if let Some(main_window) = app.get_webview_window("main") {
1035+
let _ = main_window.show();
1036+
}
1037+
Ok(())
1038+
}
1039+
1040+
#[tauri::command]
1041+
async fn complete_oobe(app: tauri::AppHandle) -> Result<(), String> {
1042+
OOBE_ACTIVE.store(false, Ordering::SeqCst);
1043+
1044+
let main_window = app.get_webview_window("main").ok_or("Main window not found")?;
1045+
1046+
let config_dir = app.path().app_config_dir().map_err(|e| e.to_string())?;
1047+
let config_path = config_dir.join("config.json");
1048+
1049+
if config_path.exists() {
1050+
if let Ok(config_content) = std::fs::read_to_string(&config_path) {
1051+
if let Ok(config) = serde_json::from_str::<serde_json::Value>(&config_content) {
1052+
if let (Some(width), Some(height)) = (
1053+
config.get("width").and_then(|v| v.as_u64()),
1054+
config.get("height").and_then(|v| v.as_u64())
1055+
) {
1056+
let _ = main_window.set_size(tauri::Size::Physical(tauri::PhysicalSize {
1057+
width: width as u32,
1058+
height: height as u32,
1059+
}));
1060+
}
1061+
}
1062+
}
1063+
}
1064+
1065+
let _ = main_window.show();
1066+
let _ = main_window.set_fullscreen(true);
1067+
let _ = main_window.set_focus();
1068+
1069+
if let Some(oobe_window) = app.get_webview_window("oobe") {
1070+
let _ = oobe_window.close();
1071+
}
1072+
1073+
main_window.eval("location.reload()").map_err(|e| e.to_string())?;
1074+
1075+
Ok(())
1076+
}
1077+
1078+
#[tauri::command]
1079+
fn is_oobe_active() -> bool {
1080+
OOBE_ACTIVE.load(Ordering::SeqCst)
1081+
}
1082+
10281083
#[cfg_attr(mobile, tauri::mobile_entry_point)]
10291084
pub fn run() {
10301085
tauri::Builder::default()
@@ -1051,8 +1106,36 @@ pub fn run() {
10511106
let config_dir = app.path().app_config_dir().unwrap();
10521107
let config_path = config_dir.join("config.json");
10531108

1054-
if config_path.exists() {
1055-
if let Ok(config_content) = std::fs::read_to_string(config_path) {
1109+
let is_first_run = !config_path.exists();
1110+
1111+
if is_first_run {
1112+
println!("首次运行,打开 OOBE 界面");
1113+
1114+
OOBE_ACTIVE.store(true, Ordering::SeqCst);
1115+
1116+
use tauri::WebviewWindowBuilder;
1117+
1118+
let oobe_window = WebviewWindowBuilder::new(
1119+
app,
1120+
"oobe",
1121+
tauri::WebviewUrl::App("oobe.html".into())
1122+
)
1123+
.title("欢迎使用 ViewStage")
1124+
.inner_size(500.0, 520.0)
1125+
.resizable(false)
1126+
.decorations(false)
1127+
.center()
1128+
.always_on_top(true)
1129+
.build()
1130+
.expect("Failed to create OOBE window");
1131+
1132+
let _ = oobe_window.set_focus();
1133+
1134+
if let Some(splashscreen) = app.get_webview_window("splashscreen") {
1135+
let _ = splashscreen.close();
1136+
}
1137+
} else {
1138+
if let Ok(config_content) = std::fs::read_to_string(&config_path) {
10561139
if let Ok(config) = serde_json::from_str::<serde_json::Value>(&config_content) {
10571140
if let (Some(width), Some(height)) = (
10581141
config.get("width").and_then(|v| v.as_u64()),
@@ -1067,26 +1150,38 @@ pub fn run() {
10671150
let _ = window.set_fullscreen(true);
10681151
}
10691152
}
1070-
}
1071-
1072-
let args: Vec<String> = std::env::args().collect();
1073-
println!("启动参数: {:?}", args);
1074-
1075-
if args.len() > 1 {
1076-
let file_path = args[1].clone();
1077-
println!("检测到文件参数: {}", file_path);
1153+
1154+
let args: Vec<String> = std::env::args().collect();
1155+
println!("启动参数: {:?}", args);
1156+
1157+
if args.len() > 1 {
1158+
let file_path = args[1].clone();
1159+
println!("检测到文件参数: {}", file_path);
1160+
1161+
let app_handle = app.handle().clone();
1162+
std::thread::spawn(move || {
1163+
std::thread::sleep(std::time::Duration::from_millis(2000));
1164+
println!("发送文件打开事件: {}", file_path);
1165+
let _ = app_handle.emit("file-opened", file_path.clone());
1166+
println!("已发送文件打开事件: {}", file_path);
1167+
});
1168+
}
1169+
1170+
println!("应用已启动,等待文件打开事件...");
10781171

10791172
let app_handle = app.handle().clone();
10801173
std::thread::spawn(move || {
1081-
std::thread::sleep(std::time::Duration::from_millis(2000));
1082-
println!("发送文件打开事件: {}", file_path);
1083-
let _ = app_handle.emit("file-opened", file_path.clone());
1084-
println!("已发送文件打开事件: {}", file_path);
1174+
std::thread::sleep(std::time::Duration::from_millis(1000));
1175+
if let Some(splashscreen) = app_handle.get_webview_window("splashscreen") {
1176+
let _ = splashscreen.close();
1177+
}
1178+
if let Some(main_window) = app_handle.get_webview_window("main") {
1179+
let _ = main_window.show();
1180+
let _ = main_window.set_focus();
1181+
}
10851182
});
10861183
}
10871184

1088-
println!("应用已启动,等待文件打开事件...");
1089-
10901185
Ok(())
10911186
})
10921187
.invoke_handler(tauri::generate_handler![
@@ -1114,7 +1209,10 @@ pub fn run() {
11141209
reset_settings,
11151210
restart_app,
11161211
get_available_resolutions,
1117-
check_pdf_default_app
1212+
check_pdf_default_app,
1213+
close_splashscreen,
1214+
complete_oobe,
1215+
is_oobe_active
11181216
])
11191217
.run(tauri::generate_context!())
11201218
.expect("error while running tauri application");

src-tauri/tauri.conf.json

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"$schema": "https://schema.tauri.app/config/2",
33
"productName": "ViewStage",
4-
"version": "0.3.0",
4+
"version": "0.4.0",
55
"identifier": "com.viewstage.app",
66
"build": {
77
"frontendDist": "../src"
@@ -16,11 +16,22 @@
1616
"fullscreen": true,
1717
"resizable": false,
1818
"label": "main",
19-
"title": "ViewStage"
19+
"title": "ViewStage",
20+
"visible": false
21+
},
22+
{
23+
"width": 400,
24+
"height": 250,
25+
"decorations": false,
26+
"url": "splashscreen.html",
27+
"label": "splashscreen",
28+
"title": "ViewStage",
29+
"center": true,
30+
"alwaysOnTop": true
2031
}
2132
],
2233
"security": {
23-
"csp": "default-src 'self'; media-src 'self' blob: data:; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; worker-src 'self' blob:;"
34+
"csp": "default-src 'self'; connect-src 'self' ipc.localhost: http://ipc.localhost data: blob: tauri.localhost: http://tauri.localhost; media-src 'self' blob: data:; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; worker-src 'self' blob:;"
2435
}
2536
},
2637
"bundle": {

src/assets/Chinese.png

11.9 KB
Loading

src/assets/English.png

225 KB
Loading

src/main.js

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,11 @@ function getCachedCanvasRect() {
361361
window.addEventListener('DOMContentLoaded', async () => {
362362
try {
363363
if (window.__TAURI__) {
364+
const isOobeActive = await invoke('is_oobe_active');
365+
if (isOobeActive) {
366+
console.log('OOBE 激活中,跳过主窗口初始化');
367+
return;
368+
}
364369
listenForPdfFileOpen();
365370
}
366371

@@ -386,7 +391,6 @@ window.addEventListener('DOMContentLoaded', async () => {
386391
}
387392
});
388393

389-
// 加载摄像头设置
390394
async function loadCameraSetting() {
391395
if (window.__TAURI__) {
392396
try {
@@ -3912,19 +3916,17 @@ async function setCameraState(open, options = {}) {
39123916
const { forceClose = false } = options;
39133917

39143918
if (open) {
3915-
// 开启摄像头
39163919
if (state.isCameraOpen) {
39173920
return;
39183921
}
39193922

39203923
try {
39213924
let constraints;
39223925

3923-
// 优先使用指定的摄像头设备ID
39243926
if (state.defaultCameraId) {
39253927
constraints = {
39263928
video: {
3927-
deviceId: { exact: state.defaultCameraId },
3929+
deviceId: { ideal: state.defaultCameraId },
39283930
width: { ideal: state.cameraWidth || 1280 },
39293931
height: { ideal: state.cameraHeight || 720 }
39303932
},
@@ -3941,10 +3943,25 @@ async function setCameraState(open, options = {}) {
39413943
};
39423944
}
39433945

3944-
state.cameraStream = await navigator.mediaDevices.getUserMedia(constraints);
3946+
try {
3947+
state.cameraStream = await navigator.mediaDevices.getUserMedia(constraints);
3948+
} catch (constraintError) {
3949+
if (constraintError.name === 'OverconstrainedError') {
3950+
console.warn('摄像头不支持请求的分辨率,使用默认设置');
3951+
const fallbackConstraints = {
3952+
video: {
3953+
facingMode: state.useFrontCamera ? 'user' : 'environment'
3954+
},
3955+
audio: false
3956+
};
3957+
state.cameraStream = await navigator.mediaDevices.getUserMedia(fallbackConstraints);
3958+
} else {
3959+
throw constraintError;
3960+
}
3961+
}
3962+
39453963
state.isCameraOpen = true;
39463964

3947-
// 判断是否需要镜像(前置摄像头)
39483965
const videoTrack = state.cameraStream.getVideoTracks()[0];
39493966
const settings = videoTrack.getSettings();
39503967
const label = videoTrack.label.toLowerCase();
@@ -3955,7 +3972,7 @@ async function setCameraState(open, options = {}) {
39553972
clearSidebarSelection();
39563973
updateEnhanceButtonState();
39573974

3958-
console.log('摄像头已打开:', videoTrack.label || '未知设备');
3975+
console.log('摄像头已打开:', videoTrack.label || '未知设备', '分辨率:', settings.width, 'x', settings.height);
39593976
} catch (error) {
39603977
console.error('无法访问摄像头:', error);
39613978
alert('无法访问摄像头,请确保已授权摄像头权限');

0 commit comments

Comments
 (0)