mirror of
https://github.com/jellyfin/jellyfin.org.git
synced 2026-09-03 05:30:05 +03:00
@@ -0,0 +1,80 @@
|
||||
/* stylelint-disable docusaurus/copyright-header */
|
||||
|
||||
.client__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.client__header__start {
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.client__header__start h3 {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.client__header__start__badges {
|
||||
margin-left: 1rem;
|
||||
}
|
||||
|
||||
.client__footer {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.client__platform-icon {
|
||||
margin-left: 1rem;
|
||||
}
|
||||
|
||||
.client__footer .button {
|
||||
margin-left: 1rem;
|
||||
}
|
||||
|
||||
.client__footer .button:first-of-type {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
@media (max-width: 420px) {
|
||||
.client__header {
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.client__platform-icon {
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
.client__platform-icon:first-of-type {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.card__body {
|
||||
padding-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 560px) {
|
||||
.client__header__start {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.client__header__start__badges {
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
.client__header__start__badges:first-of-type {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.client__footer {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.client__footer .button {
|
||||
margin: 1rem 0 0;
|
||||
}
|
||||
|
||||
.client__footer .button:first-of-type {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
import React from 'react';
|
||||
|
||||
import PlatformIcon from './PlatformIcon';
|
||||
import { Client, ClientType, LicenseType } from '../data/clients';
|
||||
|
||||
import './ClientDetails.css';
|
||||
|
||||
const ClientTypeBadge = ({ clientType }: { clientType: ClientType }) => {
|
||||
if (clientType === ClientType.Official) {
|
||||
return <span className='badge badge--primary margin-right--sm'>Official</span>;
|
||||
} else if (clientType === ClientType.ThirdParty) {
|
||||
return <span className='badge badge--secondary margin-right--sm'>Third Party</span>;
|
||||
}
|
||||
};
|
||||
|
||||
const LicenseTypeBadge = ({ licenseType }: { licenseType: LicenseType }) => {
|
||||
if (licenseType === LicenseType.OpenSource) {
|
||||
return <span className='badge badge--success margin-right--sm'>Open Source</span>;
|
||||
} else if (licenseType === LicenseType.Proprietary) {
|
||||
return <span className='badge badge--warning margin-right--sm'>Proprietary</span>;
|
||||
}
|
||||
};
|
||||
|
||||
const ClientDetails = ({ client }: { client: Client }) => (
|
||||
<div className='card client margin-bottom--md'>
|
||||
<div className='card__header client__header'>
|
||||
<div className='client__header__start'>
|
||||
<h3>{client.name}</h3>
|
||||
<div className='client__header__start__badges'>
|
||||
<ClientTypeBadge clientType={client.clientType} />
|
||||
<LicenseTypeBadge licenseType={client.licenseType} />
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
{client.platforms.map((platform, index) => (
|
||||
<PlatformIcon key={`${platform}-${index}`} platform={platform} size={36} className='client__platform-icon' />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div className='card__body padding-top--sm'>{client.description}</div>
|
||||
<div className='card__footer client__footer'>
|
||||
{client.secondaryLinks?.map(({ id, url, name }) => (
|
||||
<a key={id} href={url} className='button button--outline button--primary'>
|
||||
{name}
|
||||
</a>
|
||||
))}
|
||||
<div style={{ flexGrow: 1 }} />
|
||||
{client.primaryLinks.map(({ id, url, name }) => (
|
||||
<a key={id} href={url} className='button button--primary'>
|
||||
{name}
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
export default ClientDetails;
|
||||
@@ -0,0 +1,27 @@
|
||||
import clsx from 'clsx';
|
||||
import React, { FunctionComponent, ReactNode } from 'react';
|
||||
|
||||
type PillParams = {
|
||||
children: ReactNode;
|
||||
active: boolean;
|
||||
onClick(): void;
|
||||
};
|
||||
|
||||
const Pill: FunctionComponent<PillParams> = ({ children, active, onClick }: PillParams) => (
|
||||
<li
|
||||
// eslint-disable-next-line jsx-a11y/no-noninteractive-element-to-interactive-role
|
||||
role='button'
|
||||
tabIndex={0}
|
||||
className={clsx('pills__item', { 'pills__item--active': active })}
|
||||
onClick={onClick}
|
||||
onKeyUp={(keyEvent) => {
|
||||
if (keyEvent.key === 'Enter') {
|
||||
onClick();
|
||||
}
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</li>
|
||||
);
|
||||
|
||||
export default Pill;
|
||||
@@ -0,0 +1,70 @@
|
||||
import {
|
||||
Amazonfiretv,
|
||||
Android,
|
||||
Appletv,
|
||||
Discord,
|
||||
Ios,
|
||||
Kodi,
|
||||
Lg,
|
||||
Roku,
|
||||
Sailfishos
|
||||
} from '@icons-pack/react-simple-icons';
|
||||
import clsx from 'clsx';
|
||||
import React from 'react';
|
||||
|
||||
import { Platform } from '../data/clients';
|
||||
import Desktop from '../../static/images/icons/monitor.svg';
|
||||
import Web from '../../static/images/icons/web.svg';
|
||||
|
||||
const PlatformIcon = ({
|
||||
platform,
|
||||
size,
|
||||
className = ''
|
||||
}: {
|
||||
platform: Platform;
|
||||
size: string | number;
|
||||
className?: string;
|
||||
}) => {
|
||||
className = clsx(className, 'fill--white');
|
||||
|
||||
switch (platform) {
|
||||
case Platform.Android:
|
||||
case Platform.AndroidTV:
|
||||
return <Android size={size} className={className} />;
|
||||
|
||||
case Platform.Browser:
|
||||
return <Web width={size} height={size} className={className} />;
|
||||
|
||||
case Platform.Desktop:
|
||||
return <Desktop width={size} height={size} className={className} />;
|
||||
|
||||
case Platform.Discord:
|
||||
return <Discord size={size} className={className} />;
|
||||
|
||||
case Platform.FireOS:
|
||||
return <Amazonfiretv size={size} className={className} />;
|
||||
|
||||
case Platform.IOS:
|
||||
return <Ios size={size} className={className} />;
|
||||
|
||||
case Platform.Kodi:
|
||||
return <Kodi size={size} className={className} />;
|
||||
|
||||
case Platform.Roku:
|
||||
return <Roku size={size} className={className} />;
|
||||
|
||||
case Platform.SailfishOS:
|
||||
return <Sailfishos size={size} className={className} />;
|
||||
|
||||
case Platform.TVOS:
|
||||
return <Appletv size={size} className={className} />;
|
||||
|
||||
case Platform.WebOS:
|
||||
return <Lg size={size} className={className} />;
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
export default PlatformIcon;
|
||||
@@ -29,7 +29,9 @@
|
||||
--ifm-code-background: #292d3e; /* match code blocks */
|
||||
--ifm-navbar-background-color: #000b25;
|
||||
--ifm-background-color: #000b25 !important;
|
||||
--ifm-card-background-color: #172138;
|
||||
--ifm-footer-background-color: #333c44;
|
||||
--ifm-pills-color-background-active: #172138;
|
||||
--ifm-font-family-base: "Noto Sans", sans-serif;
|
||||
--ifm-h1-font-size: 2.074em;
|
||||
--ifm-h2-font-size: 1.728em;
|
||||
|
||||
@@ -0,0 +1,701 @@
|
||||
export enum ClientType {
|
||||
Official,
|
||||
ThirdParty
|
||||
}
|
||||
|
||||
export enum DeviceType {
|
||||
Desktop,
|
||||
Mobile,
|
||||
TV
|
||||
}
|
||||
|
||||
export enum LicenseType {
|
||||
OpenSource,
|
||||
Proprietary
|
||||
}
|
||||
|
||||
export enum Platform {
|
||||
Android,
|
||||
AndroidTV,
|
||||
Browser,
|
||||
Desktop,
|
||||
Discord,
|
||||
FireOS,
|
||||
IOS,
|
||||
Kodi,
|
||||
Roku,
|
||||
SailfishOS,
|
||||
TVOS,
|
||||
WebOS
|
||||
}
|
||||
|
||||
type Link = {
|
||||
id: string;
|
||||
name: string;
|
||||
url: string;
|
||||
};
|
||||
|
||||
export type Client = {
|
||||
id: string;
|
||||
name: string;
|
||||
description: string;
|
||||
clientType: ClientType;
|
||||
deviceTypes: Array<DeviceType>;
|
||||
licenseType: LicenseType;
|
||||
platforms: Array<Platform>;
|
||||
primaryLinks: Array<Link>;
|
||||
secondaryLinks?: Array<Link>;
|
||||
recommended?: boolean;
|
||||
};
|
||||
|
||||
export const Clients: Array<Client> = [
|
||||
{
|
||||
id: 'jellyfin-media-player',
|
||||
name: 'Jellyfin Media Player',
|
||||
description: 'The official Jellyfin desktop client.',
|
||||
clientType: ClientType.Official,
|
||||
deviceTypes: [DeviceType.Desktop],
|
||||
licenseType: LicenseType.OpenSource,
|
||||
platforms: [Platform.Desktop],
|
||||
primaryLinks: [
|
||||
{
|
||||
id: 'flathub',
|
||||
name: 'Flathub (Linux)',
|
||||
url: 'https://flathub.org/apps/details/com.github.iwalton3.jellyfin-media-player'
|
||||
},
|
||||
{
|
||||
id: 'gh-downloads',
|
||||
name: 'GitHub Downloads',
|
||||
url: 'https://github.com/jellyfin/jellyfin-media-player/releases'
|
||||
}
|
||||
],
|
||||
secondaryLinks: [
|
||||
{
|
||||
id: 'github',
|
||||
name: 'GitHub',
|
||||
url: 'https://github.com/jellyfin/jellyfin-media-player'
|
||||
}
|
||||
],
|
||||
recommended: true
|
||||
},
|
||||
{
|
||||
id: 'jellyfin-mpv-shim',
|
||||
name: 'Jellyfin MPV Shim',
|
||||
description: 'A cross-platform cast client for Jellyfin.',
|
||||
clientType: ClientType.Official,
|
||||
deviceTypes: [DeviceType.Desktop],
|
||||
licenseType: LicenseType.OpenSource,
|
||||
platforms: [Platform.Desktop],
|
||||
primaryLinks: [
|
||||
{
|
||||
id: 'flathub',
|
||||
name: 'Flathub (Linux)',
|
||||
url: 'https://flathub.org/apps/details/com.github.iwalton3.jellyfin-mpv-shim'
|
||||
},
|
||||
{
|
||||
id: 'gh-downloads',
|
||||
name: 'GitHub Downloads',
|
||||
url: 'https://github.com/jellyfin/jellyfin-mpv-shim/releases'
|
||||
}
|
||||
],
|
||||
secondaryLinks: [
|
||||
{
|
||||
id: 'github',
|
||||
name: 'GitHub',
|
||||
url: 'https://github.com/jellyfin/jellyfin-mpv-shim'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'jellyamp',
|
||||
name: 'Jellyamp',
|
||||
description: 'A desktop client for listening to music from a Jellyfin server.',
|
||||
clientType: ClientType.ThirdParty,
|
||||
deviceTypes: [DeviceType.Desktop],
|
||||
licenseType: LicenseType.OpenSource,
|
||||
platforms: [Platform.Desktop],
|
||||
primaryLinks: [
|
||||
{
|
||||
id: 'gh-downloads',
|
||||
name: 'GitHub Downloads',
|
||||
url: 'https://github.com/m0ngr31/jellyamp/releases'
|
||||
}
|
||||
],
|
||||
secondaryLinks: [
|
||||
{
|
||||
id: 'github',
|
||||
name: 'GitHub',
|
||||
url: 'https://github.com/m0ngr31/jellyamp'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'preserve',
|
||||
name: 'Preserve',
|
||||
description: 'A music client inspired by players such as foobar2000 or Clementine.',
|
||||
clientType: ClientType.ThirdParty,
|
||||
deviceTypes: [DeviceType.Desktop],
|
||||
licenseType: LicenseType.OpenSource,
|
||||
platforms: [Platform.Browser, Platform.Desktop],
|
||||
primaryLinks: [
|
||||
{
|
||||
id: 'browser',
|
||||
name: 'Open in Browser',
|
||||
url: 'https://preserveplayer.com/'
|
||||
},
|
||||
{
|
||||
id: 'gl-downloads',
|
||||
name: 'GitLab Downloads',
|
||||
url: 'https://gitlab.com/tonyfinn/preserve/-/releases'
|
||||
}
|
||||
],
|
||||
secondaryLinks: [
|
||||
{
|
||||
id: 'gitlab',
|
||||
name: 'GitLab',
|
||||
url: 'https://gitlab.com/tonyfinn/preserve'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'sonixd',
|
||||
name: 'Sonixd',
|
||||
description: 'A full-featured Subsonic/Jellyfin compatible desktop music player.',
|
||||
clientType: ClientType.ThirdParty,
|
||||
deviceTypes: [DeviceType.Desktop],
|
||||
licenseType: LicenseType.OpenSource,
|
||||
platforms: [Platform.Desktop],
|
||||
primaryLinks: [
|
||||
{
|
||||
id: 'install',
|
||||
name: 'Installation Guide',
|
||||
url: 'https://github.com/jeffvli/sonixd#install'
|
||||
}
|
||||
],
|
||||
secondaryLinks: [
|
||||
{
|
||||
id: 'github',
|
||||
name: 'GitHub',
|
||||
url: 'https://github.com/jeffvli/sonixd'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'tauon-music-box',
|
||||
name: 'Tauon Music Box',
|
||||
description: "A modern streamlined music player for desktop with a minimal interface that's packed with features!",
|
||||
clientType: ClientType.ThirdParty,
|
||||
deviceTypes: [DeviceType.Desktop],
|
||||
licenseType: LicenseType.OpenSource,
|
||||
platforms: [Platform.Desktop],
|
||||
primaryLinks: [
|
||||
{
|
||||
id: 'flathub',
|
||||
name: 'Flathub (Linux)',
|
||||
url: 'https://flathub.org/apps/details/com.github.taiko2k.tauonmb'
|
||||
},
|
||||
{
|
||||
id: 'install',
|
||||
name: 'Installation Guide',
|
||||
url: 'https://github.com/Taiko2k/TauonMusicBox#download-and-install-dizzy'
|
||||
}
|
||||
],
|
||||
secondaryLinks: [
|
||||
{
|
||||
id: 'github',
|
||||
name: 'GitHub',
|
||||
url: 'https://github.com/Taiko2k/TauonMusicBox'
|
||||
},
|
||||
{
|
||||
id: 'tauon',
|
||||
name: 'Website',
|
||||
url: 'https://tauonmusicbox.rocks'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'jellycon',
|
||||
name: 'JellyCon',
|
||||
description:
|
||||
'A lightweight Kodi add-on that lets you browse and play media files directly from your Jellyfin server within the Kodi interface.',
|
||||
clientType: ClientType.Official,
|
||||
deviceTypes: [DeviceType.Desktop, DeviceType.Mobile, DeviceType.TV],
|
||||
licenseType: LicenseType.OpenSource,
|
||||
platforms: [Platform.Kodi],
|
||||
primaryLinks: [
|
||||
{
|
||||
id: 'install',
|
||||
name: 'Installation Guide',
|
||||
url: 'https://github.com/jellyfin/jellycon#installation'
|
||||
}
|
||||
],
|
||||
secondaryLinks: [
|
||||
{
|
||||
id: 'github',
|
||||
name: 'GitHub',
|
||||
url: 'https://github.com/jellyfin/jellycon'
|
||||
}
|
||||
],
|
||||
recommended: true
|
||||
},
|
||||
{
|
||||
id: 'jellyfin-kodi',
|
||||
name: 'Jellyfin for Kodi',
|
||||
description: 'A Kodi add-on that syncs metadata from selected Jellyfin libraries into the local Kodi database.',
|
||||
clientType: ClientType.Official,
|
||||
deviceTypes: [DeviceType.Desktop, DeviceType.Mobile, DeviceType.TV],
|
||||
licenseType: LicenseType.OpenSource,
|
||||
platforms: [Platform.Kodi],
|
||||
primaryLinks: [
|
||||
{
|
||||
id: 'install',
|
||||
name: 'Installation Guide',
|
||||
url: 'https://docs.jellyfin.org/general/clients/kodi.html'
|
||||
}
|
||||
],
|
||||
secondaryLinks: [
|
||||
{
|
||||
id: 'github',
|
||||
name: 'GitHub',
|
||||
url: 'https://github.com/jellyfin/jellyfin-kodi'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'jellyfin-android',
|
||||
name: 'Jellyfin for Android',
|
||||
description: 'The official Jellyfin app for Android devices.',
|
||||
clientType: ClientType.Official,
|
||||
deviceTypes: [DeviceType.Mobile],
|
||||
licenseType: LicenseType.OpenSource,
|
||||
platforms: [Platform.Android],
|
||||
primaryLinks: [
|
||||
{
|
||||
id: 'fdroid',
|
||||
name: 'F-Droid',
|
||||
url: 'https://f-droid.org/en/packages/org.jellyfin.mobile/'
|
||||
},
|
||||
{
|
||||
id: 'amazon-store',
|
||||
name: 'Amazon Appstore',
|
||||
url: 'https://www.amazon.com/gp/aw/d/B081RFTTQ9'
|
||||
},
|
||||
{
|
||||
id: 'play-store',
|
||||
name: 'Play Store',
|
||||
url: 'https://play.google.com/store/apps/details?id=org.jellyfin.mobile'
|
||||
}
|
||||
],
|
||||
secondaryLinks: [
|
||||
{
|
||||
id: 'github',
|
||||
name: 'GitHub',
|
||||
url: 'https://github.com/jellyfin/jellyfin-android'
|
||||
}
|
||||
],
|
||||
recommended: true
|
||||
},
|
||||
{
|
||||
id: 'jellyfin-expo',
|
||||
name: 'Jellyfin Mobile for iOS',
|
||||
description: 'The official Jellyfin app for iOS and iPadOS devices.',
|
||||
clientType: ClientType.Official,
|
||||
deviceTypes: [DeviceType.Mobile],
|
||||
licenseType: LicenseType.OpenSource,
|
||||
platforms: [Platform.IOS],
|
||||
primaryLinks: [
|
||||
{
|
||||
id: 'apple-store',
|
||||
name: 'App Store',
|
||||
url: 'https://apps.apple.com/us/app/jellyfin-mobile/id1480192618?mt=8'
|
||||
}
|
||||
],
|
||||
secondaryLinks: [
|
||||
{
|
||||
id: 'github',
|
||||
name: 'GitHub',
|
||||
url: 'https://github.com/jellyfin/jellyfin-expo'
|
||||
}
|
||||
],
|
||||
recommended: true
|
||||
},
|
||||
{
|
||||
id: 'findroid',
|
||||
name: 'Findroid',
|
||||
description:
|
||||
'A third-party Android application for Jellyfin that provides a native user interface to browse and play movies and series.',
|
||||
clientType: ClientType.ThirdParty,
|
||||
deviceTypes: [DeviceType.Mobile],
|
||||
licenseType: LicenseType.OpenSource,
|
||||
platforms: [Platform.Android],
|
||||
primaryLinks: [
|
||||
{
|
||||
id: 'izzy-fdroid',
|
||||
name: 'IzzyOnDroid',
|
||||
url: 'https://apt.izzysoft.de/fdroid/index/apk/dev.jdtech.jellyfin'
|
||||
},
|
||||
{
|
||||
id: 'play-store',
|
||||
name: 'Play Store',
|
||||
url: 'https://play.google.com/store/apps/details?id=dev.jdtech.jellyfin'
|
||||
}
|
||||
],
|
||||
secondaryLinks: [
|
||||
{
|
||||
id: 'github',
|
||||
name: 'GitHub',
|
||||
url: 'https://github.com/jarnedemeulemeester/findroid'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'gelli',
|
||||
name: 'Gelli',
|
||||
description:
|
||||
'A native music player for Android devices with transcoding support, gapless playback, favorites, playlists, and many other features.',
|
||||
clientType: ClientType.ThirdParty,
|
||||
deviceTypes: [DeviceType.Mobile],
|
||||
licenseType: LicenseType.OpenSource,
|
||||
platforms: [Platform.Android],
|
||||
primaryLinks: [
|
||||
{
|
||||
id: 'gh-downloads',
|
||||
name: 'GitHub Downloads',
|
||||
url: 'https://github.com/dkanada/gelli/releases'
|
||||
},
|
||||
{
|
||||
id: 'fdroid',
|
||||
name: 'F-Droid',
|
||||
url: 'https://f-droid.org/packages/com.dkanada.gramophone/'
|
||||
}
|
||||
],
|
||||
secondaryLinks: [
|
||||
{
|
||||
id: 'github',
|
||||
name: 'GitHub',
|
||||
url: 'https://github.com/dkanada/gelli'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'finamp',
|
||||
name: 'Finamp',
|
||||
description: 'A third party app for music playback with support for offline mode/downloading songs.',
|
||||
clientType: ClientType.ThirdParty,
|
||||
deviceTypes: [DeviceType.Mobile],
|
||||
licenseType: LicenseType.OpenSource,
|
||||
platforms: [Platform.Android, Platform.IOS],
|
||||
primaryLinks: [
|
||||
{
|
||||
id: 'fdroid',
|
||||
name: 'F-Droid',
|
||||
url: 'https://f-droid.org/packages/com.unicornsonlsd.finamp/'
|
||||
},
|
||||
{
|
||||
id: 'play-store',
|
||||
name: 'Play Store',
|
||||
url: 'https://play.google.com/store/apps/details?id=com.unicornsonlsd.finamp'
|
||||
},
|
||||
{
|
||||
id: 'app-store',
|
||||
name: 'App Store',
|
||||
url: 'https://apps.apple.com/us/app/finamp/id1574922594'
|
||||
}
|
||||
],
|
||||
secondaryLinks: [
|
||||
{
|
||||
id: 'github',
|
||||
name: 'GitHub',
|
||||
url: 'https://github.com/UnicornsOnLSD/finamp'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'sailfin',
|
||||
name: 'Sailfin',
|
||||
description: 'A Sailfish OS client for Jellyfin.',
|
||||
clientType: ClientType.ThirdParty,
|
||||
deviceTypes: [DeviceType.Mobile],
|
||||
licenseType: LicenseType.OpenSource,
|
||||
platforms: [Platform.SailfishOS],
|
||||
primaryLinks: [
|
||||
{
|
||||
id: 'open-repos',
|
||||
name: 'OpenRepos',
|
||||
url: 'https://openrepos.net/content/ahappyhuman/sailfin'
|
||||
}
|
||||
],
|
||||
secondaryLinks: [
|
||||
{
|
||||
id: 'github',
|
||||
name: 'GitHub',
|
||||
url: 'https://github.com/heartfin/harbour-sailfin'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'yatse',
|
||||
name: 'Yatse',
|
||||
description: 'A third party remote control for Jellyfin with support for Chromecast playback.',
|
||||
clientType: ClientType.ThirdParty,
|
||||
deviceTypes: [DeviceType.Mobile],
|
||||
licenseType: LicenseType.Proprietary,
|
||||
platforms: [Platform.Android],
|
||||
primaryLinks: [
|
||||
{
|
||||
id: 'play-store',
|
||||
name: 'Play Store',
|
||||
url: 'https://play.google.com/store/apps/details?id=org.leetzone.android.yatsewidgetfree'
|
||||
}
|
||||
],
|
||||
secondaryLinks: [
|
||||
{
|
||||
id: 'yatse',
|
||||
name: 'Website',
|
||||
url: 'https://yatse.tv/'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'jellyfin-androidtv',
|
||||
name: 'Jellyfin for Android TV',
|
||||
description: 'The official Jellyfin app for Android TV devices.',
|
||||
clientType: ClientType.Official,
|
||||
deviceTypes: [DeviceType.TV],
|
||||
licenseType: LicenseType.OpenSource,
|
||||
platforms: [Platform.AndroidTV, Platform.FireOS],
|
||||
primaryLinks: [
|
||||
{
|
||||
id: 'amazon-store',
|
||||
name: 'Amazon Appstore',
|
||||
url: 'https://www.amazon.com/gp/aw/d/B07TX7Z725'
|
||||
},
|
||||
{
|
||||
id: 'play-store',
|
||||
name: 'Play Store',
|
||||
url: 'https://play.google.com/store/apps/details?id=org.jellyfin.androidtv'
|
||||
}
|
||||
],
|
||||
secondaryLinks: [
|
||||
{
|
||||
id: 'github',
|
||||
name: 'GitHub',
|
||||
url: 'https://github.com/jellyfin/jellyfin-androidtv'
|
||||
}
|
||||
],
|
||||
recommended: true
|
||||
},
|
||||
{
|
||||
id: 'jellyfin-roku',
|
||||
name: 'Jellyfin for Roku',
|
||||
description: 'The official Jellyfin app for Roku devices.',
|
||||
clientType: ClientType.Official,
|
||||
deviceTypes: [DeviceType.TV],
|
||||
licenseType: LicenseType.OpenSource,
|
||||
platforms: [Platform.Roku],
|
||||
primaryLinks: [
|
||||
{
|
||||
id: 'roku-store',
|
||||
name: 'Channel Store',
|
||||
url: 'https://channelstore.roku.com/details/592369/jellyfin'
|
||||
}
|
||||
],
|
||||
secondaryLinks: [
|
||||
{
|
||||
id: 'github',
|
||||
name: 'GitHub',
|
||||
url: 'https://github.com/jellyfin/jellyfin-roku'
|
||||
}
|
||||
],
|
||||
recommended: true
|
||||
},
|
||||
{
|
||||
id: 'jellyfin-webos',
|
||||
name: 'Jellyfin for WebOS',
|
||||
description: 'The official Jellyfin app for WebOS devices.',
|
||||
clientType: ClientType.Official,
|
||||
deviceTypes: [DeviceType.TV],
|
||||
licenseType: LicenseType.OpenSource,
|
||||
platforms: [Platform.WebOS],
|
||||
primaryLinks: [
|
||||
{
|
||||
id: 'jf-blog',
|
||||
name: 'Older webOS Versions',
|
||||
url: '/posts/webos-july2022'
|
||||
},
|
||||
{
|
||||
id: 'lg-store',
|
||||
name: 'Content Store - webOS 6+',
|
||||
url: 'https://us.lgappstv.com/main/tvapp/detail?appId=1030579'
|
||||
}
|
||||
],
|
||||
secondaryLinks: [
|
||||
{
|
||||
id: 'github',
|
||||
name: 'GitHub',
|
||||
url: 'https://github.com/jellyfin/jellyfin-webos'
|
||||
}
|
||||
],
|
||||
recommended: true
|
||||
},
|
||||
{
|
||||
id: 'infuse',
|
||||
name: 'Infuse',
|
||||
description: 'A third-party client for iOS, iPadOS, and tvOS devices.',
|
||||
clientType: ClientType.ThirdParty,
|
||||
deviceTypes: [DeviceType.Mobile, DeviceType.TV],
|
||||
licenseType: LicenseType.Proprietary,
|
||||
platforms: [Platform.IOS, Platform.TVOS],
|
||||
primaryLinks: [
|
||||
{
|
||||
id: 'apple-store',
|
||||
name: 'App Store',
|
||||
url: 'https://apps.apple.com/app/id1136220934?mt=8'
|
||||
}
|
||||
],
|
||||
secondaryLinks: [
|
||||
{
|
||||
id: 'website',
|
||||
name: 'Website',
|
||||
url: 'https://firecore.com/infuse'
|
||||
}
|
||||
],
|
||||
recommended: true
|
||||
},
|
||||
{
|
||||
id: 'mopidy',
|
||||
name: 'Mopidy-Jellyfin',
|
||||
description: 'An official plugin for Mopidy that uses Jellyfin as a backend.',
|
||||
clientType: ClientType.Official,
|
||||
deviceTypes: [],
|
||||
licenseType: LicenseType.OpenSource,
|
||||
platforms: [],
|
||||
primaryLinks: [
|
||||
{
|
||||
id: 'install',
|
||||
name: 'Installation Guide',
|
||||
url: 'https://jellyfin.org/docs/general/clients/mopidy.html'
|
||||
}
|
||||
],
|
||||
secondaryLinks: [
|
||||
{
|
||||
id: 'github',
|
||||
name: 'GitHub',
|
||||
url: 'https://github.com/jellyfin/mopidy-jellyfin'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'volumio',
|
||||
name: 'Jellyfin Plugin for Volumio',
|
||||
description: 'A Volumio plugin for playing audio from one or more Jellyfin servers.',
|
||||
clientType: ClientType.ThirdParty,
|
||||
deviceTypes: [],
|
||||
licenseType: LicenseType.OpenSource,
|
||||
platforms: [],
|
||||
primaryLinks: [
|
||||
{
|
||||
id: 'github',
|
||||
name: 'GitHub',
|
||||
url: 'https://github.com/patrickkfkan/volumio-jellyfin'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'discord-music',
|
||||
name: 'Discord Music Bot for Jellyfin',
|
||||
description: 'A Discord bot that allows playing your Jellyfin music library in Discord voice channels.',
|
||||
clientType: ClientType.ThirdParty,
|
||||
deviceTypes: [],
|
||||
licenseType: LicenseType.OpenSource,
|
||||
platforms: [Platform.Discord],
|
||||
primaryLinks: [
|
||||
{
|
||||
id: 'install',
|
||||
name: 'Installation Guide',
|
||||
url: 'https://github.com/kgt1/jellyfin-discord-music-bot#getting-started'
|
||||
}
|
||||
],
|
||||
secondaryLinks: [
|
||||
{
|
||||
id: 'github',
|
||||
name: 'GitHub',
|
||||
url: 'https://github.com/kgt1/jellyfin-discord-music-bot'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'jellycli',
|
||||
name: 'Jellycli',
|
||||
description: 'A terminal player for Jellyfin, only for music at the moment.',
|
||||
clientType: ClientType.ThirdParty,
|
||||
deviceTypes: [],
|
||||
licenseType: LicenseType.OpenSource,
|
||||
platforms: [],
|
||||
primaryLinks: [
|
||||
{
|
||||
id: 'gh-downloads',
|
||||
name: 'GitHub Downloads',
|
||||
url: 'https://github.com/tryffel/jellycli/releases'
|
||||
}
|
||||
],
|
||||
secondaryLinks: [
|
||||
{
|
||||
id: 'github',
|
||||
name: 'GitHub',
|
||||
url: 'https://github.com/tryffel/jellycli'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'jftui',
|
||||
name: 'jftui',
|
||||
description: 'A terminal client for Jellyfin built as a REPL interface, that uses mpv for multimedia playback.',
|
||||
clientType: ClientType.ThirdParty,
|
||||
deviceTypes: [],
|
||||
licenseType: LicenseType.OpenSource,
|
||||
platforms: [],
|
||||
primaryLinks: [
|
||||
{
|
||||
id: 'install',
|
||||
name: 'Installation Guide',
|
||||
url: 'https://github.com/Aanok/jftui#installation'
|
||||
}
|
||||
],
|
||||
secondaryLinks: [
|
||||
{
|
||||
id: 'github',
|
||||
name: 'GitHub',
|
||||
url: 'https://github.com/Aanok/jftui'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'web-scrobbler',
|
||||
name: 'Web Scrobbler',
|
||||
description: 'Web Scrobbler helps online music listeners to scrobble their playback history.',
|
||||
clientType: ClientType.ThirdParty,
|
||||
deviceTypes: [],
|
||||
licenseType: LicenseType.OpenSource,
|
||||
platforms: [Platform.Browser],
|
||||
primaryLinks: [
|
||||
{
|
||||
id: 'install',
|
||||
name: 'Installation Guide',
|
||||
url: 'https://github.com/web-scrobbler/web-scrobbler#installation'
|
||||
}
|
||||
],
|
||||
secondaryLinks: [
|
||||
{
|
||||
id: 'github',
|
||||
name: 'GitHub',
|
||||
url: 'https://github.com/web-scrobbler/web-scrobbler'
|
||||
},
|
||||
{
|
||||
id: 'website',
|
||||
name: 'Website',
|
||||
url: 'https://web-scrobbler.com'
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
+60
-4
@@ -1,11 +1,67 @@
|
||||
import React from 'react';
|
||||
import Layout from '@theme/Layout';
|
||||
import React, { useState } from 'react';
|
||||
|
||||
import ClientDetails from '../components/ClientDetails';
|
||||
import Pill from '../components/Pill';
|
||||
import { Clients, DeviceType, Platform } from '../data/clients';
|
||||
|
||||
type ClientFilter = {
|
||||
recommended: boolean;
|
||||
deviceType?: DeviceType;
|
||||
platform?: Platform;
|
||||
};
|
||||
|
||||
export default function Plugins() {
|
||||
const [filter, setFilter] = useState<ClientFilter>({
|
||||
recommended: true
|
||||
});
|
||||
|
||||
return (
|
||||
<Layout>
|
||||
<h1>Clients</h1>
|
||||
<p>Placeholder page</p>
|
||||
<Layout title='Clients'>
|
||||
<h1 className='text--center'>Clients</h1>
|
||||
|
||||
<main className='margin-vert--lg'>
|
||||
<section className='container'>
|
||||
<ul className='pills'>
|
||||
<Pill
|
||||
active={filter.recommended}
|
||||
onClick={() => {
|
||||
setFilter({ ...filter, recommended: true });
|
||||
}}
|
||||
>
|
||||
Recommended Clients
|
||||
</Pill>
|
||||
<Pill
|
||||
active={!filter.recommended}
|
||||
onClick={() => {
|
||||
setFilter({ ...filter, recommended: false });
|
||||
}}
|
||||
>
|
||||
All Clients
|
||||
</Pill>
|
||||
</ul>
|
||||
|
||||
{Clients.filter((client) => {
|
||||
let result = true;
|
||||
|
||||
if (filter.recommended) {
|
||||
result = result && !!client.recommended;
|
||||
}
|
||||
|
||||
if (typeof filter.deviceType !== 'undefined') {
|
||||
result = result && client.deviceTypes.includes(filter.deviceType);
|
||||
}
|
||||
|
||||
if (typeof filter.platform !== 'undefined') {
|
||||
result = result && client.platforms.includes(filter.platform);
|
||||
}
|
||||
|
||||
return result;
|
||||
}).map((client) => (
|
||||
<ClientDetails key={client.id} client={client} />
|
||||
))}
|
||||
</section>
|
||||
</main>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user