Skip to content

Commit

Permalink
wip: fixup showing module help
Browse files Browse the repository at this point in the history
  • Loading branch information
Julusian committed Dec 15, 2024
1 parent 63802cd commit a484ec8
Show file tree
Hide file tree
Showing 23 changed files with 208 additions and 230 deletions.
7 changes: 4 additions & 3 deletions companion/lib/Instance/ModuleInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { ModuleVersionInfo } from './Types.js'
import semver from 'semver'
import { compact } from 'lodash-es'
import { isModuleApiVersionCompatible } from '@companion-app/shared/ModuleApiVersionCheck.js'
import { getHelpPathForInstalledModule } from './ModuleScanner.js'

/**
* Information about a module
Expand Down Expand Up @@ -68,14 +69,14 @@ function translateStableVersion(version: ModuleVersionInfo | null): ClientModule
displayName: 'Dev',
isLegacy: false,
isBeta: false,
hasHelp: version.helpPath !== null,
helpPath: getHelpPathForInstalledModule(version.manifest.id, version.versionId),
versionId: 'dev',
}
} else {
return {
displayName: `Latest ${version.isBeta ? 'Beta' : 'Stable'} (v${version.versionId})`,
isLegacy: version.isLegacy,
hasHelp: version.helpPath !== null,
helpPath: getHelpPathForInstalledModule(version.manifest.id, version.versionId),
isBeta: version.isBeta,
versionId: version.versionId,
}
Expand All @@ -87,7 +88,7 @@ function translateReleaseVersion(version: ModuleVersionInfo): ClientModuleVersio
displayName: `v${version.versionId}`,
isLegacy: version.isLegacy,
isBeta: version.isBeta,
hasHelp: version.helpPath !== null,
helpPath: getHelpPathForInstalledModule(version.manifest.id, version.versionId),
versionId: version.versionId,
}
}
6 changes: 5 additions & 1 deletion companion/lib/Instance/ModuleScanner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export class InstanceModuleScanner {
id: manifestJson.id,
name: manifestJson.manufacturer + ': ' + manifestJson.products.join('; '),
// version: manifestJson.version,
// hasHelp: hasHelp,
helpPath: getHelpPathForInstalledModule(manifestJson.id, manifestJson.version),
bugUrl: manifestJson.bugs || manifestJson.repository,
shortname: manifestJson.shortname,
manufacturer: manifestJson.manufacturer,
Expand Down Expand Up @@ -100,3 +100,7 @@ export class InstanceModuleScanner {
}
}
}

export function getHelpPathForInstalledModule(moduleId: string, versionId: string) {
return `/int/help/module/${moduleId}/${versionId}/HELP.md`
}
3 changes: 3 additions & 0 deletions companion/lib/Instance/ModuleStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ export class ModuleStoreService {

storeUrl: data.storeUrl,
githubUrl: data.githubUrl ?? null,
helpUrl: data.latestHelpUrl,

deprecationReason: data.deprecationReason ?? null,
} satisfies Complete<ModuleStoreListCacheEntry>, // Match what the on disk scanner generates
Expand Down Expand Up @@ -268,6 +269,8 @@ export class ModuleStoreService {
deprecationReason: data.deprecationReason ?? null,

apiVersion: data.apiVersion,

helpUrl: data.helpUrl,
}) satisfies Complete<ModuleStoreModuleInfoVersion>
),
}
Expand Down
47 changes: 5 additions & 42 deletions companion/lib/Instance/Modules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,13 @@
*
*/

import fs from 'fs-extra'
import path from 'path'
import { cloneDeep } from 'lodash-es'
import { InstanceModuleScanner } from './ModuleScanner.js'
import type express from 'express'
import { type ModuleManifest } from '@companion-module/base'
import type { ClientModuleInfo } from '@companion-app/shared/Model/ModuleInfo.js'
import type { ClientSocket, UIHandler } from '../UI/Handler.js'
import type { HelpDescription } from '@companion-app/shared/Model/Common.js'
import LogController from '../Log/Controller.js'
import type { InstanceController } from './Controller.js'
import jsonPatch from 'fast-json-patch'
Expand Down Expand Up @@ -314,8 +312,6 @@ export class InstanceModules {
client.onPromise('modules:unsubscribe', () => {
client.leave(ModulesRoom)
})

client.onPromise('connections:get-help', this.#getHelpForModule)
}

/**
Expand Down Expand Up @@ -348,41 +344,6 @@ export class InstanceModules {
return this.#knownModules.has(moduleId)
}

/**
* Load the help markdown file for a specified moduleId
*/
#getHelpForModule = async (
moduleId: string,
versionId: string | null
): Promise<[err: string, result: null] | [err: null, result: HelpDescription]> => {
try {
const moduleInfo = this.#knownModules.get(moduleId)?.getVersion(versionId)
if (moduleInfo && moduleInfo.helpPath) {
const stats = await fs.stat(moduleInfo.helpPath)
if (stats.isFile()) {
const data = await fs.readFile(moduleInfo.helpPath)
return [
null,
{
markdown: data.toString(),
baseUrl: `/int/help/module/${moduleId}/${versionId ?? 'current'}`,
},
]
} else {
this.#logger.silly(`Error loading help for ${moduleId}`, moduleInfo.helpPath)
this.#logger.silly('Not a file')
return ['nofile', null]
}
} else {
return ['nofile', null]
}
} catch (err) {
this.#logger.silly(`Error loading help for ${moduleId}`)
this.#logger.silly(err)
return ['nofile', null]
}
}

