@waterwx/dsh-novel-forge 2.1.2-alpha → 2.1.3
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/README.md +278 -368
- package/lib/client.js +19568 -21381
- package/lib/index.js +5158 -3958
- package/lib/types/action-guard.d.ts +61 -0
- package/lib/types/ai-scan.d.ts +80 -12
- package/lib/types/assets.d.ts +7 -9
- package/lib/types/assistant.d.ts +25 -0
- package/lib/types/author-assets.d.ts +1 -3
- package/lib/types/bookshelf.d.ts +13 -3
- package/lib/types/client/api.d.ts +49 -29
- package/lib/types/client/chip-prefs.d.ts +36 -0
- package/lib/types/client/docx.d.ts +2 -2
- package/lib/types/client/llmLive.d.ts +12 -14
- package/lib/types/client/locales.d.ts +12 -67
- package/lib/types/client/mount.d.ts +0 -2
- package/lib/types/client/panel/AdaptModeView.d.ts +1 -1
- package/lib/types/client/panel/AiTag.d.ts +1 -0
- package/lib/types/client/panel/AssetsTab.d.ts +1 -1
- package/lib/types/client/panel/AssistantTab.d.ts +4 -1
- package/lib/types/client/panel/AuthorAssetsView.d.ts +1 -1
- package/lib/types/client/panel/AuthorHome.d.ts +12 -12
- package/lib/types/client/panel/CmdPalette.d.ts +12 -0
- package/lib/types/client/panel/CreateBookView.d.ts +1 -1
- package/lib/types/client/panel/GlobalAssetLibraryView.d.ts +1 -1
- package/lib/types/client/panel/ImportModal.d.ts +1 -1
- package/lib/types/client/panel/LiveFeedLog.d.ts +8 -0
- package/lib/types/client/panel/ModelManager.d.ts +2 -2
- package/lib/types/client/panel/NovelPanel.d.ts +7 -2
- package/lib/types/client/panel/PageHeader.d.ts +18 -0
- package/lib/types/client/panel/ProgressConsole.d.ts +1 -1
- package/lib/types/client/panel/PromptSlotsView.d.ts +11 -0
- package/lib/types/client/panel/ReaderView.d.ts +1 -1
- package/lib/types/client/panel/RunPanel.d.ts +1 -1
- package/lib/types/client/panel/SettingsView.d.ts +13 -10
- package/lib/types/client/panel/ShelfView.d.ts +11 -2
- package/lib/types/client/panel/SubPage.d.ts +27 -0
- package/lib/types/client/panel/TensionView.d.ts +18 -0
- package/lib/types/client/panel/TimelineView.d.ts +18 -0
- package/lib/types/client/panel/WorldTab.d.ts +1 -1
- package/lib/types/client/panel/helpers.d.ts +5 -3
- package/lib/types/client/panel/market-radar-state.d.ts +56 -0
- package/lib/types/client/panel/outline-markdown.d.ts +112 -0
- package/lib/types/client/panel/status-badge.d.ts +13 -0
- package/lib/types/client/panel/storage-parse.d.ts +46 -0
- package/lib/types/client/panel/toast.d.ts +2 -0
- package/lib/types/client/panel/usePersistentState.d.ts +17 -0
- package/lib/types/client/panel/views.d.ts +21 -35
- package/lib/types/client/run-status.d.ts +21 -0
- package/lib/types/client/sidebar-entry.d.ts +0 -2
- package/lib/types/digest-parse.d.ts +29 -0
- package/lib/types/docx-core.d.ts +16 -0
- package/lib/types/docx.d.ts +2 -3
- package/lib/types/engine.d.ts +122 -103
- package/lib/types/home.d.ts +11 -0
- package/lib/types/index.d.ts +21 -13
- package/lib/types/llm-live.d.ts +62 -36
- package/lib/types/llm-retry.d.ts +38 -0
- package/lib/types/market-radar-scan.d.ts +0 -1
- package/lib/types/market-radar-sources.d.ts +1 -1
- package/lib/types/migrate-output.d.ts +25 -0
- package/lib/types/model-capability.d.ts +119 -0
- package/lib/types/model-request.d.ts +36 -0
- package/lib/types/output-budget.d.ts +86 -0
- package/lib/types/plotline-align.d.ts +35 -0
- package/lib/types/prompt-slots.d.ts +57 -0
- package/lib/types/prompting.d.ts +2 -27
- package/lib/types/protocol.d.ts +479 -595
- package/lib/types/revision.d.ts +76 -0
- package/lib/types/routes.d.ts +9 -3
- package/lib/types/run-selection.d.ts +51 -0
- package/lib/types/run.d.ts +31 -0
- package/lib/types/settings-persist.d.ts +59 -0
- package/lib/types/snapshots.d.ts +46 -0
- package/lib/types/stage-contract.d.ts +58 -0
- package/lib/types/stream-fallback.d.ts +60 -0
- package/lib/types/strip-headings.d.ts +33 -0
- package/lib/types/style-fingerprint.d.ts +78 -0
- package/lib/types/tension.d.ts +53 -0
- package/lib/types/timeline.d.ts +37 -0
- package/package.json +41 -28
- package/assets/styles/arcane-thick-3d.webp +0 -0
- package/assets/styles/chinese-ink.webp +0 -0
- package/assets/styles/clay-stopmotion-3d.webp +0 -0
- package/assets/styles/dark-ghibli.webp +0 -0
- package/assets/styles/dark-gothic-3d.webp +0 -0
- package/assets/styles/film-photo.webp +0 -0
- package/assets/styles/guofeng-heavy.webp +0 -0
- package/assets/styles/guoman-2d-gufeng.webp +0 -0
- package/assets/styles/guoman-3d-tianyuan.webp +0 -0
- package/assets/styles/guoman-3d-xuanhuan.webp +0 -0
- package/assets/styles/horror-game-3d.webp +0 -0
- package/assets/styles/hyperreal-3d.webp +0 -0
- package/assets/styles/japan-cel-dark.webp +0 -0
- package/assets/styles/korean-webtoon.webp +0 -0
- package/assets/styles/low-cyberpunk-3d.webp +0 -0
- package/assets/styles/nextgen-cg.webp +0 -0
- package/assets/styles/noir-film.webp +0 -0
- package/assets/styles/openworld-survival.webp +0 -0
- package/assets/styles/paper-cut-3d.webp +0 -0
- package/assets/styles/pixar-adult-3d.webp +0 -0
- package/assets/styles/pop-marvel-2d.webp +0 -0
- package/assets/styles/sandiao-qban.webp +0 -0
- package/assets/styles/shinkai-anime.webp +0 -0
- package/assets/styles/tactical-stealth.webp +0 -0
- package/assets/styles/urban-lightreal-3d.webp +0 -0
- package/assets/styles/vaporwave-3d.webp +0 -0
- package/assets/styles/vhs90.webp +0 -0
- package/lib/types/client/panel/BookshelfBar.d.ts +0 -11
- package/lib/types/client/panel/FlowGuide.d.ts +0 -22
- package/lib/types/client/panel/MangaRoleLibrary.d.ts +0 -20
- package/lib/types/client/panel/MangaWorkspace.d.ts +0 -12
- package/lib/types/client/panel/ModelPicker.d.ts +0 -11
- package/lib/types/client/panel/ProgressHomeView.d.ts +0 -5
- package/lib/types/client/panel/PropLibrary.d.ts +0 -8
- package/lib/types/client/panel/SceneLibrary.d.ts +0 -16
- package/lib/types/client/panel/StoryboardTab.d.ts +0 -19
- package/lib/types/client/panel/StyleCard.d.ts +0 -8
- package/lib/types/client/panel/StyleGallery.d.ts +0 -1
- package/lib/types/comic-presets.d.ts +0 -12
- package/lib/types/manga-genre-rules.d.ts +0 -22
- package/lib/types/prompt-utils.d.ts +0 -35
- package/lib/types/review-policy.d.ts +0 -97
- package/lib/types/shot-language.d.ts +0 -46
- package/lib/types/src/ai-scan.d.ts +0 -36
- package/lib/types/src/assets.d.ts +0 -37
- package/lib/types/src/assistant.d.ts +0 -45
- package/lib/types/src/author-assets.d.ts +0 -25
- package/lib/types/src/bookshelf.d.ts +0 -42
- package/lib/types/src/client/api.d.ts +0 -234
- package/lib/types/src/client/docx.d.ts +0 -15
- package/lib/types/src/client/index.d.ts +0 -14
- package/lib/types/src/client/locales.d.ts +0 -212
- package/lib/types/src/client/mount.d.ts +0 -9
- package/lib/types/src/client/panel/AdaptModeView.d.ts +0 -5
- package/lib/types/src/client/panel/AssetsTab.d.ts +0 -12
- package/lib/types/src/client/panel/AssistantTab.d.ts +0 -7
- package/lib/types/src/client/panel/AuthorAssetsView.d.ts +0 -4
- package/lib/types/src/client/panel/AuthorHome.d.ts +0 -32
- package/lib/types/src/client/panel/BookshelfBar.d.ts +0 -11
- package/lib/types/src/client/panel/CreateBookView.d.ts +0 -9
- package/lib/types/src/client/panel/FlowGuide.d.ts +0 -22
- package/lib/types/src/client/panel/GlobalAssetLibraryView.d.ts +0 -4
- package/lib/types/src/client/panel/ImportModal.d.ts +0 -7
- package/lib/types/src/client/panel/MangaRoleLibrary.d.ts +0 -20
- package/lib/types/src/client/panel/MangaWorkspace.d.ts +0 -12
- package/lib/types/src/client/panel/ModelManager.d.ts +0 -14
- package/lib/types/src/client/panel/NovelPanel.d.ts +0 -13
- package/lib/types/src/client/panel/ProgressConsole.d.ts +0 -17
- package/lib/types/src/client/panel/ProgressHomeView.d.ts +0 -5
- package/lib/types/src/client/panel/PropLibrary.d.ts +0 -8
- package/lib/types/src/client/panel/ReaderView.d.ts +0 -8
- package/lib/types/src/client/panel/ReasoningSection.d.ts +0 -10
- package/lib/types/src/client/panel/RunPanel.d.ts +0 -5
- package/lib/types/src/client/panel/SceneLibrary.d.ts +0 -16
- package/lib/types/src/client/panel/SettingsView.d.ts +0 -16
- package/lib/types/src/client/panel/ShelfView.d.ts +0 -15
- package/lib/types/src/client/panel/StoryboardTab.d.ts +0 -19
- package/lib/types/src/client/panel/StyleCard.d.ts +0 -8
- package/lib/types/src/client/panel/StyleGallery.d.ts +0 -1
- package/lib/types/src/client/panel/WorldTab.d.ts +0 -10
- package/lib/types/src/client/panel/controller.d.ts +0 -19
- package/lib/types/src/client/panel/helpers.d.ts +0 -18
- package/lib/types/src/client/panel/views.d.ts +0 -77
- package/lib/types/src/client/sidebar-entry.d.ts +0 -13
- package/lib/types/src/client/text.d.ts +0 -9
- package/lib/types/src/comic-presets.d.ts +0 -12
- package/lib/types/src/docx.d.ts +0 -19
- package/lib/types/src/engine.d.ts +0 -402
- package/lib/types/src/index.d.ts +0 -79
- package/lib/types/src/manga-genre-rules.d.ts +0 -22
- package/lib/types/src/novel-context.d.ts +0 -80
- package/lib/types/src/prompt-utils.d.ts +0 -35
- package/lib/types/src/protocol.d.ts +0 -2176
- package/lib/types/src/review-policy.d.ts +0 -97
- package/lib/types/src/routes.d.ts +0 -29
- package/lib/types/src/run.d.ts +0 -32
- package/lib/types/src/shot-language.d.ts +0 -46
- package/lib/types/src/story-beat-language.d.ts +0 -35
- package/lib/types/src/style-library.d.ts +0 -33
- package/lib/types/story-beat-language.d.ts +0 -35
- package/lib/types/style-library.d.ts +0 -33
- package/src/ai-scan.ts +0 -179
- package/src/assets.ts +0 -1774
- package/src/assistant.ts +0 -915
- package/src/author-assets.ts +0 -147
- package/src/bookshelf.ts +0 -167
- package/src/client/api.ts +0 -716
- package/src/client/css-modules.d.ts +0 -8
- package/src/client/docx.ts +0 -69
- package/src/client/index.ts +0 -34
- package/src/client/llmLive.ts +0 -101
- package/src/client/locales.ts +0 -418
- package/src/client/mount.tsx +0 -97
- package/src/client/mount.tsx._new +0 -97
- package/src/client/mount.tsx._nf +0 -97
- package/src/client/mount.tsx._tmp +0 -97
- package/src/client/panel/AdaptModeView.tsx +0 -535
- package/src/client/panel/AssetsTab.tsx +0 -458
- package/src/client/panel/AssistantTab.tsx +0 -339
- package/src/client/panel/AuthorAssetsView.tsx +0 -208
- package/src/client/panel/AuthorHome.tsx +0 -234
- package/src/client/panel/BookAnalysisView.tsx +0 -60
- package/src/client/panel/BookshelfBar.tsx +0 -170
- package/src/client/panel/CreateBookView.tsx +0 -371
- package/src/client/panel/DirectorView.tsx +0 -200
- package/src/client/panel/FlowGuide.tsx +0 -84
- package/src/client/panel/GlobalAssetLibraryView.tsx +0 -172
- package/src/client/panel/IdeaInspirationView.tsx +0 -71
- package/src/client/panel/ImportModal.tsx +0 -303
- package/src/client/panel/KnowledgeBaseView.tsx +0 -73
- package/src/client/panel/LiveFeedLog.tsx +0 -76
- package/src/client/panel/MangaRoleLibrary.tsx +0 -1002
- package/src/client/panel/MangaWorkspace.tsx +0 -715
- package/src/client/panel/MarketRadarView.tsx +0 -374
- package/src/client/panel/ModelManager.tsx +0 -205
- package/src/client/panel/NovelPanel.tsx +0 -4721
- package/src/client/panel/ProgressConsole.tsx +0 -63
- package/src/client/panel/ProgressHomeView.tsx +0 -87
- package/src/client/panel/PropLibrary.tsx +0 -175
- package/src/client/panel/ReaderView.tsx +0 -306
- package/src/client/panel/ReasoningSection.tsx +0 -31
- package/src/client/panel/RunPanel.tsx +0 -204
- package/src/client/panel/SceneLibrary.tsx +0 -453
- package/src/client/panel/SettingsView.tsx +0 -289
- package/src/client/panel/ShelfView.tsx +0 -242
- package/src/client/panel/StoryboardTab.tsx +0 -472
- package/src/client/panel/StyleCard.tsx +0 -90
- package/src/client/panel/StyleGallery.tsx +0 -58
- package/src/client/panel/WorldTab.tsx +0 -202
- package/src/client/panel/controller.ts +0 -45
- package/src/client/panel/helpers.ts +0 -67
- package/src/client/panel/panel.module.css +0 -4359
- package/src/client/panel/views.tsx +0 -314
- package/src/client/sidebar-entry.ts +0 -122
- package/src/client/text.ts +0 -28
- package/src/comic-presets.ts +0 -67
- package/src/docx.ts +0 -83
- package/src/engine.ts +0 -5636
- package/src/global-assets.ts +0 -59
- package/src/index.ts +0 -346
- package/src/llm-live.ts +0 -68
- package/src/manga-genre-rules.ts +0 -87
- package/src/market-radar-scan.ts +0 -41
- package/src/market-radar-sources.ts +0 -173
- package/src/novel-context.ts +0 -287
- package/src/prompt-utils.ts +0 -73
- package/src/prompting.ts +0 -159
- package/src/protocol.ts +0 -2565
- package/src/review-policy.ts +0 -161
- package/src/routes.ts +0 -3939
- package/src/run.ts +0 -338
- package/src/shot-language.ts +0 -181
- package/src/story-beat-language.ts +0 -130
- package/src/style-library.ts +0 -84
package/src/client/mount.tsx
DELETED
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Panel view mounting — mirrors the family plugins: a container appended
|
|
3
|
-
* inside the conversation grid item, hidden while inactive; toggling is a
|
|
4
|
-
* data attribute on <html>, with cross-plugin activation events.
|
|
5
|
-
*/
|
|
6
|
-
import { createRoot, type Root } from 'react-dom/client'
|
|
7
|
-
import type { NovelApi } from './api.ts'
|
|
8
|
-
import type { PanelController } from './panel/controller.ts'
|
|
9
|
-
import { NovelPanel } from './panel/NovelPanel.tsx'
|
|
10
|
-
import css from './panel/panel.module.css'
|
|
11
|
-
|
|
12
|
-
/** The injected panel container. */
|
|
13
|
-
export const PANEL_VIEW_SELECTOR = '[data-dsh-novelforge-view]'
|
|
14
|
-
|
|
15
|
-
const CONVERSATION_COLUMN_SELECTOR = '[data-pane="conversation"], [class*="centerCol"]'
|
|
16
|
-
const ACTIVE_ATTR = 'data-dsh-novelforge-active'
|
|
17
|
-
/** Sibling panels' activation attributes (evicted when this panel opens). */
|
|
18
|
-
const OTHER_ACTIVE_ATTRS = ['data-dsh-taskboard-active', 'data-dsh-ssh-active']
|
|
19
|
-
/** Cross-plugin activation event; detail is the activating panel name. */
|
|
20
|
-
const ACTIVATE_EVENT = 'dsh-panel-activate'
|
|
21
|
-
const PANEL_NAME = 'novelforge'
|
|
22
|
-
|
|
23
|
-
/** Find the center column, or undefined while the frame is not mounted. */
|
|
24
|
-
function conversationColumn(): HTMLElement | undefined {
|
|
25
|
-
return document.querySelector<HTMLElement>(CONVERSATION_COLUMN_SELECTOR) ?? undefined
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Mount the panel React tree into the center column and bind visibility to
|
|
30
|
-
* the controller.
|
|
31
|
-
*/
|
|
32
|
-
export function mountPanel(controller: PanelController, api: NovelApi): () => void {
|
|
33
|
-
let root: Root | undefined
|
|
34
|
-
let container: HTMLDivElement | undefined
|
|
35
|
-
|
|
36
|
-
const ensure = (): void => {
|
|
37
|
-
if (container !== undefined) {
|
|
38
|
-
if (container.isConnected) return
|
|
39
|
-
root?.unmount()
|
|
40
|
-
root = undefined
|
|
41
|
-
container.remove()
|
|
42
|
-
container = undefined
|
|
43
|
-
}
|
|
44
|
-
const column = conversationColumn()
|
|
45
|
-
if (column === undefined) return
|
|
46
|
-
container = document.createElement('div')
|
|
47
|
-
container.dataset.dshNovelforgeView = 'true'
|
|
48
|
-
container.className = css.view
|
|
49
|
-
column.appendChild(container)
|
|
50
|
-
root = createRoot(container)
|
|
51
|
-
root.render(<NovelPanel controller={controller} api={api} />)
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const waitObserver = new MutationObserver(() => { ensure() })
|
|
55
|
-
waitObserver.observe(document.body, { childList: true, subtree: true })
|
|
56
|
-
|
|
57
|
-
const applyActive = (): void => {
|
|
58
|
-
if (controller.getSnapshot().panelOpen) {
|
|
59
|
-
for (const attr of OTHER_ACTIVE_ATTRS) document.documentElement.removeAttribute(attr)
|
|
60
|
-
document.documentElement.setAttribute(ACTIVE_ATTR, '')
|
|
61
|
-
document.dispatchEvent(new CustomEvent(ACTIVATE_EVENT, { detail: PANEL_NAME }))
|
|
62
|
-
} else {
|
|
63
|
-
document.documentElement.removeAttribute(ACTIVE_ATTR)
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
const onOtherActivate = (event: Event): void => {
|
|
67
|
-
const detail = (event as CustomEvent).detail
|
|
68
|
-
if ((detail === 'taskboard' || detail === 'ssh') && controller.getSnapshot().panelOpen) {
|
|
69
|
-
controller.close()
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
// Jump out on sidebar context clicks.
|
|
73
|
-
const SIDEBAR_ROW_SELECTOR = '[class*="sessionRow"], [class*="projectRow"], [class*="searchResultRow"], [class*="searchResultWorkspace"], [class*="newSession"]'
|
|
74
|
-
const onClickSidebarRow = (event: MouseEvent): void => {
|
|
75
|
-
if (!controller.getSnapshot().panelOpen) return
|
|
76
|
-
const target = event.target as HTMLElement | null
|
|
77
|
-
if (target === null) return
|
|
78
|
-
if (target.closest(SIDEBAR_ROW_SELECTOR) !== null) controller.close()
|
|
79
|
-
}
|
|
80
|
-
document.addEventListener('click', onClickSidebarRow, true)
|
|
81
|
-
document.addEventListener(ACTIVATE_EVENT, onOtherActivate)
|
|
82
|
-
const unsubscribe = controller.subscribe(applyActive)
|
|
83
|
-
applyActive()
|
|
84
|
-
ensure()
|
|
85
|
-
|
|
86
|
-
return () => {
|
|
87
|
-
document.removeEventListener('click', onClickSidebarRow, true)
|
|
88
|
-
document.removeEventListener(ACTIVATE_EVENT, onOtherActivate)
|
|
89
|
-
waitObserver.disconnect()
|
|
90
|
-
unsubscribe()
|
|
91
|
-
document.documentElement.removeAttribute(ACTIVE_ATTR)
|
|
92
|
-
root?.unmount()
|
|
93
|
-
root = undefined
|
|
94
|
-
container?.remove()
|
|
95
|
-
container = undefined
|
|
96
|
-
}
|
|
97
|
-
}
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Panel view mounting — mirrors the family plugins: a container appended
|
|
3
|
-
* inside the conversation grid item, hidden while inactive; toggling is a
|
|
4
|
-
* data attribute on <html>, with cross-plugin activation events.
|
|
5
|
-
*/
|
|
6
|
-
import { createRoot, type Root } from 'react-dom/client'
|
|
7
|
-
import type { NovelApi } from './api.ts'
|
|
8
|
-
import type { PanelController } from './panel/controller.ts'
|
|
9
|
-
import { NovelPanel } from './panel/NovelPanel.tsx'
|
|
10
|
-
import css from './panel/panel.module.css'
|
|
11
|
-
|
|
12
|
-
/** The injected panel container. */
|
|
13
|
-
export const PANEL_VIEW_SELECTOR = '[data-dsh-novelforge-view]'
|
|
14
|
-
|
|
15
|
-
const CONVERSATION_COLUMN_SELECTOR = '[data-pane="conversation"], [class*="centerCol"]'
|
|
16
|
-
const ACTIVE_ATTR = 'data-dsh-novelforge-active'
|
|
17
|
-
/** Sibling panels' activation attributes (evicted when this panel opens). */
|
|
18
|
-
const OTHER_ACTIVE_ATTRS = ['data-dsh-taskboard-active', 'data-dsh-ssh-active']
|
|
19
|
-
/** Cross-plugin activation event; detail is the activating panel name. */
|
|
20
|
-
const ACTIVATE_EVENT = 'dsh-panel-activate'
|
|
21
|
-
const PANEL_NAME = 'novelforge'
|
|
22
|
-
|
|
23
|
-
/** Find the center column, or undefined while the frame is not mounted. */
|
|
24
|
-
function conversationColumn(): HTMLElement | undefined {
|
|
25
|
-
return document.querySelector<HTMLElement>(CONVERSATION_COLUMN_SELECTOR) ?? undefined
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Mount the panel React tree into the center column and bind visibility to
|
|
30
|
-
* the controller.
|
|
31
|
-
*/
|
|
32
|
-
export function mountPanel(controller: PanelController, api: NovelApi): () => void {
|
|
33
|
-
let root: Root | undefined
|
|
34
|
-
let container: HTMLDivElement | undefined
|
|
35
|
-
|
|
36
|
-
const ensure = (): void => {
|
|
37
|
-
if (container !== undefined) {
|
|
38
|
-
if (container.isConnected) return
|
|
39
|
-
root?.unmount()
|
|
40
|
-
root = undefined
|
|
41
|
-
container.remove()
|
|
42
|
-
container = undefined
|
|
43
|
-
}
|
|
44
|
-
const column = conversationColumn()
|
|
45
|
-
if (column === undefined) return
|
|
46
|
-
container = document.createElement('div')
|
|
47
|
-
container.dataset.dshNovelforgeView = 'true'
|
|
48
|
-
container.className = css.view
|
|
49
|
-
column.appendChild(container)
|
|
50
|
-
root = createRoot(container)
|
|
51
|
-
root.render(<NovelPanel controller={controller} api={api} />)
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const waitObserver = new MutationObserver(() => { ensure() })
|
|
55
|
-
waitObserver.observe(document.body, { childList: true, subtree: true })
|
|
56
|
-
|
|
57
|
-
const applyActive = (): void => {
|
|
58
|
-
if (controller.getSnapshot().panelOpen) {
|
|
59
|
-
for (const attr of OTHER_ACTIVE_ATTRS) document.documentElement.removeAttribute(attr)
|
|
60
|
-
document.documentElement.setAttribute(ACTIVE_ATTR, '')
|
|
61
|
-
document.dispatchEvent(new CustomEvent(ACTIVATE_EVENT, { detail: PANEL_NAME }))
|
|
62
|
-
} else {
|
|
63
|
-
document.documentElement.removeAttribute(ACTIVE_ATTR)
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
const onOtherActivate = (event: Event): void => {
|
|
67
|
-
const detail = (event as CustomEvent).detail
|
|
68
|
-
if ((detail === 'taskboard' || detail === 'ssh') && controller.getSnapshot().panelOpen) {
|
|
69
|
-
controller.close()
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
// Jump out on sidebar context clicks.
|
|
73
|
-
const SIDEBAR_ROW_SELECTOR = '[class*="sessionRow"], [class*="projectRow"], [class*="searchResultRow"], [class*="searchResultWorkspace"], [class*="newSession"]'
|
|
74
|
-
const onClickSidebarRow = (event: MouseEvent): void => {
|
|
75
|
-
if (!controller.getSnapshot().panelOpen) return
|
|
76
|
-
const target = event.target as HTMLElement | null
|
|
77
|
-
if (target === null) return
|
|
78
|
-
if (target.closest(SIDEBAR_ROW_SELECTOR) !== null) controller.close()
|
|
79
|
-
}
|
|
80
|
-
document.addEventListener('click', onClickSidebarRow, true)
|
|
81
|
-
document.addEventListener(ACTIVATE_EVENT, onOtherActivate)
|
|
82
|
-
const unsubscribe = controller.subscribe(applyActive)
|
|
83
|
-
applyActive()
|
|
84
|
-
ensure()
|
|
85
|
-
|
|
86
|
-
return () => {
|
|
87
|
-
document.removeEventListener('click', onClickSidebarRow, true)
|
|
88
|
-
document.removeEventListener(ACTIVATE_EVENT, onOtherActivate)
|
|
89
|
-
waitObserver.disconnect()
|
|
90
|
-
unsubscribe()
|
|
91
|
-
document.documentElement.removeAttribute(ACTIVE_ATTR)
|
|
92
|
-
root?.unmount()
|
|
93
|
-
root = undefined
|
|
94
|
-
container?.remove()
|
|
95
|
-
container = undefined
|
|
96
|
-
}
|
|
97
|
-
}
|
package/src/client/mount.tsx._nf
DELETED
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Panel view mounting — mirrors the family plugins: a container appended
|
|
3
|
-
* inside the conversation grid item, hidden while inactive; toggling is a
|
|
4
|
-
* data attribute on <html>, with cross-plugin activation events.
|
|
5
|
-
*/
|
|
6
|
-
import { createRoot, type Root } from 'react-dom/client'
|
|
7
|
-
import type { NovelApi } from './api.ts'
|
|
8
|
-
import type { PanelController } from './panel/controller.ts'
|
|
9
|
-
import { NovelPanel } from './panel/NovelPanel.tsx'
|
|
10
|
-
import css from './panel/panel.module.css'
|
|
11
|
-
|
|
12
|
-
/** The injected panel container. */
|
|
13
|
-
export const PANEL_VIEW_SELECTOR = '[data-dsh-novelforge-view]'
|
|
14
|
-
|
|
15
|
-
const CONVERSATION_COLUMN_SELECTOR = '[data-pane="conversation"], [class*="centerCol"]'
|
|
16
|
-
const ACTIVE_ATTR = 'data-dsh-novelforge-active'
|
|
17
|
-
/** Sibling panels' activation attributes (evicted when this panel opens). */
|
|
18
|
-
const OTHER_ACTIVE_ATTRS = ['data-dsh-taskboard-active', 'data-dsh-ssh-active']
|
|
19
|
-
/** Cross-plugin activation event; detail is the activating panel name. */
|
|
20
|
-
const ACTIVATE_EVENT = 'dsh-panel-activate'
|
|
21
|
-
const PANEL_NAME = 'novelforge'
|
|
22
|
-
|
|
23
|
-
/** Find the center column, or undefined while the frame is not mounted. */
|
|
24
|
-
function conversationColumn(): HTMLElement | undefined {
|
|
25
|
-
return document.querySelector<HTMLElement>(CONVERSATION_COLUMN_SELECTOR) ?? undefined
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Mount the panel React tree into the center column and bind visibility to
|
|
30
|
-
* the controller.
|
|
31
|
-
*/
|
|
32
|
-
export function mountPanel(controller: PanelController, api: NovelApi): () => void {
|
|
33
|
-
let root: Root | undefined
|
|
34
|
-
let container: HTMLDivElement | undefined
|
|
35
|
-
|
|
36
|
-
const ensure = (): void => {
|
|
37
|
-
if (container !== undefined) {
|
|
38
|
-
if (container.isConnected) return
|
|
39
|
-
root?.unmount()
|
|
40
|
-
root = undefined
|
|
41
|
-
container.remove()
|
|
42
|
-
container = undefined
|
|
43
|
-
}
|
|
44
|
-
const column = conversationColumn()
|
|
45
|
-
if (column === undefined) return
|
|
46
|
-
container = document.createElement('div')
|
|
47
|
-
container.dataset.dshNovelforgeView = 'true'
|
|
48
|
-
container.className = css.view
|
|
49
|
-
column.appendChild(container)
|
|
50
|
-
root = createRoot(container)
|
|
51
|
-
root.render(<NovelPanel controller={controller} api={api} />)
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const waitObserver = new MutationObserver(() => { ensure() })
|
|
55
|
-
waitObserver.observe(document.body, { childList: true, subtree: true })
|
|
56
|
-
|
|
57
|
-
const applyActive = (): void => {
|
|
58
|
-
if (controller.getSnapshot().panelOpen) {
|
|
59
|
-
for (const attr of OTHER_ACTIVE_ATTRS) document.documentElement.removeAttribute(attr)
|
|
60
|
-
document.documentElement.setAttribute(ACTIVE_ATTR, '')
|
|
61
|
-
document.dispatchEvent(new CustomEvent(ACTIVATE_EVENT, { detail: PANEL_NAME }))
|
|
62
|
-
} else {
|
|
63
|
-
document.documentElement.removeAttribute(ACTIVE_ATTR)
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
const onOtherActivate = (event: Event): void => {
|
|
67
|
-
const detail = (event as CustomEvent).detail
|
|
68
|
-
if ((detail === 'taskboard' || detail === 'ssh') && controller.getSnapshot().panelOpen) {
|
|
69
|
-
controller.close()
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
// Jump out on sidebar context clicks.
|
|
73
|
-
const SIDEBAR_ROW_SELECTOR = '[class*="sessionRow"], [class*="projectRow"], [class*="searchResultRow"], [class*="searchResultWorkspace"], [class*="newSession"]'
|
|
74
|
-
const onClickSidebarRow = (event: MouseEvent): void => {
|
|
75
|
-
if (!controller.getSnapshot().panelOpen) return
|
|
76
|
-
const target = event.target as HTMLElement | null
|
|
77
|
-
if (target === null) return
|
|
78
|
-
if (target.closest(SIDEBAR_ROW_SELECTOR) !== null) controller.close()
|
|
79
|
-
}
|
|
80
|
-
document.addEventListener('click', onClickSidebarRow, true)
|
|
81
|
-
document.addEventListener(ACTIVATE_EVENT, onOtherActivate)
|
|
82
|
-
const unsubscribe = controller.subscribe(applyActive)
|
|
83
|
-
applyActive()
|
|
84
|
-
ensure()
|
|
85
|
-
|
|
86
|
-
return () => {
|
|
87
|
-
document.removeEventListener('click', onClickSidebarRow, true)
|
|
88
|
-
document.removeEventListener(ACTIVATE_EVENT, onOtherActivate)
|
|
89
|
-
waitObserver.disconnect()
|
|
90
|
-
unsubscribe()
|
|
91
|
-
document.documentElement.removeAttribute(ACTIVE_ATTR)
|
|
92
|
-
root?.unmount()
|
|
93
|
-
root = undefined
|
|
94
|
-
container?.remove()
|
|
95
|
-
container = undefined
|
|
96
|
-
}
|
|
97
|
-
}
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Panel view mounting — mirrors the family plugins: a container appended
|
|
3
|
-
* inside the conversation grid item, hidden while inactive; toggling is a
|
|
4
|
-
* data attribute on <html>, with cross-plugin activation events.
|
|
5
|
-
*/
|
|
6
|
-
import { createRoot, type Root } from 'react-dom/client'
|
|
7
|
-
import type { NovelApi } from './api.ts'
|
|
8
|
-
import type { PanelController } from './panel/controller.ts'
|
|
9
|
-
import { NovelPanel } from './panel/NovelPanel.tsx'
|
|
10
|
-
import css from './panel/panel.module.css'
|
|
11
|
-
|
|
12
|
-
/** The injected panel container. */
|
|
13
|
-
export const PANEL_VIEW_SELECTOR = '[data-dsh-novelforge-view]'
|
|
14
|
-
|
|
15
|
-
const CONVERSATION_COLUMN_SELECTOR = '[data-pane="conversation"], [class*="centerCol"]'
|
|
16
|
-
const ACTIVE_ATTR = 'data-dsh-novelforge-active'
|
|
17
|
-
/** Sibling panels' activation attributes (evicted when this panel opens). */
|
|
18
|
-
const OTHER_ACTIVE_ATTRS = ['data-dsh-taskboard-active', 'data-dsh-ssh-active']
|
|
19
|
-
/** Cross-plugin activation event; detail is the activating panel name. */
|
|
20
|
-
const ACTIVATE_EVENT = 'dsh-panel-activate'
|
|
21
|
-
const PANEL_NAME = 'novelforge'
|
|
22
|
-
|
|
23
|
-
/** Find the center column, or undefined while the frame is not mounted. */
|
|
24
|
-
function conversationColumn(): HTMLElement | undefined {
|
|
25
|
-
return document.querySelector<HTMLElement>(CONVERSATION_COLUMN_SELECTOR) ?? undefined
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Mount the panel React tree into the center column and bind visibility to
|
|
30
|
-
* the controller.
|
|
31
|
-
*/
|
|
32
|
-
export function mountPanel(controller: PanelController, api: NovelApi): () => void {
|
|
33
|
-
let root: Root | undefined
|
|
34
|
-
let container: HTMLDivElement | undefined
|
|
35
|
-
|
|
36
|
-
const ensure = (): void => {
|
|
37
|
-
if (container !== undefined) {
|
|
38
|
-
if (container.isConnected) return
|
|
39
|
-
root?.unmount()
|
|
40
|
-
root = undefined
|
|
41
|
-
container.remove()
|
|
42
|
-
container = undefined
|
|
43
|
-
}
|
|
44
|
-
const column = conversationColumn()
|
|
45
|
-
if (column === undefined) return
|
|
46
|
-
container = document.createElement('div')
|
|
47
|
-
container.dataset.dshNovelforgeView = 'true'
|
|
48
|
-
container.className = css.view
|
|
49
|
-
column.appendChild(container)
|
|
50
|
-
root = createRoot(container)
|
|
51
|
-
root.render(<NovelPanel controller={controller} api={api} />)
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const waitObserver = new MutationObserver(() => { ensure() })
|
|
55
|
-
waitObserver.observe(document.body, { childList: true, subtree: true })
|
|
56
|
-
|
|
57
|
-
const applyActive = (): void => {
|
|
58
|
-
if (controller.getSnapshot().panelOpen) {
|
|
59
|
-
for (const attr of OTHER_ACTIVE_ATTRS) document.documentElement.removeAttribute(attr)
|
|
60
|
-
document.documentElement.setAttribute(ACTIVE_ATTR, '')
|
|
61
|
-
document.dispatchEvent(new CustomEvent(ACTIVATE_EVENT, { detail: PANEL_NAME }))
|
|
62
|
-
} else {
|
|
63
|
-
document.documentElement.removeAttribute(ACTIVE_ATTR)
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
const onOtherActivate = (event: Event): void => {
|
|
67
|
-
const detail = (event as CustomEvent).detail
|
|
68
|
-
if ((detail === 'taskboard' || detail === 'ssh') && controller.getSnapshot().panelOpen) {
|
|
69
|
-
controller.close()
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
// Jump out on sidebar context clicks.
|
|
73
|
-
const SIDEBAR_ROW_SELECTOR = '[class*="sessionRow"], [class*="projectRow"], [class*="searchResultRow"], [class*="searchResultWorkspace"], [class*="newSession"]'
|
|
74
|
-
const onClickSidebarRow = (event: MouseEvent): void => {
|
|
75
|
-
if (!controller.getSnapshot().panelOpen) return
|
|
76
|
-
const target = event.target as HTMLElement | null
|
|
77
|
-
if (target === null) return
|
|
78
|
-
if (target.closest(SIDEBAR_ROW_SELECTOR) !== null) controller.close()
|
|
79
|
-
}
|
|
80
|
-
document.addEventListener('click', onClickSidebarRow, true)
|
|
81
|
-
document.addEventListener(ACTIVATE_EVENT, onOtherActivate)
|
|
82
|
-
const unsubscribe = controller.subscribe(applyActive)
|
|
83
|
-
applyActive()
|
|
84
|
-
ensure()
|
|
85
|
-
|
|
86
|
-
return () => {
|
|
87
|
-
document.removeEventListener('click', onClickSidebarRow, true)
|
|
88
|
-
document.removeEventListener(ACTIVATE_EVENT, onOtherActivate)
|
|
89
|
-
waitObserver.disconnect()
|
|
90
|
-
unsubscribe()
|
|
91
|
-
document.documentElement.removeAttribute(ACTIVE_ATTR)
|
|
92
|
-
root?.unmount()
|
|
93
|
-
root = undefined
|
|
94
|
-
container?.remove()
|
|
95
|
-
container = undefined
|
|
96
|
-
}
|
|
97
|
-
}
|