fix more stuff
multistore
Razmig Sarkissian 1 year ago
parent 3bdefc2511
commit d5adf5d83b
  1. 4
      PadelClub.xcodeproj/project.pbxproj
  2. 11
      PadelClub/Data/GroupStage.swift
  3. 50
      PadelClub/Data/Match.swift
  4. 12
      PadelClub/Data/Round.swift
  5. 28
      PadelClub/Data/Tournament.swift
  6. 8
      PadelClub/ViewModel/AgendaDestination.swift
  7. 4
      PadelClub/Views/Calling/CallSettingsView.swift
  8. 6
      PadelClub/Views/Cashier/Event/EventView.swift
  9. 2
      PadelClub/Views/Club/ClubSearchView.swift
  10. 127
      PadelClub/Views/Components/GenericDestinationPickerView.swift
  11. 41
      PadelClub/Views/Components/MatchListView.swift
  12. 6
      PadelClub/Views/GroupStage/GroupStageView.swift
  13. 15
      PadelClub/Views/GroupStage/GroupStagesView.swift
  14. 2
      PadelClub/Views/Match/MatchDetailView.swift
  15. 7
      PadelClub/Views/Round/LoserRoundsView.swift
  16. 2
      PadelClub/Views/Subscription/Guard.swift
  17. 2
      PadelClub/Views/Team/TeamPickerView.swift
  18. 7
      PadelClub/Views/Tournament/Screen/InscriptionManagerView.swift
  19. 8
      PadelClub/Views/Tournament/Screen/TournamentCallView.swift
  20. 7
      PadelClub/Views/Tournament/Screen/TournamentCashierView.swift
  21. 6
      PadelClub/Views/Tournament/Screen/TournamentScheduleView.swift
  22. 6
      PadelClub/Views/Tournament/Screen/TournamentSettingsView.swift
  23. 14
      PadelClub/Views/ViewModifiers/ListRowViewModifier.swift

@ -1935,7 +1935,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 31;
CURRENT_PROJECT_VERSION = 32;
DEFINES_MODULE = YES;
DEVELOPMENT_ASSET_PATHS = "\"PadelClub/Preview Content\"";
DEVELOPMENT_TEAM = BQ3Y44M3Q6;
@ -1973,7 +1973,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 31;
CURRENT_PROJECT_VERSION = 32;
DEFINES_MODULE = YES;
DEVELOPMENT_ASSET_PATHS = "\"PadelClub/Preview Content\"";
DEVELOPMENT_TEAM = BQ3Y44M3Q6;

@ -179,48 +179,58 @@ class GroupStage: ModelObject, Storable {
}
func availableToStart(playedMatches: [Match], in runningMatches: [Match]) async -> [Match] {
#if DEBUG_TIME
let start = Date()
defer {
let duration = Duration.milliseconds(Date().timeIntervalSince(start) * 1_000)
print("func group stage availableToStart", id, duration.formatted(.units(allowed: [.seconds, .milliseconds])))
}
#endif
return playedMatches.filter({ $0.canBeStarted(inMatches: runningMatches) && $0.isRunning() == false })
}
func runningMatches(playedMatches: [Match]) -> [Match] {
#if DEBUG_TIME
let start = Date()
defer {
let duration = Duration.milliseconds(Date().timeIntervalSince(start) * 1_000)
print("func group stage runningMatches", id, duration.formatted(.units(allowed: [.seconds, .milliseconds])))
}
#endif
return playedMatches.filter({ $0.isRunning() }).sorted(by: \.computedStartDateForSorting)
}
func asyncRunningMatches(playedMatches: [Match]) async -> [Match] {
#if DEBUG_TIME
let start = Date()
defer {
let duration = Duration.milliseconds(Date().timeIntervalSince(start) * 1_000)
print("func group stage runningMatches", id, duration.formatted(.units(allowed: [.seconds, .milliseconds])))
}
#endif
return playedMatches.filter({ $0.isRunning() }).sorted(by: \.computedStartDateForSorting)
}
func readyMatches(playedMatches: [Match]) async -> [Match] {
#if DEBUG_TIME
let start = Date()
defer {
let duration = Duration.milliseconds(Date().timeIntervalSince(start) * 1_000)
print("func group stage readyMatches", id, duration.formatted(.units(allowed: [.seconds, .milliseconds])))
}
#endif
return playedMatches.filter({ $0.isReady() && $0.isRunning() == false && $0.hasEnded() == false })
}
func finishedMatches(playedMatches: [Match]) -> [Match] {
#if DEBUG_TIME
let start = Date()
defer {
let duration = Duration.milliseconds(Date().timeIntervalSince(start) * 1_000)
print("func group stage finishedMatches", id, duration.formatted(.units(allowed: [.seconds, .milliseconds])))
}
#endif
return playedMatches.filter({ $0.hasEnded() }).sorted(by: \.computedEndDateForSorting).reversed()
}
@ -406,7 +416,6 @@ extension GroupStage: Selectable {
}
func badgeValue() -> Int? {
if teams().count < size { return nil }
return runningMatches(playedMatches: _matches()).count
}

