@lapis-notes/workspace 0.3.5 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,35 @@
1
1
  # @lapis-notes/workspace
2
2
 
3
+ ## 0.4.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#95](https://github.com/lapismd/lapis-notes/pull/95)
8
+ [`8a4d0e0`](https://github.com/lapismd/lapis-notes/commit/8a4d0e02d0642a65ec7441f4fea032739550a6ae)
9
+ Thanks [@stevejuma](https://github.com/stevejuma)! - Honor mobile layout
10
+ settings in application hosts and restore App-owned mobile Search, new-note
11
+ creation and disposable legacy navigation commands through Design Core's
12
+ public mobile actions. Require released Design Core 0.13.0 for the mobile
13
+ navigation contract.
14
+
15
+ ### Patch Changes
16
+
17
+ - Updated dependencies
18
+ [[`0ce7e30`](https://github.com/lapismd/lapis-notes/commit/0ce7e3078af8b3f9b132e2b06655a0229e72e346),
19
+ [`8a4d0e0`](https://github.com/lapismd/lapis-notes/commit/8a4d0e02d0642a65ec7441f4fea032739550a6ae)]:
20
+ - @lapis-notes/api@0.3.1
21
+ - @lapis-notes/ui@0.1.9
22
+
23
+ ## 0.3.6
24
+
25
+ ### Patch Changes
26
+
27
+ - Updated dependencies
28
+ [[`0b7ac5a`](https://github.com/lapismd/lapis-notes/commit/0b7ac5a9d6f07dd8a35d7d9fd7de8d9cb076e07b),
29
+ [`84551f9`](https://github.com/lapismd/lapis-notes/commit/84551f9f10ec73ea02fcb71d53131758a9d2d419),
30
+ [`1d9f1d1`](https://github.com/lapismd/lapis-notes/commit/1d9f1d180b38e8248f49abaf8f523fe0cddc28fd)]:
31
+ - @lapis-notes/api@0.3.0
32
+
3
33
  ## 0.3.5
4
34
 
5
35
  ### Patch Changes
@@ -26,6 +26,10 @@
26
26
  import { getWorkspaceHostBinding } from "@lapis-notes/api/workspace-host";
27
27
  import { AppShell } from "@lapismd/design-core/workspace/app-shell";
28
28
  import { bindFileConflictReviews } from "./file-conflicts/register-conflict-reviews";
29
+ import {
30
+ bindMobileWorkspaceCommands,
31
+ mobileWorkspaceActions,
32
+ } from "./mobile-workspace";
29
33
  import "./workspace-shell.css";
30
34
 
31
35
  let {
@@ -44,6 +48,7 @@
44
48
  .getConfiguration()
45
49
  .get("editor.alwaysFocusNewTabs", false),
46
50
  );
51
+ let mobileActions = $derived(mobileWorkspaceActions(app));
47
52
 
48
53
  onMount(() => {
49
54
  // AppShell.Root does not own startup. By the time this shell is mounted,
@@ -51,7 +56,9 @@
51
56
  void controller.start();
52
57
  const stopNative = bindNativeEditingProblems(app);
53
58
  const stopConflicts = bindFileConflictReviews(app);
59
+ const stopMobile = bindMobileWorkspaceCommands(app, controller);
54
60
  return () => {
61
+ stopMobile();
55
62
  stopConflicts();
56
63
  stopNative();
57
64
  };
@@ -71,6 +78,12 @@
71
78
  disposeOnDestroy={false}
72
79
  theme="inherit"
73
80
  >
74
- <AppShell.Surface {displayMode} {workspaceLabel} {workspaceNavigation} />
81
+ <AppShell.Surface
82
+ {displayMode}
83
+ {workspaceLabel}
84
+ {workspaceNavigation}
85
+ mobileSearchAction={mobileActions.search}
86
+ mobileCreateAction={mobileActions.create}
87
+ />
75
88
  </AppShell.Root>
76
89
  </div>
@@ -0,0 +1,8 @@
1
+ import { type App } from "@lapis-notes/api";
2
+ import type { AppShellController, WorkspaceAction } from "@lapismd/design-core/workspace/core";
3
+ /** Lapis-owned policy; Design Core owns the transient mobile presentation. */
4
+ export declare function bindMobileWorkspaceCommands(app: App, controller: AppShellController): () => void;
5
+ export declare function mobileWorkspaceActions(app: App): {
6
+ search: WorkspaceAction;
7
+ create: WorkspaceAction;
8
+ };
@@ -0,0 +1,134 @@
1
+ import { Notice } from "@lapis-notes/api";
2
+ /** Lapis-owned policy; Design Core owns the transient mobile presentation. */
3
+ export function bindMobileWorkspaceCommands(app, controller) {
4
+ const navigation = controller.renderer.mobileNavigation;
5
+ let disposed = false;
6
+ let previousCreation = Promise.resolve();
7
+ const setMode = (mode) => app.configuration.getConfiguration().update("workspace.mobile.mode", mode);
8
+ const mobileOnly = (action) => {
9
+ if (controller.renderer.displayMode === "mobile")
10
+ action();
11
+ else
12
+ new Notice("This action is only available while the mobile workspace layout is active.", undefined, app);
13
+ };
14
+ const openSidebar = (side) => {
15
+ if (controller.renderer.displayMode === "mobile")
16
+ navigation.openSidebar(side);
17
+ else {
18
+ app.workspace.exitFocusMode();
19
+ (side === "left"
20
+ ? app.workspace.leftSplit
21
+ : app.workspace.rightSplit).expand();
22
+ }
23
+ };
24
+ const createNote = () => {
25
+ const previous = previousCreation;
26
+ const operation = app.fileEditingSessions.track(async () => {
27
+ await previous;
28
+ if (disposed)
29
+ throw new Error("The workspace has closed.");
30
+ const path = app.fileManager.getAvailablePathForAttachment("Untitled.md");
31
+ const file = await app.fileManager.createFile(path, "");
32
+ navigation.openEditor();
33
+ await app.openFile(file);
34
+ app.workspace.requestSaveLayout();
35
+ });
36
+ previousCreation = operation.catch(() => undefined);
37
+ return operation;
38
+ };
39
+ const commands = [
40
+ {
41
+ id: "app:new-note",
42
+ name: "Create new note",
43
+ icon: "file-plus",
44
+ callback: createNote,
45
+ },
46
+ {
47
+ id: "workspace:toggle-mobile-layout",
48
+ name: "Workspace: Cycle mobile layout mode",
49
+ icon: "smartphone",
50
+ callback: () => {
51
+ const mode = app.configuration
52
+ .getConfiguration()
53
+ .get("workspace.mobile.mode", "auto");
54
+ return setMode(mode === "auto" ? "always" : mode === "always" ? "never" : "auto");
55
+ },
56
+ },
57
+ {
58
+ id: "workspace:use-mobile-layout",
59
+ name: "Workspace: Use mobile layout",
60
+ icon: "smartphone",
61
+ callback: () => setMode("always"),
62
+ },
63
+ {
64
+ id: "workspace:use-desktop-layout",
65
+ name: "Workspace: Use desktop layout",
66
+ icon: "monitor",
67
+ callback: () => setMode("never"),
68
+ },
69
+ {
70
+ id: "workspace:open-mobile-tabs",
71
+ name: "Workspace: Open mobile tabs",
72
+ icon: "panel-top-open",
73
+ callback: () => mobileOnly(() => navigation.openTabs()),
74
+ },
75
+ {
76
+ id: "workspace:open-mobile-search",
77
+ name: "Workspace: Open mobile search",
78
+ icon: "search",
79
+ callback: async () => {
80
+ if (controller.renderer.displayMode !== "mobile")
81
+ return mobileOnly(() => { });
82
+ navigation.openEditor();
83
+ await app.commands.executeCommand("search:open-search");
84
+ },
85
+ },
86
+ {
87
+ id: "workspace:open-mobile-left-sidebar",
88
+ name: "Workspace: Open mobile left sidebar",
89
+ icon: "panel-left-open",
90
+ callback: () => openSidebar("left"),
91
+ },
92
+ {
93
+ id: "workspace:open-mobile-right-sidebar",
94
+ name: "Workspace: Open mobile right sidebar",
95
+ icon: "panel-right-open",
96
+ callback: () => openSidebar("right"),
97
+ },
98
+ ];
99
+ const owned = commands.filter((command) => !app.commands.getCommand(command.id));
100
+ owned.forEach((command) => app.commands.registerCommand(command));
101
+ const registered = owned.map((command) => app.commands.getCommand(command.id));
102
+ return () => {
103
+ disposed = true;
104
+ for (const command of registered) {
105
+ if (app.commands.getCommand(command.id) === command)
106
+ app.commands.unregisterCommand(command.id);
107
+ }
108
+ };
109
+ }
110
+ export function mobileWorkspaceActions(app) {
111
+ const execute = async (id) => {
112
+ try {
113
+ await app.commands.executeCommand(id);
114
+ }
115
+ catch (error) {
116
+ new Notice(error instanceof Error ? error.message : String(error), undefined, app);
117
+ }
118
+ };
119
+ return {
120
+ search: {
121
+ id: "mobile-search",
122
+ label: "Open search sidebar",
123
+ icon: "search",
124
+ disabled: !app.commands.getCommand("search:open-search"),
125
+ onSelect: () => execute("workspace:open-mobile-search"),
126
+ },
127
+ create: {
128
+ id: "mobile-new-note",
129
+ label: "Create new note",
130
+ icon: "plus",
131
+ onSelect: () => execute("app:new-note"),
132
+ },
133
+ };
134
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lapis-notes/workspace",
3
- "version": "0.3.5",
3
+ "version": "0.4.0",
4
4
  "description": "Lapis Notes workspace shell backed by design-core",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -38,9 +38,9 @@
38
38
  }
39
39
  },
40
40
  "dependencies": {
41
- "@lapis-notes/api": "^0.2.7",
42
- "@lapis-notes/ui": "^0.1.8",
43
- "@lapismd/design-core": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.12.0",
41
+ "@lapis-notes/api": "^0.3.1",
42
+ "@lapis-notes/ui": "^0.1.9",
43
+ "@lapismd/design-core": "^0.13.0",
44
44
  "@lucide/svelte": "^0.523.0"
45
45
  },
46
46
  "peerDependencies": {