// // Picker List.swift // Pickt // // Created by Morris Richman on 2/15/22. // import SwiftUI import Firebase import FirebaseFirestore import URLImage struct PickerList: View { @State var restMock: [Restaurants] @State var mediaMock: [Media] @State var pick = Utilities.topPick @State private var showDescription = false @State private var showDescriptionTitle = "" @State var subtitle = "Subtitle, Fill Here" @State var editing = false @State var typeSelected: type enum type: String { case yes = "Yes" case no = "No" } @State private var showDescriptionMessage = "" { didSet { showDescription = true } } @State private var pickOpt = ["None"] @Environment(\.presentationMode) var presentationMode @Environment(\.horizontalSizeClass) var sizeClass let db = Firestore.firestore() func moveRest(buisness: Restaurants) { let index = restMock.firstIndex(of: buisness)! restMock.remove(at: index) if typeSelected == .yes { yes.restList.remove(at: index) no.restList.append(buisness) }else { no.restList.remove(at: index) yes.restList.append(buisness) } } func moveMedia(media: Media) { let index = mediaMock.firstIndex(of: media)! mediaMock.remove(at: index) if typeSelected == .yes { yes.mediaList.remove(at: index) no.mediaList.append(media) }else { no.mediaList.remove(at: index) yes.mediaList.append(media) } } var body: some View { NavigationView { VStack { Group { if Utilities.picktType == .media { if Utilities.mediaType == .TVShows { Text("Here are all the tv shows you said \(typeSelected.rawValue.lowercased()) to.") }else if Utilities.mediaType == .Movies { Text("Here are all the movies you said \(typeSelected.rawValue.lowercased()) to.") } }else { Text("Here are all the restaurants you said \(typeSelected.rawValue.lowercased()) to.") } } .padding() if (restMock.count == 0 && Utilities.picktType == .restaurants) || (mediaMock.count == 0 && Utilities.picktType == .media) { if Utilities.picktType == .restaurants { Text("No Restaurants Selected") }else if Utilities.picktType == .media { if Utilities.mediaType == .TVShows { Text("No TV Shows Selected") }else if Utilities.mediaType == .Movies { Text("No Movies Selected") } } }else { if Utilities.picktType == .media { List { ForEach(mediaMock) { media in if #available(iOS 15.0, *) { mediaLayout(data: media) .swipeActions(edge: .trailing, allowsFullSwipe: true) { if typeSelected == .yes { Button { moveMedia(media: media) } label: { VStack { Image(systemName: "hand.thumbsdown") Text("Move to No List") } .foregroundColor(.white) } .tint(.red) }else { Button { moveMedia(media: media) } label: { VStack { Image(systemName: "hand.thumbsup") Text("Move to Yes List") } .foregroundColor(.white) } .background(.green) } } .padding() }else { mediaLayout(data: media) .padding() } } } }else { List { ForEach(restMock) { buisness in if #available(iOS 15.0, *) { restLayout(buisness: buisness) .swipeActions(edge: .trailing, allowsFullSwipe: true) { if typeSelected == .yes { Button { moveRest(buisness: buisness) } label: { VStack { Image(systemName: "hand.thumbsdown") Text("Move to No List") } .foregroundColor(.white) } .tint(.red) }else { Button { moveRest(buisness: buisness) } label: { VStack { Image(systemName: "hand.thumbsup") Text("Move to Yes List") } .foregroundColor(.white) } .background(.green) } } } else { restLayout(buisness: buisness) .padding() } } // .frame(height: 150) } } } HStack { // Picker("Select Top Pick", selection: $pick) { // ForEach(pickOpt.reversed(), id: \.self) { pickt in // Text(pickt) // } // } // .pickerStyle(MenuPickerStyle()) // Spacer() // .frame(width: 60.0) Button("Ok") { presentationMode.wrappedValue.dismiss() } } .padding() } .toolbar(content: { Button { editing.toggle() } label: { if typeSelected == .yes { if editing { Text("Cancel") .foregroundColor(.red) }else { Text("Move to No List") .foregroundColor(.red) } }else { if editing { Text("Cancel") .foregroundColor(.green) }else { Text("Move to No List") .foregroundColor(.green) } } } }) .navigationTitle("\(typeSelected.rawValue) List") .navigationBarTitleDisplayMode(.large) .alert(isPresented: $showDescription, content: { Alert(title: Text(showDescriptionTitle), message: Text(showDescriptionMessage), dismissButton: .default(Text("Dismiss"))) }) } .navigationTitle("\(typeSelected.rawValue) List") .navigationBarTitleDisplayMode(.large) .onAppear(perform: { pick = Utilities.topPick print("pick = \(pick)") print("yes.restlist = \(restMock), yes.medialist = \(mediaMock)") for buisness in restMock { pickOpt.append(buisness.name) } }) .onDisappear { print("yes.restlist = \(restMock), yes.medialist = \(mediaMock)") } } } extension PickerList { func restLayout(buisness: Restaurants) -> some View { HStack { if #available(iOS 15, *) { AsyncImage(url: buisness.imageUrl) { image in image .resizable() .aspectRatio(contentMode: .fill) .frame(maxWidth: 70, maxHeight: 70) .clipped() .padding(.trailing) } placeholder: { Image(systemName: "photo") .resizable() .aspectRatio(contentMode: .fill) .frame(maxWidth: 70, maxHeight: 70) .clipped() .padding(.trailing) .imageScale(.large) .foregroundColor(.gray) } .ignoresSafeArea() // switch image { // case .empty: // Image(named: "No Image") // .resizable() // .aspectRatio(contentMode: .fill) // .frame(maxWidth: 70, maxHeight: 70) // .clipped() // .padding(.trailing) // case .success(let image): // image // .resizable() // .aspectRatio(contentMode: .fill) // .frame(maxWidth: 70, maxHeight: 70) // .clipped() // .padding(.trailing) // case .failure: // Image(named: "No Image") // .resizable() // .aspectRatio(contentMode: .fill) // .frame(maxWidth: 70, maxHeight: 70) // .clipped() // .padding(.trailing) // @unknown default: // // Since the AsyncImagePhase enum isn't frozen, // // we need to add this currently unused fallback // // to handle any new cases that might be added // // in the future: // Image(named: "No Image") // .resizable() // .aspectRatio(contentMode: .fill) // .frame(maxWidth: 70, maxHeight: 70) // .clipped() // } // } }else { URLImage(buisness.imageUrl) { image in image .resizable() .aspectRatio(contentMode: .fill) .frame(maxWidth: 70, maxHeight: 70) .clipped() .padding(.trailing) } } if sizeClass == .regular { VStack { HStack { HStack { Text(buisness.name) if buisness.price != "Unknown" { Text(buisness.price) } // if !buisness.isClosed { // Text("Open") // .foregroundColor(Color.green) // }else { // Text("Closed") // .foregroundColor(Color.red) // } } .padding() Group { if buisness.rating == 0 { Image(systemName: "star") Image(systemName: "star") Image(systemName: "star") Image(systemName: "star") Image(systemName: "star") }else if buisness.rating == 0.5 { Image(systemName: "star.leadinghalf.fill") Image(systemName: "star") Image(systemName: "star") Image(systemName: "star") Image(systemName: "star") }else if buisness.rating == 1.0 { Image(systemName: "star.fill") Image(systemName: "star") Image(systemName: "star") Image(systemName: "star") Image(systemName: "star") }else if buisness.rating == 1.5 { Image(systemName: "star.fill") Image(systemName: "star.leadinghalf.fill") Image(systemName: "star") Image(systemName: "star") Image(systemName: "star") }else if buisness.rating == 2.0 { Image(systemName: "star.fill") Image(systemName: "star.fill") Image(systemName: "star") Image(systemName: "star") Image(systemName: "star") }else if buisness.rating == 2.5 { Image(systemName: "star.fill") Image(systemName: "star.fill") Image(systemName: "star.leadinghalf.fill") Image(systemName: "star") Image(systemName: "star") }else if buisness.rating == 3.0 { Image(systemName: "star.fill") Image(systemName: "star.fill") Image(systemName: "star.fill") Image(systemName: "star") Image(systemName: "star") }else if buisness.rating == 3.5 { Image(systemName: "star.fill") Image(systemName: "star.fill") Image(systemName: "star.fill") Image(systemName: "star.leadinghalf.fill") Image(systemName: "star") }else if buisness.rating == 4.0 { Image(systemName: "star.fill") Image(systemName: "star.fill") Image(systemName: "star.fill") Image(systemName: "star.fill") Image(systemName: "star") }else if buisness.rating == 4.5 { Image(systemName: "star.fill") Image(systemName: "star.fill") Image(systemName: "star.fill") Image(systemName: "star.fill") Image(systemName: "star.leadinghalf.fill") }else if buisness.rating == 5.0 { Image(systemName: "star.fill") Image(systemName: "star.fill") Image(systemName: "star.fill") Image(systemName: "star.fill") Image(systemName: "star.fill") } } Text("\(buisness.reviewCount)") .lineLimit(1) .minimumScaleFactor(0.6) .foregroundColor(.primary) .padding(.trailing) Button(action: { // done(pick: buisness.name) if editing { moveRest(buisness: buisness) }else { print("opening site pressed") if let url = URL(string: buisness.url) { UIApplication.shared.open(url) } } }) { // Text("More Info") Image("yelp logo") .resizable() .aspectRatio(contentMode: .fit) .frame(maxWidth: 30, maxHeight: 30) } } if buisness.category != [] { Text("\(buisness.category.joined(separator: ", "))") .minimumScaleFactor(0.6) } } }else { VStack { HStack { Text(buisness.name) .font(.subheadline) .minimumScaleFactor(0.8) if buisness.price != "Unknown" { Text(buisness.price) .font(.subheadline) .minimumScaleFactor(0.8) } } .padding() if buisness.category != [] { Text("\(buisness.category.joined(separator: ", "))") .font(.caption) .minimumScaleFactor(0.6) } // if !buisness.isClosed { // Text("Open") // .foregroundColor(Color.green) // }else { // Text("Closed") // .foregroundColor(Color.red) // } HStack { Group { if buisness.rating == 0 { Image(systemName: "star") Image(systemName: "star") Image(systemName: "star") Image(systemName: "star") Image(systemName: "star") }else if buisness.rating == 0.5 { Image(systemName: "star.leadinghalf.fill") Image(systemName: "star") Image(systemName: "star") Image(systemName: "star") Image(systemName: "star") }else if buisness.rating == 1.0 { Image(systemName: "star.fill") Image(systemName: "star") Image(systemName: "star") Image(systemName: "star") Image(systemName: "star") }else if buisness.rating == 1.5 { Image(systemName: "star.fill") Image(systemName: "star.leadinghalf.fill") Image(systemName: "star") Image(systemName: "star") Image(systemName: "star") }else if buisness.rating == 2.0 { Image(systemName: "star.fill") Image(systemName: "star.fill") Image(systemName: "star") Image(systemName: "star") Image(systemName: "star") }else if buisness.rating == 2.5 { Image(systemName: "star.fill") Image(systemName: "star.fill") Image(systemName: "star.leadinghalf.fill") Image(systemName: "star") Image(systemName: "star") }else if buisness.rating == 3.0 { Image(systemName: "star.fill") Image(systemName: "star.fill") Image(systemName: "star.fill") Image(systemName: "star") Image(systemName: "star") }else if buisness.rating == 3.5 { Image(systemName: "star.fill") Image(systemName: "star.fill") Image(systemName: "star.fill") Image(systemName: "star.leadinghalf.fill") Image(systemName: "star") }else if buisness.rating == 4.0 { Image(systemName: "star.fill") Image(systemName: "star.fill") Image(systemName: "star.fill") Image(systemName: "star.fill") Image(systemName: "star") }else if buisness.rating == 4.5 { Image(systemName: "star.fill") Image(systemName: "star.fill") Image(systemName: "star.fill") Image(systemName: "star.fill") Image(systemName: "star.leadinghalf.fill") }else if buisness.rating == 5.0 { Image(systemName: "star.fill") Image(systemName: "star.fill") Image(systemName: "star.fill") Image(systemName: "star.fill") Image(systemName: "star.fill") } } Text("\(buisness.reviewCount)") .lineLimit(1) .minimumScaleFactor(0.6) .foregroundColor(.primary) .padding(.trailing) Button(action: { // done(pick: buisness.name) if editing { moveRest(buisness: buisness) }else { print("opening site pressed") if let url = URL(string: buisness.url) { UIApplication.shared.open(url) } } }) { // Text("More Info") Image("yelp logo") .resizable() .aspectRatio(contentMode: .fit) .frame(width: 30, height: 30) } } } } } } func mediaLayout(data: Media) -> some View { HStack { if #available(iOS 15, *) { AsyncImage(url: data.imageUrl) { image in image .resizable() .aspectRatio(contentMode: .fill) .frame(maxWidth: 70, maxHeight: 70) .clipped() .padding(.trailing) } placeholder: { Image(systemName: "photo") .resizable() .aspectRatio(contentMode: .fill) .frame(maxWidth: 70, maxHeight: 70) .clipped() .padding(.trailing) .imageScale(.large) .foregroundColor(.gray) } .ignoresSafeArea() // switch image { // case .empty: // Image(named: "No Image") // .resizable() // .aspectRatio(contentMode: .fill) // .frame(maxWidth: 70, maxHeight: 70) // .clipped() // .padding(.trailing) // case .success(let image): // image // .resizable() // .aspectRatio(contentMode: .fill) // .frame(maxWidth: 70, maxHeight: 70) // .clipped() // .padding(.trailing) // case .failure: // Image(named: "No Image") // .resizable() // .aspectRatio(contentMode: .fill) // .frame(maxWidth: 70, maxHeight: 70) // .clipped() // .padding(.trailing) // @unknown default: // // Since the AsyncImagePhase enum isn't frozen, // // we need to add this currently unused fallback // // to handle any new cases that might be added // // in the future: // Image(named: "No Image") // .resizable() // .aspectRatio(contentMode: .fill) // .frame(maxWidth: 70, maxHeight: 70) // .clipped() // } // } }else { URLImage(data.imageUrl) { image in image .resizable() .aspectRatio(contentMode: .fill) .frame(maxWidth: 70, maxHeight: 70) .clipped() .padding(.trailing) } } if sizeClass == .regular { VStack { HStack { HStack { Text(data.name) .padding(.trailing) let rating = "Avg. Rating: \(data.rating.rounded())/10 from \(data.ratingCount) reviews" Text(rating) .lineLimit(1) .minimumScaleFactor(0.6) .foregroundColor(.primary) .padding(.trailing) Button(action: { // done(pick: data.name) if editing { moveMedia(media: data) }else { print("media title = \(data.name), decription = \(data.description)") showDescriptionTitle = data.name showDescriptionMessage = data.description } }) { Text("") } // if !data.isClosed { // Text("Open") // .foregroundColor(Color.green) // }else { // Text("Closed") // .foregroundColor(Color.red) // } } } } }else { VStack { HStack { Text(data.name) Button(action: { // done(pick: data.name) if editing { moveMedia(media: data) }else { print("media title = \(data.name), decription = \(data.description)") showDescriptionTitle = data.name showDescriptionMessage = data.description } }) { Text("") } } .padding() // if !data.isClosed { // Text("Open") // .foregroundColor(Color.green) // }else { // Text("Closed") // .foregroundColor(Color.red) // } let rating = "Avg. Rating: \(data.rating.rounded())/10 from \(data.ratingCount) reviews" Text(rating) .lineLimit(1) .minimumScaleFactor(0.6) .foregroundColor(.primary) .padding(.trailing) } } } .onAppear { print("Top Pickts = \(data.tag.joined(separator: ", "))") } } } struct pickerList_Previews: PreviewProvider { static var previews: some View { PickerList(restMock: Restaurants.viewModels, mediaMock: Media.viewModels, typeSelected: .yes) } }