Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Preset text type #2846

Merged
merged 3 commits into from
Apr 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 80 additions & 63 deletions companion/lib/Instance/Definitions.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ class InstanceDefinitions extends CoreBase {

client.onPromise('presets:preview_render', async (connectionId, presetId) => {
const definition = this.#presetDefinitions[connectionId]?.[presetId]
if (definition) {
if (definition && definition.type === 'button') {
const style = {
...(definition.previewStyle ? definition.previewStyle : definition.style),
style: definition.type,
Expand Down Expand Up @@ -306,7 +306,7 @@ class InstanceDefinitions extends CoreBase {
*/
importPresetToLocation(connectionId, presetId, location) {
const definition = this.#presetDefinitions[connectionId]?.[presetId]
if (!definition) return false
if (!definition || definition.type !== 'button') return false

/** @type {import('@companion-app/shared/Model/ButtonModel.js').NormalButtonModel} */
const result = {
Expand Down Expand Up @@ -442,55 +442,59 @@ class InstanceDefinitions extends CoreBase {

for (const [id, rawPreset] of Object.entries(rawPresets)) {
try {
newPresets[id] = {
id: id,
category: rawPreset.category,
name: rawPreset.name,
type: rawPreset.type,
style: rawPreset.style,
previewStyle: rawPreset.previewStyle,
options: rawPreset.options,
feedbacks: (rawPreset.feedbacks ?? []).map((fb) => ({
type: fb.feedbackId,
options: fb.options,
style: fb.style,
isInverted: !!fb.isInverted,
})),
steps: rawPreset.steps.map((step) => {
const options = cloneDeep(ControlButtonNormal.DefaultStepOptions)
/** @type {PresetActionSets} */
const action_sets = {
down: [],
up: [],
}

for (const [setId, set] of Object.entries(step)) {
/** @type {import('@companion-module/base').CompanionPresetAction[]} */
const setActions = Array.isArray(set) ? set : set.actions
if (!isNaN(Number(setId)) && set.options?.runWhileHeld) options.runWhileHeld.push(Number(setId))

// @ts-ignore
action_sets[setId] = setActions.map((act) => ({
action: act.actionId,
options: act.options,
delay: act.delay,
}))
}

return {
options,
action_sets,
}
}),
}

if (!newPresets[id].steps.length) {
newPresets[id].steps.push({
action_sets: {
down: [],
up: [],
},
})
if (rawPreset.type === 'button') {
newPresets[id] = {
id: id,
category: rawPreset.category,
name: rawPreset.name,
type: rawPreset.type,
style: rawPreset.style,
previewStyle: rawPreset.previewStyle,
options: rawPreset.options,
feedbacks: (rawPreset.feedbacks ?? []).map((fb) => ({
type: fb.feedbackId,
options: fb.options,
style: fb.style,
isInverted: !!fb.isInverted,
})),
steps:
rawPreset.steps.length === 0
? [{ action_sets: { down: [], up: [] } }]
: rawPreset.steps.map((step) => {
const options = cloneDeep(ControlButtonNormal.DefaultStepOptions)
/** @type {PresetActionSets} */
const action_sets = {
down: [],
up: [],
}

for (const [setId, set] of Object.entries(step)) {
/** @type {import('@companion-module/base').CompanionPresetAction[]} */
const setActions = Array.isArray(set) ? set : set.actions
if (!isNaN(Number(setId)) && set.options?.runWhileHeld) options.runWhileHeld.push(Number(setId))

// @ts-ignore
action_sets[setId] = setActions.map((act) => ({
action: act.actionId,
options: act.options,
delay: act.delay,
}))
}

return {
options,
action_sets,
}
}),
}
} else if (rawPreset.type === 'text') {
newPresets[id] = {
id: id,
category: rawPreset.category,
name: rawPreset.name,
type: rawPreset.type,
text: rawPreset.text,
}
}
} catch (e) {
this.logger.warn(`${label} gave invalid preset "${id}": ${e}`)
Expand All @@ -510,10 +514,21 @@ class InstanceDefinitions extends CoreBase {
const res = {}

for (const [id, preset] of Object.entries(presets)) {
res[id] = {
id: preset.id,
label: preset.name,
category: preset.category,
if (preset.type === 'button') {
res[id] = {
id: preset.id,
label: preset.name,
category: preset.category,
type: 'button',
}
} else if (preset.type === 'text') {
res[id] = {
id: preset.id,
label: preset.name,
category: preset.category,
type: 'text',
text: preset.text,
}
}
}

Expand Down Expand Up @@ -574,14 +589,16 @@ class InstanceDefinitions extends CoreBase {
* demand that your presets MUST be dynamically generated.
*/
for (const preset of Object.values(presets)) {
if (preset.style) {
preset.style.text = replaceAllVariables(preset.style.text)
}
if (preset.type !== 'text') {
if (preset.style) {
preset.style.text = replaceAllVariables(preset.style.text)
}

if (preset.feedbacks) {
for (const feedback of preset.feedbacks) {
if (feedback.style && feedback.style.text) {
feedback.style.text = replaceAllVariables(feedback.style.text)
if (preset.feedbacks) {
for (const feedback of preset.feedbacks) {
if (feedback.style && feedback.style.text) {
feedback.style.text = replaceAllVariables(feedback.style.text)
}
}
}
}
Expand Down Expand Up @@ -623,7 +640,7 @@ export default InstanceDefinitions
/**
* @typedef {{
* id: string
* } & import('@companion-module/base').CompanionButtonPresetDefinition} PresetDefinitionTmp
* } & import('@companion-module/base').CompanionPresetDefinition} PresetDefinitionTmp
*/

/**
Expand Down
25 changes: 23 additions & 2 deletions shared-lib/lib/Model/Presets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ export interface PresetActionSteps {
action_sets: PresetActionSets
}

export interface PresetDefinition {
export type PresetDefinition = PresetDefinitionButton | PresetDefinitionText

export interface PresetDefinitionButton {
id: string
name: string
category: string
Expand All @@ -41,8 +43,27 @@ export interface PresetDefinition {
steps: PresetActionSteps[]
}

export interface UIPresetDefinition {
export interface PresetDefinitionText {
id: string
name: string
category: string
type: 'text'
text: string
}

export type UIPresetDefinition = UIPresetDefinitionButton | UIPresetDefinitionText

export interface UIPresetDefinitionButton {
id: string
label: string
category: string
type: 'button'
}

export interface UIPresetDefinitionText {
id: string
label: string
category: string
type: 'text'
text: string
}
27 changes: 23 additions & 4 deletions webui/src/Buttons/Presets.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { useDrag } from 'react-dnd'
import { ButtonPreviewBase, RedImage } from '../Components/ButtonPreview.js'
import { nanoid } from 'nanoid'
import type { ClientConnectionConfig } from '@companion-app/shared/Model/Common.js'
import type { UIPresetDefinition } from '@companion-app/shared/Model/Presets.js'
import type { UIPresetDefinition, UIPresetDefinitionText } from '@companion-app/shared/Model/Presets.js'
import type { Operation as JsonPatchOperation } from 'fast-json-patch'
import { RootAppStoreContext } from '../Stores/RootAppStore.js'
import { observer } from 'mobx-react-lite'
Expand Down Expand Up @@ -47,6 +47,7 @@ export const InstancePresets = observer(function InstancePresets({ resetToken }:

socketEmitPromise(socket, 'presets:subscribe', [])
.then((data) => {
console.log('presets:subscribe', data)
setPresetsMap(data)
})
.catch((e) => {
Expand Down Expand Up @@ -247,16 +248,34 @@ function PresetsButtonList({
<p>Drag and drop the preset buttons below into your buttons-configuration.</p>

{filteredPresets.map((preset, i) => {
return (
<PresetIconPreview key={i} connectionId={selectedConnectionId} presetId={preset.id} title={preset.label} />
)
if (preset.type === 'button') {
return (
<PresetIconPreview key={i} connectionId={selectedConnectionId} presetId={preset.id} title={preset.label} />
)
} else if (preset.type === 'text') {
return <PresetText key={i} preset={preset} />
}
return null
})}

<br style={{ clear: 'both' }} />
</div>
)
}

interface PresetTextProps {
preset: UIPresetDefinitionText
}

function PresetText({ preset }: PresetTextProps) {
return (
<div>
<h5>{preset.label}</h5>
<p>{preset.text}</p>
</div>
)
}

interface PresetIconPreviewProps {
connectionId: string
presetId: string
Expand Down