From 99f2bd8a7469fd14064856f379b2aaf0f5196388 Mon Sep 17 00:00:00 2001 From: Vladimir Dubovik Date: Fri, 14 Mar 2025 12:47:18 +0300 Subject: [PATCH] Commit --- Schedule ICTIS/LoadingScheduleView.swift | 53 +++++---- Schedule ICTIS/Main/Views/MainView.swift | 3 +- .../Settings/ListOfGroupsView.swift | 2 +- .../Settings/SelectingGroupView.swift | 4 +- .../Settings/SelectingVPKView.swift | 4 +- .../ViewModel/SearchGroupsViewModel.swift | 103 +++++++++++++++++- 6 files changed, 139 insertions(+), 30 deletions(-) diff --git a/Schedule ICTIS/LoadingScheduleView.swift b/Schedule ICTIS/LoadingScheduleView.swift index ea4122b..2a82334 100644 --- a/Schedule ICTIS/LoadingScheduleView.swift +++ b/Schedule ICTIS/LoadingScheduleView.swift @@ -1,10 +1,3 @@ -// -// LoadingScheduleView.swift -// Schedule ICTIS -// -// Created by G412 on 19.02.2025. -// - import SwiftUI struct LoadingScheduleView: View { @@ -13,27 +6,43 @@ struct LoadingScheduleView: View { ZStack { ScrollView(.vertical, showsIndicators: false) { VStack(spacing: 20) { - ForEach(0..<6, id: \.self) { _ in - RoundedRectangle(cornerRadius: 20) - .fill( - LinearGradient( - gradient: Gradient(colors: [ - isAnimated ? Color.gray.opacity(0.6) : Color.gray.opacity(0.3), - isAnimated ? Color.gray.opacity(0.3) : Color.gray.opacity(0.6) - ]), - startPoint: .topLeading, - endPoint: .bottomTrailing + ForEach(0..<5, id: \.self) { _ in + VStack (alignment: .trailing) { + RoundedRectangle(cornerRadius: 20) + .fill( + LinearGradient( + gradient: Gradient(colors: [ + isAnimated ? Color.gray.opacity(0.6) : Color.gray.opacity(0.3), + isAnimated ? Color.gray.opacity(0.3) : Color.gray.opacity(0.6) + ]), + startPoint: .topLeading, + endPoint: .bottomTrailing + ) ) - ) - .frame(height: 70) - .padding(.horizontal, 20) - .animation(.linear(duration: 0.8).repeatForever(autoreverses: true), value: isAnimated) + .frame(width: 45, height: 20) + .padding(.horizontal, 20) + .animation(.linear(duration: 0.8).repeatForever(autoreverses: true), value: isAnimated) + RoundedRectangle(cornerRadius: 20) + .fill( + LinearGradient( + gradient: Gradient(colors: [ + isAnimated ? Color.gray.opacity(0.6) : Color.gray.opacity(0.3), + isAnimated ? Color.gray.opacity(0.3) : Color.gray.opacity(0.6) + ]), + startPoint: .topLeading, + endPoint: .bottomTrailing + ) + ) + .frame(height: 70) + .padding(.horizontal, 20) + .animation(.linear(duration: 0.8).repeatForever(autoreverses: true), value: isAnimated) + } } } .onAppear { isAnimated.toggle() } - .padding(.top, 30) + .padding(.top, 10) } } } diff --git a/Schedule ICTIS/Main/Views/MainView.swift b/Schedule ICTIS/Main/Views/MainView.swift index 382553f..10b497b 100644 --- a/Schedule ICTIS/Main/Views/MainView.swift +++ b/Schedule ICTIS/Main/Views/MainView.swift @@ -82,14 +82,15 @@ struct MainView: View { if (!isShowingMonthSlider) { WeekTabView(vm: vm) .transition(.opacity) + .animation(.easeInOut(duration: 0.25), value: isShowingMonthSlider) } else { MonthTabView(vm: vm) .transition(.opacity) + .animation(.easeInOut(duration: 0.25), value: isShowingMonthSlider) } } .padding(.horizontal) - .animation(.easeInOut(duration: 0.25), value: isShowingMonthSlider) } } #Preview { diff --git a/Schedule ICTIS/Settings/ListOfGroupsView.swift b/Schedule ICTIS/Settings/ListOfGroupsView.swift index e1ab182..d6ae7aa 100644 --- a/Schedule ICTIS/Settings/ListOfGroupsView.swift +++ b/Schedule ICTIS/Settings/ListOfGroupsView.swift @@ -17,7 +17,7 @@ struct ListOfGroupsView: View { var body: some View { ScrollView(.vertical, showsIndicators: true) { ForEach(serchGroupsVM.groups) { item in - if item.name.starts(with: "ВПК") { + if item.name.starts(with: "ВПК") || item.name.starts(with: "мВПК") { VStack { Rectangle() .frame(height: 1) diff --git a/Schedule ICTIS/Settings/SelectingGroupView.swift b/Schedule ICTIS/Settings/SelectingGroupView.swift index 0b38b47..9064525 100644 --- a/Schedule ICTIS/Settings/SelectingGroupView.swift +++ b/Schedule ICTIS/Settings/SelectingGroupView.swift @@ -95,7 +95,7 @@ struct SelectingGroupView: View { if isLoading { LoadingView(isLoading: $isLoading) } - if isFocused { + //if isFocused { ScrollView(.vertical, showsIndicators: true) { ForEach(serchGroupsVM.groups) { item in if item.name.starts(with: "КТ") { //Отображаем только группы(без аудиторий и преподавателей) @@ -133,7 +133,7 @@ struct SelectingGroupView: View { } } } - } + //} } .padding(.horizontal, 10) .background(Color("background")) diff --git a/Schedule ICTIS/Settings/SelectingVPKView.swift b/Schedule ICTIS/Settings/SelectingVPKView.swift index 850e771..18fbbc2 100644 --- a/Schedule ICTIS/Settings/SelectingVPKView.swift +++ b/Schedule ICTIS/Settings/SelectingVPKView.swift @@ -94,9 +94,7 @@ struct SelectingVPKView: View { if isLoading { LoadingView(isLoading: $isLoading) } - if isFocused { - ListOfGroupsView(vm: vm, serchGroupsVM: serchGroupsVM, firstFavVPK: firstFavVPK, secondFavVPK: secondFavVPK, thirdFavVPK: thirdFavVPK) - } + ListOfGroupsView(vm: vm, serchGroupsVM: serchGroupsVM, firstFavVPK: firstFavVPK, secondFavVPK: secondFavVPK, thirdFavVPK: thirdFavVPK) } .padding(.horizontal, 10) .background(Color("background")) diff --git a/Schedule ICTIS/ViewModel/SearchGroupsViewModel.swift b/Schedule ICTIS/ViewModel/SearchGroupsViewModel.swift index 4ef9bf9..16b3e53 100644 --- a/Schedule ICTIS/ViewModel/SearchGroupsViewModel.swift +++ b/Schedule ICTIS/ViewModel/SearchGroupsViewModel.swift @@ -17,7 +17,11 @@ final class SearchGroupsViewModel: ObservableObject { var groups: Welcome groups = try await NetworkManager.shared.getGroups(group: group) self.groups = groups.choices - + if (group == "кт") { + self.sortGroups() + } else { + self.sortVPK() + } } catch { if let error = error as? NetworkError { @@ -33,4 +37,101 @@ final class SearchGroupsViewModel: ObservableObject { } } } + + // Метод сортировки + func sortGroups() { + groups.sort { (group1, group2) in + // Извлекаем компоненты из названия групп + let components1 = extractComponents(from: group1.name) + let components2 = extractComponents(from: group2.name) + + // Сравниваем сначала по номеру курса (первая цифра после букв) + if components1.courseNumber != components2.courseNumber { + return components1.courseNumber < components2.courseNumber + } + + // Если номера курсов равны, сравниваем по номеру группы (число после дефиса) + return components1.groupNumber < components2.groupNumber + } + } + + // Вспомогательная структура для хранения извлеченных компонентов + private struct GroupComponents { + let courseNumber: Int + let groupNumber: Int + } + + // Метод для извлечения числовых компонентов из названия группы + private func extractComponents(from name: String) -> GroupComponents { + // Находим индекс дефиса + guard let hyphenIndex = name.firstIndex(of: "-") else { + return GroupComponents(courseNumber: 0, groupNumber: 0) + } + + // Извлекаем часть до дефиса (буквы и номер курса) + let prefix = String(name[.. VPKComponents { + let isMinor = name.hasPrefix("мВПК") + + // Убираем префикс и разбиваем по дефису + let cleanName = isMinor ? name.replacingOccurrences(of: "мВПК-", with: "") : name.replacingOccurrences(of: "ВПК ", with: "") + let components = cleanName.split(separator: "-") + + // Извлекаем первый номер + let firstNumberString = String(components[0]).trimmingCharacters(in: .whitespaces) + let firstNumber = Int(firstNumberString) ?? 0 + + // Извлекаем второй номер, если он есть + let secondNumber: Int? + if components.count > 1 { + secondNumber = Int(components[1]) ?? 0 + } else { + secondNumber = nil + } + + return VPKComponents(isMinor: isMinor, firstNumber: firstNumber, secondNumber: secondNumber) + } }