post update
This commit is contained in:
parent
38de1cc204
commit
cca9dd3ce3
@ -21,6 +21,7 @@ struct Post: Identifiable, Codable {
|
|||||||
let isLikedByCurrentUser: Bool // Лайк текущим юзером
|
let isLikedByCurrentUser: Bool // Лайк текущим юзером
|
||||||
let isSavedByCurrentUser: Bool // Сохранено текущим юзером
|
let isSavedByCurrentUser: Bool // Сохранено текущим юзером
|
||||||
let authorID: String // Автор
|
let authorID: String // Автор
|
||||||
|
let authorUsername: String // Имя пользователя автора
|
||||||
let hashtags: [String]? // Хэштеги
|
let hashtags: [String]? // Хэштеги
|
||||||
let location: String? // Гео
|
let location: String? // Гео
|
||||||
let languageCode: [String]? // Язык
|
let languageCode: [String]? // Язык
|
||||||
|
|||||||
@ -99,6 +99,7 @@ class PostService {
|
|||||||
let thumbID = Bool.random() ? UUID() : nil
|
let thumbID = Bool.random() ? UUID() : nil
|
||||||
let postID = UUID()
|
let postID = UUID()
|
||||||
|
|
||||||
|
let authorId = "user_\(Int.random(in: 1...5))"
|
||||||
let post = Post(
|
let post = Post(
|
||||||
id: postID,
|
id: postID,
|
||||||
title: sampleTitles[i],
|
title: sampleTitles[i],
|
||||||
@ -117,7 +118,8 @@ class PostService {
|
|||||||
commentsCount: Int.random(in: 0...100),
|
commentsCount: Int.random(in: 0...100),
|
||||||
isLikedByCurrentUser: Bool.random(),
|
isLikedByCurrentUser: Bool.random(),
|
||||||
isSavedByCurrentUser: Bool.random(),
|
isSavedByCurrentUser: Bool.random(),
|
||||||
authorID: "user_\(Int.random(in: 1...5))",
|
authorID: authorId,
|
||||||
|
authorUsername: "username_\(authorId.split(separator: "_").last ?? "")",
|
||||||
hashtags: ["#тест", "#видео", "#swiftui", "#ui"].shuffled().prefix(2).map { $0 },
|
hashtags: ["#тест", "#видео", "#swiftui", "#ui"].shuffled().prefix(2).map { $0 },
|
||||||
location: Bool.random() ? "Москва" : nil,
|
location: Bool.random() ? "Москва" : nil,
|
||||||
languageCode: Bool.random() ? ["ru", "en"] : ["ru"],
|
languageCode: Bool.random() ? ["ru", "en"] : ["ru"],
|
||||||
|
|||||||
@ -2,75 +2,96 @@ import SwiftUI
|
|||||||
|
|
||||||
struct PostDetailView: View {
|
struct PostDetailView: View {
|
||||||
let postID: UUID
|
let postID: UUID
|
||||||
@Environment(\.presentationMode) var presentationMode
|
@State private var post: Post?
|
||||||
@State private var post: Post? = nil
|
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
ZStack {
|
VStack(alignment: .leading, spacing: 0) {
|
||||||
if let post = post {
|
if let post = post {
|
||||||
Color.black.ignoresSafeArea()
|
// Шапка поста
|
||||||
|
HStack {
|
||||||
VStack {
|
Image(systemName: "person.crop.circle.fill")
|
||||||
|
.resizable()
|
||||||
|
.frame(width: 36, height: 36)
|
||||||
|
.foregroundColor(.gray)
|
||||||
|
Text(post.authorUsername)
|
||||||
|
.font(.headline)
|
||||||
Spacer()
|
Spacer()
|
||||||
|
Button(action: {}) {
|
||||||
VStack(alignment: .leading, spacing: 8) {
|
Image(systemName: "ellipsis")
|
||||||
if let title = post.title {
|
.foregroundColor(.primary)
|
||||||
Text(title)
|
|
||||||
.font(.title2)
|
|
||||||
.fontWeight(.bold)
|
|
||||||
.foregroundColor(.white)
|
|
||||||
}
|
|
||||||
|
|
||||||
if let desc = post.description {
|
|
||||||
Text(desc)
|
|
||||||
.font(.subheadline)
|
|
||||||
.foregroundColor(Color.white.opacity(0.8))
|
|
||||||
}
|
|
||||||
|
|
||||||
Text("UUID: \(post.id.uuidString)")
|
|
||||||
.font(.caption2)
|
|
||||||
.foregroundColor(Color.white.opacity(0.5))
|
|
||||||
|
|
||||||
HStack(spacing: 12) {
|
|
||||||
Label("\(post.views)", systemImage: "eye")
|
|
||||||
Label("\(post.likes)", systemImage: "heart")
|
|
||||||
Label("\(post.saves)", systemImage: "bookmark")
|
|
||||||
Label("\(post.commentsCount)", systemImage: "text.bubble")
|
|
||||||
}
|
|
||||||
.font(.footnote)
|
|
||||||
.foregroundColor(Color.white.opacity(0.9))
|
|
||||||
}
|
}
|
||||||
.padding()
|
|
||||||
.background(Color.black.opacity(0.4))
|
|
||||||
.cornerRadius(12)
|
|
||||||
.padding(.horizontal)
|
|
||||||
.padding(.bottom, 32)
|
|
||||||
}
|
}
|
||||||
|
.padding(.horizontal)
|
||||||
|
.padding(.vertical, 8)
|
||||||
|
|
||||||
VStack {
|
// Изображение поста
|
||||||
HStack {
|
Rectangle()
|
||||||
Spacer()
|
.fill(Color.gray.opacity(0.3))
|
||||||
Button(action: {
|
.aspectRatio(1, contentMode: .fit)
|
||||||
presentationMode.wrappedValue.dismiss()
|
.frame(maxWidth: .infinity)
|
||||||
}) {
|
|
||||||
Image(systemName: "xmark.circle.fill")
|
// Панель действий
|
||||||
.font(.system(size: 30))
|
HStack(spacing: 16) {
|
||||||
.foregroundColor(.white)
|
Button(action: {}) {
|
||||||
.padding()
|
Image(systemName: "heart")
|
||||||
}
|
.font(.system(size: 24))
|
||||||
|
}
|
||||||
|
Button(action: {}) {
|
||||||
|
Image(systemName: "message")
|
||||||
|
.font(.system(size: 24))
|
||||||
|
}
|
||||||
|
Button(action: {}) {
|
||||||
|
Image(systemName: "paperplane")
|
||||||
|
.font(.system(size: 24))
|
||||||
}
|
}
|
||||||
Spacer()
|
Spacer()
|
||||||
|
Button(action: {}) {
|
||||||
|
Image(systemName: "bookmark")
|
||||||
|
.font(.system(size: 24))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
.foregroundColor(.primary)
|
||||||
|
.padding(.horizontal)
|
||||||
|
.padding(.top, 8)
|
||||||
|
|
||||||
|
// Лайки и описание
|
||||||
|
VStack(alignment: .leading, spacing: 4) {
|
||||||
|
Text("\(post.likes) likes")
|
||||||
|
.font(.headline)
|
||||||
|
|
||||||
|
Text(post.description ?? "")
|
||||||
|
.font(.subheadline)
|
||||||
|
}
|
||||||
|
.padding(.horizontal)
|
||||||
|
.padding(.top, 8)
|
||||||
|
|
||||||
|
// Комментарии
|
||||||
|
VStack(alignment: .leading, spacing: 4) {
|
||||||
|
Text("View all \(post.commentsCount) comments")
|
||||||
|
.font(.caption)
|
||||||
|
.foregroundColor(.secondary)
|
||||||
|
.padding(.top, 4)
|
||||||
|
|
||||||
|
Text("2 hours ago")
|
||||||
|
.font(.caption2)
|
||||||
|
.foregroundColor(.secondary)
|
||||||
|
.padding(.top, 4)
|
||||||
|
}
|
||||||
|
.padding(.horizontal)
|
||||||
|
|
||||||
|
Spacer()
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
ProgressView("Загрузка поста…")
|
ProgressView("Загрузка...")
|
||||||
.progressViewStyle(CircularProgressViewStyle(tint: .white))
|
|
||||||
.foregroundColor(.white)
|
|
||||||
.onAppear {
|
.onAppear {
|
||||||
PostService.shared.fetchPost(by: postID) { result in
|
// Симуляция загрузки поста
|
||||||
self.post = result
|
PostService.shared.fetchPost(by: postID) { fetchedPost in
|
||||||
|
self.post = fetchedPost
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.navigationBarTitleDisplayMode(.inline)
|
||||||
|
.navigationTitle("Post")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,20 +8,10 @@ struct ProfileContentGrid: View {
|
|||||||
let selectedCategory: String
|
let selectedCategory: String
|
||||||
let allPosts: [Post]
|
let allPosts: [Post]
|
||||||
let isLoading: Bool
|
let isLoading: Bool
|
||||||
@State private var selectedPostID: PostIDWrapper? = nil
|
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack(alignment: .leading, spacing: 0) {
|
VStack(alignment: .leading, spacing: 0) {
|
||||||
if isLoading {
|
if isLoading {
|
||||||
// LazyVGrid(columns: Array(repeating: .init(.flexible()), count: 3), spacing: 2) {
|
|
||||||
// ForEach(0..<100, id: \.self) { _ in
|
|
||||||
// RoundedRectangle(cornerRadius: 4)
|
|
||||||
// .fill(Color.gray.opacity(0.15))
|
|
||||||
// .aspectRatio(1, contentMode: .fit)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// .padding(.horizontal)
|
|
||||||
// .redacted(reason: .placeholder) // ⬅️ делает «размытый» стиль
|
|
||||||
VStack {
|
VStack {
|
||||||
ProgressView("Загрузка...")
|
ProgressView("Загрузка...")
|
||||||
.padding()
|
.padding()
|
||||||
@ -38,9 +28,7 @@ struct ProfileContentGrid: View {
|
|||||||
} else {
|
} else {
|
||||||
LazyVGrid(columns: Array(repeating: .init(.flexible()), count: 3), spacing: 2) {
|
LazyVGrid(columns: Array(repeating: .init(.flexible()), count: 3), spacing: 2) {
|
||||||
ForEach(filteredPosts) { post in
|
ForEach(filteredPosts) { post in
|
||||||
Button {
|
NavigationLink(destination: PostDetailView(postID: post.id)) {
|
||||||
selectedPostID = PostIDWrapper(id: post.id)
|
|
||||||
} label: {
|
|
||||||
Rectangle()
|
Rectangle()
|
||||||
.fill(Color.gray.opacity(0.2))
|
.fill(Color.gray.opacity(0.2))
|
||||||
.aspectRatio(1, contentMode: .fit)
|
.aspectRatio(1, contentMode: .fit)
|
||||||
@ -87,9 +75,6 @@ struct ProfileContentGrid: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.frame(maxWidth: .infinity, alignment: .topLeading)
|
.frame(maxWidth: .infinity, alignment: .topLeading)
|
||||||
.fullScreenCover(item: $selectedPostID) { wrapper in
|
|
||||||
PostDetailView(postID: wrapper.id)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private var filteredPosts: [Post] {
|
private var filteredPosts: [Post] {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user