mirror of
https://github.com/infinilabs/coco-app.git
synced 2025-12-16 11:37:47 +01:00
fix: fix the problem of local path not opening (#650)
* fix: fix the problem of local path not opening * docs: update changelog * chore: remove pizza-engine
This commit is contained in:
@@ -35,6 +35,7 @@ Information about release notes of Coco Server is provided here.
|
|||||||
- fix: arrow keys still navigated search when menu opened with Cmd+K #642
|
- fix: arrow keys still navigated search when menu opened with Cmd+K #642
|
||||||
- fix: input lost when reopening dialog after search #644
|
- fix: input lost when reopening dialog after search #644
|
||||||
- fix: web page unmount event #645
|
- fix: web page unmount event #645
|
||||||
|
- fix: fix the problem of local path not opening #650
|
||||||
|
|
||||||
### ✈️ Improvements
|
### ✈️ Improvements
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
"@tauri-apps/plugin-global-shortcut": "~2.0.0",
|
"@tauri-apps/plugin-global-shortcut": "~2.0.0",
|
||||||
"@tauri-apps/plugin-http": "~2.0.2",
|
"@tauri-apps/plugin-http": "~2.0.2",
|
||||||
"@tauri-apps/plugin-log": "~2.4.0",
|
"@tauri-apps/plugin-log": "~2.4.0",
|
||||||
|
"@tauri-apps/plugin-opener": "^2.2.7",
|
||||||
"@tauri-apps/plugin-os": "^2.2.1",
|
"@tauri-apps/plugin-os": "^2.2.1",
|
||||||
"@tauri-apps/plugin-process": "^2.2.1",
|
"@tauri-apps/plugin-process": "^2.2.1",
|
||||||
"@tauri-apps/plugin-shell": "^2.2.1",
|
"@tauri-apps/plugin-shell": "^2.2.1",
|
||||||
|
|||||||
10
pnpm-lock.yaml
generated
10
pnpm-lock.yaml
generated
@@ -35,6 +35,9 @@ importers:
|
|||||||
'@tauri-apps/plugin-log':
|
'@tauri-apps/plugin-log':
|
||||||
specifier: ~2.4.0
|
specifier: ~2.4.0
|
||||||
version: 2.4.0
|
version: 2.4.0
|
||||||
|
'@tauri-apps/plugin-opener':
|
||||||
|
specifier: ^2.2.7
|
||||||
|
version: 2.2.7
|
||||||
'@tauri-apps/plugin-os':
|
'@tauri-apps/plugin-os':
|
||||||
specifier: ^2.2.1
|
specifier: ^2.2.1
|
||||||
version: 2.2.1
|
version: 2.2.1
|
||||||
@@ -1265,6 +1268,9 @@ packages:
|
|||||||
'@tauri-apps/plugin-log@2.4.0':
|
'@tauri-apps/plugin-log@2.4.0':
|
||||||
resolution: {integrity: sha512-j7yrDtLNmayCBOO2esl3aZv9jSXy2an8MDLry3Ys9ZXerwUg35n1Y2uD8HoCR+8Ng/EUgx215+qOUfJasjYrHw==}
|
resolution: {integrity: sha512-j7yrDtLNmayCBOO2esl3aZv9jSXy2an8MDLry3Ys9ZXerwUg35n1Y2uD8HoCR+8Ng/EUgx215+qOUfJasjYrHw==}
|
||||||
|
|
||||||
|
'@tauri-apps/plugin-opener@2.2.7':
|
||||||
|
resolution: {integrity: sha512-uduEyvOdjpPOEeDRrhwlCspG/f9EQalHumWBtLBnp3fRp++fKGLqDOyUhSIn7PzX45b/rKep//ZQSAQoIxobLA==}
|
||||||
|
|
||||||
'@tauri-apps/plugin-os@2.2.1':
|
'@tauri-apps/plugin-os@2.2.1':
|
||||||
resolution: {integrity: sha512-cNYpNri2CCc6BaNeB6G/mOtLvg8dFyFQyCUdf2y0K8PIAKGEWdEcu8DECkydU2B+oj4OJihDPD2de5K6cbVl9A==}
|
resolution: {integrity: sha512-cNYpNri2CCc6BaNeB6G/mOtLvg8dFyFQyCUdf2y0K8PIAKGEWdEcu8DECkydU2B+oj4OJihDPD2de5K6cbVl9A==}
|
||||||
|
|
||||||
@@ -4666,6 +4672,10 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@tauri-apps/api': 2.5.0
|
'@tauri-apps/api': 2.5.0
|
||||||
|
|
||||||
|
'@tauri-apps/plugin-opener@2.2.7':
|
||||||
|
dependencies:
|
||||||
|
'@tauri-apps/api': 2.5.0
|
||||||
|
|
||||||
'@tauri-apps/plugin-os@2.2.1':
|
'@tauri-apps/plugin-os@2.2.1':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@tauri-apps/api': 2.5.0
|
'@tauri-apps/api': 2.5.0
|
||||||
|
|||||||
23
src-tauri/Cargo.lock
generated
23
src-tauri/Cargo.lock
generated
@@ -866,6 +866,7 @@ dependencies = [
|
|||||||
"tauri-plugin-http",
|
"tauri-plugin-http",
|
||||||
"tauri-plugin-log",
|
"tauri-plugin-log",
|
||||||
"tauri-plugin-macos-permissions",
|
"tauri-plugin-macos-permissions",
|
||||||
|
"tauri-plugin-opener",
|
||||||
"tauri-plugin-os",
|
"tauri-plugin-os",
|
||||||
"tauri-plugin-process",
|
"tauri-plugin-process",
|
||||||
"tauri-plugin-screenshots",
|
"tauri-plugin-screenshots",
|
||||||
@@ -6279,6 +6280,28 @@ dependencies = [
|
|||||||
"thiserror 2.0.12",
|
"thiserror 2.0.12",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tauri-plugin-opener"
|
||||||
|
version = "2.2.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "66644b71a31ec1a8a52c4a16575edd28cf763c87cf4a7da24c884122b5c77097"
|
||||||
|
dependencies = [
|
||||||
|
"dunce",
|
||||||
|
"glob",
|
||||||
|
"objc2-app-kit 0.3.1",
|
||||||
|
"objc2-foundation 0.3.1",
|
||||||
|
"open",
|
||||||
|
"schemars",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"tauri",
|
||||||
|
"tauri-plugin",
|
||||||
|
"thiserror 2.0.12",
|
||||||
|
"url",
|
||||||
|
"windows 0.61.1",
|
||||||
|
"zbus",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tauri-plugin-os"
|
name = "tauri-plugin-os"
|
||||||
version = "2.2.1"
|
version = "2.2.1"
|
||||||
|
|||||||
@@ -98,6 +98,7 @@ derive_more = { version = "2.0.1", features = ["display"] }
|
|||||||
anyhow = "1.0.98"
|
anyhow = "1.0.98"
|
||||||
function_name = "0.3.0"
|
function_name = "0.3.0"
|
||||||
regex = "1.11.1"
|
regex = "1.11.1"
|
||||||
|
tauri-plugin-opener = "2"
|
||||||
|
|
||||||
[target."cfg(target_os = \"macos\")".dependencies]
|
[target."cfg(target_os = \"macos\")".dependencies]
|
||||||
tauri-nspanel = { git = "https://github.com/ahkohd/tauri-nspanel", branch = "v2" }
|
tauri-nspanel = { git = "https://github.com/ahkohd/tauri-nspanel", branch = "v2" }
|
||||||
|
|||||||
@@ -71,6 +71,7 @@
|
|||||||
"process:default",
|
"process:default",
|
||||||
"updater:default",
|
"updater:default",
|
||||||
"windows-version:default",
|
"windows-version:default",
|
||||||
"log:default"
|
"log:default",
|
||||||
|
"opener:default"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -88,7 +88,8 @@ pub fn run() {
|
|||||||
.plugin(tauri_plugin_screenshots::init())
|
.plugin(tauri_plugin_screenshots::init())
|
||||||
.plugin(tauri_plugin_process::init())
|
.plugin(tauri_plugin_process::init())
|
||||||
.plugin(tauri_plugin_updater::Builder::new().build())
|
.plugin(tauri_plugin_updater::Builder::new().build())
|
||||||
.plugin(tauri_plugin_windows_version::init());
|
.plugin(tauri_plugin_windows_version::init())
|
||||||
|
.plugin(tauri_plugin_opener::init());
|
||||||
|
|
||||||
// Conditional compilation for macOS
|
// Conditional compilation for macOS
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ const Applications = () => {
|
|||||||
<SquareArrowOutUpRight
|
<SquareArrowOutUpRight
|
||||||
className="size-4 cursor-pointer"
|
className="size-4 cursor-pointer"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
platformAdapter.openExternal(item);
|
platformAdapter.revealItemInDir(item);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|||||||
@@ -102,13 +102,14 @@ export interface SystemOperations {
|
|||||||
checkUpdate: () => Promise<any>;
|
checkUpdate: () => Promise<any>;
|
||||||
relaunchApp: () => Promise<void>;
|
relaunchApp: () => Promise<void>;
|
||||||
isTauri: () => boolean;
|
isTauri: () => boolean;
|
||||||
openExternal: (url: string) => Promise<void>;
|
openUrl: (url: string) => Promise<void>;
|
||||||
commands: <T>(commandName: string, ...args: any[]) => Promise<T>;
|
commands: <T>(commandName: string, ...args: any[]) => Promise<T>;
|
||||||
isWindows10: () => Promise<boolean>;
|
isWindows10: () => Promise<boolean>;
|
||||||
|
revealItemInDir: (path: string) => Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Base platform adapter interface
|
// Base platform adapter interface
|
||||||
export interface BasePlatformAdapter
|
export interface BasePlatformAdapter
|
||||||
extends WindowOperations,
|
extends WindowOperations,
|
||||||
ThemeAndEvents,
|
ThemeAndEvents,
|
||||||
SystemOperations { }
|
SystemOperations {}
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ export const OpenURLWithBrowser = async (url?: string) => {
|
|||||||
if (!url) return;
|
if (!url) return;
|
||||||
if (IsTauri()) {
|
if (IsTauri()) {
|
||||||
try {
|
try {
|
||||||
await platformAdapter.openExternal(url);
|
await platformAdapter.openUrl(url);
|
||||||
await platformAdapter.commands("hide_coco");
|
await platformAdapter.commands("hide_coco");
|
||||||
console.log("URL opened in default browser");
|
console.log("URL opened in default browser");
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
// This file was generated by [tauri-specta](https://github.com/oscartbeaumont/tauri-specta). Do not edit this file manually.
|
// This file was generated by [tauri-specta](https://github.com/oscartbeaumont/tauri-specta). Do not edit this file manually.
|
||||||
|
|
||||||
/** user-defined commands **/
|
/** user-defined commands **/
|
||||||
@@ -51,8 +50,18 @@ export const commands = {
|
|||||||
async getCurrentRecording(): Promise<JsonValue<RecordingInfo | null>> {
|
async getCurrentRecording(): Promise<JsonValue<RecordingInfo | null>> {
|
||||||
return await TAURI_INVOKE("get_current_recording");
|
return await TAURI_INVOKE("get_current_recording");
|
||||||
},
|
},
|
||||||
async exportVideo(videoId: string, project: ProjectConfiguration, progress: TAURI_CHANNEL<RenderProgress>, force: boolean): Promise<string> {
|
async exportVideo(
|
||||||
return await TAURI_INVOKE("export_video", { videoId, project, progress, force });
|
videoId: string,
|
||||||
|
project: ProjectConfiguration,
|
||||||
|
progress: TAURI_CHANNEL<RenderProgress>,
|
||||||
|
force: boolean
|
||||||
|
): Promise<string> {
|
||||||
|
return await TAURI_INVOKE("export_video", {
|
||||||
|
videoId,
|
||||||
|
project,
|
||||||
|
progress,
|
||||||
|
force,
|
||||||
|
});
|
||||||
},
|
},
|
||||||
async copyFileToPath(src: string, dst: string): Promise<null> {
|
async copyFileToPath(src: string, dst: string): Promise<null> {
|
||||||
return await TAURI_INVOKE("copy_file_to_path", { src, dst });
|
return await TAURI_INVOKE("copy_file_to_path", { src, dst });
|
||||||
@@ -66,10 +75,15 @@ export const commands = {
|
|||||||
async openFilePath(path: string): Promise<null> {
|
async openFilePath(path: string): Promise<null> {
|
||||||
return await TAURI_INVOKE("open_file_path", { path });
|
return await TAURI_INVOKE("open_file_path", { path });
|
||||||
},
|
},
|
||||||
async getVideoMetadata(videoId: string, videoType: VideoType | null): Promise<VideoRecordingMetadata> {
|
async getVideoMetadata(
|
||||||
|
videoId: string,
|
||||||
|
videoType: VideoType | null
|
||||||
|
): Promise<VideoRecordingMetadata> {
|
||||||
return await TAURI_INVOKE("get_video_metadata", { videoId, videoType });
|
return await TAURI_INVOKE("get_video_metadata", { videoId, videoType });
|
||||||
},
|
},
|
||||||
async createEditorInstance(videoId: string): Promise<SerializedEditorInstance> {
|
async createEditorInstance(
|
||||||
|
videoId: string
|
||||||
|
): Promise<SerializedEditorInstance> {
|
||||||
return await TAURI_INVOKE("create_editor_instance", { videoId });
|
return await TAURI_INVOKE("create_editor_instance", { videoId });
|
||||||
},
|
},
|
||||||
async startPlayback(videoId: string): Promise<void> {
|
async startPlayback(videoId: string): Promise<void> {
|
||||||
@@ -78,10 +92,16 @@ export const commands = {
|
|||||||
async stopPlayback(videoId: string): Promise<void> {
|
async stopPlayback(videoId: string): Promise<void> {
|
||||||
await TAURI_INVOKE("stop_playback", { videoId });
|
await TAURI_INVOKE("stop_playback", { videoId });
|
||||||
},
|
},
|
||||||
async setPlayheadPosition(videoId: string, frameNumber: number): Promise<void> {
|
async setPlayheadPosition(
|
||||||
|
videoId: string,
|
||||||
|
frameNumber: number
|
||||||
|
): Promise<void> {
|
||||||
await TAURI_INVOKE("set_playhead_position", { videoId, frameNumber });
|
await TAURI_INVOKE("set_playhead_position", { videoId, frameNumber });
|
||||||
},
|
},
|
||||||
async setProjectConfig(videoId: string, config: ProjectConfiguration): Promise<void> {
|
async setProjectConfig(
|
||||||
|
videoId: string,
|
||||||
|
config: ProjectConfiguration
|
||||||
|
): Promise<void> {
|
||||||
await TAURI_INVOKE("set_project_config", { videoId, config });
|
await TAURI_INVOKE("set_project_config", { videoId, config });
|
||||||
},
|
},
|
||||||
async openEditor(id: string): Promise<void> {
|
async openEditor(id: string): Promise<void> {
|
||||||
@@ -99,7 +119,10 @@ export const commands = {
|
|||||||
async requestPermission(permission: OSPermission): Promise<void> {
|
async requestPermission(permission: OSPermission): Promise<void> {
|
||||||
await TAURI_INVOKE("request_permission", { permission });
|
await TAURI_INVOKE("request_permission", { permission });
|
||||||
},
|
},
|
||||||
async uploadExportedVideo(videoId: string, mode: UploadMode): Promise<UploadResult> {
|
async uploadExportedVideo(
|
||||||
|
videoId: string,
|
||||||
|
mode: UploadMode
|
||||||
|
): Promise<UploadResult> {
|
||||||
return await TAURI_INVOKE("upload_exported_video", { videoId, mode });
|
return await TAURI_INVOKE("upload_exported_video", { videoId, mode });
|
||||||
},
|
},
|
||||||
async uploadScreenshot(screenshotPath: string): Promise<UploadResult> {
|
async uploadScreenshot(screenshotPath: string): Promise<UploadResult> {
|
||||||
@@ -108,13 +131,16 @@ export const commands = {
|
|||||||
async getRecordingMeta(id: string, fileType: string): Promise<RecordingMeta> {
|
async getRecordingMeta(id: string, fileType: string): Promise<RecordingMeta> {
|
||||||
return await TAURI_INVOKE("get_recording_meta", { id, fileType });
|
return await TAURI_INVOKE("get_recording_meta", { id, fileType });
|
||||||
},
|
},
|
||||||
async saveFileDialog(fileName: string, fileType: string): Promise<string | null> {
|
async saveFileDialog(
|
||||||
|
fileName: string,
|
||||||
|
fileType: string
|
||||||
|
): Promise<string | null> {
|
||||||
return await TAURI_INVOKE("save_file_dialog", { fileName, fileType });
|
return await TAURI_INVOKE("save_file_dialog", { fileName, fileType });
|
||||||
},
|
},
|
||||||
async listRecordings(): Promise<([string, string, RecordingMeta])[]> {
|
async listRecordings(): Promise<[string, string, RecordingMeta][]> {
|
||||||
return await TAURI_INVOKE("list_recordings");
|
return await TAURI_INVOKE("list_recordings");
|
||||||
},
|
},
|
||||||
async listScreenshots(): Promise<([string, string, RecordingMeta])[]> {
|
async listScreenshots(): Promise<[string, string, RecordingMeta][]> {
|
||||||
return await TAURI_INVOKE("list_screenshots");
|
return await TAURI_INVOKE("list_screenshots");
|
||||||
},
|
},
|
||||||
async checkUpgradedAndUpdate(): Promise<boolean> {
|
async checkUpgradedAndUpdate(): Promise<boolean> {
|
||||||
@@ -144,7 +170,9 @@ export const commands = {
|
|||||||
async sendFeedbackRequest(feedback: string): Promise<null> {
|
async sendFeedbackRequest(feedback: string): Promise<null> {
|
||||||
return await TAURI_INVOKE("send_feedback_request", { feedback });
|
return await TAURI_INVOKE("send_feedback_request", { feedback });
|
||||||
},
|
},
|
||||||
async positionTrafficLights(controlsInset: [number, number] | null): Promise<void> {
|
async positionTrafficLights(
|
||||||
|
controlsInset: [number, number] | null
|
||||||
|
): Promise<void> {
|
||||||
await TAURI_INVOKE("position_traffic_lights", { controlsInset });
|
await TAURI_INVOKE("position_traffic_lights", { controlsInset });
|
||||||
},
|
},
|
||||||
async setTheme(theme: AppTheme): Promise<void> {
|
async setTheme(theme: AppTheme): Promise<void> {
|
||||||
@@ -158,31 +186,30 @@ export const commands = {
|
|||||||
},
|
},
|
||||||
async writeClipboardString(text: string): Promise<null> {
|
async writeClipboardString(text: string): Promise<null> {
|
||||||
return await TAURI_INVOKE("write_clipboard_string", { text });
|
return await TAURI_INVOKE("write_clipboard_string", { text });
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
|
||||||
/** user-defined events **/
|
/** user-defined events **/
|
||||||
|
|
||||||
|
|
||||||
export const events = __makeEvents__<{
|
export const events = __makeEvents__<{
|
||||||
audioInputLevelChange: AudioInputLevelChange,
|
audioInputLevelChange: AudioInputLevelChange;
|
||||||
authenticationInvalid: AuthenticationInvalid,
|
authenticationInvalid: AuthenticationInvalid;
|
||||||
currentRecordingChanged: CurrentRecordingChanged,
|
currentRecordingChanged: CurrentRecordingChanged;
|
||||||
editorStateChanged: EditorStateChanged,
|
editorStateChanged: EditorStateChanged;
|
||||||
newNotification: NewNotification,
|
newNotification: NewNotification;
|
||||||
newRecordingAdded: NewRecordingAdded,
|
newRecordingAdded: NewRecordingAdded;
|
||||||
newScreenshotAdded: NewScreenshotAdded,
|
newScreenshotAdded: NewScreenshotAdded;
|
||||||
recordingMetaChanged: RecordingMetaChanged,
|
recordingMetaChanged: RecordingMetaChanged;
|
||||||
recordingOptionsChanged: RecordingOptionsChanged,
|
recordingOptionsChanged: RecordingOptionsChanged;
|
||||||
recordingStarted: RecordingStarted,
|
recordingStarted: RecordingStarted;
|
||||||
recordingStopped: RecordingStopped,
|
recordingStopped: RecordingStopped;
|
||||||
renderFrameEvent: RenderFrameEvent,
|
renderFrameEvent: RenderFrameEvent;
|
||||||
requestNewScreenshot: RequestNewScreenshot,
|
requestNewScreenshot: RequestNewScreenshot;
|
||||||
requestOpenSettings: RequestOpenSettings,
|
requestOpenSettings: RequestOpenSettings;
|
||||||
requestRestartRecording: RequestRestartRecording,
|
requestRestartRecording: RequestRestartRecording;
|
||||||
requestStartRecording: RequestStartRecording,
|
requestStartRecording: RequestStartRecording;
|
||||||
requestStopRecording: RequestStopRecording,
|
requestStopRecording: RequestStopRecording;
|
||||||
uploadProgress: UploadProgress
|
uploadProgress: UploadProgress;
|
||||||
}>({
|
}>({
|
||||||
audioInputLevelChange: "audio-input-level-change",
|
audioInputLevelChange: "audio-input-level-change",
|
||||||
authenticationInvalid: "authentication-invalid",
|
authenticationInvalid: "authentication-invalid",
|
||||||
@@ -201,91 +228,247 @@ export const events = __makeEvents__<{
|
|||||||
requestRestartRecording: "request-restart-recording",
|
requestRestartRecording: "request-restart-recording",
|
||||||
requestStartRecording: "request-start-recording",
|
requestStartRecording: "request-start-recording",
|
||||||
requestStopRecording: "request-stop-recording",
|
requestStopRecording: "request-stop-recording",
|
||||||
uploadProgress: "upload-progress"
|
uploadProgress: "upload-progress",
|
||||||
})
|
});
|
||||||
|
|
||||||
/** user-defined constants **/
|
/** user-defined constants **/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** user-defined types **/
|
/** user-defined types **/
|
||||||
export type AppEndpoint = string
|
export type AppEndpoint = string;
|
||||||
export type AppTheme = "auto" | "light" | "dark"
|
export type AppTheme = "auto" | "light" | "dark";
|
||||||
export type WindowTheme = "light" | "dark"
|
export type WindowTheme = "light" | "dark";
|
||||||
export type AspectRatio = "wide" | "vertical" | "square" | "classic" | "tall"
|
export type AspectRatio = "wide" | "vertical" | "square" | "classic" | "tall";
|
||||||
export type Audio = { duration: number; sample_rate: number; channels: number }
|
export type Audio = { duration: number; sample_rate: number; channels: number };
|
||||||
export type AudioConfiguration = { mute: boolean; improve: boolean }
|
export type AudioConfiguration = { mute: boolean; improve: boolean };
|
||||||
export type AudioInputLevelChange = number
|
export type AudioInputLevelChange = number;
|
||||||
export type AudioMeta = { path: string }
|
export type AudioMeta = { path: string };
|
||||||
export type AuthStore = { token: string; user_id: string | null; expires: number; plan: Plan | null }
|
export type AuthStore = {
|
||||||
export type AuthenticationInvalid = null
|
token: string;
|
||||||
export type BackgroundConfiguration = { source: BackgroundSource; blur: number; padding: number; rounding: number; inset: number; crop: Crop | null }
|
user_id: string | null;
|
||||||
export type BackgroundSource = { type: "wallpaper"; id: number } | { type: "image"; path: string | null } | { type: "color"; value: [number, number, number] } | { type: "gradient"; from: [number, number, number]; to: [number, number, number]; angle?: number }
|
expires: number;
|
||||||
export type Bounds = { x: number; y: number; width: number; height: number }
|
plan: Plan | null;
|
||||||
export type Camera = { hide: boolean; mirror: boolean; position: CameraPosition; size: number; zoom_size: number | null; rounding: number; shadow: number }
|
};
|
||||||
export type CameraMeta = { path: string }
|
export type AuthenticationInvalid = null;
|
||||||
export type CameraPosition = { x: CameraXPosition; y: CameraYPosition }
|
export type BackgroundConfiguration = {
|
||||||
export type CameraXPosition = "left" | "center" | "right"
|
source: BackgroundSource;
|
||||||
export type CameraYPosition = "top" | "bottom"
|
blur: number;
|
||||||
export type CaptureScreen = { id: number; name: string }
|
padding: number;
|
||||||
export type CaptureWindow = { id: number; owner_name: string; name: string; bounds: Bounds }
|
rounding: number;
|
||||||
export type Crop = { position: XY<number>; size: XY<number> }
|
inset: number;
|
||||||
export type CurrentRecordingChanged = null
|
crop: Crop | null;
|
||||||
export type CursorAnimationStyle = "regular" | "slow" | "fast"
|
};
|
||||||
export type CursorConfiguration = { hideWhenIdle: boolean; size: number; type: CursorType; animationStyle: CursorAnimationStyle }
|
export type BackgroundSource =
|
||||||
export type CursorType = "pointer" | "circle"
|
| { type: "wallpaper"; id: number }
|
||||||
export type Display = { path: string }
|
| { type: "image"; path: string | null }
|
||||||
export type EditorStateChanged = { playhead_position: number }
|
| { type: "color"; value: [number, number, number] }
|
||||||
export type Flags = { recordMouse: boolean; split: boolean; pauseResume: boolean; zoom: boolean; customS3: boolean }
|
| {
|
||||||
export type GeneralSettingsStore = { uploadIndividualFiles?: boolean; openEditorAfterRecording?: boolean; hideDockIcon?: boolean; autoCreateShareableLink?: boolean; enableNotifications?: boolean; disableAutoOpenLinks?: boolean; hasCompletedStartup?: boolean; theme?: AppTheme }
|
type: "gradient";
|
||||||
export type Hotkey = { code: string; meta: boolean; ctrl: boolean; alt: boolean; shift: boolean }
|
from: [number, number, number];
|
||||||
export type HotkeyAction = "startRecording" | "stopRecording" | "restartRecording" | "takeScreenshot"
|
to: [number, number, number];
|
||||||
export type HotkeysConfiguration = { show: boolean }
|
angle?: number;
|
||||||
export type HotkeysStore = { hotkeys: { [key in HotkeyAction]: Hotkey } }
|
};
|
||||||
export type JsonValue<T> = [T]
|
export type Bounds = { x: number; y: number; width: number; height: number };
|
||||||
export type MultipleSegment = { display: Display; camera?: CameraMeta | null; audio?: AudioMeta | null; cursor?: string | null }
|
export type Camera = {
|
||||||
export type MultipleSegments = { segments: MultipleSegment[]; cursors: { [key in string]: string } }
|
hide: boolean;
|
||||||
export type NewNotification = { title: string; body: string; is_error: boolean }
|
mirror: boolean;
|
||||||
export type NewRecordingAdded = { path: string }
|
position: CameraPosition;
|
||||||
export type NewScreenshotAdded = { path: string }
|
size: number;
|
||||||
export type OSPermission = "screenRecording" | "camera" | "microphone" | "accessibility"
|
zoom_size: number | null;
|
||||||
export type OSPermissionStatus = "notNeeded" | "empty" | "granted" | "denied"
|
rounding: number;
|
||||||
export type OSPermissionsCheck = { screenRecording: OSPermissionStatus; microphone: OSPermissionStatus; camera: OSPermissionStatus; accessibility: OSPermissionStatus }
|
shadow: number;
|
||||||
export type Plan = { upgraded: boolean; last_checked: number }
|
};
|
||||||
export type PreCreatedVideo = { id: string; link: string; config: S3UploadMeta }
|
export type CameraMeta = { path: string };
|
||||||
export type ProjectConfiguration = { aspectRatio: AspectRatio | null; background: BackgroundConfiguration; camera: Camera; audio: AudioConfiguration; cursor: CursorConfiguration; hotkeys: HotkeysConfiguration; timeline?: TimelineConfiguration | null; motionBlur: number | null }
|
export type CameraPosition = { x: CameraXPosition; y: CameraYPosition };
|
||||||
export type ProjectRecordings = { segments: SegmentRecordings[] }
|
export type CameraXPosition = "left" | "center" | "right";
|
||||||
export type RecordingInfo = { captureTarget: ScreenCaptureTarget }
|
export type CameraYPosition = "top" | "bottom";
|
||||||
export type RecordingMeta = ({ segment: SingleSegment } | { inner: MultipleSegments }) & { pretty_name: string; sharing?: SharingMeta | null }
|
export type CaptureScreen = { id: number; name: string };
|
||||||
export type RecordingMetaChanged = { id: string }
|
export type CaptureWindow = {
|
||||||
export type RecordingOptions = { captureTarget: ScreenCaptureTarget; cameraLabel: string | null; audioInputName: string | null }
|
id: number;
|
||||||
export type RecordingOptionsChanged = null
|
owner_name: string;
|
||||||
export type RecordingStarted = null
|
name: string;
|
||||||
export type RecordingStopped = { path: string }
|
bounds: Bounds;
|
||||||
export type RenderFrameEvent = { frame_number: number }
|
};
|
||||||
export type RenderProgress = { type: "Starting"; total_frames: number } | { type: "EstimatedTotalFrames"; total_frames: number } | { type: "FrameRendered"; current_frame: number }
|
export type Crop = { position: XY<number>; size: XY<number> };
|
||||||
export type RequestNewScreenshot = null
|
export type CurrentRecordingChanged = null;
|
||||||
export type RequestOpenSettings = { page: string }
|
export type CursorAnimationStyle = "regular" | "slow" | "fast";
|
||||||
export type RequestRestartRecording = null
|
export type CursorConfiguration = {
|
||||||
export type RequestStartRecording = null
|
hideWhenIdle: boolean;
|
||||||
export type RequestStopRecording = null
|
size: number;
|
||||||
export type S3UploadMeta = { id: string; user_id: string; aws_region?: string; aws_bucket?: string }
|
type: CursorType;
|
||||||
export type ScreenCaptureTarget = ({ variant: "window" } & CaptureWindow) | ({ variant: "screen" } & CaptureScreen)
|
animationStyle: CursorAnimationStyle;
|
||||||
export type SegmentRecordings = { display: Video; camera: Video | null; audio: Audio | null }
|
};
|
||||||
export type SerializedEditorInstance = { framesSocketUrl: string; recordingDuration: number; savedProjectConfig: ProjectConfiguration; recordings: ProjectRecordings; path: string; prettyName: string }
|
export type CursorType = "pointer" | "circle";
|
||||||
export type SharingMeta = { id: string; link: string }
|
export type Display = { path: string };
|
||||||
export type ShowCapWindow = "Setup" | "Main" | { Settings: { page: string | null } } | { Editor: { project_id: string } } | "PrevRecordings" | "WindowCaptureOccluder" | { Camera: { ws_port: number } } | { InProgressRecording: { position: [number, number] | null } } | "Upgrade"
|
export type EditorStateChanged = { playhead_position: number };
|
||||||
export type SingleSegment = { display: Display; camera?: CameraMeta | null; audio?: AudioMeta | null; cursor?: string | null }
|
export type Flags = {
|
||||||
export type TimelineConfiguration = { segments: TimelineSegment[]; zoomSegments?: ZoomSegment[] }
|
recordMouse: boolean;
|
||||||
export type TimelineSegment = { recordingSegment: number | null; timescale: number; start: number; end: number }
|
split: boolean;
|
||||||
export type UploadMode = { Initial: { pre_created_video: PreCreatedVideo | null } } | "Reupload"
|
pauseResume: boolean;
|
||||||
export type UploadProgress = { stage: string; progress: number; message: string }
|
zoom: boolean;
|
||||||
export type UploadResult = { Success: string } | "NotAuthenticated" | "PlanCheckFailed" | "UpgradeRequired"
|
customS3: boolean;
|
||||||
export type Video = { duration: number; width: number; height: number }
|
};
|
||||||
export type VideoRecordingMetadata = { duration: number; size: number }
|
export type GeneralSettingsStore = {
|
||||||
export type VideoType = "screen" | "output"
|
uploadIndividualFiles?: boolean;
|
||||||
export type XY<T> = { x: T; y: T }
|
openEditorAfterRecording?: boolean;
|
||||||
export type ZoomSegment = { start: number; end: number; amount: number }
|
hideDockIcon?: boolean;
|
||||||
|
autoCreateShareableLink?: boolean;
|
||||||
|
enableNotifications?: boolean;
|
||||||
|
disableAutoOpenLinks?: boolean;
|
||||||
|
hasCompletedStartup?: boolean;
|
||||||
|
theme?: AppTheme;
|
||||||
|
};
|
||||||
|
export type Hotkey = {
|
||||||
|
code: string;
|
||||||
|
meta: boolean;
|
||||||
|
ctrl: boolean;
|
||||||
|
alt: boolean;
|
||||||
|
shift: boolean;
|
||||||
|
};
|
||||||
|
export type HotkeyAction =
|
||||||
|
| "startRecording"
|
||||||
|
| "stopRecording"
|
||||||
|
| "restartRecording"
|
||||||
|
| "takeScreenshot";
|
||||||
|
export type HotkeysConfiguration = { show: boolean };
|
||||||
|
export type HotkeysStore = { hotkeys: { [key in HotkeyAction]: Hotkey } };
|
||||||
|
export type JsonValue<T> = [T];
|
||||||
|
export type MultipleSegment = {
|
||||||
|
display: Display;
|
||||||
|
camera?: CameraMeta | null;
|
||||||
|
audio?: AudioMeta | null;
|
||||||
|
cursor?: string | null;
|
||||||
|
};
|
||||||
|
export type MultipleSegments = {
|
||||||
|
segments: MultipleSegment[];
|
||||||
|
cursors: { [key in string]: string };
|
||||||
|
};
|
||||||
|
export type NewNotification = {
|
||||||
|
title: string;
|
||||||
|
body: string;
|
||||||
|
is_error: boolean;
|
||||||
|
};
|
||||||
|
export type NewRecordingAdded = { path: string };
|
||||||
|
export type NewScreenshotAdded = { path: string };
|
||||||
|
export type OSPermission =
|
||||||
|
| "screenRecording"
|
||||||
|
| "camera"
|
||||||
|
| "microphone"
|
||||||
|
| "accessibility";
|
||||||
|
export type OSPermissionStatus = "notNeeded" | "empty" | "granted" | "denied";
|
||||||
|
export type OSPermissionsCheck = {
|
||||||
|
screenRecording: OSPermissionStatus;
|
||||||
|
microphone: OSPermissionStatus;
|
||||||
|
camera: OSPermissionStatus;
|
||||||
|
accessibility: OSPermissionStatus;
|
||||||
|
};
|
||||||
|
export type Plan = { upgraded: boolean; last_checked: number };
|
||||||
|
export type PreCreatedVideo = {
|
||||||
|
id: string;
|
||||||
|
link: string;
|
||||||
|
config: S3UploadMeta;
|
||||||
|
};
|
||||||
|
export type ProjectConfiguration = {
|
||||||
|
aspectRatio: AspectRatio | null;
|
||||||
|
background: BackgroundConfiguration;
|
||||||
|
camera: Camera;
|
||||||
|
audio: AudioConfiguration;
|
||||||
|
cursor: CursorConfiguration;
|
||||||
|
hotkeys: HotkeysConfiguration;
|
||||||
|
timeline?: TimelineConfiguration | null;
|
||||||
|
motionBlur: number | null;
|
||||||
|
};
|
||||||
|
export type ProjectRecordings = { segments: SegmentRecordings[] };
|
||||||
|
export type RecordingInfo = { captureTarget: ScreenCaptureTarget };
|
||||||
|
export type RecordingMeta = (
|
||||||
|
| { segment: SingleSegment }
|
||||||
|
| { inner: MultipleSegments }
|
||||||
|
) & { pretty_name: string; sharing?: SharingMeta | null };
|
||||||
|
export type RecordingMetaChanged = { id: string };
|
||||||
|
export type RecordingOptions = {
|
||||||
|
captureTarget: ScreenCaptureTarget;
|
||||||
|
cameraLabel: string | null;
|
||||||
|
audioInputName: string | null;
|
||||||
|
};
|
||||||
|
export type RecordingOptionsChanged = null;
|
||||||
|
export type RecordingStarted = null;
|
||||||
|
export type RecordingStopped = { path: string };
|
||||||
|
export type RenderFrameEvent = { frame_number: number };
|
||||||
|
export type RenderProgress =
|
||||||
|
| { type: "Starting"; total_frames: number }
|
||||||
|
| { type: "EstimatedTotalFrames"; total_frames: number }
|
||||||
|
| { type: "FrameRendered"; current_frame: number };
|
||||||
|
export type RequestNewScreenshot = null;
|
||||||
|
export type RequestOpenSettings = { page: string };
|
||||||
|
export type RequestRestartRecording = null;
|
||||||
|
export type RequestStartRecording = null;
|
||||||
|
export type RequestStopRecording = null;
|
||||||
|
export type S3UploadMeta = {
|
||||||
|
id: string;
|
||||||
|
user_id: string;
|
||||||
|
aws_region?: string;
|
||||||
|
aws_bucket?: string;
|
||||||
|
};
|
||||||
|
export type ScreenCaptureTarget =
|
||||||
|
| ({ variant: "window" } & CaptureWindow)
|
||||||
|
| ({ variant: "screen" } & CaptureScreen);
|
||||||
|
export type SegmentRecordings = {
|
||||||
|
display: Video;
|
||||||
|
camera: Video | null;
|
||||||
|
audio: Audio | null;
|
||||||
|
};
|
||||||
|
export type SerializedEditorInstance = {
|
||||||
|
framesSocketUrl: string;
|
||||||
|
recordingDuration: number;
|
||||||
|
savedProjectConfig: ProjectConfiguration;
|
||||||
|
recordings: ProjectRecordings;
|
||||||
|
path: string;
|
||||||
|
prettyName: string;
|
||||||
|
};
|
||||||
|
export type SharingMeta = { id: string; link: string };
|
||||||
|
export type ShowCapWindow =
|
||||||
|
| "Setup"
|
||||||
|
| "Main"
|
||||||
|
| { Settings: { page: string | null } }
|
||||||
|
| { Editor: { project_id: string } }
|
||||||
|
| "PrevRecordings"
|
||||||
|
| "WindowCaptureOccluder"
|
||||||
|
| { Camera: { ws_port: number } }
|
||||||
|
| { InProgressRecording: { position: [number, number] | null } }
|
||||||
|
| "Upgrade";
|
||||||
|
export type SingleSegment = {
|
||||||
|
display: Display;
|
||||||
|
camera?: CameraMeta | null;
|
||||||
|
audio?: AudioMeta | null;
|
||||||
|
cursor?: string | null;
|
||||||
|
};
|
||||||
|
export type TimelineConfiguration = {
|
||||||
|
segments: TimelineSegment[];
|
||||||
|
zoomSegments?: ZoomSegment[];
|
||||||
|
};
|
||||||
|
export type TimelineSegment = {
|
||||||
|
recordingSegment: number | null;
|
||||||
|
timescale: number;
|
||||||
|
start: number;
|
||||||
|
end: number;
|
||||||
|
};
|
||||||
|
export type UploadMode =
|
||||||
|
| { Initial: { pre_created_video: PreCreatedVideo | null } }
|
||||||
|
| "Reupload";
|
||||||
|
export type UploadProgress = {
|
||||||
|
stage: string;
|
||||||
|
progress: number;
|
||||||
|
message: string;
|
||||||
|
};
|
||||||
|
export type UploadResult =
|
||||||
|
| { Success: string }
|
||||||
|
| "NotAuthenticated"
|
||||||
|
| "PlanCheckFailed"
|
||||||
|
| "UpgradeRequired";
|
||||||
|
export type Video = { duration: number; width: number; height: number };
|
||||||
|
export type VideoRecordingMetadata = { duration: number; size: number };
|
||||||
|
export type VideoType = "screen" | "output";
|
||||||
|
export type XY<T> = { x: T; y: T };
|
||||||
|
export type ZoomSegment = { start: number; end: number; amount: number };
|
||||||
|
|
||||||
/** tauri-specta globals **/
|
/** tauri-specta globals **/
|
||||||
|
|
||||||
@@ -298,14 +481,14 @@ import { type WebviewWindow as __WebviewWindow__ } from "@tauri-apps/api/webview
|
|||||||
|
|
||||||
type __EventObj__<T> = {
|
type __EventObj__<T> = {
|
||||||
listen: (
|
listen: (
|
||||||
cb: TAURI_API_EVENT.EventCallback<T>,
|
cb: TAURI_API_EVENT.EventCallback<T>
|
||||||
) => ReturnType<typeof TAURI_API_EVENT.listen<T>>;
|
) => ReturnType<typeof TAURI_API_EVENT.listen<T>>;
|
||||||
once: (
|
once: (
|
||||||
cb: TAURI_API_EVENT.EventCallback<T>,
|
cb: TAURI_API_EVENT.EventCallback<T>
|
||||||
) => ReturnType<typeof TAURI_API_EVENT.once<T>>;
|
) => ReturnType<typeof TAURI_API_EVENT.once<T>>;
|
||||||
emit: null extends T
|
emit: null extends T
|
||||||
? (payload?: T) => ReturnType<typeof TAURI_API_EVENT.emit>
|
? (payload?: T) => ReturnType<typeof TAURI_API_EVENT.emit>
|
||||||
: (payload: T) => ReturnType<typeof TAURI_API_EVENT.emit>;
|
: (payload: T) => ReturnType<typeof TAURI_API_EVENT.emit>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Result<T, E> =
|
export type Result<T, E> =
|
||||||
@@ -313,7 +496,7 @@ export type Result<T, E> =
|
|||||||
| { status: "error"; error: E };
|
| { status: "error"; error: E };
|
||||||
|
|
||||||
function __makeEvents__<T extends Record<string, any>>(
|
function __makeEvents__<T extends Record<string, any>>(
|
||||||
mappings: Record<keyof T, string>,
|
mappings: Record<keyof T, string>
|
||||||
) {
|
) {
|
||||||
return new Proxy(
|
return new Proxy(
|
||||||
{} as unknown as {
|
{} as unknown as {
|
||||||
@@ -325,7 +508,7 @@ function __makeEvents__<T extends Record<string, any>>(
|
|||||||
get: (_, event) => {
|
get: (_, event) => {
|
||||||
const name = mappings[event as keyof T];
|
const name = mappings[event as keyof T];
|
||||||
|
|
||||||
return new Proxy((() => { }) as any, {
|
return new Proxy((() => {}) as any, {
|
||||||
apply: (_, __, [window]: [__WebviewWindow__]) => ({
|
apply: (_, __, [window]: [__WebviewWindow__]) => ({
|
||||||
listen: (arg: any) => window.listen(name, arg),
|
listen: (arg: any) => window.listen(name, arg),
|
||||||
once: (arg: any) => window.once(name, arg),
|
once: (arg: any) => window.once(name, arg),
|
||||||
@@ -343,6 +526,6 @@ function __makeEvents__<T extends Record<string, any>>(
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
},
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -206,10 +206,10 @@ export const createTauriAdapter = (): TauriPlatformAdapter => {
|
|||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
async openExternal(url) {
|
async openUrl(url) {
|
||||||
const { open } = await import("@tauri-apps/plugin-shell");
|
const { openUrl } = await import("@tauri-apps/plugin-opener");
|
||||||
|
|
||||||
open(url);
|
openUrl(url);
|
||||||
},
|
},
|
||||||
|
|
||||||
isWindows10,
|
isWindows10,
|
||||||
@@ -223,5 +223,11 @@ export const createTauriAdapter = (): TauriPlatformAdapter => {
|
|||||||
},
|
},
|
||||||
|
|
||||||
metadata,
|
metadata,
|
||||||
|
|
||||||
|
async revealItemInDir(path) {
|
||||||
|
const { revealItemInDir } = await import("@tauri-apps/plugin-opener");
|
||||||
|
|
||||||
|
revealItemInDir(path);
|
||||||
|
},
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ export const createWebAdapter = (): WebPlatformAdapter => {
|
|||||||
|
|
||||||
async listenEvent(event, _callback) {
|
async listenEvent(event, _callback) {
|
||||||
console.log("Web mode simulated event listen", event);
|
console.log("Web mode simulated event listen", event);
|
||||||
return () => { };
|
return () => {};
|
||||||
},
|
},
|
||||||
|
|
||||||
async setAlwaysOnTop(isPinned) {
|
async setAlwaysOnTop(isPinned) {
|
||||||
@@ -110,7 +110,7 @@ export const createWebAdapter = (): WebPlatformAdapter => {
|
|||||||
|
|
||||||
async listenThemeChanged() {
|
async listenThemeChanged() {
|
||||||
console.log("Web mode simulated theme change listener");
|
console.log("Web mode simulated theme change listener");
|
||||||
return () => { };
|
return () => {};
|
||||||
},
|
},
|
||||||
|
|
||||||
async getWebviewWindow() {
|
async getWebviewWindow() {
|
||||||
@@ -157,14 +157,14 @@ export const createWebAdapter = (): WebPlatformAdapter => {
|
|||||||
|
|
||||||
async listenWindowEvent(event, _callback) {
|
async listenWindowEvent(event, _callback) {
|
||||||
console.log("Web mode simulated listen window event:", event);
|
console.log("Web mode simulated listen window event:", event);
|
||||||
return () => { };
|
return () => {};
|
||||||
},
|
},
|
||||||
|
|
||||||
isTauri() {
|
isTauri() {
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
|
||||||
async openExternal(url) {
|
async openUrl(url) {
|
||||||
console.log(`Web mode opening URL: ${url}`);
|
console.log(`Web mode opening URL: ${url}`);
|
||||||
window.open(url, "_blank");
|
window.open(url, "_blank");
|
||||||
},
|
},
|
||||||
@@ -177,8 +177,16 @@ export const createWebAdapter = (): WebPlatformAdapter => {
|
|||||||
},
|
},
|
||||||
|
|
||||||
async metadata(path, options = {}) {
|
async metadata(path, options = {}) {
|
||||||
console.log("metadata is not supported in web environment", path, options);
|
console.log(
|
||||||
|
"metadata is not supported in web environment",
|
||||||
|
path,
|
||||||
|
options
|
||||||
|
);
|
||||||
return Promise.resolve({ isAbsolute: false });
|
return Promise.resolve({ isAbsolute: false });
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async revealItemInDir(path) {
|
||||||
|
console.log("revealItemInDir is not supported in web environment", path);
|
||||||
|
},
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user