This commit is contained in:
Vladimir Dubovik 2025-02-27 13:07:19 +03:00
parent b719ab300d
commit 13de6fa302
15 changed files with 118 additions and 66 deletions

View File

@ -18,16 +18,16 @@ struct LoadingScheduleView: View {
.fill( .fill(
LinearGradient( LinearGradient(
gradient: Gradient(colors: [ gradient: Gradient(colors: [
isAnimated ? Color.gray.opacity(0.5) : Color.gray.opacity(0.2), isAnimated ? Color.gray.opacity(0.6) : Color.gray.opacity(0.3),
isAnimated ? Color.gray.opacity(0.2) : Color.gray.opacity(0.5) isAnimated ? Color.gray.opacity(0.3) : Color.gray.opacity(0.6)
]), ]),
startPoint: .topLeading, startPoint: .topLeading,
endPoint: .bottomTrailing endPoint: .bottomTrailing
) )
) )
.frame(height: 65) .frame(height: 70)
.padding(.horizontal, 20) .padding(.horizontal, 20)
.animation(.linear(duration: 0.9).repeatForever(autoreverses: true), value: isAnimated) .animation(.linear(duration: 0.8).repeatForever(autoreverses: true), value: isAnimated)
} }
} }
.onAppear { .onAppear {

View File

@ -13,11 +13,10 @@ struct MainView: View {
@ObservedObject var vm: ScheduleViewModel @ObservedObject var vm: ScheduleViewModel
@FocusState private var isFocusedSearchBar: Bool @FocusState private var isFocusedSearchBar: Bool
@State private var isScrolling: Bool = false @State private var isScrolling: Bool = false
@State private var isShowingVPKLabel = false
var body: some View { var body: some View {
VStack { VStack {
SearchBarView(text: $searchText, isFocused: _isFocusedSearchBar, vm: vm) SearchBarView(text: $searchText, isFocused: _isFocusedSearchBar, vm: vm, isShowingMonthSlider: $isShowingMonthSlider)
.onChange(of: isScrolling, initial: false) { oldValue, newValue in .onChange(of: isScrolling, initial: false) { oldValue, newValue in
if newValue && isScrolling { if newValue && isScrolling {
isFocusedSearchBar = false isFocusedSearchBar = false
@ -28,7 +27,7 @@ struct MainView: View {
LoadingScheduleView() LoadingScheduleView()
} }
else { else {
ScheduleView(vm: vm, isScrolling: $isScrolling, isShowingVPKLabel: $isShowingVPKLabel) ScheduleView(vm: vm, isScrolling: $isScrolling)
} }
} }
.alert(isPresented: $vm.isShowingAlertForIncorrectGroup, error: vm.errorInNetwork) { error in .alert(isPresented: $vm.isShowingAlertForIncorrectGroup, error: vm.errorInNetwork) { error in
@ -81,11 +80,11 @@ struct MainView: View {
Spacer() Spacer()
} }
if (!isShowingMonthSlider) { if (!isShowingMonthSlider) {
WeekTabView(vm: vm, isShowingVPKLabel: $isShowingVPKLabel) WeekTabView(vm: vm)
.transition(.opacity) .transition(.opacity)
} }
else { else {
MonthTabView(vm: vm, isShowingVPKLabel: $isShowingVPKLabel) MonthTabView(vm: vm)
.transition(.opacity) .transition(.opacity)
} }
} }

View File

@ -9,14 +9,20 @@ import SwiftUI
struct ScheduleView: View { struct ScheduleView: View {
@ObservedObject var vm: ScheduleViewModel @ObservedObject var vm: ScheduleViewModel
@FetchRequest(fetchRequest: ClassModel.all()) private var classes //Делаем запрос в CoreData и получаем список сохраненных пар @FetchRequest(fetchRequest: ClassModel.all()) private var classes // Делаем запрос в CoreData и получаем список сохраненных пар
@State private var selectedClass: ClassModel? = nil @State private var selectedClass: ClassModel? = nil
@State private var lastOffset: CGFloat = 0 @State private var lastOffset: CGFloat = 0
@State private var scrollTimer: Timer? = nil @State private var scrollTimer: Timer? = nil
@State private var isShowingMyPairs = false @State private var isShowingMyPairs = false
@Binding var isScrolling: Bool @Binding var isScrolling: Bool
@Binding var isShowingVPKLabel: Bool
var provider = ClassProvider.shared var provider = ClassProvider.shared
var hasLessons: Bool {
return vm.classes.indices.contains(vm.selectedIndex) &&
vm.classes[vm.selectedIndex].dropFirst().contains { !$0.isEmpty }
}
var hasVPK: Bool {
return vm.vpks.indices.contains(vm.selectedIndex) && vm.vpks[vm.selectedIndex].dropFirst().contains { !$0.isEmpty }
}
var body: some View { var body: some View {
if vm.isLoading { if vm.isLoading {
LoadingScheduleView() LoadingScheduleView()
@ -27,8 +33,10 @@ struct ScheduleView: View {
ScrollView(.vertical, showsIndicators: false) { ScrollView(.vertical, showsIndicators: false) {
VStack (spacing: 30) { VStack (spacing: 30) {
VStack (alignment: .leading, spacing: 20 ) { VStack (alignment: .leading, spacing: 20 ) {
Text("Учебное расписание") if hasLessons {
.font(.custom("Montserrat-Bold", fixedSize: 20)) Text("Учебное расписание")
.font(.custom("Montserrat-Bold", fixedSize: 20))
}
ForEach(vm.classes.indices, id: \.self) { index in ForEach(vm.classes.indices, id: \.self) { index in
if index != 0 && index != 1 && index == vm.selectedIndex { if index != 0 && index != 1 && index == vm.selectedIndex {
let daySchedule = vm.classes[index] // Это массив строк для дня let daySchedule = vm.classes[index] // Это массив строк для дня
@ -86,7 +94,7 @@ struct ScheduleView: View {
} }
if UserDefaults.standard.string(forKey: "vpk") != nil { if UserDefaults.standard.string(forKey: "vpk") != nil {
VStack (alignment: .leading, spacing: 20 ) { VStack (alignment: .leading, spacing: 20 ) {
if isShowingVPKLabel { if hasVPK {
Text("ВПК") Text("ВПК")
.font(.custom("Montserrat-Bold", fixedSize: 20)) .font(.custom("Montserrat-Bold", fixedSize: 20))
} }
@ -126,9 +134,6 @@ struct ScheduleView: View {
.background(Color.white) .background(Color.white)
.cornerRadius(20) .cornerRadius(20)
.shadow(color: .black.opacity(0.25), radius: 4, x: 2, y: 2) .shadow(color: .black.opacity(0.25), radius: 4, x: 2, y: 2)
.onAppear {
isShowingVPKLabel = true
}
} }
} }
} }

View File

@ -12,6 +12,7 @@ struct SearchBarView: View {
@FocusState var isFocused: Bool @FocusState var isFocused: Bool
@State private var isShowingSheet: Bool = false @State private var isShowingSheet: Bool = false
@ObservedObject var vm: ScheduleViewModel @ObservedObject var vm: ScheduleViewModel
@Binding var isShowingMonthSlider: Bool
var provider = ClassProvider.shared var provider = ClassProvider.shared
@ -47,6 +48,9 @@ struct SearchBarView: View {
} }
} }
} }
.simultaneousGesture(TapGesture().onEnded {
self.isShowingMonthSlider = false
})
.frame(height: 40) .frame(height: 40)
.background( .background(
RoundedRectangle(cornerRadius: 10) RoundedRectangle(cornerRadius: 10)

View File

@ -18,6 +18,7 @@ struct CreateEditClassView: View {
@State private var isSelectedTime1 = false @State private var isSelectedTime1 = false
@State private var isSelectedTime2 = false @State private var isSelectedTime2 = false
@State private var textForLabelInSubjectField: String = "Предмет" @State private var textForLabelInSubjectField: String = "Предмет"
@State private var selectedType: String = "Оффлайн"
@FocusState private var isFocusedSubject: Bool @FocusState private var isFocusedSubject: Bool
@FocusState private var isFocusedAuditory: Bool @FocusState private var isFocusedAuditory: Bool
@FocusState private var isFocusedProfessor: Bool @FocusState private var isFocusedProfessor: Bool
@ -29,25 +30,47 @@ struct CreateEditClassView: View {
VStack { VStack {
SubjectFieldView(text: $vm._class.subject, isShowingSubjectFieldRed: $isShowingSubjectFieldRed, labelForField: $textForLabelInSubjectField, isFocused: _isFocusedSubject) SubjectFieldView(text: $vm._class.subject, isShowingSubjectFieldRed: $isShowingSubjectFieldRed, labelForField: $textForLabelInSubjectField, isFocused: _isFocusedSubject)
.padding(.bottom, 10) .padding(.bottom, 10)
HStack {
Text("Тип")
.font(.custom("Montserrat-Medium", fixedSize: 17))
Spacer()
Picker("Тип", selection: $vm._class.online, content: {
ForEach(MockData.onlineOrOffline, id: \.self) {
Text($0)
}
})
.accentColor(Color("grayForFields"))
}
.frame(height: 40)
.padding(.horizontal)
.background(
RoundedRectangle(cornerRadius: 10)
.fill(.white)
)
.padding(.bottom, 10)
HStack {
HStack {
Text("Тип")
.font(.custom("Montserrat-Medium", fixedSize: 17))
.foregroundColor(.black)
Spacer()
HStack {
Text(vm._class.online)
.font(.custom("Montserrat-Medium", fixedSize: 17))
.foregroundColor(Color("customGray3"))
Image("upDownArrows")
.resizable()
.scaledToFit()
.frame(width: 15, height: 15)
}
.padding(.horizontal)
}
.padding(.horizontal)
.padding(.top, 10)
.padding(.bottom, 10)
.background(
RoundedRectangle(cornerRadius: 10)
.fill(.white)
)
.overlay {
HStack {
Spacer()
Picker("Тип", selection: $vm._class.online, content: {
ForEach(MockData.onlineOrOffline, id: \.self) {
Text($0)
}
})
.accentColor(Color("grayForFields"))
.padding(.trailing, 35)
.blendMode(.destinationOver)
}
.frame(width: UIScreen.main.bounds.width)
}
}
.padding(.bottom, 10)
ZStack { ZStack {
if vm._class.online == "Оффлайн" { if vm._class.online == "Оффлайн" {
@ -136,24 +159,46 @@ struct CreateEditClassView: View {
.fill(.white) .fill(.white)
) )
.padding(.bottom, 10) .padding(.bottom, 10)
HStack { HStack {
Text("Напоминанние") HStack {
.font(.custom("Montserrat-Medium", fixedSize: 17)) Text("Напоминание")
Spacer() .font(.custom("Montserrat-Medium", fixedSize: 17))
Picker("Напоминание", selection: $vm._class.notification, content: { .foregroundColor(.black)
ForEach(MockData.notifications, id: \.self) { Spacer()
Text($0) HStack {
Text(vm._class.notification)
.font(.custom("Montserrat-Medium", fixedSize: 17)) .font(.custom("Montserrat-Medium", fixedSize: 17))
.foregroundColor(Color("customGray3"))
Image("upDownArrows")
.resizable()
.scaledToFit()
.frame(width: 15, height: 15)
} }
}) .padding(.horizontal)
.accentColor(Color("grayForFields")) }
.padding(.horizontal)
.padding(.top, 10)
.padding(.bottom, 10)
.background(
RoundedRectangle(cornerRadius: 10)
.fill(.white)
)
.overlay {
HStack {
Spacer()
Picker("", selection: $vm._class.notification , content: {
ForEach(MockData.notifications, id: \.self) {
Text($0)
}
})
.accentColor(Color("grayForFields"))
.padding(.trailing, 35)
.blendMode(.destinationOver)
}
.frame(width: UIScreen.main.bounds.width)
}
} }
.frame(height: 40)
.padding(.horizontal)
.background(
RoundedRectangle(cornerRadius: 10)
.fill(.white)
)
.padding(.bottom, 10) .padding(.bottom, 10)
CommentFieldView(textForComment: $vm._class.comment, isFocused: _isFocusedComment) CommentFieldView(textForComment: $vm._class.comment, isFocused: _isFocusedComment)

View File

@ -13,7 +13,6 @@ struct MonthTabView: View {
@State private var createMonth: Bool = false @State private var createMonth: Bool = false
@State private var currentWeekIndex: Int = 0 @State private var currentWeekIndex: Int = 0
@ObservedObject var vm: ScheduleViewModel @ObservedObject var vm: ScheduleViewModel
@Binding var isShowingVPKLabel: Bool
var body: some View { var body: some View {
VStack { VStack {
HStack (spacing: 34) { HStack (spacing: 34) {
@ -61,7 +60,7 @@ struct MonthTabView: View {
VStack (spacing: 10) { VStack (spacing: 10) {
ForEach(month.indices, id: \.self) { index in ForEach(month.indices, id: \.self) { index in
let week = month[index].week let week = month[index].week
WeekViewForMonth(week: week, vm: vm, isShowingVPKLabel: $isShowingVPKLabel) WeekViewForMonth(week: week, vm: vm)
} }
} }
.background { .background {

View File

@ -12,13 +12,12 @@ struct WeekTabView: View {
@State var weekSlider: [[Date.WeekDay]] = [] @State var weekSlider: [[Date.WeekDay]] = []
@State private var createWeek: Bool = false @State private var createWeek: Bool = false
@ObservedObject var vm: ScheduleViewModel @ObservedObject var vm: ScheduleViewModel
@Binding var isShowingVPKLabel: Bool
var body: some View { var body: some View {
HStack { HStack {
TabView(selection: $currentWeekIndex) { TabView(selection: $currentWeekIndex) {
ForEach(weekSlider.indices, id: \.self) { index in ForEach(weekSlider.indices, id: \.self) { index in
let week = weekSlider[index] let week = weekSlider[index]
WeekViewForWeek(weekSlider: $weekSlider, currentWeekIndex: $currentWeekIndex, createWeek: $createWeek, week: week, vm: vm, isShowingVPKLabel: $isShowingVPKLabel) WeekViewForWeek(weekSlider: $weekSlider, currentWeekIndex: $currentWeekIndex, createWeek: $createWeek, week: week, vm: vm)
.padding(.horizontal, 15) .padding(.horizontal, 15)
.tag(index) .tag(index)
} }

View File

@ -10,7 +10,6 @@ import SwiftUI
struct WeekViewForMonth: View { struct WeekViewForMonth: View {
let week: [Date.WeekDay] let week: [Date.WeekDay]
@ObservedObject var vm: ScheduleViewModel @ObservedObject var vm: ScheduleViewModel
@Binding var isShowingVPKLabel: Bool
var body: some View { var body: some View {
HStack(spacing: 23) { HStack(spacing: 23) {
@ -26,7 +25,6 @@ struct WeekViewForMonth: View {
.cornerRadius(15) .cornerRadius(15)
.onTapGesture { .onTapGesture {
handleTap(day: day) handleTap(day: day)
isShowingVPKLabel = false
} }
} }
} }

View File

@ -13,7 +13,6 @@ struct WeekViewForWeek: View {
@Binding var createWeek: Bool @Binding var createWeek: Bool
let week: [Date.WeekDay] let week: [Date.WeekDay]
@ObservedObject var vm: ScheduleViewModel @ObservedObject var vm: ScheduleViewModel
@Binding var isShowingVPKLabel: Bool
var body: some View { var body: some View {
HStack (spacing: 10) { HStack (spacing: 10) {
ForEach(week) { day in ForEach(week) { day in
@ -53,7 +52,6 @@ struct WeekViewForWeek: View {
) )
.cornerRadius(15) .cornerRadius(15)
.onTapGesture { .onTapGesture {
isShowingVPKLabel = false
vm.selectedDay = day.date vm.selectedDay = day.date
vm.updateSelectedDayIndex() vm.updateSelectedDayIndex()
} }

View File

@ -2,7 +2,7 @@
// GeneralGroupSettings.swift // GeneralGroupSettings.swift
// Schedule ICTIS // Schedule ICTIS
// //
// Created by G412 on 25.02.2025. // Created by Mironov Egor on 25.02.2025.
// //
import SwiftUI import SwiftUI

View File

@ -2,7 +2,7 @@
// ScheduleGroupSettings.swift // ScheduleGroupSettings.swift
// Schedule ICTIS // Schedule ICTIS
// //
// Created by G412 on 25.02.2025. // Created by Mironov Egor on 25.02.2025.
// //
import SwiftUI import SwiftUI

View File

@ -115,11 +115,13 @@ struct SelectingGroupView: View {
} }
} }
} }
} } else {
if !isFocused {
if favGroup != "" { if favGroup != "" {
Button { Button {
UserDefaults.standard.removeObject(forKey: "group") UserDefaults.standard.removeObject(forKey: "group")
vm.classes.removeAll()
vm.group = ""
vm.numOfGroup = ""
dismiss() dismiss()
} label: { } label: {
HStack { HStack {
@ -133,7 +135,7 @@ struct SelectingGroupView: View {
.background(Color.white) .background(Color.white)
.foregroundColor(Color.red) .foregroundColor(Color.red)
.cornerRadius(10) .cornerRadius(10)
.padding(.bottom, UIScreen.main.bounds.height / 11) .padding(.bottom, 50)
} }
} }
} }

View File

@ -120,6 +120,9 @@ struct SelectingVPKView: View {
if favVPK != "" { if favVPK != "" {
Button { Button {
UserDefaults.standard.removeObject(forKey: "vpk") UserDefaults.standard.removeObject(forKey: "vpk")
vm.vpks.removeAll()
vm.vpk = ""
vm.vpkHTML = ""
dismiss() dismiss()
} label: { } label: {
HStack { HStack {
@ -133,7 +136,7 @@ struct SelectingVPKView: View {
.background(Color.white) .background(Color.white)
.foregroundColor(Color.red) .foregroundColor(Color.red)
.cornerRadius(10) .cornerRadius(10)
.padding(.bottom, UIScreen.main.bounds.height / 11) .padding(.bottom, 50)
} }
} }
} }

View File

@ -2,7 +2,7 @@
// SettingsView2.swift // SettingsView2.swift
// Schedule ICTIS // Schedule ICTIS
// //
// Created by G412 on 25.02.2025. // Created by Mironov Egor on 25.02.2025.
// //
import SwiftUI import SwiftUI

View File

@ -53,11 +53,11 @@ final class ScheduleViewModel: ObservableObject {
Task { Task {
do { do {
var schedule: Schedule var schedule: Schedule
// В этот if мы заходим только если пользователь перелистывает недели и нам известы номер группы(в html формате) и номер недели, которая показывается пользователю // В этот if мы заходим только если пользователь перелистывает недели и нам ИЗВЕСТНЫ номер группы(в html формате) и номер недели, которая показывается пользователю
if (isOtherWeek || !isFirstStartOffApp) && (group == "default") { if (isOtherWeek || !isFirstStartOffApp) && (group == "default") {
schedule = try await NetworkManager.shared.getScheduleForOtherWeek(self.week, self.numOfGroup) schedule = try await NetworkManager.shared.getScheduleForOtherWeek(self.week, self.numOfGroup)
} }
// В else мы заходим в том случае, если не знаем номер недели, которую нужно отобразить и номер группы(в html формате) // В else мы заходим в том случае, если НЕ знаем номер недели, которую нужно отобразить и номер группы(в html формате)
else { else {
print("Отладка 1") print("Отладка 1")
schedule = try await NetworkManager.shared.getSchedule(group) schedule = try await NetworkManager.shared.getSchedule(group)