Skip to content

Commit

Permalink
✨ refactor code
Browse files Browse the repository at this point in the history
  • Loading branch information
ourfor committed May 1, 2024
1 parent 7b44819 commit 3632709
Show file tree
Hide file tree
Showing 19 changed files with 93 additions and 33 deletions.
11 changes: 11 additions & 0 deletions src/api/config.ts
Expand Up @@ -2,6 +2,8 @@ import { EmbySite } from "@model/EmbySite";
import { ENV, EmbyConfig } from "../helper/env";
import { Map } from "../model/Map";
import { PlaybackInfo } from "@model/PlaybackInfo";
import { PictureQuality } from "@store/configSlice";
import { Image } from "@model/Image";

export type { EmbyConfig } from "../helper/env"

Expand Down Expand Up @@ -33,6 +35,15 @@ export interface ImageProps {
quality: number
}

export function getItemImage(site: EmbySite, id: string|number, quality = PictureQuality.High) {
const image: Image = {
primary: imageUrl(site, id, null, "Primary"),
backdrop: imageUrl(site, id, null, "Backdrop"),
logo: imageUrl(site, id, null, "Logo"),
}
return image
}

export function imageUrl(site: EmbySite, id: string|number, options: string|Partial<ImageProps>|null, type: "Primary"|string = "Primary") {
const endpoint = site.server!
if (typeof options === "string") {
Expand Down
4 changes: 3 additions & 1 deletion src/api/emby.ts
Expand Up @@ -3,7 +3,7 @@ import { getActor, getCollection, getEpisodes, getItem, getLatestMedia, getMedia
import { getPublicInfo } from "./info";
import { login } from "./login";
import { EmbySite } from "@model/EmbySite";
import { imageUrl, playUrl } from "./config";
import { getItemImage, imageUrl, playUrl } from "./config";

export class Emby {
private _site?: EmbySite;
Expand Down Expand Up @@ -36,6 +36,7 @@ export class Emby {
this.getPublicInfo = getPublicInfo.bind(this, this.site)
this.getItem = getItem.bind(this, this.site)
this.getActor = getActor.bind(this, this.site)
this.getItemImage = getItemImage.bind(this, this.site)
this.imageUrl = imageUrl.bind(this, this.site)
this.videoUrl = playUrl.bind(this, this.site)
this.markFavorite = markFavorite.bind(this, this.site)
Expand All @@ -58,6 +59,7 @@ export class Emby {
public searchRecommend = this._site ? searchRecommend.bind(this, this.site) : null
public getItem = this._site ? getItem.bind(this, this.site) : null
public getActor = this._site ? getActor.bind(this, this.site) : null
public getItemImage = this._site ? getItemImage.bind(this, this.site) : null
public imageUrl = this._site ? imageUrl.bind(this, this.site) : null
public videoUrl = this._site ? playUrl.bind(this, this.site) : null
public markFavorite = this._site ? markFavorite.bind(this, this.site) : null
Expand Down
38 changes: 37 additions & 1 deletion src/api/view.ts
@@ -1,5 +1,5 @@
import { View } from "@model/View";
import { makeEmbyUrl } from "./config";
import { getItemImage, makeEmbyUrl } from "./config";
import { Media } from "@model/Media";
import { MediaDetail } from "@model/MediaDetail";
import { Season } from "@model/Season";
Expand All @@ -10,6 +10,7 @@ import { Version } from "@helper/device";
import { UserData } from "@model/UserData";
import { PlaybackData, kPlaybackData } from "@model/PlaybackData";
import { logger } from "@helper/log";
import { PictureQuality } from "@store/configSlice";

export const EMBY_CLIENT_HEADERS = {
"X-Emby-Client": Version.displayName,
Expand All @@ -32,6 +33,9 @@ export async function getView(site: EmbySite) {
}
});
const data = await response.json() as View
for (const item of data.Items) {
item.image = getItemImage(site, item.Id, PictureQuality.High)
}
return data
}

Expand All @@ -53,6 +57,9 @@ export async function getLatestMedia(site: EmbySite, parentId: number) {
}
})
const data = await response.json() as Media[]
for (const item of data) {
item.image = getItemImage(site, item.Id, PictureQuality.High)
}
return data
}

Expand All @@ -66,6 +73,10 @@ export async function getMedia(site: EmbySite, id: number) {
const url = makeEmbyUrl(params, `emby/Users/${uid}/Items/${id}`, site.server)
const response = await fetch(url)
const data = await response.json() as MediaDetail
data.image = getItemImage(site, id, PictureQuality.High)
for (const item of data.People) {
item.image = getItemImage(site, item.Id, PictureQuality.High)
}
return data
}

Expand All @@ -90,6 +101,9 @@ export async function getResume(site: EmbySite, type: "Video"|"Audio" = "Video")
}
})
const data = await response.json() as EmbyResponse<Media>
for (const item of data.Items) {
item.image = getItemImage(site, item.Id, PictureQuality.High)
}
return data.Items
}

