Commit
This commit is contained in:
parent
8bc7425e2a
commit
99f2bd8a74
@ -1,10 +1,3 @@
|
|||||||
//
|
|
||||||
// LoadingScheduleView.swift
|
|
||||||
// Schedule ICTIS
|
|
||||||
//
|
|
||||||
// Created by G412 on 19.02.2025.
|
|
||||||
//
|
|
||||||
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
struct LoadingScheduleView: View {
|
struct LoadingScheduleView: View {
|
||||||
@ -13,27 +6,43 @@ struct LoadingScheduleView: View {
|
|||||||
ZStack {
|
ZStack {
|
||||||
ScrollView(.vertical, showsIndicators: false) {
|
ScrollView(.vertical, showsIndicators: false) {
|
||||||
VStack(spacing: 20) {
|
VStack(spacing: 20) {
|
||||||
ForEach(0..<6, id: \.self) { _ in
|
ForEach(0..<5, id: \.self) { _ in
|
||||||
RoundedRectangle(cornerRadius: 20)
|
VStack (alignment: .trailing) {
|
||||||
.fill(
|
RoundedRectangle(cornerRadius: 20)
|
||||||
LinearGradient(
|
.fill(
|
||||||
gradient: Gradient(colors: [
|
LinearGradient(
|
||||||
isAnimated ? Color.gray.opacity(0.6) : Color.gray.opacity(0.3),
|
gradient: Gradient(colors: [
|
||||||
isAnimated ? Color.gray.opacity(0.3) : Color.gray.opacity(0.6)
|
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
|
startPoint: .topLeading,
|
||||||
|
endPoint: .bottomTrailing
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
.frame(width: 45, height: 20)
|
||||||
.frame(height: 70)
|
.padding(.horizontal, 20)
|
||||||
.padding(.horizontal, 20)
|
.animation(.linear(duration: 0.8).repeatForever(autoreverses: true), value: isAnimated)
|
||||||
.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 {
|
.onAppear {
|
||||||
isAnimated.toggle()
|
isAnimated.toggle()
|
||||||
}
|
}
|
||||||
.padding(.top, 30)
|
.padding(.top, 10)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -82,14 +82,15 @@ struct MainView: View {
|
|||||||
if (!isShowingMonthSlider) {
|
if (!isShowingMonthSlider) {
|
||||||
WeekTabView(vm: vm)
|
WeekTabView(vm: vm)
|
||||||
.transition(.opacity)
|
.transition(.opacity)
|
||||||
|
.animation(.easeInOut(duration: 0.25), value: isShowingMonthSlider)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
MonthTabView(vm: vm)
|
MonthTabView(vm: vm)
|
||||||
.transition(.opacity)
|
.transition(.opacity)
|
||||||
|
.animation(.easeInOut(duration: 0.25), value: isShowingMonthSlider)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.padding(.horizontal)
|
.padding(.horizontal)
|
||||||
.animation(.easeInOut(duration: 0.25), value: isShowingMonthSlider)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#Preview {
|
#Preview {
|
||||||
|
@ -17,7 +17,7 @@ struct ListOfGroupsView: View {
|
|||||||
var body: some View {
|
var body: some View {
|
||||||
ScrollView(.vertical, showsIndicators: true) {
|
ScrollView(.vertical, showsIndicators: true) {
|
||||||
ForEach(serchGroupsVM.groups) { item in
|
ForEach(serchGroupsVM.groups) { item in
|
||||||
if item.name.starts(with: "ВПК") {
|
if item.name.starts(with: "ВПК") || item.name.starts(with: "мВПК") {
|
||||||
VStack {
|
VStack {
|
||||||
Rectangle()
|
Rectangle()
|
||||||
.frame(height: 1)
|
.frame(height: 1)
|
||||||
|
@ -95,7 +95,7 @@ struct SelectingGroupView: View {
|
|||||||
if isLoading {
|
if isLoading {
|
||||||
LoadingView(isLoading: $isLoading)
|
LoadingView(isLoading: $isLoading)
|
||||||
}
|
}
|
||||||
if isFocused {
|
//if isFocused {
|
||||||
ScrollView(.vertical, showsIndicators: true) {
|
ScrollView(.vertical, showsIndicators: true) {
|
||||||
ForEach(serchGroupsVM.groups) { item in
|
ForEach(serchGroupsVM.groups) { item in
|
||||||
if item.name.starts(with: "КТ") { //Отображаем только группы(без аудиторий и преподавателей)
|
if item.name.starts(with: "КТ") { //Отображаем только группы(без аудиторий и преподавателей)
|
||||||
@ -133,7 +133,7 @@ struct SelectingGroupView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
.padding(.horizontal, 10)
|
.padding(.horizontal, 10)
|
||||||
.background(Color("background"))
|
.background(Color("background"))
|
||||||
|
@ -94,9 +94,7 @@ struct SelectingVPKView: View {
|
|||||||
if isLoading {
|
if isLoading {
|
||||||
LoadingView(isLoading: $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)
|
.padding(.horizontal, 10)
|
||||||
.background(Color("background"))
|
.background(Color("background"))
|
||||||
|
@ -17,7 +17,11 @@ final class SearchGroupsViewModel: ObservableObject {
|
|||||||
var groups: Welcome
|
var groups: Welcome
|
||||||
groups = try await NetworkManager.shared.getGroups(group: group)
|
groups = try await NetworkManager.shared.getGroups(group: group)
|
||||||
self.groups = groups.choices
|
self.groups = groups.choices
|
||||||
|
if (group == "кт") {
|
||||||
|
self.sortGroups()
|
||||||
|
} else {
|
||||||
|
self.sortVPK()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
if let error = error as? NetworkError {
|
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[..<hyphenIndex])
|
||||||
|
// Извлекаем часть после дефиса (номер группы)
|
||||||
|
let suffix = String(name[name.index(after: hyphenIndex)...])
|
||||||
|
|
||||||
|
// Извлекаем цифры из prefix
|
||||||
|
let courseNumberString = prefix.trimmingCharacters(in: CharacterSet.letters)
|
||||||
|
let courseNumber = Int(courseNumberString) ?? 0
|
||||||
|
|
||||||
|
// Преобразуем suffix в число
|
||||||
|
let groupNumber = Int(suffix) ?? 0
|
||||||
|
|
||||||
|
return GroupComponents(courseNumber: courseNumber, groupNumber: groupNumber)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Метод сортировки для ВПК групп
|
||||||
|
func sortVPK() {
|
||||||
|
groups.sort { (group1, group2) in
|
||||||
|
let components1 = extractVPKComponents(from: group1.name)
|
||||||
|
let components2 = extractVPKComponents(from: group2.name)
|
||||||
|
|
||||||
|
// Сравниваем по типу (мВПК после ВПК)
|
||||||
|
if components1.isMinor != components2.isMinor {
|
||||||
|
return !components1.isMinor // ВПК идет перед мВПК
|
||||||
|
}
|
||||||
|
|
||||||
|
// Сравниваем по первому номеру
|
||||||
|
if components1.firstNumber != components2.firstNumber {
|
||||||
|
return components1.firstNumber < components2.firstNumber
|
||||||
|
}
|
||||||
|
|
||||||
|
// Если первые номера равны, сравниваем по второму номеру (если есть)
|
||||||
|
// Используем nil coalescing для случаев, когда второго номера нет
|
||||||
|
return (components1.secondNumber ?? Int.max) < (components2.secondNumber ?? Int.max)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Вспомогательная структура для хранения компонентов ВПК
|
||||||
|
private struct VPKComponents {
|
||||||
|
let isMinor: Bool // true для мВПК, false для ВПК
|
||||||
|
let firstNumber: Int
|
||||||
|
let secondNumber: Int?
|
||||||
|
}
|
||||||
|
|
||||||
|
// Метод для извлечения компонентов из названия ВПК группы
|
||||||
|
private func extractVPKComponents(from name: String) -> 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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user