From 575da306b03eea3561de8d7dbe1b4b69674c7b2b Mon Sep 17 00:00:00 2001 From: Brandon Cohen Date: Tue, 2 Aug 2022 02:41:09 -0400 Subject: [PATCH] feat: plex deep links for iOS devices (#2680) --- server/entity/Media.ts | 7 +++++ src/components/MovieDetails/index.tsx | 33 ++++++++++++++++++++---- src/components/TvDetails/index.tsx | 37 ++++++++++++++++++++------- 3 files changed, 63 insertions(+), 14 deletions(-) diff --git a/server/entity/Media.ts b/server/entity/Media.ts index 9d106d4f5..4de7698b5 100644 --- a/server/entity/Media.ts +++ b/server/entity/Media.ts @@ -145,6 +145,9 @@ class Media { public plexUrl?: string; public plexUrl4k?: string; + public iOSPlexUrl?: string; + public iOSPlexUrl4k?: string; + public tautulliUrl?: string; public tautulliUrl4k?: string; @@ -164,6 +167,8 @@ class Media { this.ratingKey }`; + this.iOSPlexUrl = `plex://preplay/?metadataKey=%2Flibrary%2Fmetadata%2F${this.ratingKey}&server=${machineId}`; + if (tautulliUrl) { this.tautulliUrl = `${tautulliUrl}/info?rating_key=${this.ratingKey}`; } @@ -176,6 +181,8 @@ class Media { this.ratingKey4k }`; + this.iOSPlexUrl4k = `plex://preplay/?metadataKey=%2Flibrary%2Fmetadata%2F${this.ratingKey4k}&server=${machineId}`; + if (tautulliUrl) { this.tautulliUrl4k = `${tautulliUrl}/info?rating_key=${this.ratingKey4k}`; } diff --git a/src/components/MovieDetails/index.tsx b/src/components/MovieDetails/index.tsx index 8dd00159c..fb749b882 100644 --- a/src/components/MovieDetails/index.tsx +++ b/src/components/MovieDetails/index.tsx @@ -113,6 +113,30 @@ const MovieDetails: React.FC = ({ movie }) => { setShowManager(router.query.manage == '1' ? true : false); }, [router.query.manage]); + const [plexUrl, setPlexUrl] = useState(data?.mediaInfo?.plexUrl); + const [plexUrl4k, setPlexUrl4k] = useState(data?.mediaInfo?.plexUrl4k); + + useEffect(() => { + if (data) { + if ( + /iPad|iPhone|iPod/.test(navigator.userAgent) || + (navigator.userAgent === 'MacIntel' && navigator.maxTouchPoints > 1) + ) { + setPlexUrl(data.mediaInfo?.iOSPlexUrl); + setPlexUrl4k(data.mediaInfo?.iOSPlexUrl4k); + } else { + setPlexUrl(data.mediaInfo?.plexUrl); + setPlexUrl4k(data.mediaInfo?.plexUrl4k); + } + } + }, [ + data, + data?.mediaInfo?.iOSPlexUrl, + data?.mediaInfo?.iOSPlexUrl4k, + data?.mediaInfo?.plexUrl, + data?.mediaInfo?.plexUrl4k, + ]); + if (!data && !error) { return ; } @@ -125,32 +149,31 @@ const MovieDetails: React.FC = ({ movie }) => { const mediaLinks: PlayButtonLink[] = []; if ( - data.mediaInfo?.plexUrl && + plexUrl && hasPermission([Permission.REQUEST, Permission.REQUEST_MOVIE], { type: 'or', }) ) { mediaLinks.push({ text: intl.formatMessage(messages.playonplex), - url: data.mediaInfo?.plexUrl, + url: plexUrl, svg: , }); } if ( settings.currentSettings.movie4kEnabled && - data.mediaInfo?.plexUrl4k && + plexUrl4k && hasPermission([Permission.REQUEST_4K, Permission.REQUEST_4K_MOVIE], { type: 'or', }) ) { mediaLinks.push({ text: intl.formatMessage(messages.play4konplex), - url: data.mediaInfo?.plexUrl4k, + url: plexUrl4k, svg: , }); } - const trailerUrl = data.relatedVideos ?.filter((r) => r.type === 'Trailer') .sort((a, b) => a.size - b.size) diff --git a/src/components/TvDetails/index.tsx b/src/components/TvDetails/index.tsx index 64327648b..ce86c47f1 100644 --- a/src/components/TvDetails/index.tsx +++ b/src/components/TvDetails/index.tsx @@ -106,6 +106,30 @@ const TvDetails: React.FC = ({ tv }) => { setShowManager(router.query.manage == '1' ? true : false); }, [router.query.manage]); + const [plexUrl, setPlexUrl] = useState(data?.mediaInfo?.plexUrl); + const [plexUrl4k, setPlexUrl4k] = useState(data?.mediaInfo?.plexUrl4k); + + useEffect(() => { + if (data) { + if ( + /iPad|iPhone|iPod/.test(navigator.userAgent) || + (navigator.userAgent === 'MacIntel' && navigator.maxTouchPoints > 1) + ) { + setPlexUrl(data.mediaInfo?.iOSPlexUrl); + setPlexUrl4k(data.mediaInfo?.iOSPlexUrl4k); + } else { + setPlexUrl(data.mediaInfo?.plexUrl); + setPlexUrl4k(data.mediaInfo?.plexUrl4k); + } + } + }, [ + data, + data?.mediaInfo?.iOSPlexUrl, + data?.mediaInfo?.iOSPlexUrl4k, + data?.mediaInfo?.plexUrl, + data?.mediaInfo?.plexUrl4k, + ]); + if (!data && !error) { return ; } @@ -116,29 +140,24 @@ const TvDetails: React.FC = ({ tv }) => { const mediaLinks: PlayButtonLink[] = []; - if ( - data.mediaInfo?.plexUrl && - hasPermission([Permission.REQUEST, Permission.REQUEST_TV], { - type: 'or', - }) - ) { + if (plexUrl) { mediaLinks.push({ text: intl.formatMessage(messages.playonplex), - url: data.mediaInfo?.plexUrl, + url: plexUrl, svg: , }); } if ( settings.currentSettings.series4kEnabled && - data.mediaInfo?.plexUrl4k && + plexUrl4k && hasPermission([Permission.REQUEST_4K, Permission.REQUEST_4K_TV], { type: 'or', }) ) { mediaLinks.push({ text: intl.formatMessage(messages.play4konplex), - url: data.mediaInfo?.plexUrl4k, + url: plexUrl4k, svg: , }); }