Expand All @@ -106,6 +120,9 @@ export async function getRecommendations(site: EmbySite) {
}
})
const data = await response.json() as EmbyResponse<Media>
for (const item of data.Items) {
item.image = getItemImage(site, item.Id, PictureQuality.High)
}
return data.Items
}

Expand All @@ -124,6 +141,9 @@ export async function getSeasons(site: EmbySite, id: number) {
}
})
const data = await response.json() as EmbyResponse<Season>
for (const item of data.Items) {
item.image = getItemImage(site, item.Id, PictureQuality.High)
}
return data.Items
}

Expand All @@ -143,6 +163,9 @@ export async function getEpisodes(site: EmbySite, vid: number, sid: number) {
}
})
const data = await response.json() as EmbyResponse<Episode>
for (const item of data.Items) {
item.image = getItemImage(site, item.Id, PictureQuality.High)
}
return data.Items
}

Expand Down Expand Up @@ -179,6 +202,9 @@ export async function getItem(site: EmbySite, options: ItemOptions) {
}
})
const data = await response.json() as EmbyResponse<Media>
for (const item of data.Items) {
item.image = getItemImage(site, item.Id, PictureQuality.High)
}
return data
}

Expand All @@ -193,6 +219,7 @@ export async function getCollection(site: EmbySite, cid: number, type: "Series"|
Limit = kEmbyItemPageSize,
SortBy = "DateCreated,SortName"
}: CollectionOptions) {
logger.info("getCollection", cid, type, StartIndex, Limit)
const uid = site.user.User.Id
const params = {
UserId: site.user.User.Id,
Expand All @@ -216,6 +243,9 @@ export async function getCollection(site: EmbySite, cid: number, type: "Series"|
}
})
const data = await response.json() as EmbyResponse<Media>
for (const item of data.Items) {
item.image = getItemImage(site, item.Id, PictureQuality.High)
}
return data
}

Expand All @@ -238,6 +268,9 @@ export async function searchRecommend(site: EmbySite) {
}
})
const data = await response.json() as EmbyResponse<Media>
for (const item of data.Items) {
item.image = getItemImage(site, item.Id, PictureQuality.High)
}
return data
}

Expand All @@ -263,6 +296,9 @@ export async function lookupItem(site: EmbySite, title: string) {
}
})
const data = await response.json() as EmbyResponse<Media>
for (const item of data.Items) {
item.image = getItemImage(site, item.Id, PictureQuality.High)
}
return data
}

Expand Down
3 changes: 3 additions & 0 deletions src/model/Episode.ts
@@ -1,3 +1,4 @@
import { Image } from "./Image";
import { UserData } from "./UserData";

export interface Episode {
Expand All @@ -14,4 +15,6 @@ export interface Episode {
Primary: string;
};
UserData: UserData;

image: Image
}
5 changes: 5 additions & 0 deletions src/model/Image.ts
@@ -0,0 +1,5 @@
export interface Image {
primary?: string,
backdrop?: string,
logo?: string,
}
4 changes: 4 additions & 0 deletions src/model/Media.ts
@@ -1,3 +1,4 @@
import { Image } from "./Image"
import { UserData } from "./UserData"

