This commit is contained in:
Vladimir Dubovik
2025-05-21 15:43:34 +03:00
parent 52a280b0f4
commit d32511db39
33 changed files with 344 additions and 107 deletions

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array/>
</plist>

View File

@ -1,6 +1,7 @@
{ {
"images" : [ "images" : [
{ {
"filename" : "ICTIS_logo.png",
"idiom" : "universal", "idiom" : "universal",
"platform" : "ios", "platform" : "ios",
"size" : "1024x1024" "size" : "1024x1024"

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

View File

@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "ICTIS_logo.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

View File

@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "arrowRight.svg",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M9 6L15 12L9 18" stroke="#8B8B8B" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 212 B

View File

@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "arrowdown.svg",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,3 @@
<svg width="14" height="8" viewBox="0 0 14 8" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M13 1L7 7L1 1" stroke="#007AFF" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 191 B

View File

@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "arrowup.svg",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,3 @@
<svg width="14" height="8" viewBox="0 0 14 8" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1 7L7 1L13 7" stroke="#007AFF" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 191 B

View File

@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "upDownArrows.svg",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,4 @@
<svg width="14" height="18" viewBox="0 0 14 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1 7L7 1L13 7" stroke="#878787" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M13 11L7 17L1 11" stroke="#878787" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 320 B

View File

@ -34,6 +34,18 @@ struct ContentView: View {
} }
TabBarView(selectedTab: $selectedTab) TabBarView(selectedTab: $selectedTab)
} }
.alert(isPresented: $vm.isShowingAlertForIncorrectSingleGroup, error: vm.errorInNetworkForSingleGroup) { error in
Button("ОК") {
print("This alert")
vm.isShowingAlertForIncorrectSingleGroup = false
vm.errorInNetworkForSingleGroup = nil
}
} message: { error in
Text(error.failureReason)
}
.onAppear {
vm.fillFilteringGroups()
}
} }
} }

View File

@ -8,7 +8,7 @@
<string>Montserrat-BlackItalic.ttf</string> <string>Montserrat-BlackItalic.ttf</string>
<string>Montserrat-Bold.ttf</string> <string>Montserrat-Bold.ttf</string>
<string>Montserrat-BoldItalic.ttf</string> <string>Montserrat-BoldItalic.ttf</string>
<string>Monsterrat-ExtraBold.ttf</string> <string>Montserrat-ExtraBold.ttf</string>
<string>Montserrat-ExtraBoldItalic.ttf</string> <string>Montserrat-ExtraBoldItalic.ttf</string>
<string>Montserrat-ExtraLight.ttf</string> <string>Montserrat-ExtraLight.ttf</string>
<string>Montserrat-ExtraLightItalic.ttf</string> <string>Montserrat-ExtraLightItalic.ttf</string>

View File

