Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Single instance, fix titlebars, better Windows support #169

Merged
merged 18 commits into from
Nov 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions apps/desktop/src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ tauri-plugin-updater = "2.0.0"
tauri-plugin-notification = "2.0.0-rc"
tauri-plugin-oauth = { git = "https://github.com/FabianLars/tauri-plugin-oauth", branch = "v2" }
tauri-plugin-global-shortcut = "2.0.0"
tauri-plugin-single-instance = "2.0.1"
tauri-specta = { version = "=2.0.0-rc.20", features = ["derive", "typescript"] }

serde = { version = "1", features = ["derive"] }
Expand Down
Binary file added apps/desktop/src-tauri/assets/nsis-header.bmp
Binary file not shown.
Binary file added apps/desktop/src-tauri/assets/nsis-sidebar.bmp
Binary file not shown.
Binary file added apps/desktop/src-tauri/assets/wix-banner.bmp
Binary file not shown.
16 changes: 4 additions & 12 deletions apps/desktop/src-tauri/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -949,7 +949,7 @@ async fn copy_screenshot_to_clipboard(app: AppHandle, path: PathBuf) -> Result<(

#[tauri::command]
#[specta::specta]
async fn open_file_path(app: AppHandle, path: PathBuf) -> Result<(), String> {
async fn open_file_path(_app: AppHandle, path: PathBuf) -> Result<(), String> {
let path_str = path.to_str().ok_or("Invalid path")?;

#[cfg(target_os = "windows")]
Expand Down Expand Up @@ -1693,16 +1693,6 @@ async fn set_project_config(app: AppHandle, video_id: String, config: ProjectCon
editor_instance.project_config.0.send(config).ok();
}

#[tauri::command(async)]
#[specta::specta]
fn open_in_finder(path: PathBuf) {
Command::new("open")
.arg("-R")
.arg(path)
.spawn()
.expect("Failed to open in Finder");
}

#[tauri::command]
#[specta::specta]
async fn list_audio_devices() -> Result<Vec<String>, ()> {
Expand Down Expand Up @@ -2441,7 +2431,6 @@ pub async fn run() {
start_playback,
stop_playback,
set_playhead_position,
open_in_finder,
set_project_config,
open_editor,
open_main_window,
Expand Down Expand Up @@ -2519,6 +2508,9 @@ pub async fn run() {
}

builder
.plugin(tauri_plugin_single_instance::init(|app, _args, _cwd| {
let _ = CapWindow::Main.show(&app);
}))
.plugin(tauri_plugin_shell::init())
.plugin(tauri_plugin_dialog::init())
.plugin(tauri_plugin_store::Builder::new().build())
Expand Down
3 changes: 2 additions & 1 deletion apps/desktop/src-tauri/src/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ impl CapWindowId {
pub fn traffic_lights_position(&self) -> Option<Option<LogicalPosition<f64>>> {
match self {
Self::Camera | Self::WindowCaptureOccluder | Self::PrevRecordings => None,
Self::Editor { .. } => Some(Some(LogicalPosition::new(20.0, 48.0))),
Self::Editor { .. } => Some(Some(LogicalPosition::new(20.0, 40.5))),
Self::InProgressRecording => Some(Some(LogicalPosition::new(-100.0, -100.0))),
_ => Some(None),
}
Expand Down Expand Up @@ -263,6 +263,7 @@ impl CapWindow {
)
.visible(false)
.theme(Some(tauri::Theme::Dark))
.skip_taskbar(true)
.build()?
}
Self::PrevRecordings => {
Expand Down
10 changes: 10 additions & 0 deletions apps/desktop/src-tauri/tauri.conf.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,16 @@
"y": 140
}
}
},
"windows": {
"nsis": {
"headerImage": "assets/nsis-header.bmp",
"sidebarImage": "assets/nsis-sidebar.bmp",
"installerIcon": "icons/icon.ico"
},
"wix": {
"bannerPath": "assets/wix-banner.bmp"
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { cx } from "cva";
export default function (props: ComponentProps<"div">) {
const [local, otherProps] = splitProps(props, ["class"]);
const window = getCurrentWindow();

return (
<div
class={`h-full align-baseline select-none *:outline-none *:transition-all *:duration-200 ${local.class}`}
Expand All @@ -21,7 +21,7 @@ export default function (props: ComponentProps<"div">) {
? "text-black/90 dark:text-white"
: "text-gray-50 dark:text-white",
titlebarState.minimizable
? "hover:bg-[#0000000D] active:bg-[#00000008] dark:hover:bg-[#FFFFFF1A] dark:active:bg-[#FFFFFF0D]"
? "hover:bg-[#0000000D] active:bg-[#00000008]"
: "[&>*]:opacity-30"
)}
>
Expand All @@ -42,7 +42,7 @@ export default function (props: ComponentProps<"div">) {
? "text-black/90 dark:text-white"
: "text-gray-50 dark:text-white",
titlebarState.maximizable
? "hover:bg-[#0000000D] active:bg-[#00000008] dark:hover:bg-[#FFFFFF1A] dark:active:bg-[#FFFFFF0D]"
? "hover:bg-[#0000000D] active:bg-[#00000008]"
: "[&>*]:opacity-30"
)}
>
Expand Down
165 changes: 85 additions & 80 deletions apps/desktop/src/routes/(window-chrome)/settings/general.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,51 +6,54 @@ import {
isPermissionGranted,
requestPermission,
} from "@tauri-apps/plugin-notification";
import { OsType, Platform, type } from "@tauri-apps/plugin-os";

const settingsList = [
{
key: "uploadIndividualFiles",
label: "Upload individual recording files when creating shareable link",
description:
'Warning: this will cause shareable link uploads to become significantly slower, since all individual recording files will be uploaded. Shows "Download Assets" button in Share page.',
},
{
key: "openEditorAfterRecording",
label: "Open editor automatically after recording stops",
description:
"The editor will be shown immediately after you finish recording.",
},
{
key: "hideDockIcon",
label: "Hide dock icon",
description:
"The dock icon will be hidden when there are no windows available to close.",
},
{
key: "autoCreateShareableLink",
label: "Cap Pro: Automatically create shareable link after recording",
description:
"When enabled, a shareable link will be created automatically after stopping the recording. You'll be redirected to the URL while the upload continues in the background.",
},
{
key: "disableAutoOpenLinks",
label: "Cap Pro: Disable automatic link opening",
description:
"When enabled, Cap will not automatically open links in your browser (e.g. after creating a shareable link).",
},
{
key: "enableNotifications",
label: "Enable System Notifications",
description:
"Show system notifications for events like copying to clipboard, saving files, and more. You may need to manually allow Cap access via your system's notification settings.",
requiresPermission: true,
},
] satisfies Array<{
const settingsList: Array<{
key: keyof GeneralSettingsStore;
label: string;
description: string;
platforms?: OsType[],
requiresPermission?: boolean;
}>;
}> = [
{
key: "uploadIndividualFiles",
label: "Upload individual recording files when creating shareable link",
description:
'Warning: this will cause shareable link uploads to become significantly slower, since all individual recording files will be uploaded. Shows "Download Assets" button in Share page.',
},
{
key: "openEditorAfterRecording",
label: "Open editor automatically after recording stops",
description:
"The editor will be shown immediately after you finish recording.",
},
{
key: "hideDockIcon",
label: "Hide dock icon",
platforms: ["macos"],
description:
"The dock icon will be hidden when there are no windows available to close.",
},
{
key: "autoCreateShareableLink",
label: "Cap Pro: Automatically create shareable link after recording",
description:
"When enabled, a shareable link will be created automatically after stopping the recording. You'll be redirected to the URL while the upload continues in the background.",
},
{
key: "disableAutoOpenLinks",
label: "Cap Pro: Disable automatic link opening",
description:
"When enabled, Cap will not automatically open links in your browser (e.g. after creating a shareable link).",
},
{
key: "enableNotifications",
label: "Enable System Notifications",
description:
"Show system notifications for events like copying to clipboard, saving files, and more. You may need to manually allow Cap access via your system's notification settings.",
requiresPermission: true,
},
];

export default function GeneralSettings() {
const [store] = createResource(() => generalSettingsStore.get());
Expand Down Expand Up @@ -101,61 +104,63 @@ function Inner(props: { initialStore: GeneralSettingsStore | null }) {
generalSettingsStore.set({ [key]: value });
};

const ostype: OsType = type();

return (
<div class="flex flex-col w-full h-full">
<div class="flex-1 overflow-y-auto">
<div class="p-4 space-y-2 divide-y divide-gray-200">
<For each={settingsList}>
{(setting) => (
<div class="space-y-2 py-3">
<div class="flex items-center justify-between">
<p>{setting.label}</p>
<button
type="button"
role="switch"
aria-checked={
settings[setting.key as keyof GeneralSettingsStore]
}
data-state={
settings[setting.key as keyof GeneralSettingsStore]
? "checked"
: "unchecked"
}
value={
settings[setting.key as keyof GeneralSettingsStore]
? "on"
: "off"
}
class={`peer inline-flex h-4 w-8 shrink-0 cursor-pointer items-center rounded-full transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 ${
settings[setting.key as keyof GeneralSettingsStore]
? "bg-blue-400 border-blue-400"
: "bg-gray-300 border-gray-300"
}`}
onClick={() =>
handleChange(
setting.key,
!settings[setting.key as keyof GeneralSettingsStore]
)
}
>
<span
<Show when={!setting.platforms || setting.platforms.includes(ostype)}>
<div class="space-y-2 py-3">
<div class="flex items-center justify-between">
<p>{setting.label}</p>
<button
type="button"
role="switch"
aria-checked={
settings[setting.key as keyof GeneralSettingsStore]
}
data-state={
settings[setting.key as keyof GeneralSettingsStore]
? "checked"
: "unchecked"
}
class={`pointer-events-none block h-4 w-4 rounded-full bg-gray-50 shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-4 data-[state=unchecked]:translate-x-0 border-2 ${
value={
settings[setting.key as keyof GeneralSettingsStore]
? "on"
: "off"
}
class={`peer inline-flex h-4 w-8 shrink-0 cursor-pointer items-center rounded-full transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 ${settings[setting.key as keyof GeneralSettingsStore]
? "bg-blue-400 border-blue-400"
: "bg-gray-300 border-gray-300"
}`}
onClick={() =>
handleChange(
setting.key,
!settings[setting.key as keyof GeneralSettingsStore]
)
}
>
<span
data-state={
settings[setting.key as keyof GeneralSettingsStore]
? "checked"
: "unchecked"
}
class={`pointer-events-none block h-4 w-4 rounded-full bg-gray-50 shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-4 data-[state=unchecked]:translate-x-0 border-2 ${settings[setting.key as keyof GeneralSettingsStore]
? "border-blue-400"
: "border-gray-300"
}`}
/>
</button>
}`}
/>
</button>
</div>
{setting.description && (
<p class="text-xs text-gray-400">{setting.description}</p>
)}
</div>
{setting.description && (
<p class="text-xs text-gray-400">{setting.description}</p>
)}
</div>
</Show>
)}
</For>
</div>
Expand Down
Loading
Loading