@@ -312,8 +312,12 @@ class EventFlowEditor {
312312 if ( typeof chrome !== 'undefined' && chrome . runtime && typeof chrome . runtime . getURL === 'function' ) {
313313 target = chrome . runtime . getURL ( target ) ;
314314 }
315- try {
316- window . open ( target , '_blank' ) ;
315+ try {
316+ if ( window . location . href . includes ( "/actions/" ) ) {
317+ window . open ( target . replace ( "actions/" , "" ) , '_blank' ) ;
318+ } else {
319+ window . open ( target , '_blank' ) ;
320+ }
317321 } catch ( error ) {
318322 console . error ( 'Failed to open guide' , error ) ;
319323 }
@@ -1458,69 +1462,83 @@ class EventFlowEditor {
14581462 // Determine if we should test just this flow or all flows
14591463 const testAllActiveFlows = document . getElementById ( 'test-all-active-flows' ) . checked ;
14601464
1461- if ( testAllActiveFlows ) {
1462- // Test against all active flows in the system
1463- this . eventFlowSystem . processMessage ( testMessage )
1464- . then ( result => {
1465- testResult = {
1466- success : true ,
1467- message : result ? 'Message was processed successfully' : 'Message was blocked' ,
1468- result : result
1469- } ;
1470- this . displayTestResults ( testResult ) ;
1471- } ) ;
1472- } else {
1473- // Just test the flow using the real eventFlowSystem with temporarily modified flows
1474- // Save the current flows
1475- const originalFlows = this . eventFlowSystem . flows ;
1465+ if ( testAllActiveFlows ) {
1466+ // Test against all active flows in the system
1467+ this . eventFlowSystem . processMessage ( testMessage )
1468+ . then ( result => {
1469+ testResult = {
1470+ success : true ,
1471+ message : result ? 'Message was processed successfully' : 'Message was blocked' ,
1472+ result : result
1473+ } ;
1474+ this . displayTestResults ( testResult , testMessage ) ;
1475+ } ) ;
1476+ } else {
1477+ // Just test the flow using the real eventFlowSystem with temporarily modified flows
1478+ // Save the current flows
1479+ const originalFlows = this . eventFlowSystem . flows ;
14761480
14771481 // Temporarily set just this flow for testing
14781482 this . eventFlowSystem . flows = [ testFlow ] ;
14791483
14801484 // Process the message through just this flow
1481- this . eventFlowSystem . evaluateFlow ( testFlow , testMessage )
1482- . then ( result => {
1483- // Restore the original flows
1484- this . eventFlowSystem . flows = originalFlows ;
1485-
1486- testResult = {
1487- success : true ,
1488- message : result . blocked ? 'Message was blocked by this flow' :
1489- result . modified ? 'Message was modified by this flow' :
1490- 'Flow triggered but no actions affected the message' ,
1491- result : result
1492- } ;
1493- this . displayTestResults ( testResult ) ;
1494- } )
1495- . catch ( error => {
1496- // Restore the original flows even on error
1497- this . eventFlowSystem . flows = originalFlows ;
1498-
1499- testResult = {
1500- success : false ,
1501- message : 'Error testing flow: ' + error . message ,
1502- error : error
1503- } ;
1504- this . displayTestResults ( testResult ) ;
1505- } ) ;
1506- }
1485+ this . eventFlowSystem . evaluateFlow ( testFlow , testMessage )
1486+ . then ( result => {
1487+ // Restore the original flows
1488+ this . eventFlowSystem . flows = originalFlows ;
1489+
1490+ testResult = {
1491+ success : true ,
1492+ message : result . blocked ? 'Message was blocked by this flow' :
1493+ result . modified ? 'Message was modified by this flow' :
1494+ 'Flow triggered but no actions affected the message' ,
1495+ result : result
1496+ } ;
1497+ this . displayTestResults ( testResult , testMessage ) ;
1498+ } )
1499+ . catch ( error => {
1500+ // Restore the original flows even on error
1501+ this . eventFlowSystem . flows = originalFlows ;
1502+
1503+ testResult = {
1504+ success : false ,
1505+ message : 'Error testing flow: ' + error . message ,
1506+ error : error
1507+ } ;
1508+ this . displayTestResults ( testResult , testMessage ) ;
1509+ } ) ;
1510+ }
15071511
15081512 return testResult ;
15091513 }
15101514
15111515 initTestPanel ( ) {
1512- const testOverlay = document . getElementById ( 'test-overlay' ) ;
1513- const testPanel = document . getElementById ( 'test-panel' ) ;
1514- const openTestBtn = document . getElementById ( 'open-test-panel' ) ;
1515- const closeTestBtn = document . getElementById ( 'close-test-btn' ) ;
1516- const runTestBtn = document . getElementById ( 'run-test-btn' ) ;
1517- const donationCheckbox = document . getElementById ( 'test-donation' ) ;
1518- const donationAmountField = document . getElementById ( 'donation-amount' ) ;
1516+ const testOverlay = document . getElementById ( 'test-overlay' ) ;
1517+ const testPanel = document . getElementById ( 'test-panel' ) ;
1518+ const openTestBtn = document . getElementById ( 'open-test-panel' ) ;
1519+ const closeTestBtn = document . getElementById ( 'close-test-btn' ) ;
1520+ const runTestBtn = document . getElementById ( 'run-test-btn' ) ;
1521+ const donationCheckbox = document . getElementById ( 'test-donation' ) ;
1522+ const donationAmountField = document . getElementById ( 'donation-amount' ) ;
1523+ const firstTimeCheckbox = document . getElementById ( 'test-firsttime' ) ;
1524+ const lastActivityToggle = document . getElementById ( 'test-lastactivity' ) ;
1525+ const lastActivityControls = document . getElementById ( 'lastactivity-controls' ) ;
1526+ const lastActivityValue = document . getElementById ( 'test-lastactivity-value' ) ;
1527+ const lastActivityUnit = document . getElementById ( 'test-lastactivity-unit' ) ;
15191528
15201529 // Show/hide donation amount field based on checkbox
1521- donationCheckbox . addEventListener ( 'change' , function ( ) {
1522- donationAmountField . style . display = this . checked ? 'block' : 'none' ;
1523- } ) ;
1530+ donationCheckbox . addEventListener ( 'change' , function ( ) {
1531+ donationAmountField . style . display = this . checked ? 'block' : 'none' ;
1532+ } ) ;
1533+
1534+ // Toggle last-activity inputs
1535+ if ( lastActivityToggle ) {
1536+ lastActivityToggle . addEventListener ( 'change' , function ( ) {
1537+ if ( lastActivityControls ) {
1538+ lastActivityControls . style . display = this . checked ? 'block' : 'none' ;
1539+ }
1540+ } ) ;
1541+ }
15241542
15251543 // Open test panel
15261544 openTestBtn . addEventListener ( 'click' , function ( ) {
@@ -1540,46 +1558,62 @@ class EventFlowEditor {
15401558 testPanel . style . display = 'none' ;
15411559 } ) ;
15421560
1543- // Run test
1544- runTestBtn . addEventListener ( 'click' , ( ) => {
1545- // Show warning if flow has unsaved changes
1546- document . getElementById ( 'unsaved-flow-warning' ) . style . display =
1547- this . unsavedChanges ? 'block' : 'none' ;
1561+ // Run test
1562+ runTestBtn . addEventListener ( 'click' , ( ) => {
1563+ // Show warning if flow has unsaved changes
1564+ document . getElementById ( 'unsaved-flow-warning' ) . style . display =
1565+ this . unsavedChanges ? 'block' : 'none' ;
15481566
15491567 // Create test message from form inputs
1550- const testMessage = {
1551- type : document . getElementById ( 'test-source' ) . value ,
1552- chatname : document . getElementById ( 'test-username' ) . value ,
1553- userid : document . getElementById ( 'test-username' ) . value . toLowerCase ( ) ,
1554- chatmessage : document . getElementById ( 'test-message' ) . value ,
1555- mod : document . getElementById ( 'test-mod' ) . checked ,
1556- vip : document . getElementById ( 'test-vip' ) . checked ,
1557- admin : document . getElementById ( 'test-admin' ) . checked ,
1558- hasDonation : document . getElementById ( 'test-donation' ) . checked ,
1559- // Add other required properties
1560- timestamp : Date . now ( ) ,
1561- } ;
1562-
1563- // Add donation amount if donation checkbox is checked
1564- if ( testMessage . hasDonation ) {
1565- testMessage . donationAmount = document . getElementById ( 'test-donation-amount' ) . value ;
1566- }
1567-
1568- // Run the test
1569- this . runTestFlow ( testMessage ) ;
1570- } ) ;
1571- }
1572-
1573- displayTestResults ( testResult ) {
1574- const resultsEl = document . getElementById ( 'test-results' ) ;
1575- if ( ! resultsEl ) return ;
1568+ const testMessage = {
1569+ type : document . getElementById ( 'test-source' ) . value ,
1570+ chatname : document . getElementById ( 'test-username' ) . value ,
1571+ userid : document . getElementById ( 'test-username' ) . value . toLowerCase ( ) ,
1572+ chatmessage : document . getElementById ( 'test-message' ) . value ,
1573+ mod : document . getElementById ( 'test-mod' ) . checked ,
1574+ vip : document . getElementById ( 'test-vip' ) . checked ,
1575+ admin : document . getElementById ( 'test-admin' ) . checked ,
1576+ hasDonation : document . getElementById ( 'test-donation' ) . checked ,
1577+ // Add other required properties
1578+ timestamp : Date . now ( ) ,
1579+ } ;
1580+
1581+ // Apply first-time chatter flag
1582+ if ( firstTimeCheckbox ?. checked ) {
1583+ testMessage . firsttime = true ;
1584+ }
1585+
1586+ // Apply last-activity timestamp if requested
1587+ if ( lastActivityToggle ?. checked ) {
1588+ const amount = Math . max ( 0 , parseFloat ( lastActivityValue ?. value ) || 0 ) ;
1589+ const unit = lastActivityUnit ?. value || 'minutes' ;
1590+ const unitMap = { minutes : 60 * 1000 , hours : 60 * 60 * 1000 , days : 24 * 60 * 60 * 1000 } ;
1591+ const windowMs = unitMap [ unit ] || unitMap . minutes ;
1592+ const ts = Math . max ( 0 , Date . now ( ) - ( amount * windowMs ) ) ;
1593+ testMessage . lastactivity = ts ;
1594+ testMessage . lastActivity = ts ; // support either casing
1595+ }
1596+
1597+ // Add donation amount if donation checkbox is checked
1598+ if ( testMessage . hasDonation ) {
1599+ testMessage . donationAmount = document . getElementById ( 'test-donation-amount' ) . value ;
1600+ }
1601+
1602+ // Run the test
1603+ this . runTestFlow ( testMessage ) ;
1604+ } ) ;
1605+ }
1606+
1607+ displayTestResults ( testResult , originalMessage = { } ) {
1608+ const resultsEl = document . getElementById ( 'test-results' ) ;
1609+ if ( ! resultsEl ) return ;
15761610
15771611 let html = `<h4>Test Results</h4>` ;
15781612
15791613 if ( ! testResult . success ) {
15801614 html += `<p class="test-error">${ testResult . message } </p>` ;
1581- } else {
1582- const result = testResult . result ;
1615+ } else {
1616+ const result = testResult . result ;
15831617
15841618 if ( result === null ) {
15851619 html += `<p class="test-blocked">Message was BLOCKED by a flow.</p>` ;
@@ -1594,10 +1628,10 @@ class EventFlowEditor {
15941628 ` ;
15951629
15961630 // Show any properties that were modified
1597- const originalKeys = Object . keys ( testMessage ) ;
1598- const modifiedKeys = Object . keys ( result . message ) . filter ( key =>
1599- ! originalKeys . includes ( key ) || result . message [ key ] !== testMessage [ key ]
1600- ) ;
1631+ const originalKeys = Object . keys ( originalMessage || { } ) ;
1632+ const modifiedKeys = Object . keys ( result . message || { } ) . filter ( key =>
1633+ ! originalKeys . includes ( key ) || result . message [ key ] !== originalMessage [ key ]
1634+ ) ;
16011635
16021636 if ( modifiedKeys . length > 0 ) {
16031637 html += `<div class="test-result-detail"><strong>Modified Properties:</strong><ul>` ;
@@ -1612,7 +1646,7 @@ class EventFlowEditor {
16121646 }
16131647
16141648 resultsEl . innerHTML = html ;
1615- }
1649+ }
16161650
16171651 createNode ( type , subtype , x , y ) {
16181652 const id = `node_${ Date . now ( ) } _${ Math . floor ( Math . random ( ) * 1000 ) } ` ;
0 commit comments