@ -9,43 +9,69 @@ import SwiftUI
struct FilterGroupsView: View { struct FilterGroupsView: View {
@ObservedObject var vm: ScheduleViewModel @ObservedObject var vm: ScheduleViewModel
@ObservedObject var networkMonitor: NetworkMonitor
var body: some View { var body: some View {
ScrollView(.horizontal, showsIndicators: false) { ScrollView(.horizontal, showsIndicators: false) {
LazyHStack(spacing: 12) { LazyHStack(spacing: 12) {
ForEach(vm.filteringGroups, id: \.self) { group in // Кнопка добавления новой группы
VStack { NavigationLink(destination: SelectingGroupView(vm: vm, networkMonitor: networkMonitor)) {
Text(group) ZStack {
Rectangle()
.frame(width: 28, height: 28)
.foregroundStyle(.white)
.cornerRadius(20)
Image(systemName: "plus")
.foregroundColor(Color("customGray3")) .foregroundColor(Color("customGray3"))
.font(.custom("Montserrat-Medium", fixedSize: 14)) .font(.system(size: 12))
.padding(.horizontal, 15)
.padding(.vertical, 7)
} }
.background(Color.white) }
.overlay (
Group { if vm.filteringGroups.count == 2 {
if vm.showOnlyChoosenGroup == group { ForEach(vm.filteringGroups.dropFirst(), id: \.self) { group in
RoundedRectangle(cornerRadius: 20) GroupItem(group: group, isSelected: vm.showOnlyChoosenGroup == group) {
.stroke(Color("blueColor"), lineWidth: 3) vm.showOnlyChoosenGroup = group
} }
}
} else if vm.filteringGroups.count > 2 {
ForEach(vm.filteringGroups, id: \.self) { group in
GroupItem(group: group, isSelected: vm.showOnlyChoosenGroup == group) {
vm.showOnlyChoosenGroup = group
} }
)
.cornerRadius(20)
.onTapGesture {
vm.showOnlyChoosenGroup = group
} }
} }
} }
.padding(.horizontal) .padding(.horizontal)
} }
.frame(height: 40) .frame(height: 40)
.onAppear {
vm.updateFilteringGroups()
}
.padding(.bottom, 4) .padding(.bottom, 4)
} }
} }
// Вынесенный компонент для элемента группы
struct GroupItem: View {
let group: String
let isSelected: Bool
let action: () -> Void
var body: some View {
Text(group)
.foregroundColor(Color("customGray3"))
.font(.custom("Montserrat-Medium", fixedSize: 14))
.padding(.horizontal, 15)
.padding(.vertical, 7)
.background(Color.white)
.overlay(
RoundedRectangle(cornerRadius: 20)
.stroke(isSelected ? Color("blueColor") : Color.clear, lineWidth: 3)
)
.cornerRadius(20)
.onTapGesture(perform: action)
}
}
#Preview { #Preview {
@Previewable @ObservedObject var vm = ScheduleViewModel() @Previewable @ObservedObject var vm = ScheduleViewModel()
FilterGroupsView(vm: vm) @Previewable @ObservedObject var networkMonitor = NetworkMonitor()
FilterGroupsView(vm: vm, networkMonitor: networkMonitor)
} }

View File

@ -14,32 +14,34 @@ struct MainView: View {
@FocusState private var isFocusedSearchBar: Bool @FocusState private var isFocusedSearchBar: Bool
@State private var isScrolling: Bool = false @State private var isScrolling: Bool = false
var body: some View { var body: some View {
VStack { NavigationStack {
SearchBarView(isFocused: _isFocusedSearchBar, vm: vm, isShowingMonthSlider: $isShowingMonthSlider) VStack {
.onChange(of: isScrolling, initial: false) { oldValue, newValue in SearchBarView(isFocused: _isFocusedSearchBar, vm: vm, isShowingMonthSlider: $isShowingMonthSlider)
if newValue && isScrolling { .onChange(of: isScrolling, initial: false) { oldValue, newValue in
isFocusedSearchBar = false if newValue && isScrolling {
isFocusedSearchBar = false
}
} }
CurrentDateView()
FilterGroupsView(vm: vm, networkMonitor: networkMonitor)
if vm.isLoading {
LoadingScheduleView()
}
else {
ScheduleView(vm: vm, networkMonitor: networkMonitor, isScrolling: $isScrolling)
} }
CurrentDateView()
FilterGroupsView(vm: vm)
if vm.isLoading {
LoadingScheduleView()
} }
else { .alert(isPresented: $vm.isShowingAlertForIncorrectGroup, error: vm.errorInNetwork) { error in
ScheduleView(vm: vm, networkMonitor: networkMonitor, isScrolling: $isScrolling) Button("ОК") {
print("This alert")
vm.isShowingAlertForIncorrectGroup = false
vm.errorInNetwork = nil
}
} message: { error in
Text(error.failureReason)
} }
.background(Color("background"))
} }
.alert(isPresented: $vm.isShowingAlertForIncorrectGroup, error: vm.errorInNetwork) { error in
Button("ОК") {
print("This alert")
vm.isShowingAlertForIncorrectGroup = false
vm.errorInNetwork = nil
}
} message: { error in
Text(error.failureReason)
}
.background(Color("background"))
} }
@ViewBuilder @ViewBuilder

View File

@ -31,8 +31,9 @@ struct SearchBarView: View {
if (!text.isEmpty) { if (!text.isEmpty) {
vm.fetchWeekForSingleGroup(groupName: text) vm.fetchWeekForSingleGroup(groupName: text)
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
guard vm.errorInNetwork == .noError else { guard vm.errorInNetworkForSingleGroup == .noError else {
vm.isShowingAlertForIncorrectGroup = true vm.isShowingAlertForIncorrectSingleGroup = true
self.text = ""
return return
} }
vm.removeFromSchedule(group: vm.searchingGroup) vm.removeFromSchedule(group: vm.searchingGroup)
@ -40,7 +41,7 @@ struct SearchBarView: View {
vm.searchingGroup = text vm.searchingGroup = text
vm.nameToHtml[text] = "" vm.nameToHtml[text] = ""
print("Ключи: \(vm.nameToHtml.keys)") print("Ключи: \(vm.nameToHtml.keys)")
vm.updateFilteringGroups() vm.addGroupToFilteringArray(group: text)
vm.fetchWeekSchedule() vm.fetchWeekSchedule()
self.text = "" self.text = ""
} }
@ -77,12 +78,10 @@ struct SearchBarView: View {
Rectangle() Rectangle()
.frame(width: 40, height: 40) .frame(width: 40, height: 40)
.foregroundStyle(Color("blueColor")) .foregroundStyle(Color("blueColor"))
.cornerRadius(15) .cornerRadius(10)
Image(systemName: "plus") Image(systemName: "plus")
.resizable() .foregroundColor(.white)
.foregroundStyle(.white) .font(.system(size: 22))
.scaledToFit()
.frame(width: 16)
} }
} }
} }

