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

Add pagination to CarPlay Areas and Actions tabs #2543

Merged
merged 4 commits into from
Jan 30, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
18 changes: 12 additions & 6 deletions Sources/Vehicle/Templates/Actions/CarPlayActionsTemplate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@
private var actions: Results<Action>?
private let viewModel: CarPlayActionsViewModel

private let paginatedList = CarPlayPaginatedListTemplate(
title: L10n.CarPlay.Navigation.Tab.actions,
items: [],
isInsideTabBar: true
)

Check warning on line 15 in Sources/Vehicle/Templates/Actions/CarPlayActionsTemplate.swift

View check run for this annotation

Codecov / codecov/patch

Sources/Vehicle/Templates/Actions/CarPlayActionsTemplate.swift#L11-L15

Added lines #L11 - L15 were not covered by tests
var template: CPListTemplate

weak var interfaceController: CPInterfaceController?
Expand All @@ -17,7 +22,7 @@
text: L10n.CarPlay.Action.Intro.Item.title,
detailText: L10n.CarPlay.Action.Intro.Item.body,
image: MaterialDesignIcons.homeLightningBoltIcon
.carPlayIcon(carUserInterfaceStyle: interfaceController?.carTraitCollection.userInterfaceStyle)
.carPlayIcon()

Check warning on line 25 in Sources/Vehicle/Templates/Actions/CarPlayActionsTemplate.swift

View check run for this annotation

Codecov / codecov/patch

Sources/Vehicle/Templates/Actions/CarPlayActionsTemplate.swift#L25

Added line #L25 was not covered by tests
)
item.handler = { [weak self] _, completion in
self?.viewModel.sendIntroNotification()
Expand All @@ -29,7 +34,8 @@

init(viewModel: CarPlayActionsViewModel) {
self.viewModel = viewModel
self.template = CPListTemplate(title: L10n.CarPlay.Navigation.Tab.actions, sections: [])

self.template = paginatedList.template

Check warning on line 38 in Sources/Vehicle/Templates/Actions/CarPlayActionsTemplate.swift

View check run for this annotation

Codecov / codecov/patch

Sources/Vehicle/Templates/Actions/CarPlayActionsTemplate.swift#L37-L38

Added lines #L37 - L38 were not covered by tests
template.tabTitle = L10n.CarPlay.Navigation.Tab.actions
template.tabImage = MaterialDesignIcons.lightningBoltIcon.carPlayIcon()
template.tabSystemItem = .more
Expand Down Expand Up @@ -60,17 +66,17 @@
presentIntroductionItem()
return
}
template.updateSections([section(actions: actions)])
paginatedList.updateItems(items: listItems(actions: actions))

Check warning on line 69 in Sources/Vehicle/Templates/Actions/CarPlayActionsTemplate.swift

View check run for this annotation

Codecov / codecov/patch

Sources/Vehicle/Templates/Actions/CarPlayActionsTemplate.swift#L69

Added line #L69 was not covered by tests
}

private func presentIntroductionItem() {
template.updateSections([.init(items: [introduceActionsListItem])])
}

private func section(actions: Results<Action>) -> CPListSection {
private func listItems(actions: Results<Action>) -> [CPListItem] {

Check warning on line 76 in Sources/Vehicle/Templates/Actions/CarPlayActionsTemplate.swift

View check run for this annotation

Codecov / codecov/patch

Sources/Vehicle/Templates/Actions/CarPlayActionsTemplate.swift#L76

Added line #L76 was not covered by tests
let items: [CPListItem] = actions.map { action in
let materialDesignIcon = MaterialDesignIcons(named: action.IconName)
.carPlayIcon(carUserInterfaceStyle: interfaceController?.carTraitCollection.userInterfaceStyle)
.carPlayIcon()

Check warning on line 79 in Sources/Vehicle/Templates/Actions/CarPlayActionsTemplate.swift

View check run for this annotation

Codecov / codecov/patch

Sources/Vehicle/Templates/Actions/CarPlayActionsTemplate.swift#L79

Added line #L79 was not covered by tests
let item = CPListItem(
text: action.Name,
detailText: action.Text,
Expand All @@ -84,7 +90,7 @@
return item
}

return CPListSection(items: items)
return items

Check warning on line 93 in Sources/Vehicle/Templates/Actions/CarPlayActionsTemplate.swift

View check run for this annotation

Codecov / codecov/patch

Sources/Vehicle/Templates/Actions/CarPlayActionsTemplate.swift#L93

Added line #L93 was not covered by tests
}

// Present a checkmark or cross depending on success or failure
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@
return item
}

templateProvider?.template.updateSections([.init(items: items)])
templateProvider?.paginatedList.updateItems(items: items)

Check warning on line 153 in Sources/Vehicle/Templates/Areas/CarPlayAreasViewModel.swift

View check run for this annotation

Codecov / codecov/patch

Sources/Vehicle/Templates/Areas/CarPlayAreasViewModel.swift#L153

Added line #L153 was not covered by tests
}

