Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move to IdentifiedArray in PagingLibraryViewModel #1346

Merged
merged 3 commits into from
Dec 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Shared/Strings/Strings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1086,10 +1086,10 @@ internal enum L10n {
internal static let run = L10n.tr("Localizable", "run", fallback: "Run")
/// Running...
internal static let running = L10n.tr("Localizable", "running", fallback: "Running...")
/// Runtime
internal static let runtime = L10n.tr("Localizable", "runtime", fallback: "Runtime")
JPKribs marked this conversation as resolved.
Show resolved Hide resolved
/// Run Time
internal static let runTime = L10n.tr("Localizable", "runTime", fallback: "Run Time")
/// Runtime
internal static let runtime = L10n.tr("Localizable", "runtime", fallback: "Runtime")
/// Save
internal static let save = L10n.tr("Localizable", "save", fallback: "Save")
/// Scan All Libraries
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import Combine
import Defaults
import Foundation
import Get
import IdentifiedCollections
import JellyfinAPI
import OrderedCollections
import UIKit
Expand All @@ -32,7 +33,7 @@ private let DefaultPageSize = 50
on remembering other filters.
*/

class PagingLibraryViewModel<Element: Poster>: ViewModel, Eventful, Stateful {
class PagingLibraryViewModel<Element: Poster & Identifiable>: ViewModel, Eventful, Stateful {

// MARK: Event

Expand Down Expand Up @@ -67,7 +68,7 @@ class PagingLibraryViewModel<Element: Poster>: ViewModel, Eventful, Stateful {
@Published
final var backgroundStates: OrderedSet<BackgroundState> = []
@Published
final var elements: OrderedSet<Element>
final var elements: IdentifiedArrayOf<Element>
@Published
final var state: State = .initial
@Published
Expand Down Expand Up @@ -103,7 +104,7 @@ class PagingLibraryViewModel<Element: Poster>: ViewModel, Eventful, Stateful {
parent: (any LibraryParent)? = nil
) {
self.filterViewModel = nil
self.elements = OrderedSet(data)
self.elements = IdentifiedArray(uniqueElements: data)
self.isStatic = true
self.hasNextPage = false
self.pageSize = DefaultPageSize
Expand All @@ -130,7 +131,7 @@ class PagingLibraryViewModel<Element: Poster>: ViewModel, Eventful, Stateful {
filters: ItemFilterCollection? = nil,
pageSize: Int = DefaultPageSize
) {
self.elements = OrderedSet()
self.elements = IdentifiedArray()
self.isStatic = false
self.pageSize = pageSize
self.parent = parent
Expand Down
16 changes: 15 additions & 1 deletion Shared/ViewModels/MediaViewModel/MediaType.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import JellyfinAPI

extension MediaViewModel {

enum MediaType: Displayable, Hashable {
enum MediaType: Displayable, Hashable, Identifiable {

case collectionFolder(BaseItemDto)
case downloads
case favorites
Expand All @@ -29,5 +30,18 @@ extension MediaViewModel {
return L10n.liveTV
}
}

var id: String? {
switch self {
case let .collectionFolder(item):
return item.id
case .downloads:
return "downloads"
case .favorites:
return "favorites"
case let .liveTV(item):
return item.id
}
}
}
}
45 changes: 16 additions & 29 deletions Swiftfin tvOS/Components/PosterHStack.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,19 @@ import SwiftUI

// TODO: trailing content refactor?

struct PosterHStack<Item: Poster>: View {
struct PosterHStack<Element: Poster & Identifiable, Data: Collection>: View where Data.Element == Element, Data.Index == Int {

private var data: Data
private var title: String?
private var type: PosterDisplayType
private var items: Binding<OrderedSet<Item>>
private var content: (Item) -> any View
private var imageOverlay: (Item) -> any View
private var contextMenu: (Item) -> any View
private var content: (Element) -> any View
private var imageOverlay: (Element) -> any View
private var contextMenu: (Element) -> any View
private var trailingContent: () -> any View
private var onSelect: (Item) -> Void
private var onSelect: (Element) -> Void

// See PosterButton for implementation reason
private var focusedItem: Binding<Item?>?
private var focusedItem: Binding<Element?>?

var body: some View {
VStack(alignment: .leading, spacing: 20) {
Expand All @@ -42,7 +42,7 @@ struct PosterHStack<Item: Poster>: View {
}

CollectionHStack(
items,
uniqueElements: data,
columns: type == .landscape ? 4 : 7
) { item in
PosterButton(item: item, type: type)
Expand Down Expand Up @@ -86,54 +86,41 @@ extension PosterHStack {
init(
title: String? = nil,
type: PosterDisplayType,
items: Binding<OrderedSet<Item>>
items: Data
) {
self.init(
data: items,
title: title,
type: type,
items: items,
content: { PosterButton.TitleSubtitleContentView(item: $0) },
imageOverlay: { PosterButton.DefaultOverlay(item: $0) },
contextMenu: { _ in EmptyView() },
trailingContent: { EmptyView() },
onSelect: { _ in },
focusedItem: nil
onSelect: { _ in }
)
}

init<S: Sequence<Item>>(
title: String? = nil,
type: PosterDisplayType,
items: S
) {
self.init(
title: title,
type: type,
items: .constant(OrderedSet(items))
)
}

func content(@ViewBuilder _ content: @escaping (Item) -> any View) -> Self {
func content(@ViewBuilder _ content: @escaping (Element) -> any View) -> Self {
copy(modifying: \.content, with: content)
}

func imageOverlay(@ViewBuilder _ content: @escaping (Item) -> any View) -> Self {
func imageOverlay(@ViewBuilder _ content: @escaping (Element) -> any View) -> Self {
copy(modifying: \.imageOverlay, with: content)
}

func contextMenu(@ViewBuilder _ content: @escaping (Item) -> any View) -> Self {
func contextMenu(@ViewBuilder _ content: @escaping (Element) -> any View) -> Self {
copy(modifying: \.contextMenu, with: content)
}

func trailing(@ViewBuilder _ content: @escaping () -> any View) -> Self {
copy(modifying: \.trailingContent, with: content)
}

func onSelect(_ action: @escaping (Item) -> Void) -> Self {
func onSelect(_ action: @escaping (Element) -> Void) -> Self {
copy(modifying: \.onSelect, with: action)
}

func focusedItem(_ binding: Binding<Item?>) -> Self {
func focusedItem(_ binding: Binding<Element?>) -> Self {
copy(modifying: \.focusedItem, with: binding)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ struct ChannelLibraryView: View {
@ViewBuilder
private var contentView: some View {
CollectionVGrid(
$viewModel.elements,
uniqueElements: viewModel.elements,
layout: .columns(3, insets: .init(0), itemSpacing: 25, lineSpacing: 25)
) { channel in
WideChannelGridItem(channel: channel)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ extension HomeView {
PosterHStack(
title: L10n.latestWithString(viewModel.parent?.displayTitle ?? .emptyDash),
type: .portrait,
items: $viewModel.elements
items: viewModel.elements
)
.onSelect { item in
router.route(to: \.item, item)
Expand Down
2 changes: 1 addition & 1 deletion Swiftfin tvOS/Views/HomeView/Components/NextUpView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ extension HomeView {
PosterHStack(
title: L10n.nextUp,
type: nextUpPosterType,
items: $viewModel.elements
items: viewModel.elements
)
.onSelect { item in
router.route(to: \.item, item)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ extension HomeView {
PosterHStack(
title: L10n.recentlyAdded,
type: recentlyAddedPosterType,
items: $viewModel.elements
items: viewModel.elements
)
.onSelect { item in
router.route(to: \.item, item)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,13 @@ extension SeriesEpisodeSelector {
private var lastFocusedEpisodeID: String?

@StateObject
private var proxy = CollectionHStackProxy<BaseItemDto>()
private var proxy = CollectionHStackProxy()

let playButtonItem: BaseItemDto?

private func contentView(viewModel: SeasonItemViewModel) -> some View {
CollectionHStack(
$viewModel.elements,
uniqueElements: viewModel.elements,
columns: 3.5
) { episode in
SeriesEpisodeSelector.EpisodeCard(episode: episode)
Expand Down Expand Up @@ -103,7 +103,7 @@ extension SeriesEpisodeSelector {

var body: some View {
CollectionHStack(
0 ..< 1,
count: 1,
columns: 3.5
) { _ in
SeriesEpisodeSelector.ErrorCard(error: error)
Expand All @@ -121,7 +121,7 @@ extension SeriesEpisodeSelector {

var body: some View {
CollectionHStack(
0 ..< Int.random(in: 2 ..< 5),
count: Int.random(in: 2 ..< 5),
columns: 3.5
) { _ in
SeriesEpisodeSelector.LoadingCard()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ extension ItemView {
PosterHStack(
title: L10n.recommended,
type: similarPosterType,
items: $viewModel.elements
items: viewModel.elements
)
.onSelect { item in
router.route(to: \.item, item)
Expand Down
2 changes: 1 addition & 1 deletion Swiftfin tvOS/Views/MediaView/MediaView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ struct MediaView: View {
@ViewBuilder
private var contentView: some View {
CollectionVGrid(
$viewModel.mediaItems,
uniqueElements: viewModel.mediaItems,
layout: .columns(4, insets: .init(50), itemSpacing: 50, lineSpacing: 50)
) { mediaType in
MediaItem(viewModel: viewModel, type: mediaType)
Expand Down
4 changes: 2 additions & 2 deletions Swiftfin tvOS/Views/PagingLibraryView/PagingLibraryView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import SwiftUI
// TODO: list row view (LibraryRow)
// TODO: fix paging for next item focusing the tab

struct PagingLibraryView<Element: Poster>: View {
struct PagingLibraryView<Element: Poster & Identifiable>: View {

@Default(.Customization.Library.cinematicBackground)
private var cinematicBackground
Expand Down Expand Up @@ -159,7 +159,7 @@ struct PagingLibraryView<Element: Poster>: View {
@ViewBuilder
private var contentView: some View {
CollectionVGrid(
$viewModel.elements,
uniqueElements: viewModel.elements,
layout: layout
) { item in
switch (posterType, viewType) {
Expand Down
Loading