View File

@ -51,8 +51,6 @@ extension JsonClassModel {
let groupsToDelete = try context.fetch(fetchRequest) let groupsToDelete = try context.fetch(fetchRequest)
print("Пары для удаления: \(groupsToDelete)")
for group in groupsToDelete { for group in groupsToDelete {
do { do {
try ClassProvider.shared.delete(group, in: context) try ClassProvider.shared.delete(group, in: context)

View File

@ -9,6 +9,7 @@ import SwiftUI
import CoreData import CoreData
struct FavGroupsView: View { struct FavGroupsView: View {
@Environment(\.dismiss) private var dismiss
@ObservedObject var vm: ScheduleViewModel @ObservedObject var vm: ScheduleViewModel
@ObservedObject var networkMonitor: NetworkMonitor @ObservedObject var networkMonitor: NetworkMonitor
@FetchRequest(fetchRequest: FavouriteGroupModel.all()) private var favGroups // Список групп сохраненных в CoreData @FetchRequest(fetchRequest: FavouriteGroupModel.all()) private var favGroups // Список групп сохраненных в CoreData
@ -39,28 +40,39 @@ struct FavGroupsView: View {
} }
} }
} }
}
Spacer() .navigationBarBackButtonHidden(true) // Скрываем стандартную кнопку "Назад"
.background(Color("background"))
HStack { .toolbar {
Spacer() ToolbarItem(placement: .topBarLeading) {
Button(action: {
dismiss()
}) {
HStack {
Image(systemName: "chevron.left")
Text("Настройки")
}
.foregroundColor(.blue)
}
}
// Кнопка в правой части
ToolbarItem(placement: .topBarTrailing) {
if favGroups.count < 10 { if favGroups.count < 10 {
NavigationLink(destination: SelectingGroupView(vm: vm, networkMonitor: networkMonitor)) { NavigationLink(destination: SelectingGroupView(vm: vm, networkMonitor: networkMonitor)) {
HStack { ZStack {
Rectangle()
.frame(width: 40, height: 40)
.foregroundStyle(Color("blueColor"))
.cornerRadius(10)
Image(systemName: "plus") Image(systemName: "plus")
.foregroundColor(.white) .foregroundColor(.white)
.font(.system(size: 22)) .font(.system(size: 18))
.padding(EdgeInsets(top: 12, leading: 12, bottom: 12, trailing: 12))
} }
.background(Color("blueColor"))
.cornerRadius(10)
.padding(.trailing, 20)
} }
} }
} }
.padding(.bottom, 90)
} }
.background(Color("background")) .navigationBarTitleDisplayMode(.inline)
} }
} }

View File

