Skip to content
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
12 changes: 12 additions & 0 deletions electron/main.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -221,9 +221,18 @@ function sendToRenderer(channel, data) {
}

function createWindow() {
const iconPath = app.isPackaged
? path.join(__dirname, '../dist/tech_stack_streamdeck.png')
: path.join(__dirname, '../public/tech_stack_streamdeck.png')

mainWindow = new BrowserWindow({
width: 1280,
height: 800,
minWidth: 960,
minHeight: 640,
title: 'Tech Stack Studios - Streamdeck',
maximizable: false,
icon: iconPath,
autoHideMenuBar: true,
backgroundColor: '#1a1a1a',
webPreferences: {
Expand All @@ -245,6 +254,9 @@ function createWindow() {
mainWindow = null
})

// Prevent the HTML page title from overriding the window title
mainWindow.on('page-title-updated', e => { e.preventDefault() })

// Hide to tray on close unless a real quit was requested
mainWindow.on('close', e => {
if (!isQuitting) { e.preventDefault(); mainWindow.hide(); console.log('[App] Window hidden to tray') }
Expand Down
68 changes: 65 additions & 3 deletions src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -286,11 +286,69 @@
user-select: text;
}

/* ─── Help / Documentation menu ─────────────────────────── */
.help-menu-wrapper {
position: relative;
}

.icon-btn.active {
background: #252525;
color: #bbb;
}

.help-menu {
position: absolute;
top: calc(100% + 6px);
right: 0;
min-width: 200px;
background: #252525;
border: 1px solid #333;
border-radius: 8px;
padding: 6px 4px;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.6);
z-index: 200;
}

.help-menu-section-label {
padding: 4px 10px 6px;
font-size: 11px;
font-weight: 600;
color: #555;
letter-spacing: 0.06em;
text-transform: uppercase;
}

.help-menu-item {
display: flex;
align-items: center;
gap: 8px;
width: 100%;
padding: 8px 10px;
border-radius: 5px;
background: none;
border: none;
color: #e0e0e0;
font-size: 13px;
cursor: pointer;
transition: background 0.1s;
text-align: left;
}

.help-menu-item:hover {
background: #303030;
}

.help-menu-item svg {
flex-shrink: 0;
color: #666;
}

/* ─── Workspace ──────────────────────────────────────────── */
.workspace {
display: flex;
flex: 1;
overflow: hidden;
position: relative;
}

/* ─── Actions panel ──────────────────────────────────────── */
Expand Down Expand Up @@ -724,18 +782,22 @@

/* ─── Properties panel ───────────────────────────────────── */
.properties-panel {
position: absolute;
right: 0;
top: 0;
bottom: 0;
width: 280px;
flex-shrink: 0;
background: #1c1c1c;
border-left: 1px solid #262626;
display: flex;
flex-direction: column;
animation: panel-in 0.14s ease;
z-index: 10;
animation: panel-in 0.18s ease;
}

@keyframes panel-in {
from {
transform: translateX(16px);
transform: translateX(100%);
opacity: 0;
}
to {
Expand Down
63 changes: 57 additions & 6 deletions src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -1462,6 +1462,62 @@ function PluginInspector({ action, onChange, pluginManifests = [] }) {
)
}

// ─── Help / Documentation menu ──────────────────────────────
const HELP_LINKS = [
{ label: 'User Manual', url: 'https://github.com/FritzBlignaut/tech-stack-streamdeck/wiki/User-Manual' },
{ label: 'Installation Guide', url: 'https://github.com/FritzBlignaut/tech-stack-streamdeck/wiki/Installation-Guide' },
{ label: 'Release Notes', url: 'https://github.com/FritzBlignaut/tech-stack-streamdeck/releases' },
]

function HelpMenu() {
const [open, setOpen] = useState(false)
const ref = useRef(null)

useEffect(() => {
if (!open) return
const handler = (e) => {
if (ref.current && !ref.current.contains(e.target)) setOpen(false)
}
document.addEventListener('mousedown', handler)
return () => document.removeEventListener('mousedown', handler)
}, [open])

return (
<div className="help-menu-wrapper" ref={ref}>
<button
className={`icon-btn${open ? ' active' : ''}`}
title="Help &amp; Documentation"
onClick={() => setOpen(o => !o)}
>
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5">
<circle cx="8" cy="8" r="2.5" />
<path d="M8 1.5v1.8M8 12.7v1.8M1.5 8h1.8M12.7 8h1.8M3.4 3.4l1.27 1.27M11.33 11.33l1.27 1.27M3.4 12.6l1.27-1.27M11.33 4.67l1.27-1.27" />
</svg>
</button>

{open && (
<div className="help-menu">
<div className="help-menu-section-label">Documentation</div>
{HELP_LINKS.map(({ label, url }) => (
<button
key={url}
className="help-menu-item"
onClick={() => { window.streamDeck?.openUrl(url); setOpen(false) }}
>
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.4" width="14" height="14">
<path d="M3 3h5v1.5H4.5v7h7V9H13v3.5a1 1 0 0 1-1 1H3.5a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1z" />
<path d="M9 2.5h4.5V7" strokeLinecap="round" strokeLinejoin="round" />
<path d="M13.5 2.5L8 8" strokeLinecap="round" />
</svg>
{label}
</button>
))}
</div>
)}
</div>
)
}

function PropertiesPanel({ keyIndex, onClose, config, onChange, iconSize, profiles, pageCount, onEnterFolder, pluginManifests = [] }) {
const fileInputRef = useRef(null)
const pressedFileInputRef = useRef(null)
Expand Down Expand Up @@ -2606,12 +2662,7 @@ export default function App() {
</svg>
</button>

<button className="icon-btn" title="Settings">
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5">
<circle cx="8" cy="8" r="2.5" />
<path d="M8 1.5v1.8M8 12.7v1.8M1.5 8h1.8M12.7 8h1.8M3.4 3.4l1.27 1.27M11.33 11.33l1.27 1.27M3.4 12.6l1.27-1.27M11.33 4.67l1.27-1.27" />
</svg>
</button>
<HelpMenu />
{appVersion && <span className="app-version">v{appVersion}-{__GIT_HASH__}</span>}
</div>
</header>
Expand Down