big update

This commit is contained in:
15lu.akari
2025-08-26 23:37:39 +03:00
parent 6b88875bee
commit a87a3d12ab
34 changed files with 803 additions and 282 deletions

View File

@ -1,27 +1,28 @@
import SwiftUI
import AVKit
import NukeUI
import UIKit
// MARK: - SightView
struct SightView: View {
let sightId: Int
@StateObject private var viewModel = SightViewModel()
@EnvironmentObject private var appState: AppState
var body: some View {
VStack(alignment: .leading, spacing: 4) {
mediaSection
VStack(alignment: .leading, spacing: 8) {
// Заголовок статьи
Text(viewModel.selectedArticle?.isReviewArticle == true ? viewModel.sightName : viewModel.articleHeading)
Text(viewModel.selectedArticle?.isReviewArticle == true
? viewModel.sightName
: viewModel.articleHeading)
.font(.title2)
.fontWeight(.bold)
.foregroundColor(.white)
.frame(maxWidth: .infinity, alignment: viewModel.selectedArticle?.isReviewArticle == true ? .center : .leading)
.frame(maxWidth: .infinity,
alignment: viewModel.selectedArticle?.isReviewArticle == true ? .center : .leading)
.multilineTextAlignment(viewModel.selectedArticle?.isReviewArticle == true ? .center : .leading)
// Тело статьи
ScrollView {
if viewModel.selectedArticle?.isReviewArticle == true {
@ -38,16 +39,14 @@ struct SightView: View {
.frame(maxWidth: .infinity, alignment: .leading)
}
}
// Список статей (кнопки навигации) - ФИНАЛЬНОЕ ИСПРАВЛЕНИЕ ЦЕНТРИРОВАНИЯ
// Список статей
GeometryReader { geometry in
ScrollView(.horizontal, showsIndicators: false) {
HStack(spacing: 6) {
// Spacers для центрирования
HStack(spacing: 10) {
Spacer(minLength: 0)
ForEach(viewModel.allArticles) { article in
Text(article.heading)
Text(localizedHeading(article))
.font(.system(size: 12))
.lineLimit(1)
.padding(.vertical, 6)
@ -64,28 +63,34 @@ struct SightView: View {
viewModel.selectArticle(article)
}
}
Spacer(minLength: 0)
}
// Принудительно задаем ширину HStack как ширину GeometryReader
.frame(minWidth: geometry.size.width)
}
.scrollIndicators(.hidden) // Скрываем полосу прокрутки
.scrollIndicators(.hidden)
}
// Задаем высоту для GeometryReader
.frame(height: 34)
.frame(maxWidth: .infinity)
}
.padding(.horizontal, 8)
.padding(.bottom, 10)
.padding(.bottom, 4)
}
// MARK: - Initial load
.task(id: sightId) {
viewModel.setLanguage(appState.selectedLanguage)
await viewModel.loadInitialData(sightId: sightId)
}
// MARK: - Reload on language change
.onChange(of: appState.selectedLanguage) { newLang in
viewModel.setLanguage(newLang)
Task {
await viewModel.loadInitialData(sightId: sightId)
}
}
.blockStyle(cornerRadius: 25)
}
// Медиа-секция
// MARK: - Медиа
@ViewBuilder
private var mediaSection: some View {
Group {
@ -98,29 +103,29 @@ struct SightView: View {
.tint(.white)
}
.frame(maxWidth: .infinity)
.aspectRatio(16/9, contentMode: .fit)
.frame(height: 160)
.cornerRadius(24, corners: [.topLeft, .topRight])
.clipped()
case .image(let url):
LazyImage(url: url) { state in
if let image = state.image {
image
.resizable()
.scaledToFit()
image.resizable().scaledToFit()
} else {
ProgressView()
ZStack {
Color.gray.opacity(0.3)
ProgressView()
.progressViewStyle(.circular)
.tint(.white)
}
}
}
.cornerRadius(24, corners: [.topLeft, .topRight])
.clipped()
case .video(let player):
VideoPlayer(player: player)
.aspectRatio(16/9, contentMode: .fit)
.cornerRadius(24, corners: [.topLeft, .topRight])
.clipped()
case .error:
Image(systemName: "photo")
.resizable()
@ -134,4 +139,18 @@ struct SightView: View {
.padding(4)
.frame(maxWidth: .infinity)
}
// MARK: - Локализованные заголовки статей
private func localizedHeading(_ article: Article) -> String {
if article.isReviewArticle == true {
switch appState.selectedLanguage {
case "ru": return "Обзор"
case "en": return "Review"
case "zh": return "奥布佐尔"
default: return "Обзор"
}
} else {
return article.heading
}
}
}