Skip to content

Commit

Permalink
Merge branch 'master' into add-published-server-uri-examples
Browse files Browse the repository at this point in the history
  • Loading branch information
scottmckenzie authored Oct 9, 2024
2 parents 99d23b4 + 1cfaf1e commit 101f825
Show file tree
Hide file tree
Showing 18 changed files with 166 additions and 84 deletions.
14 changes: 7 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@
"@fontsource/noto-sans-sc": "5.1.0",
"@fontsource/noto-sans-tc": "5.1.0",
"@jellyfin/libass-wasm": "4.2.3",
"@jellyfin/sdk": "0.0.0-unstable.202410020501",
"@jellyfin/sdk": "0.0.0-unstable.202410080502",
"@mui/icons-material": "5.16.7",
"@mui/material": "5.16.7",
"@mui/x-date-pickers": "7.18.0",
Expand Down
6 changes: 3 additions & 3 deletions src/apps/dashboard/routes/users/access.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import type { BaseItemDto, DeviceInfoDto, UserDto } from '@jellyfin/sdk/lib/generated-client';
import React, { useCallback, useEffect, useState, useRef } from 'react';
import React, { useCallback, useEffect, useState, useRef, useMemo } from 'react';
import { useSearchParams } from 'react-router-dom';

import loading from '../../../../components/loading/loading';
import libraryMenu from '../../../../scripts/libraryMenu';
import globalize from '../../../../lib/globalize';
import toast from '../../../../components/toast/toast';
import SectionTabs from '../../../../components/dashboard/users/SectionTabs';
Expand All @@ -28,6 +27,7 @@ const UserLibraryAccess = () => {
const [channelsItems, setChannelsItems] = useState<ItemsArr[]>([]);
const [mediaFoldersItems, setMediaFoldersItems] = useState<ItemsArr[]>([]);
const [devicesItems, setDevicesItems] = useState<ItemsArr[]>([]);
const libraryMenu = useMemo(async () => ((await import('../../../../scripts/libraryMenu')).default), []);

const element = useRef<HTMLDivElement>(null);

Expand Down Expand Up @@ -133,7 +133,7 @@ const UserLibraryAccess = () => {

const loadUser = useCallback((user: UserDto, mediaFolders: BaseItemDto[], channels: BaseItemDto[], devices: DeviceInfoDto[]) => {
setUserName(user.Name || '');
libraryMenu.setTitle(user.Name);
void libraryMenu.then(menu => menu.setTitle(user.Name));
loadChannels(user, channels);
loadMediaFolders(user, mediaFolders);
loadDevices(user, devices);
Expand Down
6 changes: 3 additions & 3 deletions src/apps/dashboard/routes/users/parentalcontrol.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@ import type { AccessSchedule, ParentalRating, UserDto } from '@jellyfin/sdk/lib/
import { UnratedItem } from '@jellyfin/sdk/lib/generated-client/models/unrated-item';
import { DynamicDayOfWeek } from '@jellyfin/sdk/lib/generated-client/models/dynamic-day-of-week';
import escapeHTML from 'escape-html';
import React, { useCallback, useEffect, useState, useRef } from 'react';
import React, { useCallback, useEffect, useState, useRef, useMemo } from 'react';
import { useSearchParams } from 'react-router-dom';

import globalize from '../../../../lib/globalize';
import LibraryMenu from '../../../../scripts/libraryMenu';
import AccessScheduleList from '../../../../components/dashboard/users/AccessScheduleList';
import TagList from '../../../../components/dashboard/users/TagList';
import ButtonElement from '../../../../elements/ButtonElement';
Expand Down Expand Up @@ -69,6 +68,7 @@ const UserParentalControl = () => {
const [ accessSchedules, setAccessSchedules ] = useState<AccessSchedule[]>([]);
const [ allowedTags, setAllowedTags ] = useState<string[]>([]);
const [ blockedTags, setBlockedTags ] = useState<string[]>([]);
const libraryMenu = useMemo(async () => ((await import('../../../../scripts/libraryMenu')).default), []);

const element = useRef<HTMLDivElement>(null);

Expand Down Expand Up @@ -219,7 +219,7 @@ const UserParentalControl = () => {
}

setUserName(user.Name || '');
LibraryMenu.setTitle(user.Name);
void libraryMenu.then(menu => menu.setTitle(user.Name));
loadUnratedItems(user);

loadAllowedTags(user.Policy?.AllowedTags || []);
Expand Down
7 changes: 4 additions & 3 deletions src/apps/dashboard/routes/users/profile.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import type { BaseItemDto, NameIdPair, SyncPlayUserAccessType, UserDto } from '@jellyfin/sdk/lib/generated-client';
import escapeHTML from 'escape-html';
import React, { useCallback, useEffect, useState, useRef } from 'react';
import React, { useCallback, useEffect, useState, useRef, useMemo } from 'react';
import { useSearchParams } from 'react-router-dom';

import Dashboard from '../../../../utils/dashboard';
import globalize from '../../../../lib/globalize';
import LibraryMenu from '../../../../scripts/libraryMenu';
import ButtonElement from '../../../../elements/ButtonElement';
import CheckBoxElement from '../../../../elements/CheckBoxElement';
import InputElement from '../../../../elements/InputElement';
Expand Down Expand Up @@ -42,6 +41,7 @@ const UserEdit = () => {
const [ deleteFoldersAccess, setDeleteFoldersAccess ] = useState<ResetProvider[]>([]);
const [ authProviders, setAuthProviders ] = useState<NameIdPair[]>([]);
const [ passwordResetProviders, setPasswordResetProviders ] = useState<NameIdPair[]>([]);
const libraryMenu = useMemo(async () => ((await import('../../../../scripts/libraryMenu')).default), []);

const [ authenticationProviderId, setAuthenticationProviderId ] = useState('');
const [ passwordResetProviderId, setPasswordResetProviderId ] = useState('');
Expand Down Expand Up @@ -147,7 +147,8 @@ const UserEdit = () => {
txtUserName.disabled = false;
txtUserName.removeAttribute('disabled');

LibraryMenu.setTitle(user.Name);
void libraryMenu.then(menu => menu.setTitle(user.Name));

setUserDto(user);
(page.querySelector('#txtUserName') as HTMLInputElement).value = user.Name || '';
(page.querySelector('.chkIsAdmin') as HTMLInputElement).checked = !!user.Policy?.IsAdministrator;
Expand Down
6 changes: 3 additions & 3 deletions src/apps/stable/routes/user/userprofile.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import type { UserDto } from '@jellyfin/sdk/lib/generated-client';
import { ImageType } from '@jellyfin/sdk/lib/generated-client/models/image-type';
import React, { FunctionComponent, useEffect, useState, useRef, useCallback } from 'react';
import React, { FunctionComponent, useEffect, useState, useRef, useCallback, useMemo } from 'react';
import { useSearchParams } from 'react-router-dom';

import Dashboard from '../../../../utils/dashboard';
import globalize from '../../../../lib/globalize';
import LibraryMenu from '../../../../scripts/libraryMenu';
import { appHost } from '../../../../components/apphost';
import confirm from '../../../../components/confirm/confirm';
import ButtonElement from '../../../../elements/ButtonElement';
Expand All @@ -18,6 +17,7 @@ const UserProfile: FunctionComponent = () => {
const [ searchParams ] = useSearchParams();
const userId = searchParams.get('userId');
const [ userName, setUserName ] = useState('');
const libraryMenu = useMemo(async () => ((await import('../../../../scripts/libraryMenu')).default), []);

const element = useRef<HTMLDivElement>(null);

Expand All @@ -41,7 +41,7 @@ const UserProfile: FunctionComponent = () => {
}

setUserName(user.Name);
LibraryMenu.setTitle(user.Name);
void libraryMenu.then(menu => menu.setTitle(user.Name));

let imageUrl = 'assets/img/avatar.png';
if (user.PrimaryImageTag) {
Expand Down
6 changes: 3 additions & 3 deletions src/components/dashboard/users/UserPasswordForm.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import React, { FunctionComponent, useCallback, useEffect, useRef } from 'react';
import React, { FunctionComponent, useCallback, useEffect, useMemo, useRef } from 'react';
import type { UserDto } from '@jellyfin/sdk/lib/generated-client';
import Dashboard from '../../../utils/dashboard';
import globalize from '../../../lib/globalize';
import LibraryMenu from '../../../scripts/libraryMenu';
import confirm from '../../confirm/confirm';
import loading from '../../loading/loading';
import toast from '../../toast/toast';
Expand All @@ -16,6 +15,7 @@ type IProps = {
const UserPasswordForm: FunctionComponent<IProps> = ({ userId }: IProps) => {
const element = useRef<HTMLDivElement>(null);
const user = useRef<UserDto>();
const libraryMenu = useMemo(async () => ((await import('../../../scripts/libraryMenu')).default), []);

const loadUser = useCallback(async () => {
const page = element.current;
Expand All @@ -37,7 +37,7 @@ const UserPasswordForm: FunctionComponent<IProps> = ({ userId }: IProps) => {
throw new Error('Unexpected null user policy or configuration');
}

LibraryMenu.setTitle(user.current.Name);
(await libraryMenu).setTitle(user.current.Name);

if (user.current.HasConfiguredPassword) {
if (!user.current.Policy?.IsAdministrator) {
Expand Down
12 changes: 10 additions & 2 deletions src/components/playback/playbackmanager.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { MediaType } from '@jellyfin/sdk/lib/generated-client/models/media-type'

import { MediaError } from 'types/mediaError';
import { getMediaError } from 'utils/mediaError';
import { BaseItemKind } from '@jellyfin/sdk/lib/generated-client/models/base-item-kind.js';

const UNLIMITED_ITEMS = -1;

Expand Down Expand Up @@ -2573,8 +2574,15 @@ export class PlaybackManager {
}

const apiClient = ServerConnections.getApiClient(item.ServerId);
const mediaSourceId = playOptions.mediaSourceId || item.Id;
const getMediaStreams = apiClient.getItem(apiClient.getCurrentUserId(), mediaSourceId)
let mediaSourceId;

const isLiveTv = [BaseItemKind.TvChannel, BaseItemKind.LiveTvChannel].includes(item.Type);

if (!isLiveTv) {
mediaSourceId = playOptions.mediaSourceId || item.Id;
}

const getMediaStreams = isLiveTv ? Promise.resolve([]) : apiClient.getItem(apiClient.getCurrentUserId(), mediaSourceId)
.then(fullItem => {
return fullItem.MediaStreams;
});
Expand Down
10 changes: 5 additions & 5 deletions src/controllers/dashboard/devices/device.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,21 @@ import Dashboard from '../../../utils/dashboard';
import { getParameterByName } from '../../../utils/url.ts';

function load(page, device, deviceOptions) {
page.querySelector('#txtCustomName', page).value = deviceOptions.CustomName || '';
page.querySelector('#txtCustomName', page).value = deviceOptions?.CustomName || '';
page.querySelector('.reportedName', page).innerText = device.Name || '';
}

function loadData() {
const page = this;
loading.show();
const id = getParameterByName('id');
const promise1 = ApiClient.getJSON(ApiClient.getUrl('Devices/Info', {
const device = ApiClient.getJSON(ApiClient.getUrl('Devices/Info', {
Id: id
}));
const promise2 = ApiClient.getJSON(ApiClient.getUrl('Devices/Options', {
const deviceOptions = ApiClient.getJSON(ApiClient.getUrl('Devices/Options', {
Id: id
}));
Promise.all([promise1, promise2]).then(function (responses) {
})).catch(() => undefined);
Promise.all([device, deviceOptions]).then(function (responses) {
load(page, responses[0], responses[1]);
loading.hide();
});
Expand Down
16 changes: 13 additions & 3 deletions src/strings/be-by.json
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@
"HeaderYears": "Гады",
"LabelValue": "Значэнне",
"Image": "Малюнак",
"LastSeen": "Апошні раз бачылі {0}",
"LastSeen": "Апошняе дзеянне {0}",
"List": "Спіс",
"Live": "Трансляцыя",
"MediaInfoAnamorphic": "Анаморфны",
Expand Down Expand Up @@ -1760,7 +1760,7 @@
"LogLevel.Error": "Памылка",
"LabelTrackGain": "Узмацненне дарожкі",
"GoHome": "На галоўную",
"SelectAudioNormalizationHelp": "Узмацненне дарожкі - рэгулюе гучнасць кожнай дарожкі, каб яны прайграваліся з аднолькавай гучнасцю. Узмацненне альбома - рэгулюе гучнасць толькі ўсіх дарожак у альбоме, захоўваючы дынамічны дыяпазон альбома.",
"SelectAudioNormalizationHelp": "Узмацненне дарожкі - рэгулюе гучнасць кожнай дарожкі, каб яны прайграваліся з аднолькавай гучнасцю. Узмацненне альбома - рэгулюе гучнасць толькі ўсіх дарожак у альбоме, захоўваючы дынамічны дыяпазон альбома. Пераключэнне паміж \"Выкл\" і іншымі опцыямі патрабуе перазапуску бягучага прайгравання.",
"SearchResultsEmpty": "Выбачайце! Няма вынікаў для \"{0}\"",
"UnknownError": "Адбылася невядомая памылка.",
"LabelIsHearingImpaired": "Для людзей з парушэннем слыху (SDH)",
Expand Down Expand Up @@ -1893,5 +1893,15 @@
"PluginEnableError": "Адбылася памылка пры ўключэнні плагіна.",
"PluginLoadConfigError": "Адбылася памылка падчас атрымання старонак канфігурацыі плагіна.",
"PluginLoadRepoError": "Адбылася памылка падчас атрымання дэталяў плагіна з рэпазітара.",
"PluginUninstallError": "Адбылася памылка пры выдаленні плагіна."
"PluginUninstallError": "Адбылася памылка пры выдаленні плагіна.",
"HeaderAudioAdvanced": "Пашыраны аўдыё",
"EnableHi10p": "Уключыць профіль H.264 High 10",
"HeaderUploadLyrics": "Спампаваць тэксты песень",
"DateModified": "Дата змяненняў",
"DisableVbrAudioEncodingHelp": "Забараніць серверу кадаваць аўдыя з VBR для гэтага кліента.",
"HeaderPreviewLyrics": "Папярэдні прагляд тэкстаў песень",
"LabelIsSynced": "Сінхранізавана",
"LabelDuration": "Працягласць",
"NoLyricsSearchResultsFound": "Тэксты песень не знойдзены.",
"FallbackMaxStreamingBitrateHelp": "Максімальны бітрэйт плыні выкарыстоўваецца ў якасці запаснога, калі ffprobe не можа вызначыць бітрэйт зыходнага патоку. Гэта дапамагае прадухіліць кліенты ад запытаў празмерна высокага бітрэйту транскадавання, які можа прывесці да збою прайгравальніка і перагрузкі кадавальніка."
}
2 changes: 1 addition & 1 deletion src/strings/cs.json
Original file line number Diff line number Diff line change
Expand Up @@ -1780,7 +1780,7 @@
"LabelSelectAudioNormalization": "Normalizace hlasitosti",
"LabelAlbumGain": "Na úrovni alba",
"LabelTrackGain": "Na úrovni skladby",
"SelectAudioNormalizationHelp": "Normalizace na úrovni skladby upraví hlasitost všech skladeb tak, aby byla všude stejná. Normalizace na úrovni alba upraví hlasitost všech skladeb tak, aby byla hlasitost stejná v rámci jednotlivých alb.",
"SelectAudioNormalizationHelp": "Normalizace na úrovni skladby upraví hlasitost všech skladeb tak, aby byla všude stejná. Normalizace na úrovni alba upraví hlasitost všech skladeb tak, aby byla hlasitost stejná v rámci jednotlivých alb. Vypnutí a následné zapnutí vyžaduje restart aktuálně hrající skladby.",
"SearchResultsEmpty": "Pro “{0}” nebylo nic nalezeno",
"HeaderAllRecordings": "Všechny nahrávky",
"LabelBuildVersion": "Verze sestavení",
Expand Down
Loading

0 comments on commit 101f825

Please sign in to comment.