@ -184,15 +184,11 @@ class Match: ModelObject, Storable {
}
func resetScores() {
if hasEnded() == false {
teamScores.forEach({ $0.score = nil })
do {
try DataStore.shared.teamScores.addOrUpdate(contentOfs: teamScores)
} catch {
Logger.error(error)
}
} else {
updateTeamScores()
teamScores.forEach({ $0.score = nil })
do {
try DataStore.shared.teamScores.addOrUpdate(contentOfs: teamScores)
} catch {
Logger.error(error)
}
}
@ -468,6 +464,9 @@ class Match: ModelObject, Storable {
if endDate == nil {
endDate = Date()
}
if startDate == nil {
startDate = endDate?.addingTimeInterval(Double(-getDuration()*60))
}
winningTeamId = team(matchDescriptor.winner)?.id
losingTeamId = team(matchDescriptor.winner.otherTeam)?.id
groupStageObject?.updateGroupStageState()
@ -705,34 +704,13 @@ class Match: ModelObject, Storable {
}
func team(_ team: TeamPosition) -> TeamRegistration? {
// let start = Date()
// defer {
// let duration = Duration.milliseconds(Date().timeIntervalSince(start) * 1_000)
// print("func match get team", id, duration.formatted(.units(allowed: [.seconds, .milliseconds])))
// }
if groupStage != nil {
switch team {
case .one:
return groupStageProjectedTeam(.one)
case .two:
return groupStageProjectedTeam(.two)
}
} else {
switch team {
case .one:
return roundProjectedTeam(.one)
case .two:
return roundProjectedTeam(.two)
}
#if DEBUG_TIME
let start = Date()
defer {
let duration = Duration.milliseconds(Date().timeIntervalSince(start) * 1_000)
print("func match get team", id, duration.formatted(.units(allowed: [.seconds, .milliseconds])))
}
}
func asyncTeam(_ team: TeamPosition) async -> TeamRegistration? {
// let start = Date()
// defer {
// let duration = Duration.milliseconds(Date().timeIntervalSince(start) * 1_000)
// print("func match get team", id, duration.formatted(.units(allowed: [.seconds, .milliseconds])))
// }
#endif
if groupStage != nil {
switch team {
case .one:

@ -221,11 +221,6 @@ class Round: ModelObject, Storable {
}
func playedMatches() -> [Match] {
// let start = Date()
// defer {
// let duration = Duration.milliseconds(Date().timeIntervalSince(start) * 1_000)
// print("func round playedMatches", id, duration.formatted(.units(allowed: [.seconds, .milliseconds])))
// }
if parent == nil {
return enabledMatches()
} else {
@ -549,7 +544,12 @@ class Round: ModelObject, Storable {
}
extension Round: Selectable {
extension Round: Selectable, Equatable {
static func == (lhs: Round, rhs: Round) -> Bool {
lhs.id == rhs.id
}
func selectionLabel() -> String {
if let parentRound {
return "Tour #\(parentRound.loserRounds().count - index)"

@ -727,12 +727,13 @@ class Tournament : ModelObject, Storable {
}
func selectedSortedTeams() -> [TeamRegistration] {
// let start = Date()
// defer {
// let duration = Duration.milliseconds(Date().timeIntervalSince(start) * 1_000)
// print("func selectedSortedTeams", id, tournamentTitle(), duration.formatted(.units(allowed: [.seconds, .milliseconds])))
// }
#if DEBUG_TIME
let start = Date()
defer {
let duration = Duration.milliseconds(Date().timeIntervalSince(start) * 1_000)
print("func selectedSortedTeams", id, tournamentTitle(), duration.formatted(.units(allowed: [.seconds, .milliseconds])))
}
#endif
var _sortedTeams : [TeamRegistration] = []
let _teams = unsortedTeams().filter({ $0.walkOut == false })
@ -956,47 +957,57 @@ class Tournament : ModelObject, Storable {
}
func availableToStart(_ allMatches: [Match], in runningMatches: [Match]) async -> [Match] {
#if DEBUG_TIME
let start = Date()
defer {
let duration = Duration.milliseconds(Date().timeIntervalSince(start) * 1_000)
print("func tournament availableToStart", id, duration.formatted(.units(allowed: [.seconds, .milliseconds])))
}
#endif
return allMatches.filter({ $0.canBeStarted(inMatches: runningMatches) && $0.isRunning() == false }).sorted(by: \.computedStartDateForSorting)
}
func asyncRunningMatches(_ allMatches: [Match]) async -> [Match] {
#if DEBUG_TIME
let start = Date()
defer {
let duration = Duration.milliseconds(Date().timeIntervalSince(start) * 1_000)
print("func tournament runningMatches", id, duration.formatted(.units(allowed: [.seconds, .milliseconds])))
}
#endif
return allMatches.filter({ $0.isRunning() && $0.isReady() }).sorted(by: \.computedStartDateForSorting)
}
func runningMatches(_ allMatches: [Match]) -> [Match] {
#if DEBUG_TIME
let start = Date()
defer {
let duration = Duration.milliseconds(Date().timeIntervalSince(start) * 1_000)
print("func tournament runningMatches", id, duration.formatted(.units(allowed: [.seconds, .milliseconds])))
}
#endif
return allMatches.filter({ $0.isRunning() && $0.isReady() }).sorted(by: \.computedStartDateForSorting)
}
func readyMatches(_ allMatches: [Match]) async -> [Match] {
#if DEBUG_TIME
let start = Date()
defer {
let duration = Duration.milliseconds(Date().timeIntervalSince(start) * 1_000)
print("func tournament readyMatches", id, duration.formatted(.units(allowed: [.seconds, .milliseconds])))
}
#endif
return allMatches.filter({ $0.isReady() && $0.isRunning() == false && $0.hasEnded() == false }).sorted(by: \.computedStartDateForSorting)
}
func finishedMatches(_ allMatches: [Match], limit: Int? = nil) -> [Match] {
#if DEBUG_TIME
let start = Date()
defer {
let duration = Duration.milliseconds(Date().timeIntervalSince(start) * 1_000)
print("func tournament finishedMatches", id, duration.formatted(.units(allowed: [.seconds, .milliseconds])))
}
#endif
let _limit = limit ?? courtCount
return Array(allMatches.filter({ $0.hasEnded() }).sorted(by: \.computedEndDateForSorting).reversed().prefix(_limit))
}
@ -1653,7 +1664,10 @@ class Tournament : ModelObject, Storable {
func getGroupStageChunkValue() -> Int {
if teamsPerGroupStage >= 2 {
return min(groupStageCount, courtCount / (teamsPerGroupStage / 2))
let result = courtCount / (teamsPerGroupStage / 2)
let remainder = courtCount % (teamsPerGroupStage / 2)
let value = remainder == 0 ? result : result + 1
return min(groupStageCount, value)
} else {
return 1
}

@ -8,8 +8,12 @@
import Foundation
import SwiftUI
enum AgendaDestination: CaseIterable, Identifiable, Selectable {
var id: Self { self }
enum AgendaDestination: Int, CaseIterable, Identifiable, Selectable, Equatable {
var id: Int { self.rawValue }
static func == (lhs: AgendaDestination, rhs: AgendaDestination) -> Bool {
return lhs.id == rhs.id
}
case activity
case history

@ -51,7 +51,7 @@ struct CallSettingsView: View {
}
}
#if DEBUG
// #if DEBUG
Section {
RowButtonView("Annuler toutes les convocations", role: .destructive) {
let teams = tournament.unsortedTeams()
@ -79,7 +79,7 @@ struct CallSettingsView: View {
}
}
}
#endif
//#endif
}
.sheet(isPresented: $showSendToAllView) {
SendToAllView(addLink: false)

@ -8,7 +8,11 @@
import SwiftUI
import LeStorage
enum EventDestination: Identifiable, Selectable {
enum EventDestination: Identifiable, Selectable, Equatable {
static func == (lhs: EventDestination, rhs: EventDestination) -> Bool {
return lhs.id == rhs.id
}
case links
case tournaments(Event)
case cashier

@ -96,9 +96,9 @@ struct ClubSearchView: View {
_importClub(clubToEdit: clubToEdit, clubMarker: clubMark)
} label: {
clubView(clubMark)
.frame(maxWidth: .infinity)
.contentShape(Rectangle())
}
.frame(maxWidth: .infinity)
.buttonStyle(.plain)
}
} header: {

@ -7,75 +7,86 @@
import SwiftUI
struct GenericDestinationPickerView<T: Identifiable & Selectable>: View {
struct GenericDestinationPickerView<T: Identifiable & Selectable & Equatable >: View {
@EnvironmentObject var dataStore: DataStore
@Binding var selectedDestination: T?
let destinations: [T]
let nilDestinationIsValid: Bool
var body: some View {
ScrollView(.horizontal) {
HStack {
if nilDestinationIsValid {
Button {
selectedDestination = nil
} label: {
Image(systemName: "wrench.and.screwdriver")
.foregroundColor(selectedDestination == nil ? .white : .black)
}
.padding()
.background {
Circle()
.fill(selectedDestination == nil ? .master : .beige)
}
.buttonStyle(.plain)
}
ForEach(destinations) { destination in
Button {
selectedDestination = destination
} label: {
Text(destination.selectionLabel())
.foregroundStyle(selectedDestination?.id == destination.id ? .white : .black)
}
.padding()
.background {
Capsule()
.fill(selectedDestination?.id == destination.id ? .master : .beige)
ScrollViewReader { proxy in
ScrollView(.horizontal) {
HStack {
if nilDestinationIsValid {
Button {
selectedDestination = nil
} label: {
Image(systemName: "wrench.and.screwdriver")
.foregroundColor(selectedDestination == nil ? .white : .black)
}
.padding()
.background {
Circle()
.fill(selectedDestination == nil ? .master : .beige)
}
.buttonStyle(.plain)
.id("settings")
}
.buttonStyle(.plain)
.overlay(alignment: .bottomTrailing) {
if let badge = destination.badgeImage() {
Image(systemName: badge.systemName())
.foregroundColor(badge.color())
.imageScale(.medium)
.background (
Color(.systemBackground)
.clipShape(.circle)
)
.offset(x: 3, y: 3)
} else if let count = destination.badgeValue(), count > 0 {
Image(systemName: count <= 50 ? "\(count).circle.fill" : "plus.circle.fill")
.foregroundColor(destination.badgeValueColor() ?? .red)
.imageScale(.medium)
.background (
Color(.systemBackground)
.clipShape(.circle)
)
.offset(x: 3, y: 3)
ForEach(destinations) { destination in
Button {
selectedDestination = destination
} label: {
Text(destination.selectionLabel())
.foregroundStyle(selectedDestination?.id == destination.id ? .white : .black)
}
.padding()
.background {
Capsule()
.fill(selectedDestination?.id == destination.id ? .master : .beige)
}
.id(destination.id)
.buttonStyle(.plain)
.overlay(alignment: .bottomTrailing) {
if let badge = destination.badgeImage() {
Image(systemName: badge.systemName())
.foregroundColor(badge.color())
.imageScale(.medium)
.background (
Color(.systemBackground)
.clipShape(.circle)
)
.offset(x: 3, y: 3)
} else if let count = destination.badgeValue(), count > 0 {
Image(systemName: count <= 50 ? "\(count).circle.fill" : "plus.circle.fill")
.foregroundColor(destination.badgeValueColor() ?? .red)
.imageScale(.medium)
.background (
Color(.systemBackground)
.clipShape(.circle)
)
.offset(x: 3, y: 3)
}
}
}
}
.fixedSize()
.padding(8)
}
.fixedSize()
.padding(8)
}
.listRowInsets(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0))
.background(Material.ultraThinMaterial)
.overlay {
VStack(spacing: 0) {
Spacer()
Divider()
.listRowInsets(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0))
.background(Material.ultraThinMaterial)
.overlay {
VStack(spacing: 0) {
Spacer()
Divider()
}
}
.onAppear {
if let selectedDestination {
proxy.scrollTo(selectedDestination.id)
} else {
proxy.scrollTo("settings")
}
}
}
}

@ -12,28 +12,39 @@ struct MatchListView: View {
let section: String
let matches: [Match]?
var matchViewStyle: MatchViewStyle = .standardStyle
var hideWhenEmpty: Bool = false
@State var isExpanded: Bool = true
private func _shouldHide() -> Bool {
if matches != nil && matches!.isEmpty && hideWhenEmpty == true {
return true
} else {
return false
}
}
@ViewBuilder
var body: some View {
Section {
DisclosureGroup(isExpanded: $isExpanded) {
if let matches {
ForEach(matches) { match in
MatchRowView(match: match, matchViewStyle: matchViewStyle)
.listRowInsets(EdgeInsets(top: 0, leading: -2, bottom: 0, trailing: 8))
}
}
} label: {
LabeledContent {
if matches == nil {
ProgressView()
} else {
Text(matches!.count.formatted() + " match" + matches!.count.pluralSuffix)
if _shouldHide() == false {
Section {
DisclosureGroup(isExpanded: $isExpanded) {
if let matches {
ForEach(matches) { match in
MatchRowView(match: match, matchViewStyle: matchViewStyle)
.listRowInsets(EdgeInsets(top: 0, leading: -2, bottom: 0, trailing: 8))
}
}
} label: {
Text(section.firstCapitalized)
LabeledContent {
if matches == nil {
ProgressView()
} else {
Text(matches!.count.formatted() + " match" + matches!.count.pluralSuffix)
}
} label: {
Text(section.firstCapitalized)
}
}
}
}

@ -48,9 +48,9 @@ struct GroupStageView: View {
}
.headerProminence(.increased)
MatchListView(section: "en cours", matches: runningMatches)
MatchListView(section: "prêt à démarrer", matches: availableToStart)
MatchListView(section: "à lancer", matches: self.readyMatches)
MatchListView(section: "en cours", matches: runningMatches, hideWhenEmpty: true)
MatchListView(section: "prêt à démarrer", matches: availableToStart, hideWhenEmpty: true)
MatchListView(section: "à lancer", matches: self.readyMatches, hideWhenEmpty: true)
MatchListView(section: "terminés", matches: groupStage.finishedMatches(playedMatches: playedMatches), isExpanded: false)
}
.task {

@ -11,7 +11,11 @@ struct GroupStagesView: View {
var tournament: Tournament
@State private var selectedDestination: GroupStageDestination?
enum GroupStageDestination: Selectable, Identifiable {
enum GroupStageDestination: Selectable, Identifiable, Equatable {
static func == (lhs: GroupStagesView.GroupStageDestination, rhs: GroupStagesView.GroupStageDestination) -> Bool {
lhs.id == rhs.id
}
case all
case groupStage(GroupStage)
@ -47,7 +51,12 @@ struct GroupStagesView: View {
}
func badgeImage() -> Badge? {
nil
switch self {
case .all:
return nil
case .groupStage(let groupStage):
return groupStage.badgeImage()
}
}
}
@ -105,7 +114,7 @@ struct GroupStagesView: View {
}
.navigationTitle("Toutes les poules")
case .groupStage(let groupStage):
GroupStageView(groupStage: groupStage)
GroupStageView(groupStage: groupStage).id(groupStage.id)
case nil:
GroupStageSettingsView()
.navigationTitle("Réglages")

@ -308,6 +308,8 @@ struct MatchDetailView: View {
Button(role: .destructive) {
match.resetScores()
match.resetMatch()
match.confirmed = false
save()
} label: {
Text("Supprimer les scores")

@ -34,7 +34,12 @@ struct LoserRound: Identifiable, Selectable {
}
extension LoserRound {
extension LoserRound: Equatable {
static func == (lhs: LoserRound, rhs: LoserRound) -> Bool {
lhs.id == rhs.id
}
func selectionLabel() -> String {
return "Tour #\(turnIndex + 1)"
}

@ -141,7 +141,7 @@ import LeStorage
var currentPlan: StoreItem? {
// #if DEBUG
// return .monthlyUnlimited
return .monthlyUnlimited
// #else
if let currentBestPlan = self.currentBestPlan, let plan = StoreItem(rawValue: currentBestPlan.productID) {
return plan

@ -80,7 +80,9 @@ struct TeamPickerView: View {
presentTeamPickerView = false
} label: {
TeamRowView(team: team)
.contentShape(Rectangle())
}
.frame(maxWidth: .infinity)
.buttonStyle(.plain)
}
}

@ -138,12 +138,13 @@ struct InscriptionManagerView: View {
}
private func _setHash() async {
#if DEBUG_TIME
let start = Date()
defer {
let duration = Duration.milliseconds(Date().timeIntervalSince(start) * 1_000)
print("func _setHash", duration.formatted(.units(allowed: [.seconds, .milliseconds])))
}
#endif
let selectedSortedTeams = tournament.selectedSortedTeams()
if self.teamsHash == nil, selectedSortedTeams.isEmpty == false {
self.teamsHash = _simpleHash(ids: selectedSortedTeams.map { $0.id })
@ -410,11 +411,13 @@ struct InscriptionManagerView: View {
}
private func _prepareStats() async {
#if DEBUG_TIME
let start = Date()
defer {
let duration = Duration.milliseconds(Date().timeIntervalSince(start) * 1_000)
print("func _prepareStats", duration.formatted(.units(allowed: [.seconds, .milliseconds])))
}
#endif
unsortedPlayers = tournament.unsortedPlayers()
walkoutTeams = tournament.walkoutTeams()
@ -448,11 +451,13 @@ struct InscriptionManagerView: View {
}
private func _getIssues() async {
#if DEBUG_TIME
let start = Date()
defer {
let duration = Duration.milliseconds(Date().timeIntervalSince(start) * 1_000)
print("func _getIssues", duration.formatted(.units(allowed: [.seconds, .milliseconds])))
}
#endif
await registrationIssues = tournament.registrationIssues()
}

@ -7,7 +7,13 @@
import SwiftUI
enum CallDestination: Identifiable, Selectable {
enum CallDestination: Identifiable, Selectable, Equatable {
static func == (lhs: CallDestination, rhs: CallDestination) -> Bool {
return lhs.id == rhs.id
}
case seeds(Tournament)
case groupStages(Tournament)

@ -7,7 +7,12 @@
import SwiftUI
enum CashierDestination: Identifiable, Selectable {
enum CashierDestination: Identifiable, Selectable, Equatable {
static func == (lhs: CashierDestination, rhs: CashierDestination) -> Bool {
return lhs.id == rhs.id
}
case summary
case groupStage(GroupStage)
case bracket(Round)

@ -20,7 +20,11 @@ extension Schedulable {
}
}
enum ScheduleDestination: String, Identifiable, Selectable {
enum ScheduleDestination: String, Identifiable, Selectable, Equatable {
static func == (lhs: ScheduleDestination, rhs: ScheduleDestination) -> Bool {
return lhs.id == rhs.id
}
var id: String { self.rawValue }
case planning

@ -7,7 +7,11 @@
import SwiftUI
enum TournamentSettings: Identifiable, Selectable {
enum TournamentSettings: Identifiable, Selectable, Equatable {
static func == (lhs: TournamentSettings, rhs: TournamentSettings) -> Bool {
return lhs.id == rhs.id
}
case status
case general
case club(Tournament)

@ -14,12 +14,12 @@ struct ListRowViewModifier: ViewModifier {
func body(content: Content) -> some View {
if isActive {
content
// .listRowBackground(
// color.variation()
// .overlay(alignment: .leading, content: {
// color.frame(width: 8)
// })
// )
.listRowBackground(
color.variation()
.overlay(alignment: .leading, content: {
color.frame(width: 8)
})
)
} else {
content
}
@ -27,7 +27,7 @@ struct ListRowViewModifier: ViewModifier {
}
extension View {
func listRowView(isActive: Bool = true, color: Color) -> some View {
func listRowView(isActive: Bool = false, color: Color) -> some View {
modifier(ListRowViewModifier(isActive: isActive, color: color))
}
}

Loading…
Cancel
Save