Compare commits

...
This repository has been archived on 2025-11-05. You can view files and clone it, but cannot push or open issues or pull requests.

1 Commits

Author SHA1 Message Date
cheykrym
6d5b32602b aboba 2025-08-14 02:09:38 +03:00
5 changed files with 142 additions and 37 deletions

View File

@ -132,9 +132,16 @@ class PostService {
} }
} }
func fetchAllPosts(completion: @escaping ([Post]) -> Void) { func fetchAllPosts(page: Int, limit: Int, completion: @escaping ([Post]) -> Void) {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
completion(self.posts) let start = page * limit
let end = min(start + limit, self.posts.count)
if start < end {
completion(Array(self.posts[start..<end]))
} else {
completion([])
}
} }
} }

View File

@ -5,26 +5,70 @@ class NewHomeTabViewModel: ObservableObject {
@Published var posts: [Post] = [] @Published var posts: [Post] = []
@Published var isLoading = true @Published var isLoading = true
@Published var isRefreshing = false @Published var isRefreshing = false
@Published var isLoadingPage = false
@Published var canLoadMorePages = true
private var currentPage = 0
private let postsPerPage = 10
private var hasLoadedData = false
func fetchDataIfNeeded() { func fetchDataIfNeeded() {
guard !hasLoadedData else { return } guard posts.isEmpty else { return }
refreshData() fetchPosts()
} }
func refreshData() { func refreshData() {
DispatchQueue.main.async { guard !isRefreshing else { return }
self.isRefreshing = true
isRefreshing = true
currentPage = 0
canLoadMorePages = true
fetchPosts(isRefresh: true)
}
func loadMoreContentIfNeeded(currentItem item: Post?) {
guard let item = item else {
fetchPosts()
return
} }
PostService.shared.fetchAllPosts { [weak self] fetchedPosts in let thresholdIndex = posts.index(posts.endIndex, offsetBy: -5)
if posts.firstIndex(where: { $0.id == item.id }) == thresholdIndex {
fetchPosts()
}
}
private func fetchPosts(isRefresh: Bool = false) {
guard !isLoadingPage, canLoadMorePages else {
if isRefresh {
DispatchQueue.main.async {
self.isRefreshing = false
}
}
return
}
isLoadingPage = true
if isRefresh {
currentPage = 0
} else {
currentPage += 1
}
PostService.shared.fetchAllPosts(page: currentPage, limit: postsPerPage) { [weak self] fetchedPosts in
guard let self = self else { return } guard let self = self else { return }
DispatchQueue.main.async { DispatchQueue.main.async {
self.posts = fetchedPosts if isRefresh {
self.posts = fetchedPosts
} else {
self.posts.append(contentsOf: fetchedPosts)
}
self.canLoadMorePages = !fetchedPosts.isEmpty
self.isLoading = false self.isLoading = false
self.hasLoadedData = true self.isLoadingPage = false
self.isRefreshing = false self.isRefreshing = false
} }
} }

View File

@ -32,6 +32,25 @@ struct HomeTab: View {
} }
} }
// private func fetchData(isInitialLoad: Bool = false) {
// if isInitialLoad {
// isLoading = true
// } else {
// isRefreshing = true
// }
//
// PostService.shared.fetchAllPosts { fetchedPosts in
// self.posts = fetchedPosts
//
// if isInitialLoad {
// print("content updated")
// self.isLoading = false
// }
// self.isRefreshing = false
// }
// }
private func fetchData(isInitialLoad: Bool = false) { private func fetchData(isInitialLoad: Bool = false) {
if isInitialLoad { if isInitialLoad {
isLoading = true isLoading = true
@ -39,14 +58,13 @@ struct HomeTab: View {
isRefreshing = true isRefreshing = true
} }
PostService.shared.fetchAllPosts { fetchedPosts in // Временный код вместо PostService
self.posts = fetchedPosts self.posts = [] // или сюда можно подставить мок-данные
if isInitialLoad { // Сбрасываем индикаторы загрузки
print("content updated") if isInitialLoad {
self.isLoading = false self.isLoading = false
}
self.isRefreshing = false
} }
self.isRefreshing = false
} }
} }

View File

@ -19,19 +19,37 @@ struct NewHomeTab: View {
RefreshableScrollView(isRefreshing: $viewModel.isRefreshing, onRefresh: { RefreshableScrollView(isRefreshing: $viewModel.isRefreshing, onRefresh: {
viewModel.refreshData() viewModel.refreshData()
}) { }) {
HStack(alignment: .top, spacing: 6) { VStack {
LazyVStack(spacing: 6) { HStack(alignment: .top, spacing: 6) {
ForEach(column1Posts) { post in LazyVStack(spacing: 6) {
PostGridItem(post: post) ForEach(column1Posts) { post in
PostGridItem(post: post)
.onAppear {
viewModel.loadMoreContentIfNeeded(currentItem: post)
}
}
}
LazyVStack(spacing: 6) {
ForEach(column2Posts) { post in
PostGridItem(post: post)
.onAppear {
viewModel.loadMoreContentIfNeeded(currentItem: post)
}
}
} }
} }
LazyVStack(spacing: 6) { .padding(.horizontal, 4)
ForEach(column2Posts) { post in
PostGridItem(post: post) if viewModel.isLoadingPage {
} ProgressView()
} else if !viewModel.canLoadMorePages {
Text(":(")
.foregroundColor(.secondary)
.padding()
} }
Spacer()
} }
.padding(.horizontal, 4)
} }
} }
} }

View File

@ -67,6 +67,7 @@ struct ProfileTab: View {
self.selectedPostData = (post, posts) self.selectedPostData = (post, posts)
} }
) )
Spacer()
} }
} }
} }
@ -79,6 +80,23 @@ struct ProfileTab: View {
} }
} }
// private func fetchData(isInitialLoad: Bool = false) {
// if isInitialLoad {
// isLoading = true
// } else {
// isRefreshing = true
// }
//
// PostService.shared.fetchAllPosts { fetchedPosts in
// self.allPosts = fetchedPosts
//
// if isInitialLoad {
// self.isLoading = false
// }
// self.isRefreshing = false
// }
// }
private func fetchData(isInitialLoad: Bool = false) { private func fetchData(isInitialLoad: Bool = false) {
if isInitialLoad { if isInitialLoad {
isLoading = true isLoading = true
@ -86,16 +104,16 @@ struct ProfileTab: View {
isRefreshing = true isRefreshing = true
} }
PostService.shared.fetchAllPosts { fetchedPosts in // Временный код вместо PostService
self.allPosts = fetchedPosts self.allPosts = [] // или сюда можно подставить мок-данные
if isInitialLoad {
self.isLoading = false
}
self.isRefreshing = false
}
}
// Сбрасываем индикаторы загрузки
if isInitialLoad {
self.isLoading = false
}
self.isRefreshing = false
}
// MARK: - Шапка профиля // MARK: - Шапка профиля
private var header: some View { private var header: some View {
VStack(spacing: 12) { VStack(spacing: 12) {