@ -8,6 +8,7 @@
import SwiftUI import SwiftUI
struct FavVPKView: View { struct FavVPKView: View {
@Environment(\.dismiss) private var dismiss
@ObservedObject var vm: ScheduleViewModel @ObservedObject var vm: ScheduleViewModel
@ObservedObject var networkMonitor: NetworkMonitor @ObservedObject var networkMonitor: NetworkMonitor
@FetchRequest(fetchRequest: FavouriteVpkModel.all()) private var favVpk // Список ВПК сохраненных в CoreData @FetchRequest(fetchRequest: FavouriteVpkModel.all()) private var favVpk // Список ВПК сохраненных в CoreData
@ -38,28 +39,39 @@ struct FavVPKView: View {
} }
} }
} }
}
Spacer() .navigationBarBackButtonHidden(true) // Скрываем стандартную кнопку "Назад"
.background(Color("background"))
HStack { .toolbar {
Spacer() ToolbarItem(placement: .topBarLeading) {
Button(action: {
dismiss()
}) {
HStack {
Image(systemName: "chevron.left")
Text("Настройки")
}
.foregroundColor(.blue)
}
}
// Кнопка в правой части
ToolbarItem(placement: .topBarTrailing) {
if favVpk.count < 5 { if favVpk.count < 5 {
NavigationLink(destination: SelectingVPKView(vm: vm, networkMonitor: networkMonitor)) { NavigationLink(destination: SelectingVPKView(vm: vm, networkMonitor: networkMonitor)) {
HStack { ZStack {
Rectangle()
.frame(width: 40, height: 40)
.foregroundStyle(Color("blueColor"))
.cornerRadius(10)
Image(systemName: "plus") Image(systemName: "plus")
.foregroundColor(.white) .foregroundColor(.white)
.font(.system(size: 22)) .font(.system(size: 18))
.padding(EdgeInsets(top: 12, leading: 12, bottom: 12, trailing: 12))
} }
.background(Color("blueColor"))
.cornerRadius(10)
.padding(.trailing, 20)
} }
} }
} }
.padding(.bottom, 90)
} }
.background(Color("background")) .navigationBarTitleDisplayMode(.inline)
} }
} }

View File

@ -38,7 +38,7 @@ struct ListOfGroupsView: View {
try saveGroup(name: item.name) try saveGroup(name: item.name)
saveScheduleForVpkToMemory(withName: item.name) saveScheduleForVpkToMemory(withName: item.name)
vm.nameToHtml[item.name] = "" vm.nameToHtml[item.name] = ""
vm.updateFilteringGroups() vm.addGroupToFilteringArray(group: item.name)
vm.fetchWeekSchedule() vm.fetchWeekSchedule()
dismiss() dismiss()
} catch { } catch {

View File

@ -45,30 +45,29 @@ struct SelectingGroupView: View {
self.isFocused = false self.isFocused = false
guard !text.isEmpty else { return } guard !text.isEmpty else { return }
vm.fetchWeekForSingleGroup(groupName: text)
self.isLoading = true self.isLoading = true
vm.fetchWeekForSingleGroup(groupName: text)
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
guard vm.errorInNetwork == .noError else { if vm.errorInNetworkForSingleGroup != .noError {
vm.isShowingAlertForIncorrectGroup = true
return return
} }
vm.errorInNetwork = nil vm.errorInNetworkForSingleGroup = nil
let formattedText = transformStringToFormat(text) let formattedText = transformStringToFormat(text)
do { do {
try saveGroup(name: formattedText) try saveGroup(name: formattedText)
saveScheduleForGroupToMemory(withName: formattedText) saveScheduleForGroupToMemory(withName: formattedText)
vm.nameToHtml[formattedText] = "" vm.nameToHtml[formattedText] = ""
vm.updateFilteringGroups() vm.addGroupToFilteringArray(group: formattedText)
vm.fetchWeekSchedule() vm.fetchWeekSchedule()
self.isLoading = false self.isLoading = false
self.text = "" self.text = ""
dismiss() dismiss()
} catch { } catch {
print("Ошибка сохранения: \(error.localizedDescription)") print("Ошибка сохранения: \(error.localizedDescription)")
vm.isShowingAlertForIncorrectGroup = true vm.isShowingAlertForIncorrectSingleGroup = true
} }
} }
} }
@ -88,10 +87,10 @@ struct SelectingGroupView: View {
} }
} }
.frame(height: 40) .frame(height: 40)
.background( .background (
RoundedRectangle(cornerRadius: 15) RoundedRectangle(cornerRadius: 10)
.fill(.white) .fill(.white)
) )
Spacer() Spacer()
if isLoading { if isLoading {
LoadingView() LoadingView()
@ -121,7 +120,7 @@ struct SelectingGroupView: View {
try saveGroup(name: item.name) try saveGroup(name: item.name)
saveScheduleForGroupToMemory(withName: item.name) saveScheduleForGroupToMemory(withName: item.name)
vm.nameToHtml[item.name] = "" vm.nameToHtml[item.name] = ""
vm.updateFilteringGroups() vm.addGroupToFilteringArray(group: item.name)
vm.fetchWeekSchedule() vm.fetchWeekSchedule()
self.isLoading = false self.isLoading = false
self.text = "" self.text = ""
@ -144,6 +143,21 @@ struct SelectingGroupView: View {
.onAppear { .onAppear {
serchGroupsVM.fetchGroups(group: "кт") serchGroupsVM.fetchGroups(group: "кт")
} }
.navigationBarBackButtonHidden(true) // Скрываем стандартную кнопку "Назад"
.toolbar {
ToolbarItem(placement: .topBarLeading) {
Button(action: {
dismiss()
}) {
HStack {
Image(systemName: "chevron.left")
Text("Назад")
}
.foregroundColor(.blue)
}
}
}
.navigationBarTitleDisplayMode(.inline)
} }
} }

