mirror of
https://github.com/aleksilassila/reiverr.git
synced 2026-04-24 09:45:11 +02:00
feat: Loading source plugins
This commit is contained in:
59
src/app.css
59
src/app.css
@@ -3,19 +3,19 @@
|
||||
@tailwind utilities;
|
||||
|
||||
a {
|
||||
@apply hover:text-amber-200;
|
||||
@apply hover:text-amber-200;
|
||||
}
|
||||
|
||||
.placeholder {
|
||||
@apply bg-zinc-700 bg-opacity-40 animate-pulse;
|
||||
@apply bg-zinc-700 bg-opacity-40 animate-pulse;
|
||||
}
|
||||
|
||||
.placeholder-image {
|
||||
@apply bg-zinc-700 bg-opacity-75;
|
||||
@apply bg-zinc-700 bg-opacity-75;
|
||||
}
|
||||
|
||||
.placeholder-text {
|
||||
@apply bg-zinc-700 bg-opacity-40 animate-pulse text-transparent rounded-lg select-none;
|
||||
@apply bg-zinc-700 bg-opacity-40 animate-pulse text-transparent rounded-lg select-none;
|
||||
}
|
||||
|
||||
/*html:not([data-useragent*="Tizen"]) .selectable, html:not([data-useragent*="Tizen"]) .selectable-offset {*/
|
||||
@@ -38,74 +38,73 @@ a {
|
||||
/* @apply outline-offset-[2px]*/
|
||||
/*}*/
|
||||
|
||||
html:not([data-useragent*="Tizen"]) .selectable {
|
||||
@apply focus:border-primary-500 focus-visible:border-primary-500;
|
||||
html:not([data-useragent*='Tizen']) .selectable {
|
||||
@apply focus:border-primary-500 focus-visible:border-primary-500;
|
||||
}
|
||||
|
||||
html[data-useragent*="Tizen"] .selectable {
|
||||
@apply focus:border-primary-500 focus-within:border-primary-500;
|
||||
html[data-useragent*='Tizen'] .selectable {
|
||||
@apply focus:border-primary-500 focus-within:border-primary-500;
|
||||
}
|
||||
|
||||
.selectable {
|
||||
@apply outline-none outline-0 border-2 border-[#00000000] transition-colors hover:border-primary-500;
|
||||
@apply outline-none outline-0 border-2 border-[#00000000] transition-colors hover:border-primary-500;
|
||||
}
|
||||
|
||||
.selectable:focus, .selectable:focus-within {
|
||||
border-width: 2px;
|
||||
.selectable:focus,
|
||||
.selectable:focus-within {
|
||||
border-width: 2px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.selectable-secondary {
|
||||
@apply outline-none outline-0 border-2 transition-colors hover:border-primary-500;
|
||||
@apply outline-none outline-0 border-2 transition-colors hover:border-primary-500;
|
||||
}
|
||||
|
||||
html:not([data-useragent*="Tizen"]) .selectable-secondary {
|
||||
@apply focus-visible:border-primary-500;
|
||||
html:not([data-useragent*='Tizen']) .selectable-secondary {
|
||||
@apply focus-visible:border-primary-500;
|
||||
}
|
||||
|
||||
html[data-useragent*="Tizen"] .selectable-secondary {
|
||||
@apply focus-within:border-primary-500;
|
||||
html[data-useragent*='Tizen'] .selectable-secondary {
|
||||
@apply focus-within:border-primary-500;
|
||||
}
|
||||
|
||||
.selected {
|
||||
@apply outline-none outline-0 border-2 border-primary-500;
|
||||
@apply outline-none outline-0 border-2 border-primary-500;
|
||||
}
|
||||
|
||||
.unselected {
|
||||
@apply outline-none outline-0 border-2 border-transparent;
|
||||
@apply outline-none outline-0 border-2 border-transparent;
|
||||
}
|
||||
|
||||
.peer-selectable {
|
||||
@apply peer-focus-visible:outline outline-2 outline-primary-500 outline-offset-2;
|
||||
@apply peer-focus-visible:outline outline-2 outline-primary-500 outline-offset-2;
|
||||
}
|
||||
|
||||
.selectable-explicit {
|
||||
@apply focus-within:outline outline-2 outline-[#f0cd6dc2] outline-offset-2;
|
||||
@apply focus-within:outline outline-2 outline-[#f0cd6dc2] outline-offset-2;
|
||||
}
|
||||
|
||||
.header1 {
|
||||
@apply font-semibold text-xl text-secondary-100;
|
||||
@apply font-semibold text-xl text-secondary-100;
|
||||
}
|
||||
|
||||
.header2 {
|
||||
@apply font-semibold text-2xl text-secondary-100;
|
||||
@apply font-semibold text-2xl text-secondary-100;
|
||||
}
|
||||
|
||||
.header3 {
|
||||
@apply font-semibold text-3xl text-secondary-100;
|
||||
@apply font-semibold text-3xl text-secondary-100;
|
||||
}
|
||||
|
||||
.header4 {
|
||||
@apply font-semibold text-4xl text-secondary-100 tracking-wider;
|
||||
@apply font-semibold text-4xl text-secondary-100 tracking-wider;
|
||||
}
|
||||
|
||||
.body {
|
||||
@apply font-medium text-lg text-secondary-300;
|
||||
@apply font-medium text-lg text-secondary-300;
|
||||
}
|
||||
|
||||
@media tv {
|
||||
html {
|
||||
font-size: 24px;
|
||||
}
|
||||
html {
|
||||
font-size: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,36 +3,34 @@
|
||||
*/
|
||||
|
||||
import {
|
||||
hasAacSupport,
|
||||
hasAc3InHlsSupport,
|
||||
hasAc3Support,
|
||||
hasEac3Support,
|
||||
hasMp3AudioSupport
|
||||
hasAacSupport,
|
||||
hasAc3InHlsSupport,
|
||||
hasAc3Support,
|
||||
hasEac3Support,
|
||||
hasMp3AudioSupport
|
||||
} from './mp4-audio-formats';
|
||||
|
||||
/**
|
||||
* List of supported Ts audio codecs
|
||||
*/
|
||||
export function getSupportedTsAudioCodecs(
|
||||
videoTestElement: HTMLVideoElement
|
||||
): string[] {
|
||||
const codecs = [];
|
||||
export function getSupportedTsAudioCodecs(videoTestElement: HTMLVideoElement): string[] {
|
||||
const codecs = [];
|
||||
|
||||
if (hasAacSupport(videoTestElement)) {
|
||||
codecs.push('aac');
|
||||
}
|
||||
if (hasAacSupport(videoTestElement)) {
|
||||
codecs.push('aac');
|
||||
}
|
||||
|
||||
if (hasMp3AudioSupport(videoTestElement)) {
|
||||
codecs.push('mp3');
|
||||
}
|
||||
if (hasMp3AudioSupport(videoTestElement)) {
|
||||
codecs.push('mp3');
|
||||
}
|
||||
|
||||
if (hasAc3Support(videoTestElement) && hasAc3InHlsSupport(videoTestElement)) {
|
||||
codecs.push('ac3');
|
||||
if (hasAc3Support(videoTestElement) && hasAc3InHlsSupport(videoTestElement)) {
|
||||
codecs.push('ac3');
|
||||
|
||||
if (hasEac3Support(videoTestElement)) {
|
||||
codecs.push('eac3');
|
||||
}
|
||||
}
|
||||
if (hasEac3Support(videoTestElement)) {
|
||||
codecs.push('eac3');
|
||||
}
|
||||
}
|
||||
|
||||
return codecs;
|
||||
return codecs;
|
||||
}
|
||||
|
||||
@@ -7,14 +7,12 @@ import { hasH264Support } from './mp4-video-formats';
|
||||
/**
|
||||
* List of supported ts video codecs
|
||||
*/
|
||||
export function getSupportedTsVideoCodecs(
|
||||
videoTestElement: HTMLVideoElement
|
||||
): string[] {
|
||||
const codecs = [];
|
||||
export function getSupportedTsVideoCodecs(videoTestElement: HTMLVideoElement): string[] {
|
||||
const codecs = [];
|
||||
|
||||
if (hasH264Support(videoTestElement)) {
|
||||
codecs.push('h264');
|
||||
}
|
||||
if (hasH264Support(videoTestElement)) {
|
||||
codecs.push('h264');
|
||||
}
|
||||
|
||||
return codecs;
|
||||
return codecs;
|
||||
}
|
||||
|
||||
@@ -2,31 +2,25 @@
|
||||
* @deprecated - Check @/utils/playback-profiles/index
|
||||
*/
|
||||
|
||||
import {
|
||||
hasAv1Support,
|
||||
hasVp8Support,
|
||||
hasVp9Support
|
||||
} from './mp4-video-formats';
|
||||
import { hasAv1Support, hasVp8Support, hasVp9Support } from './mp4-video-formats';
|
||||
|
||||
/**
|
||||
* Get an array of supported codecs WebM video codecs
|
||||
*/
|
||||
export function getSupportedWebMVideoCodecs(
|
||||
videoTestElement: HTMLVideoElement
|
||||
): string[] {
|
||||
const codecs = [];
|
||||
export function getSupportedWebMVideoCodecs(videoTestElement: HTMLVideoElement): string[] {
|
||||
const codecs = [];
|
||||
|
||||
if (hasVp8Support(videoTestElement)) {
|
||||
codecs.push('vp8');
|
||||
}
|
||||
if (hasVp8Support(videoTestElement)) {
|
||||
codecs.push('vp8');
|
||||
}
|
||||
|
||||
if (hasVp9Support(videoTestElement)) {
|
||||
codecs.push('vp9');
|
||||
}
|
||||
if (hasVp9Support(videoTestElement)) {
|
||||
codecs.push('vp9');
|
||||
}
|
||||
|
||||
if (hasAv1Support(videoTestElement)) {
|
||||
codecs.push('av1');
|
||||
}
|
||||
if (hasAv1Support(videoTestElement)) {
|
||||
codecs.push('av1');
|
||||
}
|
||||
|
||||
return codecs;
|
||||
return codecs;
|
||||
}
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
* than ideal.
|
||||
*/
|
||||
export function supportsMediaSource(): boolean {
|
||||
// Browsers that lack a media source implementation will have no reference
|
||||
// to |window.MediaSource|.
|
||||
return !!window.MediaSource;
|
||||
// Browsers that lack a media source implementation will have no reference
|
||||
// to |window.MediaSource|.
|
||||
return !!window.MediaSource;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -31,9 +31,9 @@ export function supportsMediaSource(): boolean {
|
||||
* @returns Determines if user agent of navigator contains a key
|
||||
*/
|
||||
function userAgentContains(key: string): boolean {
|
||||
const userAgent = navigator.userAgent || '';
|
||||
const userAgent = navigator.userAgent || '';
|
||||
|
||||
return userAgent.includes(key);
|
||||
return userAgent.includes(key);
|
||||
}
|
||||
|
||||
/* Desktop Browsers */
|
||||
@@ -44,7 +44,7 @@ function userAgentContains(key: string): boolean {
|
||||
* @returns Determines if browser is Mozilla Firefox
|
||||
*/
|
||||
export function isFirefox(): boolean {
|
||||
return userAgentContains('Firefox/');
|
||||
return userAgentContains('Firefox/');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -54,7 +54,7 @@ export function isFirefox(): boolean {
|
||||
* @returns Determines if browser is Microsoft Edge
|
||||
*/
|
||||
export function isEdge(): boolean {
|
||||
return userAgentContains('Edg/') || userAgentContains('Edge/');
|
||||
return userAgentContains('Edg/') || userAgentContains('Edge/');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -63,7 +63,7 @@ export function isEdge(): boolean {
|
||||
* @returns Determines if browser is Chromium based
|
||||
*/
|
||||
export function isChromiumBased(): boolean {
|
||||
return userAgentContains('Chrome');
|
||||
return userAgentContains('Chrome');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -72,9 +72,9 @@ export function isChromiumBased(): boolean {
|
||||
* @returns Determines if browser is Google Chrome
|
||||
*/
|
||||
export function isChrome(): boolean {
|
||||
// The Edge user agent will also contain the "Chrome" keyword, so we need
|
||||
// to make sure this is not Edge.
|
||||
return userAgentContains('Chrome') && !isEdge() && !isWebOS();
|
||||
// The Edge user agent will also contain the "Chrome" keyword, so we need
|
||||
// to make sure this is not Edge.
|
||||
return userAgentContains('Chrome') && !isEdge() && !isWebOS();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -88,7 +88,7 @@ export function isChrome(): boolean {
|
||||
* @returns Determines if current platform is from Apple
|
||||
*/
|
||||
export function isApple(): boolean {
|
||||
return navigator?.vendor.includes('Apple') && !isTizen();
|
||||
return navigator?.vendor.includes('Apple') && !isTizen();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -97,32 +97,32 @@ export function isApple(): boolean {
|
||||
* @returns The major version number for Safari
|
||||
*/
|
||||
export function safariVersion(): number | undefined {
|
||||
// All iOS browsers and desktop Safari will return true for isApple().
|
||||
if (!isApple()) {
|
||||
return;
|
||||
}
|
||||
// All iOS browsers and desktop Safari will return true for isApple().
|
||||
if (!isApple()) {
|
||||
return;
|
||||
}
|
||||
|
||||
let userAgent = '';
|
||||
let userAgent = '';
|
||||
|
||||
if (navigator.userAgent) {
|
||||
userAgent = navigator.userAgent;
|
||||
}
|
||||
if (navigator.userAgent) {
|
||||
userAgent = navigator.userAgent;
|
||||
}
|
||||
|
||||
// This works for iOS Safari and desktop Safari, which contain something
|
||||
// like "Version/13.0" indicating the major Safari or iOS version.
|
||||
let match = userAgent.match(/Version\/(\d+)/);
|
||||
// This works for iOS Safari and desktop Safari, which contain something
|
||||
// like "Version/13.0" indicating the major Safari or iOS version.
|
||||
let match = userAgent.match(/Version\/(\d+)/);
|
||||
|
||||
if (match) {
|
||||
return Number.parseInt(match[1], /* base= */ 10);
|
||||
}
|
||||
if (match) {
|
||||
return Number.parseInt(match[1], /* base= */ 10);
|
||||
}
|
||||
|
||||
// This works for all other browsers on iOS, which contain something like
|
||||
// "OS 13_3" indicating the major & minor iOS version.
|
||||
match = userAgent.match(/OS (\d+)(?:_\d+)?/);
|
||||
// This works for all other browsers on iOS, which contain something like
|
||||
// "OS 13_3" indicating the major & minor iOS version.
|
||||
match = userAgent.match(/OS (\d+)(?:_\d+)?/);
|
||||
|
||||
if (match) {
|
||||
return Number.parseInt(match[1], /* base= */ 10);
|
||||
}
|
||||
if (match) {
|
||||
return Number.parseInt(match[1], /* base= */ 10);
|
||||
}
|
||||
}
|
||||
|
||||
/* TV Platforms */
|
||||
@@ -133,7 +133,7 @@ export function safariVersion(): number | undefined {
|
||||
* @returns Determines if current platform is Tizen
|
||||
*/
|
||||
export function isTizen(): boolean {
|
||||
return userAgentContains('Tizen');
|
||||
return userAgentContains('Tizen');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -142,7 +142,7 @@ export function isTizen(): boolean {
|
||||
* @returns Determines if current platform is Tizen 2
|
||||
*/
|
||||
export function isTizen2(): boolean {
|
||||
return userAgentContains('Tizen 2');
|
||||
return userAgentContains('Tizen 2');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -152,7 +152,7 @@ export function isTizen2(): boolean {
|
||||
* @memberof BrowserDetector
|
||||
*/
|
||||
export function isTizen3(): boolean {
|
||||
return userAgentContains('Tizen 3');
|
||||
return userAgentContains('Tizen 3');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -162,7 +162,7 @@ export function isTizen3(): boolean {
|
||||
* @memberof BrowserDetector
|
||||
*/
|
||||
export function isTizen4(): boolean {
|
||||
return userAgentContains('Tizen 4');
|
||||
return userAgentContains('Tizen 4');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -172,7 +172,7 @@ export function isTizen4(): boolean {
|
||||
* @memberof BrowserDetector
|
||||
*/
|
||||
export function isTizen5(): boolean {
|
||||
return userAgentContains('Tizen 5');
|
||||
return userAgentContains('Tizen 5');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -182,7 +182,7 @@ export function isTizen5(): boolean {
|
||||
* @memberof BrowserDetector
|
||||
*/
|
||||
export function isTizen55(): boolean {
|
||||
return userAgentContains('Tizen 5.5');
|
||||
return userAgentContains('Tizen 5.5');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -192,50 +192,42 @@ export function isTizen55(): boolean {
|
||||
* @memberof BrowserDetector
|
||||
*/
|
||||
export function isWebOS(): boolean {
|
||||
return userAgentContains('Web0S');
|
||||
return userAgentContains('Web0S');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if current platform is WebOS1
|
||||
*/
|
||||
export function isWebOS1(): boolean {
|
||||
return (
|
||||
isWebOS() &&
|
||||
userAgentContains('AppleWebKit/537') &&
|
||||
!userAgentContains('Chrome/')
|
||||
);
|
||||
return isWebOS() && userAgentContains('AppleWebKit/537') && !userAgentContains('Chrome/');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if current platform is WebOS2
|
||||
*/
|
||||
export function isWebOS2(): boolean {
|
||||
return (
|
||||
isWebOS() &&
|
||||
userAgentContains('AppleWebKit/538') &&
|
||||
!userAgentContains('Chrome/')
|
||||
);
|
||||
return isWebOS() && userAgentContains('AppleWebKit/538') && !userAgentContains('Chrome/');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if current platform is WebOS3
|
||||
*/
|
||||
export function isWebOS3(): boolean {
|
||||
return isWebOS() && userAgentContains('Chrome/38');
|
||||
return isWebOS() && userAgentContains('Chrome/38');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if current platform is WebOS4
|
||||
*/
|
||||
export function isWebOS4(): boolean {
|
||||
return isWebOS() && userAgentContains('Chrome/53');
|
||||
return isWebOS() && userAgentContains('Chrome/53');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if current platform is WebOS5
|
||||
*/
|
||||
export function isWebOS5(): boolean {
|
||||
return isWebOS() && userAgentContains('Chrome/68');
|
||||
return isWebOS() && userAgentContains('Chrome/68');
|
||||
}
|
||||
|
||||
/* Platform Utilities */
|
||||
@@ -244,7 +236,7 @@ export function isWebOS5(): boolean {
|
||||
* Determines if current platform is Android
|
||||
*/
|
||||
export function isAndroid(): boolean {
|
||||
return userAgentContains('Android');
|
||||
return userAgentContains('Android');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -253,27 +245,27 @@ export function isAndroid(): boolean {
|
||||
* @returns Determines if current platform is mobile (Guess)
|
||||
*/
|
||||
export function isMobile(): boolean {
|
||||
let userAgent = '';
|
||||
let userAgent = '';
|
||||
|
||||
if (navigator.userAgent) {
|
||||
userAgent = navigator.userAgent;
|
||||
}
|
||||
if (navigator.userAgent) {
|
||||
userAgent = navigator.userAgent;
|
||||
}
|
||||
|
||||
if (/iPhone|iPad|iPod|Android/.test(userAgent)) {
|
||||
// This is Android, iOS, or iPad < 13.
|
||||
return true;
|
||||
}
|
||||
if (/iPhone|iPad|iPod|Android/.test(userAgent)) {
|
||||
// This is Android, iOS, or iPad < 13.
|
||||
return true;
|
||||
}
|
||||
|
||||
// Starting with iOS 13 on iPad, the user agent string no longer has the
|
||||
// word "iPad" in it. It looks very similar to desktop Safari. This seems
|
||||
// to be intentional on Apple's part.
|
||||
// See: https://forums.developer.apple.com/thread/119186
|
||||
//
|
||||
// So if it's an Apple device with multi-touch support, assume it's a mobile
|
||||
// device. If some future iOS version starts masking their user agent on
|
||||
// both iPhone & iPad, this clause should still work. If a future
|
||||
// multi-touch desktop Mac is released, this will need some adjustment.
|
||||
return isApple() && navigator.maxTouchPoints > 1;
|
||||
// Starting with iOS 13 on iPad, the user agent string no longer has the
|
||||
// word "iPad" in it. It looks very similar to desktop Safari. This seems
|
||||
// to be intentional on Apple's part.
|
||||
// See: https://forums.developer.apple.com/thread/119186
|
||||
//
|
||||
// So if it's an Apple device with multi-touch support, assume it's a mobile
|
||||
// device. If some future iOS version starts masking their user agent on
|
||||
// both iPhone & iPad, this clause should still work. If a future
|
||||
// multi-touch desktop Mac is released, this will need some adjustment.
|
||||
return isApple() && navigator.maxTouchPoints > 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -282,7 +274,7 @@ export function isMobile(): boolean {
|
||||
* @returns Determines if platform is a Smart TV
|
||||
*/
|
||||
export function isTv(): boolean {
|
||||
return isTizen() || isWebOS();
|
||||
return isTizen() || isWebOS();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -291,7 +283,7 @@ export function isTv(): boolean {
|
||||
* @returns Determines if the device is a PS4
|
||||
*/
|
||||
export function isPs4(): boolean {
|
||||
return userAgentContains('playstation 4');
|
||||
return userAgentContains('playstation 4');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -300,5 +292,5 @@ export function isPs4(): boolean {
|
||||
* @returns Determines if the device is a Xbox
|
||||
*/
|
||||
export function isXbox(): boolean {
|
||||
return userAgentContains('xbox');
|
||||
return userAgentContains('xbox');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user