дзеркало
https://github.com/l0ng-ai/openidea.git
синхронізовано 2026-11-09 19:25:54 +02:00
Merge remote-tracking branch 'origin/main' into feat/maven-dependency-analyzer
# Conflicts: # src/platform/locales/text/zh.json
Цей коміт міститься в:
коміт
8ca6206f18
57 files changed
+2945
-268
No files matched your search
@@ -332,6 +332,7 @@ pub fn builder() -> tauri_specta::Builder<tauri::Wry> {
|
||||
plugin::plugin_run_command,
|
||||
plugin::plugin_set_active_file,
|
||||
plugin::plugin_set_theme,
|
||||
plugin::plugin_set_theme_frame,
|
||||
perf::app_metrics,
|
||||
perf::clear_caches,
|
||||
analysis::inspect_code,
|
||||
|
||||
@@ -11,9 +11,13 @@ use parking_lot::Mutex;
|
||||
use std::collections::HashMap;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::{Arc, LazyLock};
|
||||
use std::time::Duration;
|
||||
use tauri::ipc::Channel;
|
||||
use tauri::{AppHandle, Manager, State, Window};
|
||||
|
||||
/// How long `plugin_list` waits for the startup load before answering with what it has.
|
||||
const INITIAL_LOAD_WAIT: Duration = Duration::from_secs(5);
|
||||
|
||||
/// Window label → its event channel.
|
||||
static SUBSCRIBERS: LazyLock<Mutex<HashMap<String, Channel<PluginEvent>>>> = LazyLock::new(Default::default);
|
||||
|
||||
@@ -62,6 +66,8 @@ pub async fn plugin_list(window: Window, state: State<'_, AppState>) -> IdeResul
|
||||
let host = state.plugins.clone();
|
||||
let root = state.project(window.label()).ok().map(|p| p.root.clone());
|
||||
blocking(move || {
|
||||
// A window opened at startup would otherwise see no plugins and drop the selected theme.
|
||||
host.wait_initial_load(INITIAL_LOAD_WAIT);
|
||||
if let Some(root) = &root {
|
||||
host.sync_project(root);
|
||||
}
|
||||
@@ -156,3 +162,11 @@ pub fn plugin_set_theme(
|
||||
_ => state.plugins.set_theme(None),
|
||||
}
|
||||
}
|
||||
|
||||
/// The UI reports the selected plugin theme's resolved frame colour (`#rrggbb[aa]`),
|
||||
/// which new windows open in before their page loads.
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub fn plugin_set_theme_frame(state: State<'_, AppState>, color: Option<String>) -> IdeResult<()> {
|
||||
state.plugins.set_theme_frame(color.as_deref())
|
||||
}
|
||||
@@ -230,11 +230,21 @@ pub fn frame_color(appearance: &AppearanceSettings, os_dark: bool) -> Color {
|
||||
}
|
||||
}
|
||||
|
||||
/// A `#rgb` / `#rrggbb` / `#rrggbbaa` colour sent by the UI (Tauri's own parser).
|
||||
fn hex_color(hex: &str) -> Option<Color> {
|
||||
serde_json::from_value(serde_json::Value::String(hex.to_owned())).ok()
|
||||
}
|
||||
|
||||
/// Builds a project window painted in the saved theme's frame colour, so it
|
||||
/// doesn't flash the light default before its page (and splash) loads.
|
||||
fn build_project_window(app: &AppHandle, mut config: WindowConfig) -> IdeResult<WebviewWindow> {
|
||||
let appearance = app.try_state::<AppState>().map(|s| s.global_settings.effective().appearance);
|
||||
if let Some(a) = &appearance {
|
||||
let state = app.try_state::<AppState>();
|
||||
let appearance = state.as_ref().map(|s| s.global_settings.effective().appearance);
|
||||
// A plugin theme replaces the built-in one in either OS mode; the UI records its resolved frame.
|
||||
let plugin_frame = state.as_ref().and_then(|s| s.plugins.startup_frame()).and_then(|c| hex_color(&c));
|
||||
if let Some(color) = plugin_frame {
|
||||
config.background_color = Some(color);
|
||||
} else if let Some(a) = &appearance {
|
||||
config.background_color = Some(frame_color(a, false));
|
||||
}
|
||||
let window = WebviewWindowBuilder::from_config(app, &config)
|
||||
@@ -242,7 +252,7 @@ fn build_project_window(app: &AppHandle, mut config: WindowConfig) -> IdeResult<
|
||||
.map_err(|e| IdeError::internal(format!("cannot create window: {e}")))?;
|
||||
apply_zoom(app, &window);
|
||||
// "Sync with OS" needs the OS mode, known once the window exists.
|
||||
if let Some(a) = appearance.filter(|a| a.sync_with_os || a.theme == "system")
|
||||
if let Some(a) = appearance.filter(|a| plugin_frame.is_none() && (a.sync_with_os || a.theme == "system"))
|
||||
&& window.theme().is_ok_and(|t| t == Theme::Dark)
|
||||
{
|
||||
let _ = window.set_background_color(Some(frame_color(&a, true)));
|
||||
@@ -418,7 +428,7 @@ pub fn open_settings_window(
|
||||
config.fullscreen = false;
|
||||
config.drag_drop_enabled = false;
|
||||
// macOS shows a child window as soon as it is attached, before the page loads: paint the theme's frame colour.
|
||||
if let Some(color) = background.and_then(|c| serde_json::from_value(serde_json::Value::String(c)).ok()) {
|
||||
if let Some(color) = background.as_deref().and_then(hex_color) {
|
||||
config.background_color = Some(color);
|
||||
}
|
||||
windows.set_launch(&label, Launch { project: None, settings_page: page, new_projects });
|
||||
@@ -465,6 +475,19 @@ mod tests {
|
||||
assert_eq!(frame_color(&a, true), Color(0x26, 0x28, 0x2c, 0xff));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn frame_colours_from_the_ui_parse_as_hex() {
|
||||
for (hex, expected) in [
|
||||
("#eaeaeb", Color(0xea, 0xea, 0xeb, 0xff)),
|
||||
("#21252b", Color(0x21, 0x25, 0x2b, 0xff)),
|
||||
("#8040bfcc", Color(0x80, 0x40, 0xbf, 0xcc)),
|
||||
("#fff", Color(0xff, 0xff, 0xff, 0xff)),
|
||||
] {
|
||||
assert_eq!(hex_color(hex), Some(expected), "{hex}");
|
||||
}
|
||||
assert_eq!(hex_color("hsl(220, 13%, 15%)"), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn labels_sort_main_first_then_numerically() {
|
||||
assert_eq!(
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://schema.tauri.app/config/2",
|
||||
"productName": "OpenIDEA",
|
||||
"version": "0.1.16",
|
||||
"version": "0.1.17",
|
||||
"identifier": "ai.l0ng.openidea",
|
||||
"build": {
|
||||
"beforeDevCommand": "pnpm dev",
|
||||
|
||||
Reference in new issue
Заблокувати користувача