diff --git a/.gitignore b/.gitignore index 6f3a1e8c..bf5cd822 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ node_modules/ dist/ +target/ .env .env.* !.env.example diff --git a/.moon/toolchains.yml b/.moon/toolchains.yml index bcafd62b..7dd8dfaa 100644 --- a/.moon/toolchains.yml +++ b/.moon/toolchains.yml @@ -8,7 +8,5 @@ bun: # Auto-install deps when lockfile/manifest changes installDependencies: true -# Rust toolchain — no crates yet, but enabling it now means -# moon will automatically understand Cargo.toml files and -# track Cargo.lock for hashing when they appear. +# Version is inherited from .prototools (versionFromPrototools) rust: {} diff --git a/.moon/workspace.yml b/.moon/workspace.yml index 2f52bb98..b057b6ae 100644 --- a/.moon/workspace.yml +++ b/.moon/workspace.yml @@ -1,6 +1,6 @@ $schema: 'https://moonrepo.dev/schemas/workspace.json' # Discover all projects under apps/ automatically. -# When Rust crates land, add a 'crates/*' glob here. +# When shared crates land under crates/, add a 'crates/*' glob here. projects: - 'apps/*' diff --git a/.prototools b/.prototools index da366ed1..9c03f109 100644 --- a/.prototools +++ b/.prototools @@ -2,3 +2,4 @@ # Every developer and CI machine gets the exact same versions automatically. moon = "2.3.3" bun = "1.3.11" +rust = "1.97.0" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 00000000..ae1e4689 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,13 @@ +[workspace] +resolver = "3" +members = [ + 'apps/desktop', +] + +[workspace.package] +version = "0.1.0" +edition = "2024" +license = "MIT" + +[workspace.dependencies] +gpui = "0.2.2" diff --git a/README.md b/README.md index 617893c8..51823a18 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ - MCP support - A scripting tab directly in the editor -You can still find the previous version at [opencut-app/opencut-classic](https://github.com/opencut-app/opencut-classic), which is the one to reach for today. [opencut.app](https://opencut.app) still runs the classic version; the rewrite will live at [new.opencut.app](https://new.opencut.app) until it's ready to take over. +You can still find the previous version at [opencut-app/opencut-classic](https://github.com/opencut-app/opencut-classic), which is the one to reach for today. [opencut.app](https://opencut.app) still runs the classic version. The rewrite will live at [new.opencut.app](https://new.opencut.app) until it's ready to take over. ## Development @@ -37,13 +37,13 @@ bash <(curl -fsSL https://moonrepo.dev/install/proto.sh) From the repo root: ```sh -proto use # installs bun + moon at the versions pinned in .prototools -bun install +proto use # installs the tools pinned in .prototools ``` ```sh -moon run web:dev # localhost:5173 -moon run api:dev # localhost:8787 +moon run web:dev # localhost:5173 +moon run api:dev # localhost:8787 +moon run desktop:dev # see apps/desktop/README.md ``` ## Contributing diff --git a/apps/api/moon.yml b/apps/api/moon.yml index 9ac80080..b8df9d67 100644 --- a/apps/api/moon.yml +++ b/apps/api/moon.yml @@ -7,7 +7,7 @@ tasks: dev: command: 'bun run dev' options: - runInCI: false # dev server — skipped in CI, never cached + runInCI: false # dev server: skipped in CI, never cached build: command: 'bun run build' diff --git a/apps/api/src/index.ts b/apps/api/src/index.ts index 2dee514f..86aba057 100644 --- a/apps/api/src/index.ts +++ b/apps/api/src/index.ts @@ -11,5 +11,5 @@ export default new Elysia({ adapter: CloudflareAdapter }) body: t.Object({ message: t.String() }), } ) - // .compile() is required — it triggers AoT compilation at startup + // .compile() is required, it triggers AoT compilation at startup .compile(); diff --git a/apps/desktop/Cargo.toml b/apps/desktop/Cargo.toml new file mode 100644 index 00000000..3f9495f2 --- /dev/null +++ b/apps/desktop/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "opencut-desktop" +description = "OpenCut desktop app, built with GPUI" +version.workspace = true +edition.workspace = true +license.workspace = true + +[[bin]] +name = "opencut-desktop" +path = "src/main.rs" + +[dependencies] +gpui = { workspace = true } diff --git a/apps/desktop/README.md b/apps/desktop/README.md new file mode 100644 index 00000000..96677d0f --- /dev/null +++ b/apps/desktop/README.md @@ -0,0 +1,24 @@ +# OpenCut Desktop + +Built with [GPUI](https://www.gpui.rs). + +> [!WARNING] +> Very early. Right now this is just a window that opens. + +## Running + +Rust is pinned in `.prototools` at the repo root (`proto use` installs it). + +```sh +moon run desktop:dev # cargo run +moon run desktop:check # cargo check +moon run desktop:build # cargo build --release +``` + +The first build compiles GPUI from source and takes a while. The root `Cargo.lock` is committed. + +## Platform requirements + +- **macOS**: Xcode command line tools (Metal renderer). +- **Windows**: no extra dependencies (Win32 + DirectWrite). +- **Linux**: renders via Vulkan (Blade), windows via Wayland or X11 (both enabled by default). System packages (Debian/Ubuntu names): `libvulkan1` + working Vulkan drivers, `libwayland-dev`, `libx11-xcb-dev`, `libxkbcommon-x11-dev`, `libfontconfig-dev`, plus a C toolchain and `cmake`. diff --git a/apps/desktop/moon.yml b/apps/desktop/moon.yml new file mode 100644 index 00000000..4f022348 --- /dev/null +++ b/apps/desktop/moon.yml @@ -0,0 +1,28 @@ +$schema: 'https://moonrepo.dev/schemas/project.json' + +language: 'rust' +layer: 'application' + +tasks: + dev: + command: 'cargo run' + options: + runInCI: false + + check: + command: 'cargo check' + inputs: + - 'src/**/*' + - 'Cargo.toml' + - '/Cargo.toml' + - '/Cargo.lock' + + build: + command: 'cargo build --release' + inputs: + - 'src/**/*' + - 'Cargo.toml' + - '/Cargo.toml' + - '/Cargo.lock' + outputs: + - '/target/release/opencut-desktop' diff --git a/apps/desktop/src/main.rs b/apps/desktop/src/main.rs new file mode 100644 index 00000000..8a40cb06 --- /dev/null +++ b/apps/desktop/src/main.rs @@ -0,0 +1,51 @@ +use gpui::{ + div, prelude::*, px, rgb, size, App, Application, Bounds, Context, SharedString, + TitlebarOptions, Window, WindowBounds, WindowOptions, +}; + +struct Root { + status: SharedString, +} + +impl Render for Root { + fn render(&mut self, _window: &mut Window, _cx: &mut Context) -> impl IntoElement { + div() + .flex() + .flex_col() + .gap_2() + .size_full() + .justify_center() + .items_center() + .bg(rgb(0x111111)) + .text_color(rgb(0xffffff)) + .child(div().text_xl().child("OpenCut")) + .child( + div() + .text_sm() + .text_color(rgb(0x888888)) + .child(self.status.clone()), + ) + } +} + +fn main() { + Application::new().run(|cx: &mut App| { + let bounds = Bounds::centered(None, size(px(960.), px(600.)), cx); + cx.open_window( + WindowOptions { + titlebar: Some(TitlebarOptions { + title: Some(SharedString::from("OpenCut")), + ..Default::default() + }), + window_bounds: Some(WindowBounds::Windowed(bounds)), + ..Default::default() + }, + |_, cx| { + cx.new(|_| Root { + status: "desktop shell scaffold".into(), + }) + }, + ) + .expect("failed to open the main window"); + }); +} diff --git a/apps/web/moon.yml b/apps/web/moon.yml index cb7c1101..09c094a5 100644 --- a/apps/web/moon.yml +++ b/apps/web/moon.yml @@ -7,7 +7,7 @@ tasks: dev: command: 'bun run dev' options: - runInCI: false # dev server — skipped in CI, never cached + runInCI: false # dev server: skipped in CI, never cached build: command: 'bun run build' diff --git a/apps/web/src/routes/__root.tsx b/apps/web/src/routes/__root.tsx index bb59694d..908ec711 100644 --- a/apps/web/src/routes/__root.tsx +++ b/apps/web/src/routes/__root.tsx @@ -16,7 +16,7 @@ export const Route = createRootRoute({ content: 'width=device-width, initial-scale=1', }, { - title: 'OpenCut rewrite — beta.opencut.app', + title: 'OpenCut rewrite | beta.opencut.app', }, ], links: [