diff --git a/package-lock.json b/package-lock.json
index a3edbab4..5ae411b3 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "imwald",
- "version": "22.5.1",
+ "version": "22.5.2",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "imwald",
- "version": "22.5.1",
+ "version": "22.5.2",
"license": "MIT",
"dependencies": {
"@asciidoctor/core": "^3.0.4",
diff --git a/package.json b/package.json
index 07655b3c..4a7e0ceb 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "imwald",
- "version": "22.5.1",
+ "version": "22.5.2",
"description": "Imwald — a user-friendly Nostr client focused on relay feed browsing, publications, and relay discovery",
"private": true,
"type": "module",
diff --git a/src/components/ConnectedRelays/ActiveRelaysTitlebarButton.tsx b/src/components/ConnectedRelays/ActiveRelaysTitlebarButton.tsx
index 6741c0b8..5962b316 100644
--- a/src/components/ConnectedRelays/ActiveRelaysTitlebarButton.tsx
+++ b/src/components/ConnectedRelays/ActiveRelaysTitlebarButton.tsx
@@ -1,4 +1,4 @@
-import { useSecondaryPage } from '@/PageManager'
+import { useSmartRelayNavigation } from '@/PageManager'
import { Button } from '@/components/ui/button'
import { Drawer, DrawerContent, DrawerHeader, DrawerTitle, DrawerOverlay } from '@/components/ui/drawer'
import {
@@ -42,7 +42,7 @@ function rowTitle(
export function ActiveRelaysTitlebarButton() {
const { t } = useTranslation()
const { isSmallScreen } = useScreenSize()
- const { push } = useSecondaryPage()
+ const { navigateToRelay } = useSmartRelayNavigation()
const { rows, connectedCount } = useRelayConnectionRows()
const [drawerOpen, setDrawerOpen] = useState(false)
@@ -94,7 +94,7 @@ export function ActiveRelaysTitlebarButton() {
title={rowTitle(url, connected, sessionStriked, t)}
onClick={() => {
setDrawerOpen(false)
- setTimeout(() => push(toRelay(url)), 50)
+ setTimeout(() => navigateToRelay(toRelay(url)), 50)
}}
>
@@ -118,7 +118,7 @@ export function ActiveRelaysTitlebarButton() {
push(toRelay(url))}
+ onClick={() => navigateToRelay(toRelay(url))}
className={cn('min-w-52 gap-2', rowClass(connected, sessionStriked))}
>
diff --git a/src/components/ConnectedRelays/ConnectedRelaysSidebarStrip.tsx b/src/components/ConnectedRelays/ConnectedRelaysSidebarStrip.tsx
index feb846f9..68e917d9 100644
--- a/src/components/ConnectedRelays/ConnectedRelaysSidebarStrip.tsx
+++ b/src/components/ConnectedRelays/ConnectedRelaysSidebarStrip.tsx
@@ -1,4 +1,4 @@
-import { useSecondaryPage } from '@/PageManager'
+import { useSmartRelayNavigation } from '@/PageManager'
import { Button } from '@/components/ui/button'
import {
DropdownMenu,
@@ -42,7 +42,7 @@ function rowTitle(
*/
export function ConnectedRelaysSidebarStrip({ className }: { className?: string }) {
const { t } = useTranslation()
- const { push } = useSecondaryPage()
+ const { navigateToRelay } = useSmartRelayNavigation()
const { rows } = useRelayConnectionRows()
const shown = rows.slice(0, MAX_ICONS)
const overflowRows = rows.slice(MAX_ICONS)
@@ -64,13 +64,21 @@ export function ConnectedRelaysSidebarStrip({ className }: { className?: string
{shown.map(({ url, connected, sessionStriked }) => (
-
navigateToRelay(toRelay(url))}
>
-
+
))}
{overflow > 0 ? (
@@ -96,7 +104,7 @@ export function ConnectedRelaysSidebarStrip({ className }: { className?: string
key={url}
className={cn('min-w-0 gap-2', rowMenuClass(connected, sessionStriked))}
title={rowTitle(url, connected, sessionStriked, t)}
- onClick={() => push(toRelay(url))}
+ onClick={() => navigateToRelay(toRelay(url))}
>
{simplifyUrl(url)}
diff --git a/src/components/YoutubeEmbeddedPlayer/index.tsx b/src/components/YoutubeEmbeddedPlayer/index.tsx
index aefb4466..32631c7f 100644
--- a/src/components/YoutubeEmbeddedPlayer/index.tsx
+++ b/src/components/YoutubeEmbeddedPlayer/index.tsx
@@ -33,8 +33,15 @@ export default function YoutubeEmbeddedPlayer({
}, [autoLoadMedia])
const showEmbed = mustLoad || autoLoadMedia || userClickedLoad
- /** Packaged app uses `file:`; YT’s JS API often errors there; a plain embed iframe works. */
- const useNativeEmbed = isImwaldElectron()
+ /**
+ * Electron + dev server (http/https): use the same YT Iframe API as the browser — plain `/embed/` iframes often
+ * show error 150 (player configuration) in Electron while the API path works.
+ * Packaged app loads `file:`; keep a plain iframe there and pass a stable `origin` so YouTube accepts the embed.
+ */
+ const useNativeEmbed =
+ isImwaldElectron() &&
+ typeof window !== 'undefined' &&
+ window.location.protocol === 'file:'
const posterUrl = useMemo(
() => (videoId ? `https://i.ytimg.com/vi/${videoId}/hqdefault.jpg` : undefined),
@@ -119,7 +126,14 @@ export default function YoutubeEmbeddedPlayer({
}
if (useNativeEmbed && videoId) {
- const embedSrc = `https://www.youtube.com/embed/${encodeURIComponent(videoId)}?playsinline=1&rel=0`
+ // `file:` has no usable origin for YT; use the canonical web app origin (matches typical production URL).
+ const embedParams = new URLSearchParams({
+ playsinline: '1',
+ rel: '0',
+ enablejsapi: '1',
+ origin: 'https://jumble.imwald.eu'
+ })
+ const embedSrc = `https://www.youtube.com/embed/${encodeURIComponent(videoId)}?${embedParams}`
return (
{title && (
- <>
-
-
- Imwald
-
-
-
- >
+
)}
{children}
@@ -119,16 +111,13 @@ const SecondaryPageLayout = forwardRef(
{title && (
- <>
-
-
- >
+
)}