private func listItemHandler(area: HAAreaResponse, entityIdsForAreaId: [String], server: Server) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,18 @@
final class CarPlayAreasZonesTemplate: CarPlayTemplateProvider {
private var childTemplateProvider: (any CarPlayTemplateProvider)?
private let viewModel: CarPlayAreasViewModel

let paginatedList = CarPlayPaginatedListTemplate(
title: L10n.CarPlay.Navigation.Tab.areas,
items: [],
isInsideTabBar: true
)

Check warning on line 15 in Sources/Vehicle/Templates/Areas/CarPlayAreasZonesTemplate.swift

View check run for this annotation

Codecov / codecov/patch

Sources/Vehicle/Templates/Areas/CarPlayAreasZonesTemplate.swift#L11-L15

Added lines #L11 - L15 were not covered by tests
var template: CPListTemplate
weak var interfaceController: CPInterfaceController?

init(viewModel: CarPlayAreasViewModel) {
self.viewModel = viewModel
self.template = CPListTemplate(title: "", sections: [])
self.template = paginatedList.template

Check warning on line 21 in Sources/Vehicle/Templates/Areas/CarPlayAreasZonesTemplate.swift

View check run for this annotation

Codecov / codecov/patch

Sources/Vehicle/Templates/Areas/CarPlayAreasZonesTemplate.swift#L21

Added line #L21 was not covered by tests
template.tabImage = MaterialDesignIcons.sofaIcon.carPlayIcon()
template.tabTitle = L10n.CarPlay.Navigation.Tab.areas

Expand Down
44 changes: 36 additions & 8 deletions Sources/Vehicle/Templates/CarPlayPaginatedListTemplate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@
private var items: [CPListItem]
private var currentPage: Int
private let title: String
private let isInsideTabBar: Bool

private let itemsPerPage: Int = CPListTemplate.maximumItemCount
private(set) var template: CPListTemplate

init(title: String, items: [CPListItem]) {
init(title: String, items: [CPListItem], isInsideTabBar: Bool = false) {

Check warning on line 18 in Sources/Vehicle/Templates/CarPlayPaginatedListTemplate.swift

View check run for this annotation

Codecov / codecov/patch

Sources/Vehicle/Templates/CarPlayPaginatedListTemplate.swift#L18

Added line #L18 was not covered by tests
bgoncal marked this conversation as resolved.
Show resolved Hide resolved
self.title = title
self.items = items
self.isInsideTabBar = isInsideTabBar

Check warning on line 21 in Sources/Vehicle/Templates/CarPlayPaginatedListTemplate.swift

View check run for this annotation

Codecov / codecov/patch

Sources/Vehicle/Templates/CarPlayPaginatedListTemplate.swift#L21

Added line #L21 was not covered by tests
self.currentPage = 0
self.template = CPListTemplate(title: title, sections: [])
}
Expand All @@ -29,17 +30,44 @@

func updateTemplate() {
let totalItems = items.count
var itemsPerPage = CPListTemplate.maximumItemCount

if isInsideTabBar, items.count > itemsPerPage {
itemsPerPage = CPListTemplate.maximumItemCount - 2
}

Check warning on line 38 in Sources/Vehicle/Templates/CarPlayPaginatedListTemplate.swift

View check run for this annotation

Codecov / codecov/patch

Sources/Vehicle/Templates/CarPlayPaginatedListTemplate.swift#L33-L38

Added lines #L33 - L38 were not covered by tests
let startIndex = currentPage * itemsPerPage
let endIndex = min(startIndex + itemsPerPage, totalItems)
let pageItems = Array(items[startIndex ..< endIndex])
var pageItems = Array(items[startIndex ..< endIndex])

Check warning on line 41 in Sources/Vehicle/Templates/CarPlayPaginatedListTemplate.swift

View check run for this annotation

Codecov / codecov/patch

Sources/Vehicle/Templates/CarPlayPaginatedListTemplate.swift#L41

Added line #L41 was not covered by tests

if isInsideTabBar {
if currentPage > 0 {
let previousItem = CPListItem(text: nil, detailText: nil)
previousItem.setImage(MaterialDesignIcons.arrowLeftIcon.carPlayIcon())
previousItem.handler = { [weak self] _, completion in
self?.changePage(to: .previous)
completion()
}
pageItems.insert(previousItem, at: 0)
}
if endIndex < totalItems {
let nextItem = CPListItem(text: nil, detailText: nil)
nextItem.setImage(MaterialDesignIcons.arrowRightIcon.carPlayIcon())
nextItem.handler = { [weak self] _, completion in
self?.changePage(to: .next)
completion()
}
pageItems.insert(nextItem, at: pageItems.endIndex)
}
} else {
template.trailingNavigationBarButtons = getPageButtons(
endIndex: endIndex,
currentPage: currentPage,
totalCount: totalItems
)
}

Check warning on line 68 in Sources/Vehicle/Templates/CarPlayPaginatedListTemplate.swift

View check run for this annotation

Codecov / codecov/patch

Sources/Vehicle/Templates/CarPlayPaginatedListTemplate.swift#L43-L68

Added lines #L43 - L68 were not covered by tests
let section = CPListSection(items: pageItems)
template.updateSections([section])
template.trailingNavigationBarButtons = getPageButtons(
endIndex: endIndex,
currentPage: currentPage,
totalCount: totalItems
)
}

private func getPageButtons(endIndex: Int, currentPage: Int, totalCount: Int) -> [CPBarButton] {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@
text: itemTitle,
detailText: nil,
image: domain == .cover ? overrideCoverIcon
.carPlayIcon(carUserInterfaceStyle: userInterfaceStyle) : domain.icon
.carPlayIcon(carUserInterfaceStyle: userInterfaceStyle)
.carPlayIcon() : domain.icon
.carPlayIcon()

Check warning on line 40 in Sources/Vehicle/Templates/Domains/CarPlayDomainsListTemplate.swift

View check run for this annotation

Codecov / codecov/patch

Sources/Vehicle/Templates/Domains/CarPlayDomainsListTemplate.swift#L39-L40

Added lines #L39 - L40 were not covered by tests
)
listItem.accessoryType = CPListItemAccessoryType.disclosureIndicator
listItem.handler = { [weak self] _, completion in
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,6 @@
var template: CPListItem
weak var interfaceController: CPInterfaceController?

private var userInterfaceStyle: UIUserInterfaceStyle? {
interfaceController?.carTraitCollection.userInterfaceStyle
}

init(entity: HAEntity) {
self.template = CPListItem(text: nil, detailText: nil)
self.entity = entity
Expand All @@ -24,8 +20,8 @@
template.setDetailText(entity.localizedState)
template
.setImage(
entity.getIcon(carUserInterfaceStyle: userInterfaceStyle) ?? MaterialDesignIcons.bookmarkIcon
.carPlayIcon(carUserInterfaceStyle: userInterfaceStyle)
entity.getIcon() ?? MaterialDesignIcons.bookmarkIcon
.carPlayIcon()

Check warning on line 24 in Sources/Vehicle/Templates/Entities/CarPlayEntityListItem.swift

View check run for this annotation

Codecov / codecov/patch

Sources/Vehicle/Templates/Entities/CarPlayEntityListItem.swift#L23-L24

Added lines #L23 - L24 were not covered by tests
)
}
}
8 changes: 5 additions & 3 deletions Sources/Vehicle/Templates/HAEntity+CarPlay.swift
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
}
}

func getIcon(carUserInterfaceStyle: UIUserInterfaceStyle?) -> UIImage? {
func getIcon() -> UIImage? {

Check warning on line 73 in Sources/Vehicle/Templates/HAEntity+CarPlay.swift

View check run for this annotation

Codecov / codecov/patch

Sources/Vehicle/Templates/HAEntity+CarPlay.swift#L73

Added line #L73 was not covered by tests
var image = MaterialDesignIcons.bookmarkIcon
var tint: UIColor?

Expand Down Expand Up @@ -102,13 +102,15 @@

if let state = Domain.State(rawValue: state) {
if [.on, .open, .opening, .unlocked, .unlocking].contains(state) {
tint = Constants.tintColor
tint = Constants.lighterTintColor

Check warning on line 105 in Sources/Vehicle/Templates/HAEntity+CarPlay.swift

View check run for this annotation

Codecov / codecov/patch

Sources/Vehicle/Templates/HAEntity+CarPlay.swift#L105

Added line #L105 was not covered by tests
} else if [.unavailable, .unknown].contains(state) {
tint = .gray
} else {
tint = .lightGray

Check warning on line 109 in Sources/Vehicle/Templates/HAEntity+CarPlay.swift

View check run for this annotation

Codecov / codecov/patch

Sources/Vehicle/Templates/HAEntity+CarPlay.swift#L108-L109

Added lines #L108 - L109 were not covered by tests
}
}

return image.carPlayIcon(color: tint, carUserInterfaceStyle: carUserInterfaceStyle)
return image.carPlayIcon(color: tint)

Check warning on line 113 in Sources/Vehicle/Templates/HAEntity+CarPlay.swift

View check run for this annotation

Codecov / codecov/patch

Sources/Vehicle/Templates/HAEntity+CarPlay.swift#L113

Added line #L113 was not covered by tests
}

private func getInputBooleanIcon() -> MaterialDesignIcons {
Expand Down
10 changes: 2 additions & 8 deletions Sources/Vehicle/Templates/MaterialDesignIcons+CarPlay.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,8 @@
import UIKit

extension MaterialDesignIcons {
func carPlayIcon(color: UIColor? = nil, carUserInterfaceStyle: UIUserInterfaceStyle? = nil) -> UIImage {
let color: UIColor = color ?? {
if let carUserInterfaceStyle, carUserInterfaceStyle == .light {
.black
} else {
.white
}
}()
func carPlayIcon(color: UIColor? = nil) -> UIImage {
let color = color ?? Constants.lighterTintColor

Check warning on line 8 in Sources/Vehicle/Templates/MaterialDesignIcons+CarPlay.swift

View check run for this annotation

Codecov / codecov/patch

Sources/Vehicle/Templates/MaterialDesignIcons+CarPlay.swift#L7-L8

Added lines #L7 - L8 were not covered by tests
return image(ofSize: CPListItem.maximumImageSize, color: color)
}
}