/**
* Return a module help asset over http
*/
Expand All @@ -397,10 +358,12 @@ export class InstanceModules {

const moduleInfo = this.#knownModules.get(moduleId)?.getVersion(versionId)
if (moduleInfo && moduleInfo.helpPath && moduleInfo.basePath) {
const fullpath = path.join(moduleInfo.basePath, 'companion', file)
if (file.match(/\.(jpe?g|gif|png|pdf|companionconfig)$/) && fs.existsSync(fullpath)) {
const basePath = path.join(moduleInfo.basePath, 'companion')
if (file.match(/\.(jpe?g|gif|png|pdf|companionconfig|md)$/)) {
// Send the file, then stop
res.sendFile(fullpath)
res.sendFile(file, {
root: basePath, // This is needed to prevent path traversal, and because this could be inside a dotfile
})
return
}
}
Expand Down
5 changes: 0 additions & 5 deletions shared-lib/lib/Model/Common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,6 @@ export interface WrappedImage {
isUsed: boolean
}

export interface HelpDescription {
markdown: string
baseUrl: string
}

export interface ClientEditConnectionConfig {
fields: Array<ExtendedInputField & { width: number }>
config: unknown
Expand Down
4 changes: 2 additions & 2 deletions shared-lib/lib/Model/ModuleInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { Operation as JsonPatchOperation } from 'fast-json-patch'
export interface ModuleDisplayInfo {
id: string
name: string
// hasHelp: boolean
helpPath: string
bugUrl: string
shortname: string
manufacturer: string
Expand All @@ -15,7 +15,7 @@ export interface ClientModuleVersionInfo {
displayName: string
isLegacy: boolean
isBeta: boolean
hasHelp: boolean
helpPath: string
versionId: string
}

Expand Down
7 changes: 3 additions & 4 deletions shared-lib/lib/Model/ModulesStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@ export interface ModuleStoreListCacheEntry {

deprecationReason: string | null

helpUrl: string

// description: string | null

// licenseSPDX: string
// isPaid

// Platform support?
// Has compatible version?

// TODO - more props
}

export interface ModuleStoreModuleInfoStore {
Expand All @@ -37,7 +37,6 @@ export interface ModuleStoreModuleInfoStore {
lastUpdateAttempt: number
updateWarning: string | null

// TODO
versions: ModuleStoreModuleInfoVersion[]
}
export interface ModuleStoreModuleInfoVersion {
Expand All @@ -51,5 +50,5 @@ export interface ModuleStoreModuleInfoVersion {

apiVersion: string

// TODO - more props
helpUrl: string
}
2 changes: 2 additions & 0 deletions shared-lib/lib/OpenApi/ModuleStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ export interface components {
storeUrl: string
/** @description Url to the module source code */
githubUrl?: string
latestHelpUrl: string
/** @description Reason for deprecation (if deprecated) */
deprecationReason?: string
}
Expand All @@ -127,6 +128,7 @@ export interface components {
apiVersion: string
/** @description Reason for deprecation (if deprecated) */
deprecationReason?: string
helpUrl: string
}
}
responses: never
Expand Down
5 changes: 0 additions & 5 deletions shared-lib/lib/SocketIO.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import type {
EmulatorConfig,
EmulatorImage,
EmulatorImageCache,
HelpDescription,
WrappedImage,
} from './Model/Common.js'
import type {
Expand Down Expand Up @@ -332,10 +331,6 @@ export interface ClientToBackendEventsMap {
'connections:set-order': (sortedIds: string[]) => void
'connections:delete': (connectionId: string) => void
'connections:get-statuses': () => Record<string, ConnectionStatusEntry>
'connections:get-help': (
id: string,
versionId: string | null
) => [err: string, result: null] | [err: null, result: HelpDescription]
'modules:install-all-missing': () => void
'modules:install-module-tar': (moduleTar: Uint8Array) => string | null
'modules:install-store-module': (moduleId: string, versionId: string) => string | null
Expand Down
39 changes: 24 additions & 15 deletions webui/src/Connections/AddConnectionModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,28 +15,25 @@ import { PreventDefaultHandler, socketEmitPromise } from '../util.js'
import { RootAppStoreContext } from '../Stores/RootAppStore.js'
import { observer } from 'mobx-react-lite'
import { CModalExt } from '../Components/CModalExt.js'
import { ClientModuleVersionInfo } from '@companion-app/shared/Model/ModuleInfo.js'
import { makeLabelSafe } from '@companion-app/shared/Label.js'
import { ClientConnectionConfig } from '@companion-app/shared/Model/Connections.js'
import { useConnectionVersionSelectOptions } from './ConnectionEditPanel.js'
import { ModuleVersionsRefresh } from './ModuleVersionsRefresh.js'
import type { FuzzyProduct } from '../Hooks/useFilteredProducts.js'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faQuestionCircle } from '@fortawesome/free-solid-svg-icons'

export interface AddConnectionModalRef {
show(info: FuzzyProduct): void
}

interface AddConnectionModalProps {
doConfigureConnection: (connectionId: string) => void
showHelp: (moduleId: string, moduleVersion: ClientModuleVersionInfo) => void
}

export const AddConnectionModal = observer(
forwardRef<AddConnectionModalRef, AddConnectionModalProps>(function AddActionsModal(
{ doConfigureConnection, showHelp },
ref
) {
const { socket, notifier, connections, modules } = useContext(RootAppStoreContext)
forwardRef<AddConnectionModalRef, AddConnectionModalProps>(function AddActionsModal({ doConfigureConnection }, ref) {
const { socket, helpViewer, notifier, connections, modules } = useContext(RootAppStoreContext)

const [show, setShow] = useState(false)
const [moduleInfo, setModuleInfo] = useState<FuzzyProduct | null>(null)
Expand Down Expand Up @@ -114,8 +111,16 @@ export const AddConnectionModal = observer(
})
}, [versionChoices, defaultVersionId])

const selectedVersionIsLegacy =
moduleInfo?.installedInfo?.installedVersions.find((v) => v.versionId === selectedVersion)?.isLegacy ?? false
const selectedVersionInfo =
selectedVersion === 'dev'
? moduleInfo?.installedInfo?.devVersion
: moduleInfo?.installedInfo?.installedVersions.find((v) => v.versionId === selectedVersion)
const selectedVersionIsLegacy = selectedVersionInfo?.isLegacy ?? false

const showHelpClick = useCallback(() => {
if (!moduleInfo || !selectedVersionInfo) return
helpViewer.current?.showFromUrl(moduleInfo.id, selectedVersionInfo.versionId, selectedVersionInfo.helpPath)
}, [helpViewer, moduleInfo?.id, selectedVersionInfo])

return (
<CModalExt visible={show} onClose={doClose} onClosed={onClosed} scrollable={true}>
Expand Down Expand Up @@ -146,11 +151,11 @@ export const AddConnectionModal = observer(

<CFormLabel htmlFor="colFormVersion" className="col-sm-4 col-form-label col-form-label-sm">
Module Version&nbsp;
{/* {moduleVersion?.hasHelp && (
<div className="float_right" onClick={() => showHelp(moduleInfo.id, moduleVersion)}>
{moduleInfo && selectedVersionInfo && (
<div className="float_right" onClick={showHelpClick}>
<FontAwesomeIcon icon={faQuestionCircle} />
</div>
)} */}
)}
{isModuleOnStore && <ModuleVersionsRefresh moduleId={moduleInfo.id} />}
</CFormLabel>
<CCol sm={8}>
Expand Down Expand Up @@ -179,9 +184,13 @@ export const AddConnectionModal = observer(
</p>
<p>
If this module is broken, please let the module author know on{' '}
<a target="_blank" rel="noreferrer" href={moduleInfo.bugUrl}>
Github
</a>
{moduleInfo.bugUrl ? (
<a target="_blank" rel="noreferrer" href={moduleInfo.bugUrl}>
Github
</a>
) : (
'Github'
)}
</p>
</CAlert>
</>
Expand Down
Loading

0 comments on commit a484ec8

Please sign in to comment.