big update
This commit is contained in:
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user