Skip to content

Commit f5a10b8

Browse files
committed
Merge branch 'main' into release
2 parents 68b43b1 + cc5c139 commit f5a10b8

File tree

13 files changed

+238
-207
lines changed

13 files changed

+238
-207
lines changed

docs/architecture.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Pavo 项目架构设计
2+
3+
Pavo 是一款基于 Tauri 的跨平台桌面壁纸应用,采用前后端分离架构,前端使用 Svelte,后端核心逻辑用 Rust 实现。
4+
5+
## 架构总览
6+
7+
```mermaid
8+
graph TD
9+
subgraph 前端Svelte
10+
FE1[壁纸页 Bing]
11+
FE2[设置页 Settings]
12+
FE3[关于页 About]
13+
FE4[Updater 检查更新]
14+
end
15+
subgraph Tauri 后端Rust
16+
CMD[命令接口 cmd.rs]
17+
CONF[配置管理 config.rs]
18+
SCHED[调度器 scheduler.rs]
19+
BG[后台服务 background.rs]
20+
TRAY[托盘交互 tray.rs]
21+
PLUG[插件系统 plugins.rs]
22+
SVCS[服务 services/mod.rs]
23+
BING[壁纸服务 bing.rs]
24+
SHUFFLE[自动切换 shuffle_thread.rs]
25+
end
26+
FE1--invoke-->CMD
27+
FE2--invoke-->CMD
28+
FE3--invoke-->CMD
29+
FE4--invoke-->CMD
30+
CMD--读写配置-->CONF
31+
CMD--调度壁纸-->SCHED
32+
CMD--调用服务-->SVCS
33+
CMD--托盘交互-->TRAY
34+
CMD--插件注册-->PLUG
35+
SCHED--调用Bing服务-->BING
36+
SCHED--自动切换-->SHUFFLE
37+
BG--消息调度-->SCHED
38+
BG--消息调度-->SHUFFLE
39+
SVCS--下载/保存壁纸-->BING
40+
TRAY--发送消息-->BG
41+
```
42+
43+
## 说明
44+
- **前端(Svelte)**:负责 UI 展示和用户交互,通过 Tauri invoke 与后端通信。
45+
- **Tauri 后端(Rust)**:实现所有业务逻辑,包括配置管理、壁纸调度、后台服务、托盘菜单、插件注册、壁纸下载与切换等。
46+
- **核心流程**
47+
1. 前端页面通过 invoke 调用后端命令(如获取壁纸列表、设置、关于等)。
48+
2. 后端命令分发到对应模块(如 scheduler、services、config)。
49+
3. 调度器负责壁纸的获取、缓存、切换,支持自动定时切换(shuffle_thread)。
50+
4. 托盘菜单和后台服务通过消息通道与调度器联动,实现快捷操作和自动化。
51+
5. 插件系统用于扩展功能,如日志、更新、文件系统等。
52+
53+
---

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "pavo",
3-
"version": "0.0.10",
3+
"version": "0.0.11",
44
"description": "bing daily wallpaper",
55
"type": "module",
66
"scripts": {

public/yew.png

-7.46 KB
Binary file not shown.

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 = "pavo"
3-
version = "0.0.10"
3+
version = "0.0.11"
44
description = "wallpaper"
55
authors = ["you"]
66
license = ""

src-tauri/src/scheduler.rs

Lines changed: 29 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
11
use chrono::offset::Utc;
22
use chrono::Local;
33
use once_cell::sync::Lazy;
4-
use reqwest::Client;
54
use serde::{Deserialize, Serialize};
6-
use std::path::Path;
7-
use tokio::{self, sync::Mutex};
5+
use tokio::{sync::Mutex};
86

9-
use crate::config;
107
use crate::services::bing;
11-
use crate::services::download_file;
8+
use crate::services::{save_wallpaper};
129

1310
#[allow(dead_code)]
1411
fn now() -> String {
@@ -149,71 +146,65 @@ impl Scheduler {
149146
list
150147
}
151148

152-
pub async fn save_wallpaper(url: &str, filename: &str) -> Result<String, String> {
153-
let app_folder = config::PavoConfig::get_app_folder().unwrap();
154-
let path = Path::new(&app_folder).join(&*filename);
155-
let res = download_file(&Client::new(), &url, path.clone().to_str().unwrap())
156-
.await
157-
.unwrap();
158-
159-
println!("{:?}", res);
160-
161-
Ok(res)
162-
}
163-
164-
pub async fn set_wallpaper_from_local(a: String) -> String {
165-
wallpaper::set_from_path(a.as_str()).unwrap();
149+
pub async fn set_wallpaper_from_local(path: &str) -> Result<&str, Box<dyn std::error::Error + Send + Sync>> {
150+
wallpaper::set_from_path(path).map_err(|e| e.to_string())?;
166151

167152
if cfg!(not(target_os = "macos")) {
168-
wallpaper::set_mode(wallpaper::Mode::Crop).unwrap();
153+
wallpaper::set_mode(wallpaper::Mode::Crop).map_err(|e| e.to_string())?;
169154
}
170155

171-
a
156+
Ok(path)
172157
}
173158

174-
pub async fn set_wallpaper(url: &str, filename: &str) -> Result<String, String> {
175-
let a = Self::save_wallpaper(url, filename).await;
159+
pub async fn set_wallpaper(url: &str, filename: &str) -> Result<String, Box<dyn std::error::Error + Send + Sync>> {
160+
let file_path = save_wallpaper(url, filename).await?;
176161

177-
match a {
178-
Ok(a) => {
179-
Self::set_wallpaper_from_local(a).await;
162+
Self::set_wallpaper_from_local(&file_path).await
163+
.map_err(|e| format!("Failed to set wallpaper from local file: {}", e))?;
180164

181-
Ok(String::from("OK"))
182-
}
183-
Err(e) => Err(e.to_string().into()),
184-
}
165+
Ok(String::from("Ok"))
185166
}
186167

187-
pub async fn previous_photo(&mut self) {
168+
pub async fn previous_photo(&mut self) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
188169
let list = self.cache_list.clone();
189170

171+
if list.is_empty() {
172+
return Err("No wallpapers available in cache".into());
173+
}
174+
190175
if self.current_idx <= 0 {
191176
self.current_idx = list.len() - 1;
192177
} else {
193178
self.current_idx -= 1;
194179
}
195180

196-
let item = list[self.current_idx].clone();
181+
let item = &list[self.current_idx];
197182

198183
Self::set_wallpaper(&item.urls[0], &item.filename)
199-
.await
200-
.unwrap();
184+
.await?;
185+
186+
Ok(())
201187
}
202188

203-
pub async fn next_photo(&mut self) {
189+
pub async fn next_photo(&mut self) -> Result<(), Box<dyn std::error::Error + Send + Sync>>{
204190
let list = self.cache_list.clone();
205191

192+
if list.is_empty() {
193+
return Err("No wallpapers available in cache".into());
194+
}
195+
206196
if self.current_idx >= list.len() - 1 {
207197
self.current_idx = 0;
208198
} else {
209199
self.current_idx += 1;
210200
}
211201

212-
let item = list[self.current_idx].clone();
202+
let item = &list[self.current_idx];
213203

214204
Self::set_wallpaper(&item.urls[0], &item.filename)
215-
.await
216-
.unwrap();
205+
.await?;
206+
207+
Ok(())
217208
}
218209
}
219210

src-tauri/src/services/bing.rs

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@ use crate::config;
77

88
pub type Result<T> = std::result::Result<T, Box<dyn std::error::Error + Send + Sync>>;
99

10+
use once_cell::sync::Lazy;
11+
use std::sync::Arc;
12+
13+
static GLOBAL_CLIENT: Lazy<Arc<Client>> = Lazy::new(|| {
14+
Arc::new(Client::new())
15+
});
16+
1017
#[derive(Debug, Clone, Serialize, Deserialize)]
1118
pub struct UrlParams {
1219
pub index: u8,
@@ -87,24 +94,29 @@ impl Wallpaper {
8794
index,
8895
number,
8996
files: vec![],
90-
json,
97+
json
9198
})
9299
}
93100

94-
pub async fn save_wallpaper(url: &str, filename: Option<&str>) -> Result<String> {
101+
pub async fn save_wallpaper(
102+
url: &str,
103+
filename: Option<&str>,
104+
) -> Result<String> {
95105
let filename = match filename {
96106
Some(filename) => filename,
97107
None => Images::get_filename(url),
98108
};
99-
let app_folder = config::PavoConfig::get_app_folder().unwrap();
109+
let app_folder = config::PavoConfig::get_app_folder()
110+
.map_err(|e| -> Box<dyn std::error::Error + Send + Sync> {
111+
Box::new(std::io::Error::new(std::io::ErrorKind::Other, format!("Error code: {}, message: {}", e.0, e.1)))
112+
})?;
100113
let path = Path::new(&app_folder).join(&*filename);
101-
let res = download_file(&Client::new(), &url, path.clone().to_str().unwrap())
102-
.await
103-
.unwrap();
114+
let client = GLOBAL_CLIENT.clone();
115+
let res = download_file(&client, &url, path.clone().to_str().unwrap()).await;
104116

105117
println!("{:?}", res);
106118

107-
Ok(res)
119+
return res;
108120
}
109121

110122
/// set wallpaper from local file

0 commit comments

Comments
 (0)