Skip to content

Commit

Permalink
Merge pull request #894 from marcelhillesheim/feature/streaming-tutorial
Browse files Browse the repository at this point in the history
FE: streaming: added tutorial
  • Loading branch information
FlorianSW authored Feb 2, 2025
2 parents 82ebfbf + 07d6ee0 commit f88038a
Show file tree
Hide file tree
Showing 4 changed files with 149 additions and 6 deletions.
17 changes: 17 additions & 0 deletions rcongui_public/src/i18n/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,23 @@
"weekday": "Weekday"
},
"streaming": {
"streamerView": "Streamer View",
"tutorial": {
"title": "Tutorial",
"introduction": "This is a tool for people, who want to stream Hell Let Loose.",
"stepByStep": "Here is a step-by-step guide to integrate the scrolling banner into your stream:",
"openOBS": "open OBS",
"createSource": "Add source -> Browser -> Create",
"enterFollowingValues": "Enter the following values",
"url": "URL",
"width": "Width",
"height": "Height",
"customCSS": "Custom CSS (optional)",
"adjustColors": "Adjust the css colors as you like either with hex values or color names.",
"andSave": "and save",
"crop": "Crop by pressing ALT key and dragging sides of source",
"changeSettings": "Right click on source -> 'interact' to change settings"
},
"playerCount": "Player count",
"cycleDuration": "Cycle Duration",
"pauseWidth": "Pause width",
Expand Down
25 changes: 24 additions & 1 deletion rcongui_public/src/pages/home/streaming/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@ import {useTranslation} from "react-i18next";
import {useOutletContext} from "react-router";
import {GameLiveOutletContext} from "@/pages/home/layout";
import SelectBox from "@/components/ui/select-box";
import {
Accordion,
AccordionContent,
AccordionItem,
AccordionTrigger
} from "@/components/ui/accordion";
import {AccordionHeader} from "@radix-ui/react-accordion";
import {GraduationCap} from "lucide-react";
import StreamTutorial from "@/pages/home/streaming/stream-tutorial";

export default function Streaming() {
const { t } = useTranslation('translation', {keyPrefix: 'streaming'});
Expand All @@ -31,7 +40,21 @@ export default function Streaming() {
);

return <div className="w-full lg:w-2/3">
<div className="w-full border gap-3 p-2 flex flex-wrap">
<h1 className="text-2xl text-center pb-6">{t("streamerView")}</h1>
<Accordion type="single" collapsible className="border-x border-t bg-background">
<AccordionItem value="tutorial">
<AccordionHeader>
<AccordionTrigger>
<span className="w-full flex flex-row items-center justify-center"><GraduationCap className="inline-block size-7 mr-1"/> {t('tutorial.title')}</span>
</AccordionTrigger>
</AccordionHeader>
<AccordionContent>
<StreamTutorial/>
</AccordionContent>
</AccordionItem>
</Accordion>
{/*bg background necessary so the background stays within obs*/}
<div className="bg-background w-full border-x border-b gap-3 p-2 flex flex-wrap">
<div className="w-52 h-12 flex flex-col justify-between pb-2">
<span className="text-nowrap">
{t('playerCount')} ({playerAmount})
Expand Down
10 changes: 5 additions & 5 deletions rcongui_public/src/pages/home/streaming/stream-banner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export default function StreamBanner({ playerAmount, settings }: StreamBannerPro
.sort((a, b) => b.kills - a.kills)
.slice(0, playerAmount);

return <div className="w-full h-12 inline-flex flex-nowrap bg-white overflow-hidden">
return <div className="stream-banner w-full h-12 inline-flex flex-nowrap bg-white overflow-hidden">
<Stream players={displayedPlayers} settings={settings}/>
<Stream players={displayedPlayers} settings={settings}/>
</div>
Expand All @@ -40,12 +40,12 @@ interface StreamProps {
const Stream = ({ players, settings }: StreamProps) => {
return <div className="flex items-center justify-center animate-infinite-scroll transform" style={{animationDuration: settings.animationDuration + 's'}}>
<div className="flex-shrink-0" style={{width: settings.pauseWidth}}/>
<div className="text-black text-right font-bold text-2xl pb-0.5 whitespace-pre mr-2">
<div className="stream-banner-text text-black text-right font-bold text-2xl pb-0.5 whitespace-pre mr-2">
{settings.text}
</div>
{players.map((player =>
<div className="h-full flex-shrink-0 px-2 py-2 text-black whitespace-nowrap flex items-center mr-3">
<div className="text-primary text-2xl font-bold pb-0.5 mr-2">
<div className="stream-banner-kills text-primary text-2xl font-bold pb-0.5 mr-2">
{player.kills}
</div>
{settings.showAvatars && player.steaminfo?.profile?.avatar && <Avatar className="size-7 mr-1">
Expand All @@ -56,11 +56,11 @@ const Stream = ({ players, settings }: StreamProps) => {
<CircleHelp className="text-wh ite"/>
</AvatarFallback>
</Avatar>}
<div className="block">
<div className="stream-banner-player block">
<div>
{player.player}
</div>
{settings.showWeapons && <div className="text-gray-500 text-xs">
{settings.showWeapons && <div className="stream-banner-weapon text-gray-500 text-xs">
{
Object.entries(player.weapons)
.sort(([n1, v1], [n2, v2]) => v2 - v1)[0]?.[0]
Expand Down
103 changes: 103 additions & 0 deletions rcongui_public/src/pages/home/streaming/stream-tutorial.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import React from 'react';
import { useTranslation } from "react-i18next";
import { siObsstudio } from "simple-icons";
import { SimpleIcon } from "@/components/simple-icon";

const StreamTutorial = () => {
const { t } = useTranslation('translation', { keyPrefix: 'streaming.tutorial' });

const cssValue = `.stream-banner {
background-color: black !important;
}
.stream-banner-text {
color: #ffa500 !important;
}
.stream-banner-kills {
color: red !important;
}
.stream-banner-player {
color: #6a5acd !important;
}
.stream-banner-weapon {
color: #6a5acd !important;
}`;

const steps = [
{
id: 'obs',
content: t("openOBS"),
icon: <SimpleIcon size={20} icon={siObsstudio} className="dark:fill-current inline-block ml-2" />
},
{
id: 'source',
content: t("createSource")
},
{
id: 'values',
content: t("enterFollowingValues"),
subContent: (
<div className="ml-4 space-y-2 mt-2">
<p className="flex justify-between">
<span className="font-semibold">{t("url")}:</span>
<span className="font-mono">{window.location.href}</span>
</p>
<p className="flex justify-between">
<span className="font-semibold">{t("width")}:</span>
<span className="font-mono">1000</span>
</p>
<p className="flex justify-between">
<span className="font-semibold">{t("height")}:</span>
<span className="font-mono">800</span>
</p>
<p className="font-semibold">{t("customCSS")}:</p>
<pre
className="w-full p-4 bg-accent rounded-md font-mono text-sm text-gray-100 whitespace-pre overflow-x-auto">
{cssValue}
</pre>
<p>
{t("adjustColors")}
</p>
<p className="italic">{t("andSave")}</p>
</div>
)
},
{
id: 'crop',
content: t("crop")
},
{
id: 'settings',
content: t("changeSettings")
}
];

return (
<div className="w-full flex justify-center">
<div className="w-96 space-y-3">
<div className="space-y-3">
<p>{t("introduction")}</p>
<p>{t("stepByStep")}</p>
</div>

<ol className="space-y-4">
{steps.map((step, index) => (
<li key={step.id} className="flex flex-col">
<div className="flex items-center">
<span className="font-semibold">{index + 1}. </span>
<span className="ml-2">{step.content}</span>
{step.icon}
</div>
{step.subContent}
</li>
))}
</ol>
</div>
</div>
);
};

export default StreamTutorial;

0 comments on commit f88038a

Please sign in to comment.