View File

@ -45,30 +45,29 @@ struct SelectingVPKView: View {
self.isFocused = false self.isFocused = false
guard !text.isEmpty else { return } guard !text.isEmpty else { return }
vm.fetchWeekForSingleGroup(groupName: text)
self.isLoading = true self.isLoading = true
vm.fetchWeekForSingleGroup(groupName: text)
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
guard vm.errorInNetwork == .noError else { guard vm.errorInNetworkForSingleGroup == .noError else {
vm.isShowingAlertForIncorrectGroup = true
return return
} }
vm.errorInNetwork = nil vm.errorInNetworkForSingleGroup = nil
let formattedText = transformStringToFormat(text) let formattedText = transformStringToFormat(text)
do { do {
try saveGroup(name: formattedText) try saveGroup(name: formattedText)
saveScheduleForVpkToMemory(withName: formattedText) saveScheduleForVpkToMemory(withName: formattedText)
vm.nameToHtml[formattedText] = "" vm.nameToHtml[formattedText] = ""
vm.updateFilteringGroups() vm.addGroupToFilteringArray(group: formattedText)
vm.fetchWeekSchedule() vm.fetchWeekSchedule()
self.isLoading = false self.isLoading = false
self.text = "" self.text = ""
dismiss() dismiss()
} catch { } catch {
print("Ошибка сохранения: \(error.localizedDescription)") print("Ошибка сохранения: \(error.localizedDescription)")
vm.isShowingAlertForIncorrectGroup = true vm.isShowingAlertForIncorrectSingleGroup = true
} }
} }
} }
@ -107,6 +106,21 @@ struct SelectingVPKView: View {
.onAppear { .onAppear {
serchGroupsVM.fetchGroups(group: "ВПК") serchGroupsVM.fetchGroups(group: "ВПК")
} }
.navigationBarBackButtonHidden(true) // Скрываем стандартную кнопку "Назад"
.toolbar {
ToolbarItem(placement: .topBarLeading) {
Button(action: {
dismiss()
}) {
HStack {
Image(systemName: "chevron.left")
Text("Назад")
}
.foregroundColor(.blue)
}
}
}
.navigationBarTitleDisplayMode(.inline)
} }
} }

View File

