@@ -678,7 +678,7 @@ function OpenAppEditor({ target, mode, onChange }) {
678678}
679679
680680// ─── Sub-Action Row ─────────────────────────────────────────
681- function SubActionRow ( { subAction, onChange, onRemove } ) {
681+ function SubActionRow ( { subAction, onChange, onRemove, pageCount = 1 } ) {
682682 const label = SUB_ACTION_TYPES . find ( t => t . id === subAction . type ) ?. name ?? subAction . type
683683 return (
684684 < div className = "sub-action-row" >
@@ -737,6 +737,21 @@ function SubActionRow({ subAction, onChange, onRemove }) {
737737 < span className = "delay-unit" > ms</ span >
738738 </ div >
739739 ) }
740+ { subAction . type === 'page-switcher' && (
741+ < div className = "delay-input-row" >
742+ < label className = "prop-label" > Page</ label >
743+ < input
744+ className = "prop-input"
745+ type = "number"
746+ min = "1"
747+ max = { pageCount }
748+ step = "1"
749+ value = { ( subAction . targetPage ?? 0 ) + 1 }
750+ onChange = { e => onChange ( { ...subAction , targetPage : Math . max ( 0 , Math . min ( pageCount - 1 , Number ( e . target . value ) - 1 ) ) } ) }
751+ />
752+ < span className = "delay-unit" > / { pageCount } </ span >
753+ </ div >
754+ ) }
740755 { subAction . type === 'sleep-toggle' && (
741756 < p className = "action-hint" > Puts the deck to sleep.</ p >
742757 ) }
@@ -746,7 +761,7 @@ function SubActionRow({ subAction, onChange, onRemove }) {
746761}
747762
748763// ─── Multi Action Editor ─────────────────────────────────────
749- function MultiActionEditor ( { actions, onChange } ) {
764+ function MultiActionEditor ( { actions, onChange, pageCount = 1 } ) {
750765 const [ addingNew , setAddingNew ] = useState ( false )
751766
752767 const addSubAction = ( type ) => {
@@ -772,6 +787,7 @@ function MultiActionEditor({ actions, onChange }) {
772787 subAction = { sub }
773788 onChange = { updated => updateAt ( i , updated ) }
774789 onRemove = { ( ) => removeAt ( i ) }
790+ pageCount = { pageCount }
775791 />
776792 ) ) }
777793
@@ -802,21 +818,23 @@ const ENABLED_ACTIONS = new Set(['hotkey', 'open-app', 'open-url', 'run-cmd', 's
802818
803819// Sub-action types available inside a Multi Action (no nesting)
804820const SUB_ACTION_TYPES = [
805- { id : 'hotkey' , name : 'Hotkey' , icon : '⌫' } ,
806- { id : 'open-app' , name : 'Open Application' , icon : '⎈' } ,
807- { id : 'open-url' , name : 'Open URL' , icon : '⊕' } ,
808- { id : 'run-cmd' , name : 'Run Command' , icon : '›_' } ,
809- { id : 'sleep-toggle' , name : 'Sleep' , icon : '☽' } ,
810- { id : 'delay' , name : 'Delay' , icon : '⏱' } ,
821+ { id : 'hotkey' , name : 'Hotkey' , icon : '⌫' } ,
822+ { id : 'open-app' , name : 'Open Application' , icon : '⎈' } ,
823+ { id : 'open-url' , name : 'Open URL' , icon : '⊕' } ,
824+ { id : 'run-cmd' , name : 'Run Command' , icon : '›_' } ,
825+ { id : 'page-switcher' , name : 'Page' , icon : '⊞' } ,
826+ { id : 'sleep-toggle' , name : 'Sleep' , icon : '☽' } ,
827+ { id : 'delay' , name : 'Delay' , icon : '⏱' } ,
811828]
812829
813830const SUB_ACTION_DEFAULTS = {
814- 'hotkey' : { type : 'hotkey' , keys : '' } ,
815- 'open-app' : { type : 'open-app' , target : '' , mode : 'gtk-launch' } ,
816- 'open-url' : { type : 'open-url' , url : '' } ,
817- 'run-cmd' : { type : 'run-cmd' , command : '' } ,
818- 'sleep-toggle' : { type : 'sleep-toggle' } ,
819- 'delay' : { type : 'delay' , ms : 500 } ,
831+ 'hotkey' : { type : 'hotkey' , keys : '' } ,
832+ 'open-app' : { type : 'open-app' , target : '' , mode : 'gtk-launch' } ,
833+ 'open-url' : { type : 'open-url' , url : '' } ,
834+ 'run-cmd' : { type : 'run-cmd' , command : '' } ,
835+ 'page-switcher' : { type : 'page-switcher' , targetPage : 0 } ,
836+ 'sleep-toggle' : { type : 'sleep-toggle' } ,
837+ 'delay' : { type : 'delay' , ms : 500 } ,
820838}
821839
822840// Default configs for top-level button actions (used by drag-and-drop and the picker)
@@ -856,14 +874,15 @@ const ACTION_DEFAULTS = {
856874}
857875
858876// Dispatches a single leaf action — returns a Promise
859- function dispatchSubAction ( sd , act ) {
877+ function dispatchSubAction ( sd , act , switchToPage ) {
860878 if ( ! act || ! sd ) return Promise . resolve ( )
861- if ( act . type === 'hotkey' && act . keys ) return sd . executeHotkey ( act . keys )
862- if ( act . type === 'open-app' && act . target ) return sd . openApplication ( act . target , act . mode ?? 'gtk-launch' )
863- if ( act . type === 'open-url' && act . url ) return sd . openUrl ( act . url )
864- if ( act . type === 'run-cmd' && act . command ) return sd . runCommand ( act . command )
865- if ( act . type === 'sleep-toggle' ) return sd . sleepToggle ( )
866- if ( act . type === 'delay' ) return new Promise ( r => setTimeout ( r , act . ms ?? 500 ) )
879+ if ( act . type === 'hotkey' && act . keys ) return sd . executeHotkey ( act . keys )
880+ if ( act . type === 'open-app' && act . target ) return sd . openApplication ( act . target , act . mode ?? 'gtk-launch' )
881+ if ( act . type === 'open-url' && act . url ) return sd . openUrl ( act . url )
882+ if ( act . type === 'run-cmd' && act . command ) return sd . runCommand ( act . command )
883+ if ( act . type === 'page-switcher' && switchToPage ) { switchToPage ( act . targetPage ?? 0 ) ; return Promise . resolve ( ) }
884+ if ( act . type === 'sleep-toggle' ) return sd . sleepToggle ( )
885+ if ( act . type === 'delay' ) return new Promise ( r => setTimeout ( r , act . ms ?? 500 ) )
867886 return Promise . resolve ( )
868887}
869888
@@ -1123,6 +1142,7 @@ export function ActionSection({ action, onChange, profiles = [], pageCount = 1,
11231142 < MultiActionEditor
11241143 actions = { action . actions ?? [ ] }
11251144 onChange = { actions => onChange ( { action : { type : 'multi-action' , actions } } ) }
1145+ pageCount = { pageCount }
11261146 />
11271147 </ div >
11281148 )
@@ -2952,9 +2972,10 @@ export default function App() {
29522972 exitFolderRef . current ( )
29532973 } else if ( action ?. type === 'multi-action' && action . actions ?. length ) {
29542974 const sd = window . streamDeck
2975+ const switchFn = switchToPageRef . current
29552976 ; ( async ( ) => {
29562977 for ( const sub of action . actions ) {
2957- await dispatchSubAction ( sd , sub )
2978+ await dispatchSubAction ( sd , sub , switchFn )
29582979 }
29592980 } ) ( )
29602981 } else if ( action ?. type === 'volume' && action . operation && action . operation !== 'display-only' ) {
0 commit comments