feat: add macOS app icon support and update project configuration
|
|
@ -3,6 +3,7 @@
|
|||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
|
||||
<title>ClaudePrism | LaTeX Writing Workspace</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
|
|
|
|||
BIN
apps/desktop/public/favicon.ico
Normal file
|
After Width: | Height: | Size: 5.1 KiB |
BIN
apps/desktop/public/icon-192.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
3
apps/desktop/src-tauri/Cargo.lock
generated
|
|
@ -317,6 +317,9 @@ dependencies = [
|
|||
"dotenvy",
|
||||
"git2",
|
||||
"hmac",
|
||||
"objc2",
|
||||
"objc2-app-kit",
|
||||
"objc2-foundation",
|
||||
"reqwest 0.12.28",
|
||||
"serde",
|
||||
"serde_json",
|
||||
|
|
|
|||
|
|
@ -28,3 +28,8 @@ base64 = "0.22"
|
|||
dotenvy = "0.15"
|
||||
git2 = "0.20"
|
||||
chrono = "0.4"
|
||||
|
||||
[target.'cfg(target_os = "macos")'.dependencies]
|
||||
objc2 = "0.6"
|
||||
objc2-app-kit = { version = "0.3", features = ["NSApplication", "NSImage", "NSRunningApplication"] }
|
||||
objc2-foundation = { version = "0.3", features = ["NSData"] }
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 782 B After Width: | Height: | Size: 8 KiB |
BIN
apps/desktop/src-tauri/icons/128x128@2x.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 236 B After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 5 KiB After Width: | Height: | Size: 331 KiB |
|
Before Width: | Height: | Size: 5 KiB After Width: | Height: | Size: 42 KiB |
|
|
@ -6,6 +6,26 @@ use std::process::Command;
|
|||
use std::sync::Mutex;
|
||||
use tauri::Manager;
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
fn set_macos_app_icon() {
|
||||
use objc2::{AnyThread, MainThreadMarker};
|
||||
use objc2_foundation::NSData;
|
||||
use objc2_app_kit::{NSApplication, NSImage};
|
||||
|
||||
let icon_bytes = include_bytes!("../icons/icon.png");
|
||||
|
||||
// We're in the setup callback which runs on the main thread
|
||||
if let Some(mtm) = MainThreadMarker::new() {
|
||||
unsafe {
|
||||
let data = NSData::with_bytes(icon_bytes);
|
||||
if let Some(image) = NSImage::initWithData(NSImage::alloc(), &data) {
|
||||
let app = NSApplication::sharedApplication(mtm);
|
||||
app.setApplicationIconImage(Some(&image));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct SidecarState {
|
||||
child: Option<std::process::Child>,
|
||||
}
|
||||
|
|
@ -49,6 +69,10 @@ pub fn run() {
|
|||
.manage(claude::ClaudeProcessState::default())
|
||||
.manage(zotero::ZoteroOAuthState::default())
|
||||
.setup(|app| {
|
||||
// Set macOS Dock icon (dev mode doesn't use bundle, so set it at runtime)
|
||||
#[cfg(target_os = "macos")]
|
||||
set_macos_app_icon();
|
||||
|
||||
// In dev mode, the sidecar is started separately (via pnpm dev:desktop)
|
||||
// In production, start the sidecar from the bundled resources
|
||||
let sidecar_path = if let Ok(path) = std::env::var("SIDECAR_PATH") {
|
||||
|
|
|
|||
|
|
@ -25,5 +25,14 @@
|
|||
"csp": "default-src 'self'; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; connect-src 'self' http://localhost:3001 https://api.zotero.org https://fonts.googleapis.com https://fonts.gstatic.com; img-src 'self' asset: http://asset.localhost data: blob:; worker-src 'self' blob:"
|
||||
}
|
||||
},
|
||||
"bundle": {
|
||||
"icon": [
|
||||
"icons/32x32.png",
|
||||
"icons/128x128.png",
|
||||
"icons/128x128@2x.png",
|
||||
"icons/icon.icns",
|
||||
"icons/icon.png"
|
||||
]
|
||||
},
|
||||
"plugins": {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import {
|
|||
FolderPlusIcon,
|
||||
ClockIcon,
|
||||
XIcon,
|
||||
FileTextIcon,
|
||||
} from "lucide-react";
|
||||
import { useProjectStore } from "@/stores/project-store";
|
||||
import { useDocumentStore } from "@/stores/document-store";
|
||||
|
|
@ -184,7 +183,7 @@ export function ProjectPicker() {
|
|||
<div className="flex h-full items-center justify-center bg-background">
|
||||
<div className="flex w-full max-w-md flex-col items-center gap-8 px-8">
|
||||
<div className="flex flex-col items-center gap-2">
|
||||
<FileTextIcon className="size-12 text-primary" />
|
||||
<img src="/icon-192.png" alt="ClaudePrism" className="size-16" />
|
||||
<h1 className="font-bold text-2xl">ClaudePrism</h1>
|
||||
<p className="text-center text-muted-foreground text-sm">
|
||||
AI-powered LaTeX writing workspace
|
||||
|
|
|
|||
1
apps/desktop/tsconfig.tsbuildinfo
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"root":["./src/app.tsx","./src/main.tsx","./src/vite-env.d.ts","./src/components/project-picker.tsx","./src/components/assistant-ui/tooltip-icon-button.tsx","./src/components/claude-chat/chat-composer.tsx","./src/components/claude-chat/chat-messages.tsx","./src/components/claude-chat/claude-chat-drawer.tsx","./src/components/claude-chat/markdown-renderer.tsx","./src/components/claude-chat/proposed-changes-panel.tsx","./src/components/claude-chat/tool-widgets.tsx","./src/components/ui/button.tsx","./src/components/ui/context-menu.tsx","./src/components/ui/dialog.tsx","./src/components/ui/dropdown-menu.tsx","./src/components/ui/input.tsx","./src/components/ui/label.tsx","./src/components/ui/select.tsx","./src/components/ui/separator.tsx","./src/components/ui/sheet.tsx","./src/components/ui/skeleton.tsx","./src/components/ui/sonner.tsx","./src/components/ui/textarea.tsx","./src/components/ui/toggle.tsx","./src/components/ui/tooltip.tsx","./src/components/workspace/history-panel.tsx","./src/components/workspace/sidebar.tsx","./src/components/workspace/workspace-layout.tsx","./src/components/workspace/zotero-panel.tsx","./src/components/workspace/editor/editor-toolbar.tsx","./src/components/workspace/editor/image-preview.tsx","./src/components/workspace/editor/latex-editor.tsx","./src/components/workspace/editor/problems-panel.tsx","./src/components/workspace/editor/search-panel.tsx","./src/components/workspace/editor/selection-toolbar.tsx","./src/components/workspace/preview/pdf-preview.tsx","./src/components/workspace/preview/pdf-viewer.tsx","./src/hooks/use-claude-events.ts","./src/hooks/use-keyboard-shortcuts.ts","./src/hooks/use-mobile.ts","./src/lib/latex-compiler.ts","./src/lib/utils.ts","./src/lib/zotero-api.ts","./src/lib/tauri/fs.ts","./src/stores/claude-chat-store.ts","./src/stores/document-store.ts","./src/stores/history-store.ts","./src/stores/project-store.ts","./src/stores/proposed-changes-store.ts","./src/stores/zotero-store.ts"],"version":"5.9.3"}
|
||||
|
|
@ -14,6 +14,7 @@
|
|||
"scripts": {
|
||||
"dev:web": "pnpm turbo dev --filter=@claude-prism/web --filter=@claude-prism/latex-api",
|
||||
"dev:desktop": "pnpm --filter=@claude-prism/desktop-sidecar dev & pnpm --filter=@claude-prism/desktop tauri dev",
|
||||
"build:desktop": "pnpm --filter=@claude-prism/desktop tauri build",
|
||||
"lint": "pnpm exec biome check",
|
||||
"lint:fix": "pnpm exec biome check --fix"
|
||||
},
|
||||
|
|
|
|||