export interface Media {
Expand Down Expand Up @@ -32,4 +33,7 @@ export interface Media {
SupportsSync: boolean
Type: "Series"|"Movie"|"Episode"
UserData: UserData


image: Image
}
5 changes: 5 additions & 0 deletions src/model/MediaDetail.ts
@@ -1,5 +1,6 @@
import { MediaSource } from "@model/PlaybackInfo"
import { UserData } from "./UserData"
import { Image } from "./Image"
export interface MediaDetail {
Name: string
OriginalTitle: string
Expand All @@ -21,6 +22,8 @@ export interface MediaDetail {
SeriesId: string
SeriesName: string
MediaSources?: MediaSource[]

image: Image
}

export interface People {
Expand All @@ -29,4 +32,6 @@ export interface People {
PrimaryImageTag: string
Role: string
Type: string

image: Image
}
3 changes: 3 additions & 0 deletions src/model/Season.ts
@@ -1,3 +1,4 @@
import { Image } from "./Image"
import { UserData } from "./UserData"

export interface Season {
Expand All @@ -22,4 +23,6 @@ export interface Season {
SupportsSync: boolean
Type: string
UserData: UserData

image: Image
}
4 changes: 4 additions & 0 deletions src/model/View.ts
@@ -1,3 +1,5 @@
import { Image } from "./Image"

export interface ViewDetail {
BackdropImageTags: string[]
CanDelete: boolean
Expand Down Expand Up @@ -31,6 +33,8 @@ export interface ViewDetail {
SortName: string
Taglines: string[]
Type: string

image: Image
}

export interface View {
Expand Down
7 changes: 4 additions & 3 deletions src/page/album/index.tsx
Expand Up @@ -21,7 +21,7 @@ const style = StyleSheet.create({
});


export function Page({ navigation, route}: PropsWithNavigation<'album'>) {
export function Page({ route}: PropsWithNavigation<'album'>) {
const data = useAppSelector(state => state.emby?.source?.albumMedia?.[route.params.albumId]);
const [loading, setLoading] = useState(true);
const theme = useAppSelector(selectThemeBasicStyle);
Expand All @@ -32,7 +32,7 @@ export function Page({ navigation, route}: PropsWithNavigation<'album'>) {

useEffect(() => {
setLoading(!cached);
logger.info("fetch album media", route.params.albumId)
logger.info("fetch album medias", route.params.albumId)
const id = route.params.albumId;
const query = {
id,
Expand All @@ -57,13 +57,14 @@ export function Page({ navigation, route}: PropsWithNavigation<'album'>) {
(kFullScreenStyle.width - 20) /
Math.floor((kFullScreenStyle.width - 20) / 120);

logger.info(`data[0] = ${data?.[0]}`)
return (
<View style={{...style.root, paddingTop: pageStyle.paddingTop}}>
{data && data.length > 0 ? (
<ListView
items={data}
style={{width: '100%', flex: 1, padding: 10}}
typeForIndex={i => layoutType ?? LayoutType.Card}
typeForIndex={() => layoutType ?? LayoutType.Card}
layoutForType={(i, dim) => {
if (i === LayoutType.Card) {
dim.width = rowItemWidth;
Expand Down
8 changes: 3 additions & 5 deletions src/page/movie/index.tsx
Expand Up @@ -7,7 +7,7 @@ import { SeasonCardList } from "@view/SeasonCard";
import { Tag } from "@view/Tag";
import { ExternalPlayer } from "@view/player/ExternalPlayer";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { DimensionValue, ImageStyle, ScrollView, StyleProp, StyleSheet, Text, TouchableOpacity, View } from "react-native";
import { DimensionValue, ScrollView, StyleSheet, Text, TouchableOpacity, View } from "react-native";
import { Image } from '@view/Image';
import { Toast } from "@helper/toast";
import { Spin, SpinBox } from "@view/Spin";
Expand Down Expand Up @@ -103,9 +103,7 @@ export function Page({route, navigation}: PropsWithNavigation<"movie">) {
const [infoLoading, setInfoLoading] = useState(false)
const pageStyle = useAppSelector(selectThemedPageStyle)
const subtitleFontName = useAppSelector(s => s.player.fontFamily)
const poster = type==="Episode" ?
emby?.imageUrl?.(movie.Id, null) :
emby?.imageUrl?.(movie.Id, movie.BackdropImageTags?.[0], "Backdrop/0")
const poster = type==="Episode" ? movie.image.primary : movie.image.backdrop

const fetchPlayUrl = useCallback(async () => {
let url = getPlayUrl(detail)
Expand Down Expand Up @@ -197,7 +195,7 @@ export function Page({route, navigation}: PropsWithNavigation<"movie">) {
}))
}
}
const logoUrl = emby?.imageUrl?.(movie.Id, movie.BackdropImageTags?.[0], "Logo")
const logoUrl = movie.image.logo
const isPlayable = movie.Type === "Movie" || movie.Type === "Episode"
const iconSize = preferedSize(24, 56, windowWidth/9)
const layout = useMemo(() => ({
Expand Down
3 changes: 1 addition & 2 deletions src/page/player/index.tsx
Expand Up @@ -83,7 +83,7 @@ export function Page({navigation, route}: PlayerPageProps) {
const playEpisode = (episode: Episode) => {
setLoading(true)
setEpisode(episode)
setPoster(emby?.imageUrl?.(episode.Id, episode.ImageTags.Primary))
setPoster(episode.image.primary)
emby?.getPlaybackInfo?.(Number(episode.Id))
.then(res => {
setUrl(emby?.videoUrl?.(res))
Expand Down Expand Up @@ -178,7 +178,6 @@ export function Page({navigation, route}: PlayerPageProps) {
showsVerticalScrollIndicator={false}>
{showExternalPlayer && !isTablet && url ? <ExternalPlayer src={url} title={episode.Name} /> : null}
{episodes?.map((e, idx) => <EpisodeCard key={idx}
emby={emby}
theme={theme}
style={e === episode ? style.playing : style.inactive}
onPress={playEpisode}
Expand Down
4 changes: 2 additions & 2 deletions src/page/season/index.tsx
Expand Up @@ -45,7 +45,7 @@ export function Page({route, navigation}: SeasonPageProps) {
});
}

const coverUrl = emby?.imageUrl?.(season.Id, season.BackdropImageTags[0])
const coverUrl = season.image.backdrop
const isTablet = Device.isTablet
const layout = useMemo(() => ({
page: {
Expand Down Expand Up @@ -92,7 +92,7 @@ export function Page({route, navigation}: SeasonPageProps) {
</View>
}
{episodes?.map(episode =>
<EpisodeCard key={episode.Id} emby={emby}
<EpisodeCard key={episode.Id}
onPress={onPress}
theme={theme}
episode={episode} />
Expand Down
1 change: 1 addition & 0 deletions src/store/embySlice.ts
Expand Up @@ -334,6 +334,7 @@ export const slice = createSlice({
.addCase(fetchAlbumMediaAsync.fulfilled, (state, action) => {
const album = action.payload
if (!album) return
logger.info(`album.items[0]`, album.items[0])
if (state.source.albumMedia) {
state.source.albumMedia[album.id] = album.items
} else {
Expand Down
3 changes: 1 addition & 2 deletions src/view/ActorCard.tsx
Expand Up @@ -35,8 +35,7 @@ export interface ActorCardProps {
}

export function ActorCard({actor, theme, onPress}: ActorCardProps) {
const emby = useAppSelector(state => state.emby?.emby)
const avatorUrl = emby?.imageUrl?.(actor.Id, actor.PrimaryImageTag, "Primary")
const avatorUrl = actor.image.primary
return (
<TouchableOpacity activeOpacity={1.0} onPress={() => onPress?.(actor)}>
<View style={style.root}>
Expand Down
2 changes: 1 addition & 1 deletion src/view/AlbumList.tsx
Expand Up @@ -63,7 +63,7 @@ export function AlbumCardList({albums, theme}: {albums: ViewDetail[], theme?: Th
<TouchableOpacity activeOpacity={1.0} key={album.Id} onPress={() => onPress(album)}>
<View key={album.Id} style={style.album}>
<Image style={style.albumImage}
source={{uri: emby?.imageUrl?.(album.Id, album.Etag)}}
source={{uri: album.image.primary}}
/>
<Text style={theme}>{album.Name}</Text>
</View>
Expand Down

0 comments on commit 3632709

Please sign in to comment.