| ... | ... | @@ -1,11 +1,11 @@ |
| 1 | | import { EDITORS, EditorId, type EnvironmentId } from "@t3tools/contracts"; |
| 1 | import { EDITORS, EditorId, EnvironmentId } from "@t3tools/contracts"; |
| 2 | 2 | import { |
| 3 | 3 | mapAtomCommandResult, |
| 4 | 4 | type AtomCommandFailure, |
| 5 | 5 | type AtomCommandResult, |
| 6 | 6 | } from "@t3tools/client-runtime/state/runtime"; |
| 7 | 7 | import * as Cause from "effect/Cause"; |
| 8 | | import * as Data from "effect/Data"; |
| 8 | import * as Schema from "effect/Schema"; |
| 9 | 9 | import { AsyncResult } from "effect/unstable/reactivity"; |
| 10 | 10 | import { getLocalStorageItem, setLocalStorageItem, useLocalStorage } from "./hooks/useLocalStorage"; |
| 11 | 11 | import { useCallback, useMemo } from "react"; |
| ... | ... | @@ -14,11 +14,29 @@ import { useAtomCommand } from "./state/use-atom-command"; |
| 14 | 14 | |
| 15 | 15 | const LAST_EDITOR_KEY = "t3code:last-editor"; |
| 16 | 16 | |
| 17 | | export class PreferredEditorUnavailableError extends Data.TaggedError( |
| 17 | export class PreferredEditorEnvironmentRequiredError extends Schema.TaggedErrorClass<PreferredEditorEnvironmentRequiredError>()( |
| 18 | "PreferredEditorEnvironmentRequiredError", |
| 19 | { |
| 20 | targetPath: Schema.String, |
| 21 | }, |
| 22 | ) { |
| 23 | override get message(): string { |
| 24 | return `Cannot open ${this.targetPath} because no environment is selected.`; |
| 25 | } |
| 26 | } |
| 27 | |
| 28 | export class PreferredEditorUnavailableError extends Schema.TaggedErrorClass<PreferredEditorUnavailableError>()( |
| 18 | 29 | "PreferredEditorUnavailableError", |
| 19 | | )<{ |
| 20 | | readonly message: string; |
| 21 | | }> {} |
| 30 | { |
| 31 | environmentId: EnvironmentId, |
| 32 | targetPath: Schema.String, |
| 33 | availableEditorIds: Schema.Array(EditorId), |
| 34 | }, |
| 35 | ) { |
| 36 | override get message(): string { |
| 37 | return `No available editor can open ${this.targetPath} in environment ${this.environmentId}.`; |
| 38 | } |
| 39 | } |
| 22 | 40 | |
| 23 | 41 | export function usePreferredEditor(availableEditors: ReadonlyArray<EditorId>) { |
| 24 | 42 | const [lastEditor, setLastEditor] = useLocalStorage(LAST_EDITOR_KEY, null, EditorId); |
| ... | ... | @@ -55,13 +73,18 @@ export function useOpenInPreferredEditor( |
| 55 | 73 | async ( |
| 56 | 74 | targetPath: string, |
| 57 | 75 | ): Promise< |
| 58 | | AtomCommandResult<EditorId, OpenInEditorError | PreferredEditorUnavailableError> |
| 76 | AtomCommandResult< |
| 77 | EditorId, |
| 78 | | OpenInEditorError |
| 79 | | PreferredEditorEnvironmentRequiredError |
| 80 | | PreferredEditorUnavailableError |
| 81 | > |
| 59 | 82 | > => { |
| 60 | 83 | if (environmentId === null) { |
| 61 | 84 | return AsyncResult.failure( |
| 62 | 85 | Cause.fail( |
| 63 | | new PreferredEditorUnavailableError({ |
| 64 | | message: "No environment is selected.", |
| 86 | new PreferredEditorEnvironmentRequiredError({ |
| 87 | targetPath, |
| 65 | 88 | }), |
| 66 | 89 | ), |
| 67 | 90 | ); |
| ... | ... | @@ -71,7 +94,9 @@ export function useOpenInPreferredEditor( |
| 71 | 94 | return AsyncResult.failure( |
| 72 | 95 | Cause.fail( |
| 73 | 96 | new PreferredEditorUnavailableError({ |
| 74 | | message: "No available editors found.", |
| 97 | environmentId, |
| 98 | targetPath, |
| 99 | availableEditorIds: availableEditors, |
| 75 | 100 | }), |
| 76 | 101 | ), |
| 77 | 102 | ); |