313 lines
11 KiB
Swift
313 lines
11 KiB
Swift
//
|
||
// View+Extensions.swift
|
||
// Schedule ICTIS
|
||
//
|
||
// Created by Mironov Egor on 15.11.2024.
|
||
//
|
||
|
||
import SwiftUI
|
||
|
||
extension View {
|
||
func isSameDate(_ date1: Date, _ date2: Date) -> Bool {
|
||
return Calendar.current.isDate(date1, inSameDayAs: date2)
|
||
}
|
||
|
||
func isDateInCurrentMonth(_ date: Date) -> Bool {
|
||
let calendar = Calendar.current
|
||
let currentDate = Date()
|
||
|
||
let currentMonth = calendar.component(.month, from: currentDate)
|
||
let currentYear = calendar.component(.year, from: currentDate)
|
||
|
||
let dateMonth = calendar.component(.month, from: date)
|
||
let dateYear = calendar.component(.year, from: date)
|
||
|
||
return currentMonth == dateMonth && currentYear == dateYear
|
||
}
|
||
|
||
func isSameWeek(_ date1: Date, _ date2: Date) -> Bool {
|
||
return Calendar.current.compare(date1, to: date2, toGranularity: .weekOfYear) == .orderedSame
|
||
}
|
||
|
||
func weeksBetween(startDate: Date, endDate: Date) -> Int {
|
||
let calendar = Calendar.current
|
||
let startOfFirstDate = calendar.startOfDay(for: startDate)
|
||
let startOfEndDate = calendar.startOfDay(for: endDate)
|
||
|
||
let weekForDate1 = calendar.dateInterval(of: .weekOfMonth, for: startOfFirstDate)
|
||
let weekForDate2 = calendar.dateInterval(of: .weekOfMonth, for: startOfEndDate)
|
||
|
||
guard let startOfWeek1 = weekForDate1?.start else {
|
||
return 0
|
||
}
|
||
|
||
guard let startOfWeek2 = weekForDate2?.start else {
|
||
return 0
|
||
}
|
||
|
||
let components = calendar.dateComponents([.day], from: startOfWeek1, to: startOfWeek2)
|
||
let daysDifference = components.day ?? 0
|
||
return Int(ceil(Double(abs(daysDifference)) / 7.0))
|
||
}
|
||
|
||
func convertTimeString(_ input: String) -> [String] {
|
||
let parts = input.split(separator: "-")
|
||
if let firstPart = parts.first, let lastPart = parts.last {
|
||
return [String(firstPart), String(lastPart)]
|
||
} else {
|
||
return []
|
||
}
|
||
}
|
||
|
||
func getColorForClass(_ str: String) -> Color {
|
||
if (str.contains("LMS")) {
|
||
return Color("blueForOnline")
|
||
}
|
||
else if (str.contains("ВПК")) {
|
||
return Color("turquoise")
|
||
}
|
||
else {
|
||
return Color("greenForOffline")
|
||
}
|
||
}
|
||
|
||
func hoursMinutesAreEqual(date1: Date, isEqualTo date2: Date) -> Bool {
|
||
let calendar = Calendar.current
|
||
|
||
let components1 = calendar.dateComponents([.day, .hour, .minute], from: date1)
|
||
let components2 = calendar.dateComponents([.day, .hour, .minute], from: date2)
|
||
|
||
return components1.day == components2.day && components1.hour == components2.hour && components1.minute == components2.minute
|
||
}
|
||
|
||
// MARK: ScheduleView
|
||
func daysAreEqual(_ date1: Date, _ date2: Date) -> Bool {
|
||
let calendar = Calendar.current
|
||
|
||
let components1 = calendar.dateComponents([.year, .month, .day], from: date1)
|
||
let components2 = calendar.dateComponents([.year, .month, .day], from: date2)
|
||
|
||
return components1.year == components2.year &&
|
||
components1.month == components2.month &&
|
||
components1.day == components2.day
|
||
}
|
||
|
||
func onlineOrNot(_ str: String) -> Color {
|
||
if (str == "Онлайн") {
|
||
return Color("blueForOnline")
|
||
}
|
||
else {
|
||
return Color("greenForOffline")
|
||
}
|
||
}
|
||
|
||
func getSubjectName(_ subject: String, _ professor: String, _ auditory: String) -> String {
|
||
return "\(subject) \(professor) \(auditory)"
|
||
}
|
||
|
||
func getTimeString(_ date: Date) -> String {
|
||
let calendar = Calendar.current
|
||
let components = calendar.dateComponents([.hour, .minute], from: date)
|
||
|
||
guard let hour = components.hour, let minute = components.minute else {
|
||
return "Invalid time"
|
||
}
|
||
|
||
return String(format: "%02d:%02d", hour, minute)
|
||
}
|
||
|
||
var dateFormatter: DateFormatter {
|
||
let formatter = DateFormatter()
|
||
formatter.dateStyle = .medium
|
||
formatter.timeStyle = .none
|
||
return formatter
|
||
}
|
||
|
||
var timeFormatter: DateFormatter {
|
||
let formatter = DateFormatter()
|
||
formatter.dateFormat = "HH:mm"
|
||
return formatter
|
||
}
|
||
|
||
func checkStartTimeLessThenEndTime(_ startTime: Date, _ endTime: Date) -> Bool {
|
||
let calendar = Calendar.current
|
||
|
||
let firstComponents = calendar.dateComponents([.hour, .minute], from: startTime)
|
||
let secondComponents = calendar.dateComponents([.hour, .minute], from: endTime)
|
||
|
||
guard let startHours = firstComponents.hour, let startMinutes = firstComponents.minute else {
|
||
return false
|
||
}
|
||
guard let endHours = secondComponents.hour, let endMinutes = secondComponents.minute else {
|
||
return false
|
||
}
|
||
|
||
print("\(startHours) - \(endHours)")
|
||
print("\(startMinutes) - \(endMinutes)")
|
||
if Int(startHours) > Int(endHours) {
|
||
return false
|
||
}
|
||
else if startHours == endHours {
|
||
if startMinutes < endMinutes {
|
||
return true
|
||
}
|
||
else {
|
||
return false
|
||
}
|
||
}
|
||
else {
|
||
return true
|
||
}
|
||
}
|
||
}
|
||
|
||
extension WeekTabView {
|
||
func updateWeekScreenViewForNewGroup() {
|
||
vm.updateSelectedDayIndex()
|
||
if weekSlider.isEmpty {
|
||
let currentWeek = Date().fetchWeek(vm.selectedDay)
|
||
|
||
if let firstDate = currentWeek.first?.date {
|
||
weekSlider.append(firstDate.createPrevioustWeek())
|
||
}
|
||
|
||
weekSlider.append(currentWeek)
|
||
|
||
if let lastDate = currentWeek.last?.date {
|
||
weekSlider.append(lastDate.createNextWeek())
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
extension WeekViewForWeek {
|
||
func paginateWeek() {
|
||
let calendar = Calendar.current
|
||
if weekSlider.indices.contains(currentWeekIndex) {
|
||
if let firstDate = weekSlider[currentWeekIndex].first?.date,
|
||
currentWeekIndex == 0 {
|
||
vm.week -= 1
|
||
if !vm.nameGroups.isEmpty {
|
||
vm.fetchWeekSchedule(isOtherWeek: true)
|
||
}
|
||
if UserDefaults.standard.string(forKey: "vpk") != nil {
|
||
//vm.fetchWeekVPK(isOtherWeek: true, vpk: UserDefaults.standard.string(forKey: "vpk"))
|
||
}
|
||
weekSlider.insert(firstDate.createPrevioustWeek(), at: 0)
|
||
weekSlider.removeLast()
|
||
currentWeekIndex = 1
|
||
vm.selectedDay = calendar.date(byAdding: .weekOfYear, value: -1, to: vm.selectedDay) ?? Date.init()
|
||
vm.updateSelectedDayIndex()
|
||
}
|
||
|
||
if let lastDate = weekSlider[currentWeekIndex].last?.date,
|
||
currentWeekIndex == (weekSlider.count - 1) {
|
||
vm.week += 1
|
||
if !vm.nameGroups.isEmpty {
|
||
vm.fetchWeekSchedule(isOtherWeek: true)
|
||
}
|
||
weekSlider.append(lastDate.createNextWeek())
|
||
weekSlider.removeFirst()
|
||
currentWeekIndex = weekSlider.count - 2
|
||
vm.selectedDay = calendar.date(byAdding: .weekOfYear, value: 1, to: vm.selectedDay) ?? Date.init()
|
||
vm.updateSelectedDayIndex()
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
extension WeekViewForMonth {
|
||
func getForegroundColor(day: Date.WeekDay) -> Color {
|
||
if isDateInCurrentMonth(day.date) {
|
||
return isSameDate(day.date, vm.selectedDay) ? .white : .black
|
||
} else {
|
||
return isSameDate(day.date, vm.selectedDay) ? .white : Color("greyForDaysInMonthTabView")
|
||
}
|
||
}
|
||
|
||
func getBackgroundColor(day: Date.WeekDay) -> Color {
|
||
return isSameDate(day.date, vm.selectedDay) ? Color("blueColor") : Color("background")
|
||
}
|
||
|
||
func overlay(day: Date.WeekDay) -> some View {
|
||
Group {
|
||
if day.date.isToday && !isSameDate(day.date, vm.selectedDay) {
|
||
RoundedRectangle(cornerRadius: 100)
|
||
.stroke(Color("blueColor"), lineWidth: 2)
|
||
}
|
||
}
|
||
}
|
||
|
||
func handleTap(day: Date.WeekDay) {
|
||
if isSameWeek(day.date, vm.selectedDay) {
|
||
print("На одной неделе")
|
||
}
|
||
else {
|
||
var difBetweenWeeks = weeksBetween(startDate: vm.selectedDay, endDate: day.date)
|
||
if day.date < vm.selectedDay {
|
||
difBetweenWeeks = difBetweenWeeks * -1
|
||
}
|
||
print(difBetweenWeeks)
|
||
vm.week += difBetweenWeeks
|
||
if !vm.nameGroups.isEmpty {
|
||
vm.fetchWeekSchedule(isOtherWeek: true)
|
||
}
|
||
if UserDefaults.standard.string(forKey: "vpk") != nil {
|
||
//vm.fetchWeekVPK(isOtherWeek: true, vpk: UserDefaults.standard.string(forKey: "vpk"))
|
||
}
|
||
}
|
||
vm.selectedDay = day.date
|
||
vm.updateSelectedDayIndex()
|
||
}
|
||
}
|
||
|
||
extension MonthTabView {
|
||
func updateMonthScreenViewForNewGroup() {
|
||
vm.updateSelectedDayIndex()
|
||
if monthSlider.isEmpty {
|
||
let currentMonth = Date().fetchMonth(vm.selectedDay)
|
||
|
||
if let firstDate = currentMonth.first?.week[0].date {
|
||
monthSlider.append(firstDate.createPreviousMonth())
|
||
}
|
||
|
||
monthSlider.append(currentMonth)
|
||
|
||
if let lastDate = currentMonth.last?.week[6].date {
|
||
monthSlider.append(lastDate.createNextMonth())
|
||
}
|
||
}
|
||
}
|
||
|
||
func paginateMonth(_ indexOfWeek: Int = 0) {
|
||
let calendar = Calendar.current
|
||
if monthSlider.indices.contains(currentMonthIndex) {
|
||
if let firstDate = monthSlider[currentMonthIndex].first?.week[0].date,
|
||
currentMonthIndex == 0 {
|
||
monthSlider.insert(firstDate.createPreviousMonth(), at: 0)
|
||
monthSlider.removeLast()
|
||
currentMonthIndex = 1
|
||
vm.selectedDay = calendar.date(byAdding: .weekOfYear, value: -5, to: vm.selectedDay) ?? Date.init()
|
||
vm.updateSelectedDayIndex()
|
||
vm.week -= 5
|
||
if !vm.nameGroups.isEmpty {
|
||
vm.fetchWeekSchedule(isOtherWeek: true)
|
||
}
|
||
}
|
||
|
||
if let lastDate = monthSlider[currentMonthIndex].last?.week[6].date,
|
||
currentMonthIndex == (monthSlider.count - 1) {
|
||
monthSlider.append(lastDate.createNextMonth())
|
||
monthSlider.removeFirst()
|
||
currentMonthIndex = monthSlider.count - 2
|
||
vm.selectedDay = calendar.date(byAdding: .weekOfYear, value: 5, to: vm.selectedDay) ?? Date.init()
|
||
vm.updateSelectedDayIndex()
|
||
vm.week += 5
|
||
if !vm.nameGroups.isEmpty {
|
||
vm.fetchWeekSchedule(isOtherWeek: true)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|