mirror of
https://github.com/streamyfin/streamyfin.git
synced 2026-06-01 19:48:28 +01:00
refactor: remove dead code
Delete unused components, hooks and utilities that have no remaining references, and drop their now-unused exports (augmentations/string, Number.prototype.hoursToMilliseconds). Also drop the dangling ExampleGlobalModalUsage reference from GLOBAL_MODAL_GUIDE.md.
This commit is contained in:
@@ -1,18 +0,0 @@
|
||||
/**
|
||||
* Convert bits to megabits or gigabits
|
||||
*
|
||||
* Return nice looking string
|
||||
* If under 1000Mb, return XXXMB, else return X.XGB
|
||||
*/
|
||||
|
||||
export function convertBitsToMegabitsOrGigabits(bits?: number | null): string {
|
||||
if (!bits) return "0MB";
|
||||
|
||||
const megabits = bits / 1000000;
|
||||
|
||||
if (megabits < 1000) {
|
||||
return `${Math.round(megabits)}MB`;
|
||||
}
|
||||
const gigabits = megabits / 1000;
|
||||
return `${gigabits.toFixed(1)}GB`;
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
import {
|
||||
BaseItemKind,
|
||||
CollectionType,
|
||||
} from "@jellyfin/sdk/lib/generated-client";
|
||||
|
||||
/**
|
||||
* Converts a ColletionType to a BaseItemKind (also called ItemType)
|
||||
*
|
||||
* CollectionTypes
|
||||
* readonly Unknown: "unknown";
|
||||
readonly Movies: "movies";
|
||||
readonly Tvshows: "tvshows";
|
||||
readonly Trailers: "trailers";
|
||||
readonly Homevideos: "homevideos";
|
||||
readonly Boxsets: "boxsets";
|
||||
readonly Books: "books";
|
||||
readonly Photos: "photos";
|
||||
readonly Livetv: "livetv";
|
||||
readonly Playlists: "playlists";
|
||||
readonly Folders: "folders";
|
||||
*/
|
||||
export const colletionTypeToItemType = (
|
||||
collectionType?: CollectionType | null,
|
||||
): BaseItemKind | undefined => {
|
||||
if (!collectionType) return undefined;
|
||||
|
||||
switch (collectionType) {
|
||||
case CollectionType.Movies:
|
||||
return BaseItemKind.Movie;
|
||||
case CollectionType.Tvshows:
|
||||
return BaseItemKind.Series;
|
||||
case CollectionType.Homevideos:
|
||||
return BaseItemKind.Video;
|
||||
case CollectionType.Books:
|
||||
return BaseItemKind.Book;
|
||||
case CollectionType.Playlists:
|
||||
return BaseItemKind.Playlist;
|
||||
case CollectionType.Folders:
|
||||
return BaseItemKind.Folder;
|
||||
case CollectionType.Photos:
|
||||
return BaseItemKind.Photo;
|
||||
case CollectionType.Trailers:
|
||||
return BaseItemKind.Trailer;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
};
|
||||
@@ -1,56 +0,0 @@
|
||||
import axios from "axios";
|
||||
|
||||
export interface SubtitleTrack {
|
||||
index: number;
|
||||
name: string;
|
||||
uri: string;
|
||||
language: string;
|
||||
default: boolean;
|
||||
forced: boolean;
|
||||
autoSelect: boolean;
|
||||
}
|
||||
|
||||
export async function parseM3U8ForSubtitles(
|
||||
url: string,
|
||||
): Promise<SubtitleTrack[]> {
|
||||
try {
|
||||
const response = await axios.get(url, { responseType: "text" });
|
||||
const lines = response.data.split(/\r?\n/);
|
||||
const subtitleTracks: SubtitleTrack[] = [];
|
||||
let index = 0;
|
||||
|
||||
lines.forEach((line: string) => {
|
||||
if (line.startsWith("#EXT-X-MEDIA:TYPE=SUBTITLES")) {
|
||||
const attributes = parseAttributes(line);
|
||||
const track: SubtitleTrack = {
|
||||
index: index++,
|
||||
name: attributes.NAME || "",
|
||||
uri: attributes.URI || "",
|
||||
language: attributes.LANGUAGE || "",
|
||||
default: attributes.DEFAULT === "YES",
|
||||
forced: attributes.FORCED === "YES",
|
||||
autoSelect: attributes.AUTOSELECT === "YES",
|
||||
};
|
||||
subtitleTracks.push(track);
|
||||
}
|
||||
});
|
||||
|
||||
return subtitleTracks;
|
||||
} catch (error) {
|
||||
console.error("Failed to fetch or parse the M3U8 file:", error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
function parseAttributes(line: string): { [key: string]: string } {
|
||||
const attributes: { [key: string]: string } = {};
|
||||
const regex = /([A-Z-]+)=(?:"([^"]*)"|([^,]*))/g;
|
||||
|
||||
for (const match of line.matchAll(regex)) {
|
||||
const key = match[1];
|
||||
const value = match[2] ?? match[3]; // quoted or unquoted
|
||||
attributes[key] = value;
|
||||
}
|
||||
|
||||
return attributes;
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
import type { Api } from "@jellyfin/sdk";
|
||||
import type { AxiosResponse } from "axios";
|
||||
import type { Settings } from "../../atoms/settings";
|
||||
import { generateDeviceProfile } from "../../profiles/native";
|
||||
import { getAuthHeaders } from "../jellyfin";
|
||||
|
||||
interface PostCapabilitiesParams {
|
||||
api: Api | null | undefined;
|
||||
itemId: string | null | undefined;
|
||||
sessionId: string | null | undefined;
|
||||
deviceProfile: Settings["deviceProfile"];
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks a media item as not played for a specific user.
|
||||
*
|
||||
* @param params - The parameters for marking an item as not played
|
||||
* @returns A promise that resolves to true if the operation was successful, false otherwise
|
||||
*/
|
||||
export const postCapabilities = async ({
|
||||
api,
|
||||
itemId,
|
||||
sessionId,
|
||||
}: PostCapabilitiesParams): Promise<AxiosResponse> => {
|
||||
if (!api || !itemId || !sessionId) {
|
||||
throw new Error("Missing parameters for marking item as not played");
|
||||
}
|
||||
|
||||
try {
|
||||
const d = api.axiosInstance.post(
|
||||
`${api.basePath}/Sessions/Capabilities/Full`,
|
||||
{
|
||||
playableMediaTypes: ["Audio", "Video"],
|
||||
supportedCommands: [
|
||||
"PlayState",
|
||||
"Play",
|
||||
"ToggleFullscreen",
|
||||
"DisplayMessage",
|
||||
"Mute",
|
||||
"Unmute",
|
||||
"SetVolume",
|
||||
"ToggleMute",
|
||||
],
|
||||
supportsMediaControl: true,
|
||||
id: sessionId,
|
||||
DeviceProfile: generateDeviceProfile(),
|
||||
},
|
||||
{
|
||||
headers: getAuthHeaders(api),
|
||||
},
|
||||
);
|
||||
return d;
|
||||
} catch (_error) {
|
||||
throw new Error("Failed to mark as not played");
|
||||
}
|
||||
};
|
||||
@@ -1,44 +0,0 @@
|
||||
import type { Api } from "@jellyfin/sdk";
|
||||
import type { BaseItemDto } from "@jellyfin/sdk/lib/generated-client/models";
|
||||
import { getAuthHeaders } from "../jellyfin";
|
||||
|
||||
interface NextUpParams {
|
||||
itemId?: string | null;
|
||||
userId?: string | null;
|
||||
api?: Api | null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the next up episodes for a series or all series for a user.
|
||||
*
|
||||
* @param params - The parameters for fetching next up episodes
|
||||
* @returns A promise that resolves to an array of BaseItemDto representing the next up episodes
|
||||
*/
|
||||
export const nextUp = async ({
|
||||
itemId,
|
||||
userId,
|
||||
api,
|
||||
}: NextUpParams): Promise<BaseItemDto[]> => {
|
||||
if (!userId || !api) {
|
||||
console.error("Invalid parameters for nextUp: missing userId or api");
|
||||
return [];
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await api.axiosInstance.get<{ Items: BaseItemDto[] }>(
|
||||
`${api.basePath}/Shows/NextUp`,
|
||||
{
|
||||
params: {
|
||||
SeriesId: itemId || undefined,
|
||||
UserId: userId,
|
||||
Fields: "MediaSourceCount",
|
||||
},
|
||||
headers: getAuthHeaders(api),
|
||||
},
|
||||
);
|
||||
|
||||
return response.data.Items;
|
||||
} catch (_error) {
|
||||
return [];
|
||||
}
|
||||
};
|
||||
@@ -1,34 +0,0 @@
|
||||
import type { Api } from "@jellyfin/sdk";
|
||||
import type { BaseItemDto } from "@jellyfin/sdk/lib/generated-client/models";
|
||||
import { getUserLibraryApi } from "@jellyfin/sdk/lib/utils/api";
|
||||
|
||||
/**
|
||||
* Retrieves an item by its ID from the API.
|
||||
*
|
||||
* @param api - The Jellyfin API instance.
|
||||
* @param itemId - The ID of the item to retrieve.
|
||||
* @returns The item object or undefined if no item matches the ID.
|
||||
*/
|
||||
export const getItemById = async (
|
||||
api?: Api | null | undefined,
|
||||
itemId?: string | null | undefined,
|
||||
): Promise<BaseItemDto | undefined> => {
|
||||
if (!api || !itemId) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
try {
|
||||
const itemData = await getUserLibraryApi(api).getItem({ itemId });
|
||||
|
||||
const item = itemData.data;
|
||||
if (!item) {
|
||||
console.error("No items found with the specified ID:", itemId);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return item;
|
||||
} catch (error) {
|
||||
console.error("Failed to retrieve the item:", error);
|
||||
throw new Error(`Failed to retrieve the item due to an error: ${error}`);
|
||||
}
|
||||
};
|
||||
@@ -1,5 +0,0 @@
|
||||
// seconds to ticks util
|
||||
|
||||
export function secondsToTicks(seconds: number): number {
|
||||
return seconds * 10000000;
|
||||
}
|
||||
Reference in New Issue
Block a user