@ -13,7 +13,7 @@ struct SettingsView: View {
@State private var selectedTheme = "Светлая" @State private var selectedTheme = "Светлая"
@State private var selectedLanguage = "Русский" @State private var selectedLanguage = "Русский"
var body: some View { var body: some View {
NavigationView { NavigationStack {
VStack { VStack {
ScrollView (.vertical, showsIndicators: false) { ScrollView (.vertical, showsIndicators: false) {
VStack (alignment: .leading) { VStack (alignment: .leading) {

View File

@ -21,7 +21,7 @@ enum NetworkError: String, Error, LocalizedError {
case .invalidResponse: case .invalidResponse:
"InvalidResponse" "InvalidResponse"
case .invalidData: case .invalidData:
"Проверьте номер группы" "Проверьте имя группы"
case .timeout: case .timeout:
"Ошибка сети" "Ошибка сети"
case .noError: case .noError:

View File

@ -17,7 +17,7 @@ final class ScheduleViewModel: ObservableObject {
@Published var classesGroups: [[ClassInfo]] = [] @Published var classesGroups: [[ClassInfo]] = []
@Published var searchingGroup = "" @Published var searchingGroup = ""
@Published var filteringGroups: [String] = ["Все"] @Published var filteringGroups: [String] = ["Все"]
@Published var showOnlyChoosenGroup: String = "Все" @Published var showOnlyChoosenGroup: String = ""
//Schedule //Schedule
@Published var weekScheduleGroup: Table = Table( @Published var weekScheduleGroup: Table = Table(
@ -34,7 +34,9 @@ final class ScheduleViewModel: ObservableObject {
@Published var isFirstStartOffApp = true @Published var isFirstStartOffApp = true
@Published var isShowingAlertForIncorrectGroup: Bool = false @Published var isShowingAlertForIncorrectGroup: Bool = false
@Published var isShowingAlertForIncorrectSingleGroup: Bool = false
@Published var errorInNetwork: NetworkError? @Published var errorInNetwork: NetworkError?
@Published var errorInNetworkForSingleGroup: NetworkError?
@Published var isLoading: Bool = false @Published var isLoading: Bool = false
@Published var isNewGroup: Bool = false @Published var isNewGroup: Bool = false
@ -141,25 +143,25 @@ final class ScheduleViewModel: ObservableObject {
// Обновляем данные // Обновляем данные
self.classesForSingleGroup = singleSchedule self.classesForSingleGroup = singleSchedule
self.isShowingAlertForIncorrectGroup = false self.isShowingAlertForIncorrectSingleGroup = false
self.isLoading = false self.isLoading = false
self.errorInNetwork = .noError self.errorInNetworkForSingleGroup = .noError
} catch { } catch {
if let urlError = error as? URLError, urlError.code == .timedOut { if let urlError = error as? URLError, urlError.code == .timedOut {
errorInNetwork = .timeout errorInNetworkForSingleGroup = .timeout
print("Ошибка: превышено время ожидания ответа от сервера") print("Ошибка: превышено время ожидания ответа от сервера")
} else if let error = error as? NetworkError { } else if let error = error as? NetworkError {
switch error { switch error {
case .invalidResponse: case .invalidResponse:
errorInNetwork = .invalidResponse errorInNetworkForSingleGroup = .invalidResponse
case .invalidData: case .invalidData:
errorInNetwork = .invalidData errorInNetworkForSingleGroup = .invalidData
print("FetchSingle: InvalidData") print("FetchSingle: InvalidData")
self.isShowingAlertForIncorrectGroup = true
default: default:
print("Неизвестная ошибка: \(error)") print("Неизвестная ошибка: \(error)")
} }
self.isShowingAlertForIncorrectSingleGroup = true
print("Есть ошибка: \(error)") print("Есть ошибка: \(error)")
} }
isLoading = false isLoading = false
@ -229,12 +231,34 @@ final class ScheduleViewModel: ObservableObject {
classesGroups[i].remove(at: j) classesGroups[i].remove(at: j)
} }
} }
self.filteringGroups = self.filteringGroups.filter {$0 != group}
if group == self.showOnlyChoosenGroup || self.filteringGroups.count == 2 {
selectShowingGroup()
}
} }
func updateFilteringGroups() { func selectShowingGroup() {
self.filteringGroups = ["Все"] if self.filteringGroups.count == 2 {
self.showOnlyChoosenGroup = self.filteringGroups[1]
} else if self.filteringGroups.count < 2 {
self.showOnlyChoosenGroup = ""
}
else {
self.showOnlyChoosenGroup = "Все"
}
}
func addGroupToFilteringArray(group: String) {
self.filteringGroups.append(group)
}
func fillFilteringGroups() {
let keys = self.nameToHtml.keys let keys = self.nameToHtml.keys
print(keys) print(keys)
self.filteringGroups.append(contentsOf: keys) self.filteringGroups.append(contentsOf: keys)
selectShowingGroup()
} }
} }