// // AllMoods.swift // Reflect (iOS) // // Created by Trey Tartt on 2/6/22. // import SwiftUI struct LongestStreakTemplate: View, SharingTemplate { static var description: String { "Longest Streak" } private let itemFormatter: DateFormatter = { let formatter = DateFormatter() formatter.dateStyle = .short return formatter }() var isPreview: Bool var startDate: Date var endDate: Date var fakeData: Bool @State var moodEntries = [MoodEntryModel]() @State var selectedMood: Mood = .great @State var showSharingTemplate = false @StateObject private var shareImage = ShareImageStateViewModel() @Environment(\.presentationMode) var presentationMode @AppStorage(UserDefaultsStore.Keys.moodTint.rawValue, store: GroupUserDefaults.groupDefaults) private var moodTint: MoodTints = .Default @AppStorage(UserDefaultsStore.Keys.theme.rawValue, store: GroupUserDefaults.groupDefaults) private var theme: Theme = .system private var textColor: Color { theme.currentTheme.labelColor } let columns = [ GridItem(.flexible(minimum: 5, maximum: .infinity), alignment: .center), GridItem(.flexible(minimum: 5, maximum: .infinity), alignment: .center), GridItem(.flexible(minimum: 5, maximum: .infinity), alignment: .center), GridItem(.flexible(minimum: 5, maximum: .infinity), alignment: .center), GridItem(.flexible(minimum: 5, maximum: .infinity), alignment: .center) ] init(isPreview: Bool, startDate: Date, endDate: Date, fakeData: Bool) { self.isPreview = isPreview self.startDate = startDate self.endDate = endDate self.fakeData = fakeData configureData(fakeData: self.fakeData, mood: self.selectedMood) } var image: UIImage { let image = shareView.asImage(size: CGSize(width: 650, height: 400)) return image } @MainActor private func configureData(fakeData: Bool, mood: Mood) { var _moodEntries: [MoodEntryModel]? if fakeData { _moodEntries = DataController.shared.randomEntries(count: 10) } else { _moodEntries = DataController.shared.getData(startDate:startDate, endDate: endDate, includedDays: [1,2,3,4,5,6,7]) } let data = _moodEntries ?? [MoodEntryModel]() var splitArrays = createSubArrays(fromMoodEntries: data, splitOn: mood) splitArrays = splitArrays.sorted(by: { $0.count > $1.count } ) self.moodEntries = splitArrays.first ?? [MoodEntryModel]() } private func createSubArrays(fromMoodEntries: [MoodEntryModel], splitOn: Mood) -> [[MoodEntryModel]] { var splitArrays = [[MoodEntryModel]]() var currentSplit = [MoodEntryModel]() for entry in fromMoodEntries { if entry.mood == splitOn { currentSplit.append(entry) } else { splitArrays.append(currentSplit) currentSplit.removeAll() } } // append the last grouping splitArrays.append(currentSplit) return splitArrays } var preview: some View { HStack { VStack { LazyVGrid(columns: columns, spacing: 0) { ForEach(moodEntries) { entry in entry.mood.icon .resizable() .aspectRatio(contentMode: .fit) .foregroundColor(moodTint.color(forMood: entry.mood)) } } } } .frame(height: 88) .clipped() .onAppear(perform: { self.configureData(fakeData: self.fakeData, mood: self.selectedMood) }) } var shareView: some View { VStack { Text(String(format: String(localized: "share_view_longest_streak_template_title"), self.selectedMood.strValue)) .font(.title) .foregroundColor(textColor) .frame(maxWidth: .infinity, alignment: .center) .padding() selectedMood.icon .resizable() .aspectRatio(contentMode: .fit) .frame(width: 75, height: 75) .foregroundColor(moodTint.color(forMood: selectedMood)) VStack { Text(self.moodEntries.first?.forDate ?? Date(), formatter: itemFormatter) .font(.title) .foregroundColor(textColor) .frame(maxWidth: .infinity, alignment: .center) .padding(.top, 1) Text("-") .font(.title) .foregroundColor(textColor) .frame(maxWidth: .infinity, alignment: .center) .padding(.top, 1) Text(self.moodEntries.last?.forDate ?? Date(), formatter: itemFormatter) .font(.title) .foregroundColor(textColor) .frame(maxWidth: .infinity, alignment: .center) .padding(.top, 1) } .padding() } .onAppear(perform: { self.configureData(fakeData: self.fakeData, mood: self.selectedMood) }) .background(Color(UIColor.secondarySystemBackground)) .cornerRadius(10) .padding() } var mainView: some View { VStack { shareView Spacer() Menu(content: { ForEach(Mood.allValues) { mood in Button(mood.strValue, action: { selectedMood = mood configureData(fakeData: self.fakeData, mood: self.selectedMood) }) .accessibilityIdentifier(AccessibilityID.SharingTemplate.moodMenuButton(mood.strValue)) } }, label: { Text("Pick Mood") .font(.title) .foregroundColor(textColor) .padding() }) .accessibilityIdentifier(AccessibilityID.SharingTemplate.moodMenu) .frame(maxWidth: .infinity, alignment: .center) .background( theme.currentTheme.secondaryBGColor ) .padding([.leading, .trailing], -5) .cornerRadius(10) .padding() HStack(alignment: .center) { Button(action: { let _image = self.image self.shareImage.showSheet = true self.shareImage.selectedShareImage = _image }, label: { Text("Share") .font(.title) .fontWeight(.bold) .foregroundColor(Color.white) .padding(.top, 20) }) .accessibilityIdentifier(AccessibilityID.SharingTemplate.shareButton) .sheet(isPresented: self.$shareImage.showSheet) { if let uiImage = self.shareImage.selectedShareImage { ShareSheet(photo: uiImage) } } .frame(maxWidth: .infinity, alignment: .center) .background( Color.green ) .padding(.trailing, -5) Button(action: { presentationMode.wrappedValue.dismiss() }, label: { Text("Exit") .font(.title) .fontWeight(.bold) .foregroundColor(Color.white) .padding(.top, 20) }) .accessibilityIdentifier(AccessibilityID.SharingTemplate.dismissButton) .frame(maxWidth: .infinity, alignment: .center) .background( Color.red ) .padding(.leading, -5) } .padding([.leading, .trailing], -20) }.sheet(isPresented: $showSharingTemplate) { ActivityViewController(activityItems: [self.image]) } } var body: some View { if isPreview { shareView .scaleEffect(2) } else { mainView } } } struct CurrentStreakSharingTemplate_Previews: PreviewProvider { static var previews: some View { Group { LongestStreakTemplate(isPreview: true, startDate: Date(), endDate: Date(), fakeData: true) LongestStreakTemplate(isPreview: false, startDate: Date(), endDate: Date(), fakeData: true) LongestStreakTemplate(isPreview: false, startDate: Date(), endDate: Date(), fakeData: true).shareView } } }