mirror of
https://github.com/Mueller-Patrick/DHBW-Service-App.git
synced 2024-11-01 08:53:58 +00:00
235 lines
8.9 KiB
Swift
235 lines
8.9 KiB
Swift
//
|
|
// LecturePlanList.swift
|
|
// DHBW-Service
|
|
//
|
|
// Created by Patrick Müller on 30.01.21.
|
|
//
|
|
|
|
import SwiftUI
|
|
import CoreData
|
|
import Combine
|
|
|
|
struct LecturePlanList: View {
|
|
@State private var events: [RaPlaEvent] = []
|
|
@State private var daysWithEvents: [Date:[RaPlaEvent]] = [:]
|
|
@State private var sortingAscending = true
|
|
|
|
|
|
var body: some View {
|
|
NavigationView() {
|
|
ScrollView(.vertical) {
|
|
ScrollViewReader { scrollView in
|
|
// Button("Jump to today") {
|
|
// withAnimation(){
|
|
// scrollView.scrollTo(8, anchor: .center)
|
|
// }
|
|
// }
|
|
// .padding()
|
|
|
|
ForEach(daysWithEvents.sorted(by: {$0.key < $1.key}), id: \.key) { key, value in
|
|
HStack {
|
|
Spacer()
|
|
DayWithEventsBlock(date: key, eventsList: value, parent: self)
|
|
Spacer()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.navigationBarTitle(Text("Lectures"))
|
|
// .navigationBarItems(trailing: {
|
|
// Button(action: {
|
|
// // This is obviously bullshit, but it could be used to sort afer summary or smth like that
|
|
//
|
|
// self.sortingAscending = !self.sortingAscending
|
|
// let sectionSortDescriptor = NSSortDescriptor(key: "startDate", ascending: sortingAscending)
|
|
// let sortDescriptors = [sectionSortDescriptor]
|
|
// self.events = UtilityFunctions.getCoreDataObject(entity: "RaPlaEvent", sortDescriptors: sortDescriptors)
|
|
// }){
|
|
// Text("Switch order")
|
|
// }
|
|
// })
|
|
}
|
|
.navigationViewStyle(StackNavigationViewStyle())
|
|
.onAppear{
|
|
self.getRaPlaEvents()
|
|
self.findNextDay()
|
|
}
|
|
}
|
|
}
|
|
|
|
struct LecturePlanList_Previews: PreviewProvider {
|
|
static var previews: some View {
|
|
LecturePlanList()
|
|
.preferredColorScheme(.dark)
|
|
.previewDevice("iPhone 12")
|
|
.environmentObject(getFirstOpening())
|
|
.environment(\.managedObjectContext, PersistenceController.preview.container.viewContext)
|
|
}
|
|
|
|
static func getFirstOpening() -> LocalSettings {
|
|
let settings = LocalSettings();
|
|
settings.isFirstOpening = false;
|
|
return settings
|
|
}
|
|
}
|
|
|
|
extension LecturePlanList {
|
|
public func formatDate(date: Date) -> String {
|
|
let formatter = DateFormatter()
|
|
formatter.dateStyle = .short
|
|
return formatter.string(from: date)
|
|
}
|
|
|
|
public func formatTime(date: Date) -> String {
|
|
let formatter = DateFormatter()
|
|
formatter.timeStyle = .short
|
|
return formatter.string(from: date)
|
|
}
|
|
|
|
/**
|
|
Get the correct foreground color for the given event, e.g. primary for normal events and red for exams.
|
|
*/
|
|
public func getEventForegroundColor(for event: RaPlaEvent) -> Color {
|
|
var textColor: Color = .primary
|
|
if(event.category! == "Prüfung") {
|
|
textColor = Color.red
|
|
} else {
|
|
textColor = Color.primary
|
|
}
|
|
|
|
return textColor
|
|
}
|
|
|
|
/**
|
|
DEPRECATED, used to find the element in the list of days that represents the next day
|
|
*/
|
|
public func findNextDay() {
|
|
// As this list is already sorted ascending, we can just return the first event with a start date that is in the future
|
|
let sortedEvents = self.events.sorted(by: { $0.startDate! < $1.startDate! })
|
|
for event in sortedEvents {
|
|
if(event.startDate! > Date()) {
|
|
//self.focusedEvent = event
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
Loads required data from CoreData
|
|
*/
|
|
public func getRaPlaEvents() {
|
|
let sectionSortDescriptor = NSSortDescriptor(key: "startDate", ascending: true)
|
|
let sortDescriptors = [sectionSortDescriptor]
|
|
|
|
var calendar = Calendar.current
|
|
calendar.timeZone = NSTimeZone.local
|
|
let dateFrom = calendar.startOfDay(for: Date())
|
|
let fromPredicate = NSPredicate(format: "startDate >= %@", dateFrom as NSDate)
|
|
|
|
self.events = []
|
|
self.daysWithEvents = [:]
|
|
|
|
self.events = RaPlaEvent.getSpecified(sortDescriptors: sortDescriptors, searchPredicate: fromPredicate)
|
|
|
|
// Also write events to daysWithEvents map
|
|
for event in self.events {
|
|
let components = event.startDate!.get(.day, .month, .year)
|
|
let day = String(components.day!); let month = String(components.month!); let year = String(components.year!)
|
|
|
|
let dateFormatter = DateFormatter()
|
|
dateFormatter.dateFormat = "yyyy-MM-dd"
|
|
let dayOnly = dateFormatter.date(from: String(year + "-" + month + "-" + day))!
|
|
|
|
var eventsList = daysWithEvents[dayOnly]
|
|
if(eventsList == nil) {
|
|
eventsList = []
|
|
}
|
|
eventsList!.append(event)
|
|
self.daysWithEvents[dayOnly] = eventsList
|
|
}
|
|
}
|
|
|
|
public func updateDay(day: Date, events: [RaPlaEvent]) {
|
|
self.daysWithEvents[day] = events
|
|
}
|
|
}
|
|
|
|
/**
|
|
Each of these represents one day block in the view
|
|
*/
|
|
struct DayWithEventsBlock: View {
|
|
@State var date: Date
|
|
@State var eventsList: [RaPlaEvent]
|
|
@State var parent: LecturePlanList
|
|
|
|
var body: some View {
|
|
VStack {
|
|
Text(String(date.get(.day)) + "." + String(date.get(.month)) + "." + String(date.get(.year)))
|
|
.font(.title)
|
|
.frame(maxWidth: .infinity, alignment: .leading)
|
|
|
|
VStack {
|
|
if(!eventsList.isEmpty){
|
|
ForEach(eventsList, id: \.self) { event in
|
|
var visibleIconGroup = Group {
|
|
Button(action: {
|
|
event.isHidden.toggle()
|
|
}){
|
|
if(event.isHidden) {
|
|
Image(systemName: "eye.slash")
|
|
.foregroundColor(.red)
|
|
} else {
|
|
Image(systemName: "eye")
|
|
}
|
|
}
|
|
}
|
|
|
|
NavigationLink(destination: LecturePlanItem(event: event)) {
|
|
HStack {
|
|
Text(parent.formatTime(date: event.startDate!))
|
|
.foregroundColor(parent.getEventForegroundColor(for: event))
|
|
Text(event.summary!)
|
|
.foregroundColor(parent.getEventForegroundColor(for: event))
|
|
|
|
Spacer()
|
|
|
|
visibleIconGroup
|
|
}
|
|
.padding()
|
|
.background(
|
|
RoundedRectangle(cornerRadius: 10)
|
|
.fill(Color(#colorLiteral(red: 0.2549019754, green: 0.2745098174, blue: 0.3019607961, alpha: 1)))
|
|
)
|
|
}
|
|
// When an event gets updated from child view, reload it here as this will not trigger the onAppear() function
|
|
.onReceive(event.objectWillChange, perform: { _ in
|
|
print("receiving event: \(event.isHidden)")
|
|
visibleIconGroup = Group {
|
|
Button(action: {
|
|
event.isHidden.toggle()
|
|
}){
|
|
if(event.isHidden) {
|
|
Image(systemName: "eye.slash")
|
|
.foregroundColor(.red)
|
|
} else {
|
|
Image(systemName: "eye")
|
|
}
|
|
}
|
|
}
|
|
// parent.updateDay(day: self.date, events: self.eventsList)
|
|
})
|
|
}
|
|
} else {
|
|
Text("noLectures".localized(tableName: "HomeView"))
|
|
.frame(maxWidth: .infinity, alignment: .leading)
|
|
}
|
|
}
|
|
}
|
|
.padding()
|
|
.background(
|
|
RoundedRectangle(cornerRadius: 10)
|
|
.fill(Color.gray)
|
|
)
|
|
}
|
|
}
|