🎨 重构下代码
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"windows": [
|
||||
{
|
||||
"url": "https://weread.qq.com/",
|
||||
"url": "https://twitter.com/home",
|
||||
"transparent": true,
|
||||
"fullscreen": false,
|
||||
"width": 1200,
|
||||
|
||||
@@ -1,43 +1,46 @@
|
||||
use crate::app::config::PakeConfig;
|
||||
use std::path::PathBuf;
|
||||
use tauri::{App, TitleBarStyle, Window, WindowBuilder, WindowUrl};
|
||||
|
||||
pub fn get_window(app: &mut App, config: PakeConfig, _data_dir: std::path::PathBuf) -> Window {
|
||||
let window_config = config.windows.first().unwrap();
|
||||
let user_agent = config.user_agent;
|
||||
pub fn get_window(app: &mut App, config: PakeConfig, _data_dir: PathBuf) -> Window {
|
||||
let window_config = config
|
||||
.windows
|
||||
.first()
|
||||
.expect("At least one window configuration is required");
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
let user_agent = config.user_agent.macos.as_str();
|
||||
#[cfg(target_os = "linux")]
|
||||
let user_agent = config.user_agent.linux.as_str();
|
||||
#[cfg(target_os = "windows")]
|
||||
let user_agent = config.user_agent.windows.as_str();
|
||||
|
||||
let url = match window_config.url_type.as_str() {
|
||||
"web" => WindowUrl::App(window_config.url.parse().unwrap()),
|
||||
"local" => WindowUrl::App(std::path::PathBuf::from(&window_config.url)),
|
||||
"local" => WindowUrl::App(PathBuf::from(&window_config.url)),
|
||||
_ => panic!("url type only can be web or local"),
|
||||
};
|
||||
#[cfg(target_os = "macos")]
|
||||
let window = WindowBuilder::new(app, "pake", url)
|
||||
|
||||
let title_bar_style = if window_config.transparent {
|
||||
TitleBarStyle::Overlay
|
||||
} else {
|
||||
TitleBarStyle::Visible
|
||||
};
|
||||
|
||||
let window_builder = WindowBuilder::new(app, "pake", url)
|
||||
.title("")
|
||||
.user_agent(user_agent.macos.as_str())
|
||||
.user_agent(user_agent)
|
||||
.resizable(window_config.resizable)
|
||||
.fullscreen(window_config.fullscreen)
|
||||
//用于隐藏头部
|
||||
.title_bar_style(if window_config.transparent {
|
||||
TitleBarStyle::Overlay
|
||||
} else {
|
||||
TitleBarStyle::Visible
|
||||
})
|
||||
.title_bar_style(title_bar_style)
|
||||
.inner_size(window_config.width, window_config.height)
|
||||
.initialization_script(include_str!("../inject.js"));
|
||||
.initialization_script(include_str!("../inject/style.js"))
|
||||
.initialization_script(include_str!("../inject/index.js"));
|
||||
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
let window = {
|
||||
#[cfg(target_os = "linux")]
|
||||
let user_agent = user_agent.linux.as_str();
|
||||
#[cfg(target_os = "windows")]
|
||||
let user_agent = user_agent.windows.as_str();
|
||||
WindowBuilder::new(app, "pake", url)
|
||||
.title("")
|
||||
.data_directory(_data_dir)
|
||||
.resizable(window_config.resizable)
|
||||
.fullscreen(window_config.fullscreen)
|
||||
.user_agent(user_agent)
|
||||
.inner_size(window_config.width, window_config.height)
|
||||
.initialization_script(include_str!("../inject.js"))
|
||||
};
|
||||
window.build().unwrap()
|
||||
{
|
||||
window_builder = window_builder.data_directory(_data_dir);
|
||||
}
|
||||
|
||||
window_builder.build().unwrap()
|
||||
}
|
||||
|
||||
133
src-tauri/src/inject/index.js
Normal file
133
src-tauri/src/inject/index.js
Normal file
@@ -0,0 +1,133 @@
|
||||
const shortcuts = {
|
||||
ArrowUp: () => scrollTo(0, 0),
|
||||
ArrowDown: () => scrollTo(0, document.body.scrollHeight),
|
||||
ArrowLeft: () => window.history.back(),
|
||||
ArrowRight: () => window.history.forward(),
|
||||
'[': () => window.history.back(),
|
||||
']': () => window.history.forward(),
|
||||
r: () => window.location.reload(),
|
||||
'-': () => zoomOut(),
|
||||
'=': () => zoomIn(),
|
||||
'+': () => zoomIn(),
|
||||
0: () => setZoom('100%'),
|
||||
};
|
||||
|
||||
function setZoom(zoom) {
|
||||
const html = document.getElementsByTagName('html')[0];
|
||||
html.style.zoom = zoom;
|
||||
window.localStorage.setItem('htmlZoom', zoom);
|
||||
}
|
||||
|
||||
function zoomCommon(zoomChange) {
|
||||
const currentZoom = window.localStorage.getItem('htmlZoom') || '100%';
|
||||
setZoom(zoomChange(currentZoom));
|
||||
}
|
||||
|
||||
function zoomIn() {
|
||||
zoomCommon((currentZoom) => `${Math.min(parseInt(currentZoom) + 10, 200)}%`);
|
||||
}
|
||||
|
||||
function zoomOut() {
|
||||
zoomCommon((currentZoom) => `${Math.max(parseInt(currentZoom) - 10, 30)}%`);
|
||||
}
|
||||
|
||||
function handleShortcut(event) {
|
||||
if (shortcuts[event.key]) {
|
||||
event.preventDefault();
|
||||
shortcuts[event.key]();
|
||||
}
|
||||
}
|
||||
|
||||
//这里参考 ChatGPT 的代码
|
||||
const uid = () => window.crypto.getRandomValues(new Uint32Array(1))[0];
|
||||
function transformCallback(callback = () => {}, once = false) {
|
||||
const identifier = uid();
|
||||
const prop = `_${identifier}`;
|
||||
Object.defineProperty(window, prop, {
|
||||
value: (result) => {
|
||||
if (once) {
|
||||
Reflect.deleteProperty(window, prop);
|
||||
}
|
||||
return callback(result);
|
||||
},
|
||||
writable: false,
|
||||
configurable: true,
|
||||
});
|
||||
return identifier;
|
||||
}
|
||||
async function invoke(cmd, args) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!window.__TAURI_POST_MESSAGE__)
|
||||
reject('__TAURI_POST_MESSAGE__ does not exist~');
|
||||
const callback = transformCallback((e) => {
|
||||
resolve(e);
|
||||
Reflect.deleteProperty(window, `_${error}`);
|
||||
}, true);
|
||||
const error = transformCallback((e) => {
|
||||
reject(e);
|
||||
Reflect.deleteProperty(window, `_${callback}`);
|
||||
}, true);
|
||||
window.__TAURI_POST_MESSAGE__({
|
||||
cmd,
|
||||
callback,
|
||||
error,
|
||||
...args,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const topDom = document.createElement('div');
|
||||
topDom.id = 'pack-top-dom';
|
||||
document.body.appendChild(topDom);
|
||||
const domEl = document.getElementById('pack-top-dom');
|
||||
|
||||
domEl.addEventListener('mousedown', (e) => {
|
||||
if (e.buttons === 1 && e.detail !== 2) {
|
||||
invoke('drag_window');
|
||||
}
|
||||
});
|
||||
|
||||
domEl.addEventListener('touchstart', () => {
|
||||
invoke('drag_window');
|
||||
});
|
||||
|
||||
domEl.addEventListener('dblclick', () => {
|
||||
invoke('fullscreen');
|
||||
});
|
||||
|
||||
document.addEventListener('keyup', (event) => {
|
||||
if (/windows|linux/i.test(navigator.userAgent) && event.ctrlKey) {
|
||||
handleShortcut(event);
|
||||
}
|
||||
if (/macintosh|mac os x/i.test(navigator.userAgent) && event.metaKey) {
|
||||
handleShortcut(event);
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener('click', (e) => {
|
||||
const origin = e.target.closest('a');
|
||||
if (origin && origin.href) {
|
||||
const target = origin.target;
|
||||
origin.target = '_self';
|
||||
const hrefUrl = new URL(origin.href);
|
||||
|
||||
if (
|
||||
window.location.host !== hrefUrl.host && // 如果 a 标签内链接的域名和当前页面的域名不一致 且
|
||||
target === '_blank' // a 标签内链接的 target 属性为 _blank 时
|
||||
) {
|
||||
e.preventDefault();
|
||||
invoke('open_browser', { url: origin.href });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
setDefaultZoom();
|
||||
});
|
||||
|
||||
function setDefaultZoom() {
|
||||
const htmlZoom = window.localStorage.getItem('htmlZoom');
|
||||
if (htmlZoom) {
|
||||
setZoom(htmlZoom);
|
||||
}
|
||||
}
|
||||
@@ -1,67 +1,5 @@
|
||||
const metaKeyShortcuts = {
|
||||
ArrowUp: () => scrollTo(0, 0),
|
||||
ArrowDown: () => scrollTo(0, document.body.scrollHeight),
|
||||
'[': () => window.history.back(),
|
||||
']': () => window.history.forward(),
|
||||
r: () => window.location.reload(),
|
||||
'-': () => zoomOut(),
|
||||
'=': () => zoomIn(),
|
||||
'+': () => zoomIn(),
|
||||
0: () => zoomCommon(() => '100%'),
|
||||
};
|
||||
|
||||
const ctrlKeyShortcuts = {
|
||||
ArrowUp: () => scrollTo(0, 0),
|
||||
ArrowDown: () => scrollTo(0, document.body.scrollHeight),
|
||||
ArrowLeft: () => window.history.back(),
|
||||
ArrowRight: () => window.history.forward(),
|
||||
r: () => window.location.reload(),
|
||||
'-': () => zoomOut(),
|
||||
'=': () => zoomIn(),
|
||||
'+': () => zoomIn(),
|
||||
0: () => zoomCommon(() => '100%'),
|
||||
};
|
||||
|
||||
const uid = () => window.crypto.getRandomValues(new Uint32Array(1))[0];
|
||||
function transformCallback(callback = () => {}, once = false) {
|
||||
const identifier = uid();
|
||||
const prop = `_${identifier}`;
|
||||
Object.defineProperty(window, prop, {
|
||||
value: (result) => {
|
||||
if (once) {
|
||||
Reflect.deleteProperty(window, prop);
|
||||
}
|
||||
return callback(result);
|
||||
},
|
||||
writable: false,
|
||||
configurable: true,
|
||||
});
|
||||
return identifier;
|
||||
}
|
||||
async function invoke(cmd, args) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!window.__TAURI_POST_MESSAGE__)
|
||||
reject('__TAURI_POST_MESSAGE__ does not exist~');
|
||||
const callback = transformCallback((e) => {
|
||||
resolve(e);
|
||||
Reflect.deleteProperty(window, `_${error}`);
|
||||
}, true);
|
||||
const error = transformCallback((e) => {
|
||||
reject(e);
|
||||
Reflect.deleteProperty(window, `_${callback}`);
|
||||
}, true);
|
||||
window.__TAURI_POST_MESSAGE__({
|
||||
cmd,
|
||||
callback,
|
||||
error,
|
||||
...args,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
window.addEventListener('DOMContentLoaded', (_event) => {
|
||||
const style = document.createElement('style');
|
||||
style.innerHTML = `
|
||||
const css = `
|
||||
#page #footer-wrapper,
|
||||
.drawing-board .toolbar .toolbar-action,
|
||||
.c-swiper-container,
|
||||
@@ -300,89 +238,11 @@ window.addEventListener('DOMContentLoaded', (_event) => {
|
||||
height: 20px;
|
||||
cursor: grab;
|
||||
cursor: -webkit-grab;
|
||||
-webkit-app-region: drag;
|
||||
z-index: 90000;
|
||||
}
|
||||
`;
|
||||
document.head.append(style);
|
||||
const topDom = document.createElement('div');
|
||||
topDom.id = 'pack-top-dom';
|
||||
document.body.appendChild(topDom);
|
||||
|
||||
const domEl = document.getElementById('pack-top-dom');
|
||||
|
||||
domEl.addEventListener('mousedown', (e) => {
|
||||
if (e.buttons === 1 && e.detail !== 2) {
|
||||
invoke('drag_window');
|
||||
}
|
||||
});
|
||||
|
||||
domEl.addEventListener('touchstart', () => {
|
||||
invoke('drag_window');
|
||||
});
|
||||
|
||||
domEl.addEventListener('dblclick', () => {
|
||||
invoke('fullscreen');
|
||||
});
|
||||
|
||||
document.addEventListener('keyup', function (event) {
|
||||
const preventDefault = (f) => {
|
||||
event.preventDefault();
|
||||
f();
|
||||
};
|
||||
if (/windows|linux/i.test(navigator.userAgent)) {
|
||||
if (event.ctrlKey && event.key in ctrlKeyShortcuts) {
|
||||
preventDefault(ctrlKeyShortcuts[event.key]);
|
||||
}
|
||||
}
|
||||
if (/macintosh|mac os x/i.test(navigator.userAgent)) {
|
||||
if (event.metaKey && event.key in metaKeyShortcuts) {
|
||||
preventDefault(metaKeyShortcuts[event.key]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener('click', (e) => {
|
||||
const origin = e.target.closest('a');
|
||||
if (origin && origin.href) {
|
||||
const target = origin.target;
|
||||
origin.target = '_self';
|
||||
const hrefUrl = new URL(origin.href);
|
||||
|
||||
if (
|
||||
window.location.host !== hrefUrl.host && // 如果 a 标签内链接的域名和当前页面的域名不一致 且
|
||||
target === '_blank' // a 标签内链接的 target 属性为 _blank 时
|
||||
) {
|
||||
e.preventDefault();
|
||||
invoke('open_browser', { url: origin.href });
|
||||
}
|
||||
}
|
||||
});
|
||||
const styleElement = document.createElement('style');
|
||||
styleElement.innerHTML = css;
|
||||
document.head.appendChild(styleElement);
|
||||
});
|
||||
|
||||
setDefaultZoom();
|
||||
|
||||
function setDefaultZoom() {
|
||||
const htmlZoom = window.localStorage.getItem('htmlZoom');
|
||||
if (htmlZoom) {
|
||||
document.getElementsByTagName('html')[0].style.zoom = htmlZoom;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {(htmlZoom: string) => string} [zoomRule]
|
||||
*/
|
||||
function zoomCommon(zoomRule) {
|
||||
const htmlZoom = window.localStorage.getItem('htmlZoom') || '100%';
|
||||
const html = document.getElementsByTagName('html')[0];
|
||||
const zoom = zoomRule(htmlZoom);
|
||||
html.style.zoom = zoom;
|
||||
window.localStorage.setItem('htmlZoom', zoom);
|
||||
}
|
||||
|
||||
function zoomIn() {
|
||||
zoomCommon((htmlZoom) => `${Math.min(parseInt(htmlZoom) + 10, 200)}%`);
|
||||
}
|
||||
|
||||
function zoomOut() {
|
||||
zoomCommon((htmlZoom) => `${Math.max(parseInt(htmlZoom) - 10, 30)}%`);
|
||||
}
|
||||
@@ -18,39 +18,25 @@ pub fn run_app() {
|
||||
let menu = get_menu();
|
||||
let data_dir = get_data_dir(tauri_config);
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
let tauri_app = if show_menu {
|
||||
tauri::Builder::default()
|
||||
.menu(menu)
|
||||
.on_menu_event(menu_event_handle)
|
||||
} else {
|
||||
tauri::Builder::default()
|
||||
};
|
||||
let mut tauri_app = tauri::Builder::default();
|
||||
|
||||
if show_menu {
|
||||
tauri_app = tauri_app.menu(menu).on_menu_event(menu_event_handle);
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
let tauri_app = {
|
||||
{
|
||||
use pake::{get_system_tray, system_tray_handle};
|
||||
|
||||
let show_system_tray = pake_config.show_system_tray();
|
||||
let system_tray = get_system_tray(show_menu);
|
||||
let tauri_app = if show_menu && !show_system_tray {
|
||||
tauri::Builder::default()
|
||||
.menu(menu)
|
||||
.on_menu_event(menu_event_handle)
|
||||
} else if !show_menu && show_system_tray {
|
||||
tauri::Builder::default()
|
||||
|
||||
if show_system_tray {
|
||||
tauri_app = tauri_app
|
||||
.system_tray(system_tray)
|
||||
.on_system_tray_event(system_tray_handle)
|
||||
} else if show_menu && show_system_tray {
|
||||
tauri::Builder::default()
|
||||
.menu(menu)
|
||||
.on_menu_event(menu_event_handle)
|
||||
.system_tray(system_tray)
|
||||
.on_system_tray_event(system_tray_handle)
|
||||
} else {
|
||||
tauri::Builder::default()
|
||||
};
|
||||
};
|
||||
.on_system_tray_event(system_tray_handle);
|
||||
}
|
||||
}
|
||||
|
||||
tauri_app
|
||||
.plugin(tauri_plugin_window_state::Builder::default().build())
|
||||
|
||||
@@ -1,36 +1,37 @@
|
||||
use crate::app::config::PakeConfig;
|
||||
use tauri::Config;
|
||||
use std::path::PathBuf;
|
||||
|
||||
pub fn get_pake_config() -> (PakeConfig, Config) {
|
||||
let pake_config_path = include_str!("../pake.json");
|
||||
let pake_config: PakeConfig =
|
||||
serde_json::from_str(pake_config_path).expect("failed to parse pake config");
|
||||
// println!("{:#?}", config);
|
||||
let tauri_config_path = include_str!("../tauri.conf.json");
|
||||
let tauri_config: Config =
|
||||
serde_json::from_str(tauri_config_path).expect("failed to parse tauri config");
|
||||
serde_json::from_str(include_str!("../pake.json")).expect("failed to parse pake config");
|
||||
|
||||
let tauri_config: Config = serde_json::from_str(include_str!("../tauri.conf.json"))
|
||||
.expect("failed to parse tauri config");
|
||||
|
||||
(pake_config, tauri_config)
|
||||
}
|
||||
|
||||
pub fn get_data_dir(_tauri_config: Config) -> std::path::PathBuf {
|
||||
pub fn get_data_dir(_tauri_config: Config) -> PathBuf {
|
||||
#[cfg(any(target_os = "linux", target_os = "windows"))]
|
||||
let data_dir = {
|
||||
{
|
||||
let package_name = _tauri_config.package.product_name.unwrap();
|
||||
let home_dir = match home::home_dir() {
|
||||
Some(path1) => path1,
|
||||
None => panic!("Error, can't found you home dir!!"),
|
||||
let home_dir = home::home_dir().expect("Error, can't found your home dir!!");
|
||||
|
||||
let data_dir = match cfg!(target_os = "windows") {
|
||||
true => home_dir.join("AppData").join("Roaming").join(package_name),
|
||||
false => home_dir.join(".config").join(package_name),
|
||||
};
|
||||
#[cfg(target_os = "windows")]
|
||||
let data_dir = home_dir.join("AppData").join("Roaming").join(package_name);
|
||||
#[cfg(target_os = "linux")]
|
||||
let data_dir = home_dir.join(".config").join(package_name);
|
||||
|
||||
if !data_dir.exists() {
|
||||
std::fs::create_dir(&data_dir)
|
||||
.unwrap_or_else(|_| panic!("can't create dir {}", data_dir.display()));
|
||||
}
|
||||
data_dir
|
||||
};
|
||||
}
|
||||
#[cfg(target_os = "macos")]
|
||||
let data_dir = std::path::PathBuf::new();
|
||||
data_dir
|
||||
{
|
||||
PathBuf::new()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user