From a5a3a802ebced89827cd71965d7858e0d29aa779 Mon Sep 17 00:00:00 2001 From: Houssem Eddine BENABDALLAH Date: Tue, 27 Oct 2026 12:00:49 +0100 Subject: [PATCH 1/2] fix: show go live as its own button on your profile --- .../js/components/profile-actions-menu.tsx | 64 ------------------- .../js/components/profile-live-button.tsx | 53 +++++++++++++++ resources/js/pages/user/show.tsx | 4 +- tests/Unit/ProfileLiveButton.test.tsx | 25 ++++++++ 4 files changed, 80 insertions(+), 66 deletions(-) delete mode 100644 resources/js/components/profile-actions-menu.tsx create mode 100644 resources/js/components/profile-live-button.tsx create mode 100644 tests/Unit/ProfileLiveButton.test.tsx diff --git a/resources/js/components/profile-actions-menu.tsx b/resources/js/components/profile-actions-menu.tsx deleted file mode 100644 index ec2515e42..000000000 --- a/resources/js/components/profile-actions-menu.tsx +++ /dev/null @@ -1,64 +0,0 @@ -import { Ellipsis, Radio, RadioOff } from 'lucide-react'; -import { useState } from 'react'; -import { endStream, GoLiveDialog } from '@/components/go-live-dialog'; -import { Button } from '@/components/ui/button'; -import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuTrigger, -} from '@/components/ui/dropdown-menu'; -import type { User } from '@/types'; - -/** - * The quick actions on your own profile, where other people's profiles have the mute and block menu. - */ -export function ProfileActionsMenu({ user }: { user: Pick }) { - const [isGoingLive, setIsGoingLive] = useState(false); - const [isEnding, setIsEnding] = useState(false); - - return ( - <> - - - - - - {user.live ? ( - - endStream({ - onStart: () => setIsEnding(true), - onFinish: () => setIsEnding(false), - }) - } - data-test="end-stream" - > - - End stream - - ) : ( - setIsGoingLive(true)} - data-test="go-live" - > - - Go live - - )} - - - - - - ); -} diff --git a/resources/js/components/profile-live-button.tsx b/resources/js/components/profile-live-button.tsx new file mode 100644 index 000000000..a33ab9c28 --- /dev/null +++ b/resources/js/components/profile-live-button.tsx @@ -0,0 +1,53 @@ +import { Radio, RadioOff } from 'lucide-react'; +import { useState } from 'react'; +import { endStream, GoLiveDialog } from '@/components/go-live-dialog'; +import { Button } from '@/components/ui/button'; +import type { User } from '@/types'; + +/** + * Going live, or ending the stream, from your own profile, where other people's profiles have the mute and block menu. + */ +export function ProfileLiveButton({ user }: { user: Pick }) { + const [isGoingLive, setIsGoingLive] = useState(false); + const [isEnding, setIsEnding] = useState(false); + + return ( + <> + {user.live ? ( + + ) : ( + + )} + + + + ); +} diff --git a/resources/js/pages/user/show.tsx b/resources/js/pages/user/show.tsx index df299334b..8cfc27760 100644 --- a/resources/js/pages/user/show.tsx +++ b/resources/js/pages/user/show.tsx @@ -31,7 +31,7 @@ import { import { LocalTime } from '@/components/local-time'; import { PageTabs } from '@/components/page-tabs'; import { PinCommitButton } from '@/components/pin-commit-button'; -import { ProfileActionsMenu } from '@/components/profile-actions-menu'; +import { ProfileLiveButton } from '@/components/profile-live-button'; import { ProfileReadme } from '@/components/profile-readme'; import { ProfileShareButton } from '@/components/profile-share-button'; import { Button } from '@/components/ui/button'; @@ -175,7 +175,7 @@ export default function Show({ /> {isCurrentUser ? ( <> - + ) : ( diff --git a/tests/Unit/ProfileLiveButton.test.tsx b/tests/Unit/ProfileLiveButton.test.tsx new file mode 100644 index 000000000..af257c1ec --- /dev/null +++ b/tests/Unit/ProfileLiveButton.test.tsx @@ -0,0 +1,25 @@ +/// +import assert from 'node:assert/strict'; +import { renderToStaticMarkup } from 'react-dom/server'; +import { test } from 'vite-plus/test'; +import { ProfileLiveButton } from '../../resources/js/components/profile-live-button'; + +test('offers going live straight from your own profile instead of a menu with one item', () => { + const html = renderToStaticMarkup( + , + ); + + assert.match(html, /]*aria-label="Go live"/); + assert.doesNotMatch(html, /aria-haspopup|More options/); +}); + +test('offers ending the stream while you are live', () => { + const html = renderToStaticMarkup( + , + ); + + assert.match(html, /]*aria-label="End stream"/); + assert.doesNotMatch(html, /aria-label="Go live"/); +}); From bfcb3e9ef49447b1f1e45d86eb254c019830834c Mon Sep 17 00:00:00 2001 From: Houssem Eddine BENABDALLAH Date: Wed, 28 Oct 2026 22:37:39 +0100 Subject: [PATCH 2/2] docs: point the knowledge base to the go live button --- KNOWLEDGE_BASE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/KNOWLEDGE_BASE.md b/KNOWLEDGE_BASE.md index a7b1914e5..9291d4c06 100644 --- a/KNOWLEDGE_BASE.md +++ b/KNOWLEDGE_BASE.md @@ -121,7 +121,7 @@ Share a stream you are running from the **…** menu on your own profile: **Go l **End stream** in the same menu stops it at once; otherwise it stops showing when the chosen time runs out, and the scheduler clears it within five minutes. Only the platform, the link, and the end time are stored, and they are included in your export. -Sources: [go-live menu](resources/js/components/profile-actions-menu.tsx), [live avatar and card](resources/js/components/live-stream-card.tsx), [validation](app/Http/Requests/UpdateUserLiveRequest.php), [YouTube links](app/Services/LivePlatforms/YouTube.php), [Twitch links](app/Services/LivePlatforms/Twitch.php), [ending streams](app/Jobs/EndLiveStreams.php). +Sources: [go-live button](resources/js/components/profile-live-button.tsx), [live avatar and card](resources/js/components/live-stream-card.tsx), [validation](app/Http/Requests/UpdateUserLiveRequest.php), [YouTube links](app/Services/LivePlatforms/YouTube.php), [Twitch links](app/Services/LivePlatforms/Twitch.php), [ending streams](app/Jobs/EndLiveStreams.php). ### Achievement badges and XP