put the settings in the panel header

They were floating buttons over the top-right of the iframe, which was wrong
twice: they sit on top of Gitea's own controls, and an overlay on an
application that fills its whole panel is invisible until you already know it
is there. Reported as "I have no access to settings when the iframe is loaded",
which is exactly right.

The header is the platform's own furniture — always present, never competing
with the content underneath — and it is where photos and jellyfin put theirs.
It also names where you are, so /gitea/connection reads as "Gitea —
connection" rather than looking like the frame failed to load.
This commit is contained in:
officer
2026-08-19 10:11:47 +00:00
parent 921427c7a2
commit bf27793b44
3 changed files with 55 additions and 20 deletions
+2 -19
View File
@@ -1,8 +1,7 @@
import { useEffect, useState } from 'react';
import { Link, useParams } from 'react-router';
import { ExternalLink, Loader2, Plug, TriangleAlert } from 'lucide-react';
import { useParams } from 'react-router';
import { Loader2, TriangleAlert } from 'lucide-react';
import { useClient } from 'hooks/useClient';
import { Button } from '@/components/ui/button';
import { GiteaConnection, type ConnectionState } from './GiteaConnection';
// Gitea's own web interface, rendered in place.
@@ -99,22 +98,6 @@ export const GiteaFrame = () => {
{/* The escape hatch, and it is not an admission of defeat: the whole point of proxying an app that
already has a UI is that its own UI stays available. Anything the frame handles badly, this
opens properly. */}
<div className="absolute right-3 top-3 z-10 flex gap-1.5 opacity-60 transition-opacity hover:opacity-100">
{/* A real link, not a button: it is navigation, and it should be cmd-clickable like any other. */}
<Button size="sm" variant="outline" asChild title="Connection settings">
<Link to="/gitea/connection">
<Plug className="h-3.5 w-3.5" />
</Link>
</Button>
<Button
size="sm"
variant="outline"
onClick={() => window.open(FRAME_SRC, '_blank', 'noopener')}
title="Open Gitea in a new tab"
>
<ExternalLink className="h-3.5 w-3.5" />
</Button>
</div>
<iframe
src={FRAME_SRC}
title="Gitea"
+41
View File
@@ -0,0 +1,41 @@
import { Link, useParams } from 'react-router';
import { ExternalLink, GitBranch, Plug } from 'lucide-react';
// The panel header, which is where the settings live.
//
// They were floating buttons over the top-right of the iframe first, and that was wrong twice: they sit
// on top of Gitea's own controls, and an overlay on an application that fills its panel is invisible
// until you already know it is there. The header is the platform's own furniture — always present, never
// competing with the content underneath.
const FRAME_SRC = '/api/gitea/_web/';
export const GiteaViewHeader = () => {
const { section } = useParams();
const onConnection = section === 'connection';
return (
<>
<GitBranch className="h-3.5 w-3.5 shrink-0" />
<span className="flex-1 truncate text-xs font-medium">{onConnection ? 'Gitea — connection' : 'Gitea'}</span>
{/* Real links, so they are cmd-clickable like any other navigation. */}
<Link
to={onConnection ? '/gitea' : '/gitea/connection'}
title={onConnection ? 'Back to Gitea' : 'Connection settings'}
className="rounded p-1 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground"
>
<Plug className="h-3.5 w-3.5" />
</Link>
<a
href={FRAME_SRC}
target="_blank"
rel="noopener"
title="Open Gitea in a new tab"
className="rounded p-1 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground"
>
<ExternalLink className="h-3.5 w-3.5" />
</a>
</>
);
};
+12 -1
View File
@@ -1,11 +1,22 @@
import type { AppRegistryMeta } from 'officerdev';
import { GitBranch } from 'lucide-react';
import { GiteaFrame } from './GiteaFrame';
import { GiteaViewHeader } from './GiteaViewHeader';
// ONE panel, where the old screen had seventeen files behind two.
//
// There is no nav panel because Gitea has its own, inside the frame. A second navigation beside it would
// be two things claiming to say where you are, and the one that could not actually move you.
export const appRegistryMetas: AppRegistryMeta[] = [
{ key: 'gitea-frame', name: 'Gitea', icon: GitBranch, component: GiteaFrame, availableOnPanel: false },
{
key: 'gitea-frame',
name: 'Gitea',
icon: GitBranch,
component: GiteaFrame,
// The settings live in the HEADER, not floating over the frame: an overlay on an application that
// fills its own panel sits on top of that application's controls, and is invisible until you already
// know it is there.
header: GiteaViewHeader,
availableOnPanel: false,
},
];