feat: Emby support (#234)
* fix: support credential extraction from Emby * fix: minor compatibility with emby for retrieving albums * fix: rename credentials and save credentials type * fix: weird issue when changing libraries * fix: correctly map platform names in auth header * chore: properly carry over old settings * fix: only enable playlists on jellyfin * fix: remove jellyfin mentions * fix: incorporate jellyfin and emby as mentions
This commit is contained in:
@@ -36,7 +36,9 @@ export async function retrieveAlbum(id: string): Promise<Album> {
|
||||
const latestAlbumsOptions = {
|
||||
IncludeItemTypes: 'MusicAlbum',
|
||||
Fields: 'DateCreated',
|
||||
SortOrder: 'Ascending',
|
||||
SortOrder: 'Descending',
|
||||
SortBy: 'DateCreated',
|
||||
Recursive: 'true',
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -51,7 +53,8 @@ export async function retrieveRecentAlbums(numberOfAlbums = 24) {
|
||||
const params = new URLSearchParams(options).toString();
|
||||
|
||||
// Retrieve albums
|
||||
return fetchApi<Album[]>(({ user_id }) => `/Users/${user_id}/Items/Latest?${params}`);
|
||||
return fetchApi<{ Items: Album[] }>(({ user_id }) => `/Users/${user_id}/Items?${params}`)
|
||||
.then((d) => d.Items);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,6 +1,17 @@
|
||||
import type { AppState, Store } from '@/store';
|
||||
import { Platform } from 'react-native';
|
||||
import { version } from '../../../package.json';
|
||||
|
||||
type Credentials = AppState['settings']['jellyfin'];
|
||||
type Credentials = AppState['settings']['credentials'];
|
||||
|
||||
/** Map the output of `Platform.OS`, so that Jellyfin can understand it. */
|
||||
const deviceMap: Record<typeof Platform['OS'], string> = {
|
||||
ios: 'iOS',
|
||||
android: 'Android',
|
||||
macos: 'macOS',
|
||||
web: 'Web',
|
||||
windows: 'Windows',
|
||||
};
|
||||
|
||||
/**
|
||||
* This is a convenience function that converts a set of Jellyfin credentials
|
||||
@@ -10,7 +21,7 @@ type Credentials = AppState['settings']['jellyfin'];
|
||||
function generateConfig(credentials: Credentials): RequestInit {
|
||||
return {
|
||||
headers: {
|
||||
'X-Emby-Authorization': `MediaBrowser Client="", Device="", DeviceId="", Version="", Token="${credentials?.access_token}"`
|
||||
'X-Emby-Authorization': `MediaBrowser Client="Fintunes", Device="${deviceMap[Platform.OS]}", DeviceId="${credentials?.device_id}", Version="${version}", Token="${credentials?.access_token}"`
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -36,7 +47,7 @@ export async function fetchApi<T>(
|
||||
parseResponse = true
|
||||
) {
|
||||
// Retrieve the latest credentials from the Redux store
|
||||
const credentials = asyncFetchStore().getState().settings.jellyfin;
|
||||
const credentials = asyncFetchStore().getState().settings.credentials;
|
||||
|
||||
// GUARD: Check that the credentials are present
|
||||
if (!credentials) {
|
||||
@@ -95,7 +106,7 @@ export async function fetchApi<T>(
|
||||
* Retrieve an image URL for a given ItemId
|
||||
*/
|
||||
export function getImage(ItemId: string): string {
|
||||
const credentials = asyncFetchStore().getState().settings.jellyfin;
|
||||
const credentials = asyncFetchStore().getState().settings.credentials;
|
||||
const uri = encodeURI(`${credentials?.uri}/Items/${ItemId}/Images/Primary?format=jpeg`);
|
||||
return uri;
|
||||
}
|
||||
|
||||
@@ -48,6 +48,7 @@ export async function sendPlaybackEvent(
|
||||
ItemId: activeTrack.backendId,
|
||||
CanSeek: true,
|
||||
PlaybackStartTimeTicks: null,
|
||||
PlaySessionId: activeTrack?.backendId || 'fintunes',
|
||||
};
|
||||
|
||||
// Generate a config from the credentials and dispatch the request
|
||||
|
||||
@@ -27,7 +27,7 @@ export async function retrieveAllPlaylists() {
|
||||
* Retrieve all albums that are available on the Jellyfin server
|
||||
*/
|
||||
export async function retrievePlaylistTracks(ItemId: string) {
|
||||
const credentials = asyncFetchStore().getState().settings.jellyfin;
|
||||
const credentials = asyncFetchStore().getState().settings.credentials;
|
||||
const singlePlaylistOptions = {
|
||||
SortBy: 'IndexNumber,SortName',
|
||||
UserId: credentials?.user_id || '',
|
||||
|
||||
@@ -30,7 +30,7 @@ const baseTrackOptions: Record<string, string> = {
|
||||
* Generate the track streaming url from the trackId
|
||||
*/
|
||||
export function generateTrackUrl(trackId: string) {
|
||||
const credentials = store.getState().settings.jellyfin;
|
||||
const credentials = store.getState().settings.credentials;
|
||||
const trackOptions = {
|
||||
...baseTrackOptions,
|
||||
UserId: credentials?.user_id || '',
|
||||
|
||||
Reference in New Issue
Block a user