mirror of
https://github.com/jellyfin/Swiftfin.git
synced 2024-11-27 08:10:23 +00:00
Correspond to jellyfin 10.8
Update Package
This commit is contained in:
parent
7d545b0e6b
commit
2b3714cd8f
14
.github/workflows/ci.yml
vendored
14
.github/workflows/ci.yml
vendored
@ -20,12 +20,12 @@ jobs:
|
||||
steps:
|
||||
- uses: maxim-lobanov/setup-xcode@v1
|
||||
with:
|
||||
xcode-version: '13.3'
|
||||
xcode-version: '13.4.1'
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v1
|
||||
|
||||
- uses: actions/cache@v2
|
||||
- uses: actions/cache@v3
|
||||
id: carthage-cache
|
||||
with:
|
||||
path: Carthage
|
||||
@ -37,18 +37,12 @@ jobs:
|
||||
run: carthage update --use-xcframeworks --cache-builds
|
||||
|
||||
- name: Cache Swift packages
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: .build
|
||||
key: ${{ runner.os }}-${{ matrix.scheme }}-spm-${{ hashFiles('**/Package.resolved') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-${{ matrix.scheme }}-spm2-
|
||||
|
||||
- name: Cache DerivedData folder
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: "~/Library/Developer/Xcode/DerivedData"
|
||||
key: ${{ runner.os }}-${{ matrix.scheme }}-deriveddata
|
||||
${{ runner.os }}-${{ matrix.scheme }}-spm-
|
||||
|
||||
- name: xcodebuild!
|
||||
run: |
|
||||
|
@ -22,7 +22,7 @@ extension BaseItemDto {
|
||||
builder.setMaxBitrate(bitrate: tempOverkillBitrate)
|
||||
let profile = builder.buildProfile()
|
||||
|
||||
let playbackInfo = PlaybackInfoDto(userId: SessionManager.main.currentLogin.user.id,
|
||||
let getPostedPlaybackInfoRequest = GetPostedPlaybackInfoRequest(userId: SessionManager.main.currentLogin.user.id,
|
||||
maxStreamingBitrate: tempOverkillBitrate,
|
||||
startTimeTicks: self.userData?.playbackPositionTicks ?? 0,
|
||||
deviceProfile: profile,
|
||||
@ -33,7 +33,7 @@ extension BaseItemDto {
|
||||
maxStreamingBitrate: tempOverkillBitrate,
|
||||
startTimeTicks: self.userData?.playbackPositionTicks ?? 0,
|
||||
autoOpenLiveStream: true,
|
||||
playbackInfoDto: playbackInfo)
|
||||
getPostedPlaybackInfoRequest: getPostedPlaybackInfoRequest)
|
||||
.map { response -> [VideoPlayerViewModel] in
|
||||
let mediaSources = response.mediaSources!
|
||||
|
||||
@ -177,7 +177,7 @@ extension BaseItemDto {
|
||||
builder.setMaxBitrate(bitrate: tempOverkillBitrate)
|
||||
let profile = builder.buildProfile()
|
||||
|
||||
let playbackInfo = PlaybackInfoDto(userId: SessionManager.main.currentLogin.user.id,
|
||||
let getPostedPlaybackInfoRequest = GetPostedPlaybackInfoRequest(userId: SessionManager.main.currentLogin.user.id,
|
||||
maxStreamingBitrate: tempOverkillBitrate,
|
||||
startTimeTicks: self.userData?.playbackPositionTicks ?? 0,
|
||||
deviceProfile: profile,
|
||||
@ -188,7 +188,7 @@ extension BaseItemDto {
|
||||
maxStreamingBitrate: tempOverkillBitrate,
|
||||
startTimeTicks: self.userData?.playbackPositionTicks ?? 0,
|
||||
autoOpenLiveStream: true,
|
||||
playbackInfoDto: playbackInfo)
|
||||
getPostedPlaybackInfoRequest: getPostedPlaybackInfoRequest)
|
||||
.map { response -> [VideoPlayerViewModel] in
|
||||
let mediaSources = response.mediaSources!
|
||||
|
||||
|
@ -266,7 +266,7 @@ public extension BaseItemDto {
|
||||
}
|
||||
|
||||
var itemType: ItemType {
|
||||
guard let originalType = type, let knownType = ItemType(rawValue: originalType) else { return .unknown }
|
||||
guard let originalType = type, let knownType = ItemType(rawValue: originalType.rawValue) else { return .unknown }
|
||||
return knownType
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@ class DeviceProfileBuilder {
|
||||
self.bitrate = bitrate
|
||||
}
|
||||
|
||||
public func buildProfile() -> DeviceProfile {
|
||||
public func buildProfile() -> ClientCapabilitiesDeviceProfile {
|
||||
let maxStreamingBitrate = bitrate
|
||||
let maxStaticBitrate = bitrate
|
||||
let musicStreamingTranscodingBitrate = bitrate
|
||||
@ -147,10 +147,12 @@ class DeviceProfileBuilder {
|
||||
|
||||
let responseProfiles: [ResponseProfile] = [ResponseProfile(container: "m4v", type: .video, mimeType: "video/mp4")]
|
||||
|
||||
let profile = DeviceProfile(maxStreamingBitrate: maxStreamingBitrate, maxStaticBitrate: maxStaticBitrate,
|
||||
let profile = ClientCapabilitiesDeviceProfile(maxStreamingBitrate: maxStreamingBitrate, maxStaticBitrate: maxStaticBitrate,
|
||||
musicStreamingTranscodingBitrate: musicStreamingTranscodingBitrate,
|
||||
directPlayProfiles: directPlayProfiles, transcodingProfiles: transcodingProfiles, containerProfiles: [],
|
||||
codecProfiles: codecProfiles, responseProfiles: responseProfiles, subtitleProfiles: subtitleProfiles)
|
||||
directPlayProfiles: directPlayProfiles, transcodingProfiles: transcodingProfiles,
|
||||
containerProfiles: [],
|
||||
codecProfiles: codecProfiles, responseProfiles: responseProfiles,
|
||||
subtitleProfiles: subtitleProfiles)
|
||||
|
||||
return profile
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ final class SessionManager {
|
||||
let accessToken = user.accessToken else { fatalError("No associated server or access token for last user?") }
|
||||
guard let existingServer = SwiftfinStore.dataStack.fetchExisting(server) else { return }
|
||||
|
||||
JellyfinAPI.basePath = server.currentURI
|
||||
JellyfinAPIAPI.basePath = server.currentURI
|
||||
setAuthHeader(with: accessToken.value)
|
||||
currentLogin = (server: existingServer.state, user: user.state)
|
||||
}
|
||||
@ -78,7 +78,7 @@ final class SessionManager {
|
||||
uri = String(uri.dropLast())
|
||||
}
|
||||
|
||||
JellyfinAPI.basePath = uri
|
||||
JellyfinAPIAPI.basePath = uri
|
||||
|
||||
return SystemAPI.getPublicSystemInfo()
|
||||
.tryMap { response -> (SwiftfinStore.Models.StoredServer, UnsafeDataTransaction) in
|
||||
@ -188,9 +188,9 @@ final class SessionManager {
|
||||
{
|
||||
setAuthHeader(with: "")
|
||||
|
||||
JellyfinAPI.basePath = server.currentURI
|
||||
JellyfinAPIAPI.basePath = server.currentURI
|
||||
|
||||
return UserAPI.authenticateUserByName(authenticateUserByName: AuthenticateUserByName(username: username, pw: password))
|
||||
return UserAPI.authenticateUserByName(authenticateUserByNameRequest: .init(username: username, pw: password))
|
||||
.tryMap { response -> (SwiftfinStore.Models.StoredServer, SwiftfinStore.Models.StoredUser, UnsafeDataTransaction) in
|
||||
|
||||
guard let accessToken = response.accessToken else { throw JellyfinAPIError("Access token missing from network call") }
|
||||
@ -251,7 +251,7 @@ final class SessionManager {
|
||||
// MARK: loginUser
|
||||
|
||||
func loginUser(server: SwiftfinStore.State.Server, user: SwiftfinStore.State.User) {
|
||||
JellyfinAPI.basePath = server.currentURI
|
||||
JellyfinAPIAPI.basePath = server.currentURI
|
||||
Defaults[.lastServerUserID] = user.id
|
||||
setAuthHeader(with: user.accessToken)
|
||||
currentLogin = (server: server, user: user)
|
||||
@ -262,7 +262,7 @@ final class SessionManager {
|
||||
|
||||
func logout() {
|
||||
currentLogin = nil
|
||||
JellyfinAPI.basePath = ""
|
||||
JellyfinAPIAPI.basePath = ""
|
||||
setAuthHeader(with: "")
|
||||
Defaults[.lastServerUserID] = nil
|
||||
Notifications[.didSignOut].post()
|
||||
@ -339,6 +339,6 @@ final class SessionManager {
|
||||
header.append("Version=\"\(appVersion ?? "0.0.1")\", ")
|
||||
header.append("Token=\"\(accessToken)\"")
|
||||
|
||||
JellyfinAPI.customHeaders["X-Emby-Authorization"] = header
|
||||
JellyfinAPIAPI.customHeaders["X-Emby-Authorization"] = header
|
||||
}
|
||||
}
|
||||
|
@ -135,7 +135,7 @@ final class HomeViewModel: ViewModel {
|
||||
.people,
|
||||
.chapters,
|
||||
],
|
||||
includeItemTypes: ["Movie", "Series"],
|
||||
includeItemTypes: [.movie, .series],
|
||||
enableImageTypes: [.primary, .backdrop, .thumb],
|
||||
enableUserData: true,
|
||||
limit: 8)
|
||||
|
@ -36,7 +36,7 @@ final class LatestMediaViewModel: ViewModel {
|
||||
.genres,
|
||||
.people,
|
||||
],
|
||||
includeItemTypes: ["Series", "Movie"],
|
||||
includeItemTypes: [.series, .movie],
|
||||
enableUserData: true, limit: 12)
|
||||
.trackActivity(loading)
|
||||
.sink(receiveCompletion: { [weak self] completion in
|
||||
|
@ -94,7 +94,7 @@ final class LibrarySearchViewModel: ViewModel {
|
||||
limit: 20,
|
||||
recursive: true,
|
||||
parentId: parentID,
|
||||
includeItemTypes: ["Movie", "Series"],
|
||||
includeItemTypes: [.movie, .series],
|
||||
sortBy: ["IsFavoriteOrLiked", "Random"],
|
||||
imageTypeLimit: 0,
|
||||
enableTotalRecordCount: false,
|
||||
@ -113,7 +113,7 @@ final class LibrarySearchViewModel: ViewModel {
|
||||
ItemsAPI.getItemsByUserId(userId: SessionManager.main.currentLogin.user.id, limit: 50, recursive: true, searchTerm: query,
|
||||
sortOrder: [.ascending], parentId: parentID,
|
||||
fields: [.primaryImageAspectRatio, .seriesPrimaryImage, .seasonUserData, .overview, .genres, .people],
|
||||
includeItemTypes: [ItemType.movie.rawValue], sortBy: ["SortName"], enableUserData: true,
|
||||
includeItemTypes: [.movie], sortBy: ["SortName"], enableUserData: true,
|
||||
enableImages: true)
|
||||
.trackActivity(loading)
|
||||
.receive(on: DispatchQueue.main)
|
||||
@ -126,7 +126,7 @@ final class LibrarySearchViewModel: ViewModel {
|
||||
ItemsAPI.getItemsByUserId(userId: SessionManager.main.currentLogin.user.id, limit: 50, recursive: true, searchTerm: query,
|
||||
sortOrder: [.ascending], parentId: parentID,
|
||||
fields: [.primaryImageAspectRatio, .seriesPrimaryImage, .seasonUserData, .overview, .genres, .people],
|
||||
includeItemTypes: [ItemType.series.rawValue], sortBy: ["SortName"], enableUserData: true,
|
||||
includeItemTypes: [.series], sortBy: ["SortName"], enableUserData: true,
|
||||
enableImages: true)
|
||||
.trackActivity(loading)
|
||||
.receive(on: DispatchQueue.main)
|
||||
@ -139,7 +139,7 @@ final class LibrarySearchViewModel: ViewModel {
|
||||
ItemsAPI.getItemsByUserId(userId: SessionManager.main.currentLogin.user.id, limit: 50, recursive: true, searchTerm: query,
|
||||
sortOrder: [.ascending], parentId: parentID,
|
||||
fields: [.primaryImageAspectRatio, .seriesPrimaryImage, .seasonUserData, .overview, .genres, .people],
|
||||
includeItemTypes: [ItemType.episode.rawValue], sortBy: ["SortName"], enableUserData: true,
|
||||
includeItemTypes: [.episode], sortBy: ["SortName"], enableUserData: true,
|
||||
enableImages: true)
|
||||
.trackActivity(loading)
|
||||
.receive(on: DispatchQueue.main)
|
||||
|
@ -99,18 +99,18 @@ final class LibraryViewModel: ViewModel {
|
||||
self.person != nil ||
|
||||
self.genre != nil ||
|
||||
self.studio != nil
|
||||
let includeItemTypes: [String]
|
||||
let includeItemTypes: [BaseItemKind]
|
||||
if filters.filters.contains(.isFavorite) {
|
||||
includeItemTypes = ["Movie", "Series", "Season", "Episode", "BoxSet"]
|
||||
includeItemTypes = [.movie, .series, .season, .episode, .boxSet]
|
||||
} else {
|
||||
includeItemTypes = ["Movie", "Series", "BoxSet"] + (Defaults[.showFlattenView] ? [] : ["Folder"])
|
||||
includeItemTypes = [.movie, .series, .boxSet] + (Defaults[.showFlattenView] ? [] : [.folder])
|
||||
}
|
||||
|
||||
ItemsAPI.getItemsByUserId(userId: SessionManager.main.currentLogin.user.id, startIndex: currentPage * pageItemSize,
|
||||
limit: pageItemSize,
|
||||
recursive: queryRecursive,
|
||||
searchTerm: nil,
|
||||
sortOrder: filters.sortOrder,
|
||||
sortOrder: filters.sortOrder.compactMap { SortOrder(rawValue: $0.rawValue) },
|
||||
parentId: parentID,
|
||||
fields: [
|
||||
.primaryImageAspectRatio,
|
||||
|
@ -106,7 +106,7 @@ final class LiveTVChannelsViewModel: ViewModel {
|
||||
let minEndDate = Date.now.addComponentsToDate(hours: -1)
|
||||
let maxStartDate = minEndDate.addComponentsToDate(hours: 6)
|
||||
|
||||
let getProgramsDto = GetProgramsDto(channelIds: channelIds,
|
||||
let getProgramsRequest = GetProgramsRequest(channelIds: channelIds,
|
||||
userId: SessionManager.main.currentLogin.user.id,
|
||||
maxStartDate: maxStartDate,
|
||||
minEndDate: minEndDate,
|
||||
@ -117,7 +117,7 @@ final class LiveTVChannelsViewModel: ViewModel {
|
||||
enableImageTypes: [.primary],
|
||||
enableUserData: false)
|
||||
|
||||
LiveTvAPI.getPrograms(getProgramsDto: getProgramsDto)
|
||||
LiveTvAPI.getPrograms(getProgramsRequest: getProgramsRequest)
|
||||
.trackActivity(loading)
|
||||
.sink(receiveCompletion: { [weak self] completion in
|
||||
self?.handleAPIRequestError(completion: completion)
|
||||
|
@ -86,7 +86,7 @@ final class LiveTVProgramsViewModel: ViewModel {
|
||||
}
|
||||
|
||||
private func getSeries() {
|
||||
let getProgramsDto = GetProgramsDto(userId: SessionManager.main.currentLogin.user.id,
|
||||
let getProgramsRequest = GetProgramsRequest(userId: SessionManager.main.currentLogin.user.id,
|
||||
hasAired: false,
|
||||
isMovie: false,
|
||||
isSeries: true,
|
||||
@ -98,7 +98,7 @@ final class LiveTVProgramsViewModel: ViewModel {
|
||||
enableImageTypes: [.primary, .thumb],
|
||||
fields: [.channelInfo, .primaryImageAspectRatio])
|
||||
|
||||
LiveTvAPI.getPrograms(getProgramsDto: getProgramsDto)
|
||||
LiveTvAPI.getPrograms(getProgramsRequest: getProgramsRequest)
|
||||
.trackActivity(loading)
|
||||
.sink(receiveCompletion: { [weak self] completion in
|
||||
self?.handleAPIRequestError(completion: completion)
|
||||
@ -111,7 +111,7 @@ final class LiveTVProgramsViewModel: ViewModel {
|
||||
}
|
||||
|
||||
private func getMovies() {
|
||||
let getProgramsDto = GetProgramsDto(userId: SessionManager.main.currentLogin.user.id,
|
||||
let getProgramsRequest = GetProgramsRequest(userId: SessionManager.main.currentLogin.user.id,
|
||||
hasAired: false,
|
||||
isMovie: true,
|
||||
isSeries: false,
|
||||
@ -123,7 +123,7 @@ final class LiveTVProgramsViewModel: ViewModel {
|
||||
enableImageTypes: [.primary, .thumb],
|
||||
fields: [.channelInfo, .primaryImageAspectRatio])
|
||||
|
||||
LiveTvAPI.getPrograms(getProgramsDto: getProgramsDto)
|
||||
LiveTvAPI.getPrograms(getProgramsRequest: getProgramsRequest)
|
||||
.trackActivity(loading)
|
||||
.sink(receiveCompletion: { [weak self] completion in
|
||||
self?.handleAPIRequestError(completion: completion)
|
||||
@ -136,7 +136,7 @@ final class LiveTVProgramsViewModel: ViewModel {
|
||||
}
|
||||
|
||||
private func getSports() {
|
||||
let getProgramsDto = GetProgramsDto(userId: SessionManager.main.currentLogin.user.id,
|
||||
let getProgramsRequest = GetProgramsRequest(userId: SessionManager.main.currentLogin.user.id,
|
||||
hasAired: false,
|
||||
isSports: true,
|
||||
limit: 9,
|
||||
@ -144,7 +144,7 @@ final class LiveTVProgramsViewModel: ViewModel {
|
||||
enableImageTypes: [.primary, .thumb],
|
||||
fields: [.channelInfo, .primaryImageAspectRatio])
|
||||
|
||||
LiveTvAPI.getPrograms(getProgramsDto: getProgramsDto)
|
||||
LiveTvAPI.getPrograms(getProgramsRequest: getProgramsRequest)
|
||||
.trackActivity(loading)
|
||||
.sink(receiveCompletion: { [weak self] completion in
|
||||
self?.handleAPIRequestError(completion: completion)
|
||||
@ -157,7 +157,7 @@ final class LiveTVProgramsViewModel: ViewModel {
|
||||
}
|
||||
|
||||
private func getKids() {
|
||||
let getProgramsDto = GetProgramsDto(userId: SessionManager.main.currentLogin.user.id,
|
||||
let getProgramsRequest = GetProgramsRequest(userId: SessionManager.main.currentLogin.user.id,
|
||||
hasAired: false,
|
||||
isKids: true,
|
||||
limit: 9,
|
||||
@ -165,7 +165,7 @@ final class LiveTVProgramsViewModel: ViewModel {
|
||||
enableImageTypes: [.primary, .thumb],
|
||||
fields: [.channelInfo, .primaryImageAspectRatio])
|
||||
|
||||
LiveTvAPI.getPrograms(getProgramsDto: getProgramsDto)
|
||||
LiveTvAPI.getPrograms(getProgramsRequest: getProgramsRequest)
|
||||
.trackActivity(loading)
|
||||
.sink(receiveCompletion: { [weak self] completion in
|
||||
self?.handleAPIRequestError(completion: completion)
|
||||
@ -178,7 +178,7 @@ final class LiveTVProgramsViewModel: ViewModel {
|
||||
}
|
||||
|
||||
private func getNews() {
|
||||
let getProgramsDto = GetProgramsDto(userId: SessionManager.main.currentLogin.user.id,
|
||||
let getProgramsRequest = GetProgramsRequest(userId: SessionManager.main.currentLogin.user.id,
|
||||
hasAired: false,
|
||||
isNews: true,
|
||||
limit: 9,
|
||||
@ -186,7 +186,7 @@ final class LiveTVProgramsViewModel: ViewModel {
|
||||
enableImageTypes: [.primary, .thumb],
|
||||
fields: [.channelInfo, .primaryImageAspectRatio])
|
||||
|
||||
LiveTvAPI.getPrograms(getProgramsDto: getProgramsDto)
|
||||
LiveTvAPI.getPrograms(getProgramsRequest: getProgramsRequest)
|
||||
.trackActivity(loading)
|
||||
.sink(receiveCompletion: { [weak self] completion in
|
||||
self?.handleAPIRequestError(completion: completion)
|
||||
|
@ -206,7 +206,7 @@ final class VideoPlayerViewModel: ViewModel {
|
||||
// During scrubbing, many progress reports were spammed
|
||||
// Send only the current report after a delay
|
||||
private var progressReportTimer: Timer?
|
||||
private var lastProgressReport: PlaybackProgressInfo?
|
||||
private var lastProgressReport: ReportPlaybackProgressRequest?
|
||||
|
||||
// MARK: init
|
||||
|
||||
@ -474,8 +474,7 @@ extension VideoPlayerViewModel {
|
||||
|
||||
let subtitleStreamIndex = subtitlesEnabled ? selectedSubtitleStreamIndex : nil
|
||||
|
||||
let startInfo = PlaybackStartInfo(canSeek: true,
|
||||
item: item,
|
||||
let reportPlaybackStartRequest = ReportPlaybackStartRequest(canSeek: true,
|
||||
itemId: item.id,
|
||||
sessionId: response.playSessionId,
|
||||
mediaSourceId: item.id,
|
||||
@ -495,7 +494,7 @@ extension VideoPlayerViewModel {
|
||||
nowPlayingQueue: nil,
|
||||
playlistItemId: "playlistItem0")
|
||||
|
||||
PlaystateAPI.reportPlaybackStart(playbackStartInfo: startInfo)
|
||||
PlaystateAPI.reportPlaybackStart(reportPlaybackStartRequest: reportPlaybackStartRequest)
|
||||
.sink { completion in
|
||||
self.handleAPIRequestError(completion: completion)
|
||||
} receiveValue: { _ in
|
||||
@ -509,8 +508,7 @@ extension VideoPlayerViewModel {
|
||||
func sendPauseReport(paused: Bool) {
|
||||
let subtitleStreamIndex = subtitlesEnabled ? selectedSubtitleStreamIndex : nil
|
||||
|
||||
let pauseInfo = PlaybackStartInfo(canSeek: true,
|
||||
item: item,
|
||||
let reportPlaybackStartRequest = ReportPlaybackStartRequest(canSeek: true,
|
||||
itemId: item.id,
|
||||
sessionId: response.playSessionId,
|
||||
mediaSourceId: item.id,
|
||||
@ -530,7 +528,7 @@ extension VideoPlayerViewModel {
|
||||
nowPlayingQueue: nil,
|
||||
playlistItemId: "playlistItem0")
|
||||
|
||||
PlaystateAPI.reportPlaybackStart(playbackStartInfo: pauseInfo)
|
||||
PlaystateAPI.reportPlaybackStart(reportPlaybackStartRequest: reportPlaybackStartRequest)
|
||||
.sink { completion in
|
||||
self.handleAPIRequestError(completion: completion)
|
||||
} receiveValue: { _ in
|
||||
@ -544,8 +542,7 @@ extension VideoPlayerViewModel {
|
||||
func sendProgressReport() {
|
||||
let subtitleStreamIndex = subtitlesEnabled ? selectedSubtitleStreamIndex : nil
|
||||
|
||||
let progressInfo = PlaybackProgressInfo(canSeek: true,
|
||||
item: item,
|
||||
let progressInfo = ReportPlaybackProgressRequest(canSeek: true,
|
||||
itemId: item.id,
|
||||
sessionId: response.playSessionId,
|
||||
mediaSourceId: item.id,
|
||||
@ -574,7 +571,7 @@ extension VideoPlayerViewModel {
|
||||
private func _sendProgressReport() {
|
||||
guard let lastProgressReport = lastProgressReport else { return }
|
||||
|
||||
PlaystateAPI.reportPlaybackProgress(playbackProgressInfo: lastProgressReport)
|
||||
PlaystateAPI.reportPlaybackProgress(reportPlaybackProgressRequest: lastProgressReport)
|
||||
.sink { completion in
|
||||
self.handleAPIRequestError(completion: completion)
|
||||
} receiveValue: { _ in
|
||||
@ -588,8 +585,7 @@ extension VideoPlayerViewModel {
|
||||
// MARK: sendStopReport
|
||||
|
||||
func sendStopReport() {
|
||||
let stopInfo = PlaybackStopInfo(item: item,
|
||||
itemId: item.id,
|
||||
let reportPlaybackStoppedRequest = ReportPlaybackStoppedRequest(itemId: item.id,
|
||||
sessionId: response.playSessionId,
|
||||
mediaSourceId: item.id,
|
||||
positionTicks: currentSecondTicks,
|
||||
@ -600,7 +596,7 @@ extension VideoPlayerViewModel {
|
||||
playlistItemId: "playlistItem0",
|
||||
nowPlayingQueue: nil)
|
||||
|
||||
PlaystateAPI.reportPlaybackStopped(playbackStopInfo: stopInfo)
|
||||
PlaystateAPI.reportPlaybackStopped(reportPlaybackStoppedRequest: reportPlaybackStoppedRequest)
|
||||
.sink { completion in
|
||||
self.handleAPIRequestError(completion: completion)
|
||||
} receiveValue: { _ in
|
||||
|
@ -46,9 +46,9 @@ struct LandscapeItemElement: View {
|
||||
|
||||
var body: some View {
|
||||
VStack {
|
||||
ImageView(item.type == "Episode" && !(inSeasonView ?? false) ? item.getSeriesBackdropImage(maxWidth: 445) : item
|
||||
ImageView(item.type == .episode && !(inSeasonView ?? false) ? item.getSeriesBackdropImage(maxWidth: 445) : item
|
||||
.getBackdropImage(maxWidth: 445),
|
||||
blurHash: item.type == "Episode" ? item.getSeriesBackdropImageBlurHash() : item.getBackdropImageBlurHash())
|
||||
blurHash: item.type == .episode ? item.getSeriesBackdropImageBlurHash() : item.getBackdropImageBlurHash())
|
||||
.frame(width: 445, height: 250)
|
||||
.cornerRadius(10)
|
||||
.ignoresSafeArea()
|
||||
@ -97,7 +97,7 @@ struct LandscapeItemElement: View {
|
||||
.lineLimit(1)
|
||||
.frame(width: 445)
|
||||
} else {
|
||||
Text(item.type == "Episode" ? "\(item.seriesName ?? "") • \(item.getEpisodeLocator() ?? "")" : item.name ?? "")
|
||||
Text(item.type == .episode ? "\(item.seriesName ?? "") • \(item.getEpisodeLocator() ?? "")" : item.name ?? "")
|
||||
.font(.callout)
|
||||
.fontWeight(.semibold)
|
||||
.lineLimit(1)
|
||||
|
@ -21,8 +21,8 @@ struct PortraitItemElement: View {
|
||||
|
||||
var body: some View {
|
||||
VStack {
|
||||
ImageView(item.type == "Episode" ? item.getSeriesPrimaryImage(maxWidth: 200) : item.getPrimaryImage(maxWidth: 200),
|
||||
blurHash: item.type == "Episode" ? item.getSeriesPrimaryImageBlurHash() : item.getPrimaryImageBlurHash())
|
||||
ImageView(item.type == .episode ? item.getSeriesPrimaryImage(maxWidth: 200) : item.getPrimaryImage(maxWidth: 200),
|
||||
blurHash: item.type == .episode ? item.getSeriesPrimaryImageBlurHash() : item.getPrimaryImageBlurHash())
|
||||
.frame(width: 200, height: 300)
|
||||
.cornerRadius(10)
|
||||
.shadow(radius: focused ? 10.0 : 0)
|
||||
@ -58,12 +58,12 @@ struct PortraitItemElement: View {
|
||||
.opacity(1), alignment: .topTrailing).opacity(1)
|
||||
Text(item.title)
|
||||
.frame(width: 200, height: 30, alignment: .center)
|
||||
if item.type == "Movie" || item.type == "Series" {
|
||||
if item.type == .movie || item.type == .series {
|
||||
Text("\(String(item.productionYear ?? 0)) • \(item.officialRating ?? "N/A")")
|
||||
.foregroundColor(.secondary)
|
||||
.font(.caption)
|
||||
.fontWeight(.medium)
|
||||
} else if item.type == "Season" {
|
||||
} else if item.type == .season {
|
||||
Text("\(item.name ?? "") • \(String(item.productionYear ?? 0))")
|
||||
.foregroundColor(.secondary)
|
||||
.font(.caption)
|
||||
|
@ -47,7 +47,7 @@ struct MovieLibrariesView: View {
|
||||
} cell: { _, cell in
|
||||
GeometryReader { _ in
|
||||
if let item = cell.item {
|
||||
if item.type != "Folder" {
|
||||
if item.type != .folder {
|
||||
Button {
|
||||
self.movieLibrariesRouter.route(to: \.library, item)
|
||||
} label: {
|
||||
|
@ -47,7 +47,7 @@ struct TVLibrariesView: View {
|
||||
} cell: { _, cell in
|
||||
GeometryReader { _ in
|
||||
if let item = cell.item {
|
||||
if item.type != "Folder" {
|
||||
if item.type != .folder {
|
||||
Button {
|
||||
self.tvLibrariesRouter.route(to: \.library, item)
|
||||
} label: {
|
||||
|
@ -14,8 +14,8 @@
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/Flight-School/AnyCodable",
|
||||
"state" : {
|
||||
"revision" : "11423ef0c756e8a1f6b4bb576dab9d97bc016c70",
|
||||
"version" : "0.6.4"
|
||||
"revision" : "f9fda69a7b704d46fb5123005f2f7e43dbb8a0fa",
|
||||
"version" : "0.6.5"
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -32,8 +32,8 @@
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/CombineCommunity/CombineExt",
|
||||
"state" : {
|
||||
"revision" : "0880829102152185190064fd17847a7c681d2127",
|
||||
"version" : "1.5.1"
|
||||
"revision" : "38a4d4cb01f8c7750671c786d33dfbea00cbd131",
|
||||
"version" : "1.6.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -50,8 +50,8 @@
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/sindresorhus/Defaults",
|
||||
"state" : {
|
||||
"revision" : "119f654d44f7b90f00dc11f7dd1c94a36f12576b",
|
||||
"version" : "6.2.1"
|
||||
"revision" : "981ccb0a01c54abbe3c12ccb8226108527bbf115",
|
||||
"version" : "6.3.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -78,16 +78,16 @@
|
||||
"location" : "https://github.com/jellyfin/jellyfin-sdk-swift",
|
||||
"state" : {
|
||||
"branch" : "main",
|
||||
"revision" : "f315671ced976a7ec75ce6a1f37e00b4880cbf4b"
|
||||
"revision" : "9d6e46b94d2178116ee3546b03dfb67e19e3a93a"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "nuke",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/kean/Nuke.git",
|
||||
"location" : "https://github.com/kean/Nuke",
|
||||
"state" : {
|
||||
"revision" : "0ea7545b5c918285aacc044dc75048625c8257cc",
|
||||
"version" : "10.8.0"
|
||||
"revision" : "a002b7fd786f2df2ed4333fe73a9727499fd9d97",
|
||||
"version" : "10.11.2"
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -95,8 +95,8 @@
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/kean/NukeUI",
|
||||
"state" : {
|
||||
"revision" : "17f26c07e6b1d3b9258287f99f528111fcd7b7ad",
|
||||
"version" : "0.8.1"
|
||||
"revision" : "ebfed3c9a4e97e310b0ff8ee0fffe5579887a825",
|
||||
"version" : "0.8.2"
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -122,8 +122,8 @@
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/rundfunk47/stinsen",
|
||||
"state" : {
|
||||
"revision" : "36d97964075dc770046ddef9346a29bfa8982d6d",
|
||||
"version" : "2.0.7"
|
||||
"revision" : "add05384b65ae3e39474f51ab5b9281abd238c60",
|
||||
"version" : "2.0.9"
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -168,7 +168,7 @@
|
||||
"location" : "https://github.com/spacenation/swiftui-sliders",
|
||||
"state" : {
|
||||
"branch" : "master",
|
||||
"revision" : "538e16b35ad7a066a8f5624da9ecee6327886bf7"
|
||||
"revision" : "5ba8614462a7ed4bd47a93fbca6c281599f74337"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -32,7 +32,7 @@ struct NextUpWidgetProvider: TimelineProvider {
|
||||
let savedUser = currentLogin.user
|
||||
var tempCancellables = Set<AnyCancellable>()
|
||||
|
||||
JellyfinAPI.basePath = server.currentURI
|
||||
JellyfinAPIAPI.basePath = server.currentURI
|
||||
TvShowsAPI.getNextUp(userId: savedUser.id, limit: 3,
|
||||
fields: [.primaryImageAspectRatio, .seriesPrimaryImage, .seasonUserData, .overview, .genres, .people],
|
||||
imageTypeLimit: 1, enableImageTypes: [.primary, .backdrop, .thumb])
|
||||
@ -77,7 +77,7 @@ struct NextUpWidgetProvider: TimelineProvider {
|
||||
|
||||
var tempCancellables = Set<AnyCancellable>()
|
||||
|
||||
JellyfinAPI.basePath = server.currentURI
|
||||
JellyfinAPIAPI.basePath = server.currentURI
|
||||
TvShowsAPI.getNextUp(userId: savedUser.id, limit: 3,
|
||||
fields: [.primaryImageAspectRatio, .seriesPrimaryImage, .seasonUserData, .overview, .genres, .people],
|
||||
imageTypeLimit: 1, enableImageTypes: [.primary, .backdrop, .thumb])
|
||||
|
Loading…
Reference in New Issue
Block a user