Skip to content

Commit

Permalink
feat(sources): grouping Capture, Audio/Video and Media, src descriptions
Browse files Browse the repository at this point in the history
  • Loading branch information
blackxored committed Dec 13, 2024
1 parent 258b46f commit dcaec51
Show file tree
Hide file tree
Showing 4 changed files with 158 additions and 39 deletions.
112 changes: 80 additions & 32 deletions app/components-react/windows/source-showcase/SourceGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Services } from 'components-react/service-provider';
import { useVuex } from 'components-react/hooks';
import { IObsListOption } from 'components/obs/inputs/ObsInput';
import { WidgetDisplayData, WidgetType } from 'services/widgets';
import { TSourceType } from 'services/sources';
import { TSourceType, SourceDisplayData } from 'services/sources';
import { getPlatformService } from 'services/platforms';
import { $i } from 'services/utils';
import { byOS, getOS, OS } from 'util/operating-systems';
Expand All @@ -29,7 +29,9 @@ export default function SourceGrid(p: { activeTab: string }) {
// TODO: persistence
const [expandedSections, setExpandedSections] = useState([
'essentialSources',
'generalSources',
'captureSources',
'avSources',
'mediaSources',
'widgets',
'apps',
]);
Expand Down Expand Up @@ -146,6 +148,10 @@ export default function SourceGrid(p: { activeTab: string }) {

const { Panel } = Collapse;

const toSourceEl = (source: IObsListOption<TSourceType>) => (
<SourceTag key={source.value} type={source.value} essential excludeWrap={excludeWrap} />
);

const essentialSourcesList = useMemo(
() => (
<>
Expand All @@ -171,12 +177,31 @@ export default function SourceGrid(p: { activeTab: string }) {
[essentialSources, isLoggedIn, excludeWrap],
);

const generalSourcesList = useMemo(() => {
return (
const sourceDisplayData = useMemo(() => SourceDisplayData(), []);

const byGroup = (group: 'capture' | 'av' | 'media') => (source: IObsListOption<TSourceType>) => {
const displayData = sourceDisplayData[source.value];
if (!displayData) {
return true;
}

return displayData.group === group;
};

const captureSourcesList = useMemo(
() => availableSources.filter(byGroup('capture')).map(toSourceEl),
[availableSources, excludeWrap],
);

const avSourcesList = useMemo(() => availableSources.filter(byGroup('av')).map(toSourceEl), [
availableSources,
excludeWrap,
]);

const mediaSourcesList = useMemo(
() => (
<>
{availableSources.filter(filterEssential).map(source => (
<SourceTag key={source.value} type={source.value} excludeWrap={excludeWrap} />
))}
{availableSources.filter(byGroup('media')).map(toSourceEl)}
<SourceTag
key="replay"
name={$t('Instant Replay')}
Expand All @@ -192,25 +217,8 @@ export default function SourceGrid(p: { activeTab: string }) {
/>
)}
</>
);
}, [availableSources, p.activeTab, designerMode, excludeWrap]);

const appsList = useMemo(
() => (
<>
{availableAppSources.map(app => (
<SourceTag
key={`${app.appId}${app.source.id}`}
name={app.source.name}
type="app_source"
appId={app.appId}
appSourceId={app.source.id}
excludeWrap={excludeWrap}
/>
))}
</>
),
[availableAppSources, excludeWrap],
[availableSources, excludeWrap, designerMode],
);

const widgetList = useMemo(
Expand Down Expand Up @@ -243,14 +251,58 @@ export default function SourceGrid(p: { activeTab: string }) {
[isLoggedIn, iterableWidgetTypes, p.activeTab, excludeWrap],
);

const appsList = useMemo(
() => (
<>
{availableAppSources.map(app => (
<SourceTag
key={`${app.appId}${app.source.id}`}
name={app.source.name}
type="app_source"
appId={app.appId}
appSourceId={app.source.id}
excludeWrap={excludeWrap}
/>
))}
</>
),
[availableAppSources, excludeWrap],
);

const groupedSources = useMemo(
() => (
<>
<Panel header={$t('Capture Sources')} key="captureSources">
<div className="collapse-section">{captureSourcesList}</div>
</Panel>
<Panel header={$t('Video and Audio')} key="avSources">
<div className="collapse-section">{avSourcesList}</div>
</Panel>
<Panel header={$t('Media')} key="mediaSources">
<div className="collapse-section">{mediaSourcesList}</div>
</Panel>
</>
),
[captureSourcesList, avSourcesList, mediaSourcesList],
);

const individualTab = useMemo(() => {
/*
* TODO: general is called media now, should probably rename in code.
* It is the same as the All Sources tab except for widgets and apps.
*/
if (showContent('general')) {
return (
<>
<Col span={24}>
<PageHeader style={{ paddingLeft: 0 }} title={$t('General Sources')} />
<Collapse
ghost
activeKey={expandedSections}
onChange={xs => setExpandedSections(xs as string[])}
>
{groupedSources}
</Collapse>
</Col>
{generalSourcesList}
</>
);
} else if (showContent('widgets')) {
Expand Down Expand Up @@ -295,11 +347,7 @@ export default function SourceGrid(p: { activeTab: string }) {
{essentialSourcesList}
</div>
</Panel>
<Panel header={$t('General Sources')} key="generalSources">
<div className="collapse-section" data-testid="general-sources">
{generalSourcesList}
</div>
</Panel>
{groupedSources}
<Panel header={$t('Widgets')} key="widgets">
<div className="collapse-section" data-testid="widget-sources">
{widgetList}
Expand Down
24 changes: 22 additions & 2 deletions app/i18n/en-US/sources.json
Original file line number Diff line number Diff line change
@@ -1,31 +1,41 @@
{
"Add Source": "Add Source",
"Add images to your scene.": "Add images to your scene.",
"Add image to scene": "Add image to scene",
"Add a slideshow of images to your scene.": "Add a slideshow of images to your scene.",
"Add a slideshow": "Add a slideshow",
"Add videos or sound clips to your scene.": "Add videos or sound clips to your scene.",
"Videos or sound clips": "Videos or sound clips",
"Capture a specific window that's open on your computer.": "Capture a specific window that's open on your computer.",
"Share specific window": "Share specific window",
"Compatible with most modern browsers and programs": "Compatible with most modern browsers and programs",
"Display video from webcams, capture cards, and other devices.": "Display video from webcams, capture cards, and other devices.",
"Built in webcam": "Built in webcam",
"Logitech webcam": "Logitech webcam",
"Capture cards (Elgato, Avermedia, BlackMagic)": "Capture cards (Elgato, Avermedia, BlackMagic)",
"Captures your desktop audio for the purpose of playing sound, such as music or speech.": "Captures your desktop audio for the purpose of playing sound, such as music or speech.",
"Capture desktop audio": "Capture desktop audio",
"Desktop audio": "Desktop audio",
"Add a color to the background of your whole scene or just a part.": "Add a color to the background of your whole scene or just a part.",
"Allows you to add web-based content as a source, such as web pages, widgets, and streaming video.": "Allows you to add web-based content as a source, such as web pages, widgets, and streaming video.",
"Your web-based content": "Your web-based content",
"Websites": "Websites",
"Third party widget": "Third party widget",
"Add text to your scene and adjust its style.": "Add text to your scene and adjust its style.",
"Add text to scene": "Add text to scene",
"System Fonts": "System Fonts",
"System Sizes": "System Sizes",
"Capture your entire computer monitor.": "Capture your entire computer monitor.",
"Share monitor": "Share monitor",
"Primary monitor": "Primary monitor",
"Secondary monitor": "Secondary monitor",
"Capture a game you're playing on your computer.": "Capture a game you're playing on your computer.",
"Capture your game": "Capture your game",
"Built in works with most modern computer games": "Built in works with most modern computer games",
"Allow you to capture NDI output streams.": "Allow you to capture NDI output streams.",
"Capture NDI output": "Capture NDI output",
"Any device that attaches to a computer for the purpose of capturing sound, such as music or speech.": "Any device that attaches to a computer for the purpose of capturing sound, such as music or speech.",
"Capture microphone": "Capture microphone",
"Built in microphones": "Built in microphones",
"USB microphones": "USB microphones",
"Other USB devices": "Other USB devices",
Expand Down Expand Up @@ -97,6 +107,7 @@
"Unable to add a source: the scene you are trying to add already contains your current scene": "Unable to add a source: the scene you are trying to add already contains your current scene",
"Add New Source": "Add New Source",
"Please enter the name of the source": "Please enter the name of the source",
"Existing scene": "Existing scene",
"Add Existing Source": "Add Existing Source",
"Recommended": "Recommended",
"Please enter the name of the folder": "Please enter the name of the folder",
Expand Down Expand Up @@ -159,13 +170,15 @@
"New filter": "New filter",
"Third party widgets": "Third party widgets",
"OpenVR Capture": "OpenVR Capture",
"Capture VR games": "Capture VR games",
"Directly capture the OpenVR monitoring video buffer of your HMD.": "Directly capture the OpenVR monitoring video buffer of your HMD.",
"LIV Client Capture": "LIV Client Capture",
"Directly capture the LIV compositor output, reducing load and simplifying setup for Mixed Reality.": "Directly capture the LIV compositor output, reducing load and simplifying setup for Mixed Reality.",
"Looking for a game to capture": "Looking for a game to capture",
"Specified window is not a game": "Specified window is not a game",
"VLC Source": "VLC Source",
"Add playlists of videos to your scene.": "Add playlists of videos to your scene.",
"Video playlist": "Video playlist",
"Settings for %{sourceName}": "Settings for %{sourceName}",
"Visible on both Stream and Recording": "Visible on both Stream and Recording",
"Only visible on Stream": "Only visible on Stream",
Expand Down Expand Up @@ -213,14 +226,18 @@
"All Sources": "All Sources",
"Media Categories": "Media Categories",
"General Sources": "General Sources",
"Capture Sources": "Capture Sources",
"Media": "Media",
"Video and Audio": "Video and Audio",
"Add media": "Add media",
"Your webcam device": "Your webcam device",
"Display device video": "Display device video",
"Capture games and apps": "Capture games and apps",
"Capture screen": "Capture screen",
"Dynamic, live alerts": "Dynamic, live alerts",
"Dynamic live alerts": "Dynamic live alerts",
"Display recent events": "Display recent events",
"Viewer shoutouts": "Viewer shoutouts",
"Stream stats and events": "Stream stats and events",
"Capture an application window": "Capture an application window",
"Folder Expansion": "Folder Expansion",
"Wondering how to expand your folders? Just click on the <icon></icon> icon": "Wondering how to expand your folders? Just click on the <icon></icon> icon",
Expand Down Expand Up @@ -383,5 +400,8 @@
"Hide from Vertical": "Hide from Vertical",
"Show in Vertical": "Show in Vertical",
"Streamlabs Charity Donation Goal": "Streamlabs Charity Donation Goal",
"macOS Screen Capture": "macOS Screen Capture"
"macOS Screen Capture": "macOS Screen Capture",
"Stream with guests": "Stream with guests",
"Display latest replay": "Display latest replay",
"Add color to scene": "Add color to scene"
}
2 changes: 2 additions & 0 deletions app/services/sources/sources-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,4 +173,6 @@ export interface ISourceDisplayData {
shortDesc?: string;
link?: string;
linkText?: string;
// TODO: make required if none are missing
group?: string;
}
Loading

0 comments on commit dcaec51

Please sign in to comment.