// /* * SwiftFin is subject to the terms of the Mozilla Public * License, v2.0. If a copy of the MPL was not distributed with this * file, you can obtain one at https://mozilla.org/MPL/2.0/. * * Copyright 2021 Aiden Vigue & Jellyfin Contributors */ import Foundation import Introspect import SwiftUI struct HomeView: View { @EnvironmentObject var homeRouter: HomeCoordinator.Router @StateObject var viewModel = HomeViewModel() private let refreshHelper = RefreshHelper() @ViewBuilder var innerBody: some View { if let errorMessage = viewModel.errorMessage { VStack(spacing: 5) { if viewModel.isLoading { ProgressView() .frame(width: 100, height: 100) .scaleEffect(2) } else { Image(systemName: "xmark.circle.fill") .font(.system(size: 72)) .foregroundColor(Color.red) .frame(width: 100, height: 100) } Text("\(errorMessage.code)") Text(errorMessage.displayMessage) .frame(minWidth: 50, maxWidth: 240) .multilineTextAlignment(.center) PrimaryButtonView(title: "Retry") { viewModel.refresh() } } .offset(y: -50) } else if viewModel.isLoading { ProgressView() .frame(width: 100, height: 100) .scaleEffect(2) } else { ScrollView { VStack(alignment: .leading) { if !viewModel.resumeItems.isEmpty { ContinueWatchingView(items: viewModel.resumeItems) } if !viewModel.nextUpItems.isEmpty { NextUpView(items: viewModel.nextUpItems) } ForEach(viewModel.libraries, id: \.self) { library in HStack { Text(L10n.latestWithString(library.name ?? "")) .font(.title2) .fontWeight(.bold) Spacer() Button { homeRouter .route(to: \.library, (viewModel: .init(parentID: library.id!, filters: viewModel.recentFilterSet), title: library.name ?? "")) } label: { HStack { L10n.seeAll.text.font(.subheadline).fontWeight(.bold) Image(systemName: "chevron.right").font(Font.subheadline.bold()) } } }.padding(.leading, 16) .padding(.trailing, 16) LatestMediaView(viewModel: .init(libraryID: library.id!)) } } .padding(.bottom, UIDevice.current.userInterfaceIdiom == .phone ? 20 : 30) } .introspectScrollView { scrollView in let control = UIRefreshControl() refreshHelper.refreshControl = control refreshHelper.refreshAction = viewModel.refresh control.addTarget(refreshHelper, action: #selector(RefreshHelper.didRefresh), for: .valueChanged) scrollView.refreshControl = control } } } var body: some View { innerBody .navigationTitle(L10n.home) .toolbar { ToolbarItemGroup(placement: .navigationBarTrailing) { Button { homeRouter.route(to: \.settings) } label: { Image(systemName: "gearshape.fill") } } } } }