Skip to content

Commit

Permalink
Merge pull request #8 from groupeminaste/fix/pagination-and-post-details
Browse files Browse the repository at this point in the history
Pagination fixes + post details
  • Loading branch information
nathanfallet committed Jan 14, 2024
2 parents 9d69a45 + 5033fbb commit 1e8ef56
Show file tree
Hide file tree
Showing 28 changed files with 494 additions and 99 deletions.
8 changes: 4 additions & 4 deletions android/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -60,18 +60,18 @@ dependencies {
implementation("androidx.compose.material3:material3:1.1.2")
implementation("androidx.compose.runtime:runtime-livedata:1.5.4")

implementation("io.insert-koin:koin-core:3.5.0")
implementation("io.insert-koin:koin-android:3.5.0")
implementation("io.insert-koin:koin-core:3.5.3")
implementation("io.insert-koin:koin-android:3.5.3")
implementation("io.insert-koin:koin-androidx-compose:3.5.0")

implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.6.2")
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.7.0")
implementation("androidx.activity:activity-compose:1.8.2")
implementation("androidx.navigation:navigation-compose:2.7.6")
implementation("androidx.datastore:datastore-preferences:1.0.0")

implementation("com.google.android.material:material:1.11.0")
implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.5.0")
implementation("io.coil-kt:coil-compose:2.2.2")
implementation("io.coil-kt:coil-compose:2.4.0")
implementation("com.github.JamalMulla:ComposePrefs:1.0.6")

coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.0.4")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package me.nathanfallet.extopy.features.posts

import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.rickclephas.kmm.viewmodel.coroutineScope
import kotlinx.coroutines.launch
import me.nathanfallet.extopy.R
import me.nathanfallet.extopy.models.users.User
import me.nathanfallet.extopy.ui.components.posts.PostCard
import me.nathanfallet.extopy.viewmodels.posts.PostViewModel
import org.koin.androidx.compose.koinViewModel
import org.koin.core.parameter.parametersOf

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun PostView(
id: String,
viewedBy: User,
navigate: (String) -> Unit,
modifier: Modifier = Modifier,
) {

val viewModel = koinViewModel<PostViewModel>(
parameters = { parametersOf(id) }
)

LaunchedEffect(id) {
viewModel.fetchPost()
}

val post by viewModel.post.collectAsState()
val posts by viewModel.posts.collectAsState()

LazyColumn(
modifier
) {
item {
TopAppBar(
title = {
Text(stringResource(R.string.timeline_post_title))
},
)
}
item {
Spacer(modifier = Modifier.height(12.dp))
}
item {
post?.let {
PostCard(
post = it,
navigate = navigate,
onLikeClicked = { post ->
viewModel.viewModelScope.coroutineScope.launch {
viewModel.onLikeClicked(post)
}
},
onRepostClicked = { post ->
navigate.invoke("timeline/compose?repostOfId=${post.id}")
},
onReplyClicked = { post ->
navigate.invoke("timeline/compose?repliedToId=${post.id}")
}
)
}
}
items(posts ?: listOf()) {
PostCard(
post = it,
navigate = navigate,
onLikeClicked = { post ->
viewModel.viewModelScope.coroutineScope.launch {
viewModel.onLikeClicked(post)
}
},
onRepostClicked = { post ->
navigate.invoke("timeline/compose?repostOfId=${post.id}")
},
onReplyClicked = { post ->
navigate.invoke("timeline/compose?repliedToId=${post.id}")
}
)
viewModel.loadMoreIfNeeded(it.id)
}
item {
Spacer(modifier = Modifier.height(12.dp))
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import kotlinx.coroutines.launch
import me.nathanfallet.extopy.R
import me.nathanfallet.extopy.features.auth.AuthView
import me.nathanfallet.extopy.features.notifications.NotificationsView
import me.nathanfallet.extopy.features.posts.PostView
import me.nathanfallet.extopy.features.settings.SettingsView
import me.nathanfallet.extopy.features.timelines.TimelineComposeView
import me.nathanfallet.extopy.features.timelines.TimelineView
Expand Down Expand Up @@ -148,6 +149,14 @@ fun TabNavigation(
modifier = Modifier.padding(padding)
)
}
composable("timeline/post/{id}") { backStackEntry ->
PostView(
id = backStackEntry.arguments?.getString("id")!!,
viewedBy = viewedBy,
navigate = navController::navigate,
modifier = Modifier.padding(padding)
)
}
composable("direct_message") {

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ fun TimelineView(
}

val timeline by viewModel.timeline.collectAsState()
val users by viewModel.users.collectAsState()
val posts by viewModel.posts.collectAsState()
val search by viewModel.search.collectAsState()

LazyColumn(
Expand Down Expand Up @@ -116,7 +118,7 @@ fun TimelineView(
item {
Spacer(modifier = Modifier.height(12.dp))
}
items(timeline?.users ?: listOf()) {
items(users ?: listOf()) {
UserCard(
user = it,
viewedBy = viewedBy,
Expand Down Expand Up @@ -146,7 +148,7 @@ fun TimelineView(
}
)
}
items(timeline?.posts ?: listOf()) {
items(posts ?: listOf()) {
PostCard(
post = it,
navigate = navigate,
Expand All @@ -162,7 +164,7 @@ fun TimelineView(
navigate.invoke("timeline/compose?repliedToId=${post.id}")
}
)
// TODO: Load more
viewModel.loadMoreIfNeeded(it.id)
}
item {
Spacer(modifier = Modifier.height(12.dp))
Expand Down
20 changes: 16 additions & 4 deletions ios/Extopy.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
6AE16935292A632700137822 /* NotificationsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6AE16931292A62C600137822 /* NotificationsView.swift */; };
6AE16939292A768000137822 /* NumbersExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6AE16937292A768000137822 /* NumbersExtension.swift */; };
6AE50DC92B3F22FE00E1AC2B /* PostCounterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6AE50DC82B3F22FE00E1AC2B /* PostCounterView.swift */; };
6AFD935F2B5428D900ED8EB5 /* PostView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6AFD935E2B5428D900ED8EB5 /* PostView.swift */; };
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
Expand Down Expand Up @@ -86,6 +87,7 @@
6AE16931292A62C600137822 /* NotificationsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationsView.swift; sourceTree = "<group>"; };
6AE16937292A768000137822 /* NumbersExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NumbersExtension.swift; sourceTree = "<group>"; };
6AE50DC82B3F22FE00E1AC2B /* PostCounterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostCounterView.swift; sourceTree = "<group>"; };
6AFD935E2B5428D900ED8EB5 /* PostView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostView.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -134,16 +136,17 @@
isa = PBXGroup;
children = (
6AB01AE22B360595001AF7FF /* Auth */,
6AE16930292A629B00137822 /* Notifications */,
6AFD935D2B5428A400ED8EB5 /* Posts */,
6A1A52D22927FA6900D38779 /* Root */,
6A49D8D6291C3E5700C19937 /* Settings */,
6AE16930292A629B00137822 /* Notifications */,
6A49D8D1291C3DAC00C19937 /* Timeline */,
6A49D8D1291C3DAC00C19937 /* Timelines */,
6A3AAA422B5308A00096C48C /* Users */,
);
path = Features;
sourceTree = "<group>";
};
6A49D8D1291C3DAC00C19937 /* Timeline */ = {
6A49D8D1291C3DAC00C19937 /* Timelines */ = {
isa = PBXGroup;
children = (
6A49D8D2291C3DB900C19937 /* TimelineView.swift */,
Expand All @@ -152,7 +155,7 @@
6A0F580F292A958C00A7B1F5 /* TimelineUserEditViewModel.swift */,
6A996E58291EB51300F36B8C /* TimelineSheet.swift */,
);
path = Timeline;
path = Timelines;
sourceTree = "<group>";
};
6A49D8D6291C3E5700C19937 /* Settings */ = {
Expand Down Expand Up @@ -260,6 +263,14 @@
path = Notifications;
sourceTree = "<group>";
};
6AFD935D2B5428A400ED8EB5 /* Posts */ = {
isa = PBXGroup;
children = (
6AFD935E2B5428D900ED8EB5 /* PostView.swift */,
);
path = Posts;
sourceTree = "<group>";
};
7555FF72242A565900829871 = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -429,6 +440,7 @@
6AE50DC92B3F22FE00E1AC2B /* PostCounterView.swift in Sources */,
6A3F2E4829215607006D64A7 /* PostCard.swift in Sources */,
6A3AAA3F2B52F8330096C48C /* UserCounterView.swift in Sources */,
6AFD935F2B5428D900ED8EB5 /* PostView.swift in Sources */,
6A3F2E4D29215607006D64A7 /* TimelineSheet.swift in Sources */,
6A3F2E5C29215607006D64A7 /* SafariView.swift in Sources */,
6A442CEA29294710009E10AE /* UserCard.swift in Sources */,
Expand Down
81 changes: 81 additions & 0 deletions ios/Extopy/Features/Posts/PostView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
//
// PostView.swift
// Extopy
//
// Created by Nathan Fallet on 14/01/2024.
// Copyright © 2024 orgName. All rights reserved.
//

import shared
import SwiftUI
import Kingfisher
import KMMViewModelSwiftUI
import KMPNativeCoroutinesAsync

struct PostView: View {

@StateViewModel var viewModel: PostViewModel

let viewedBy: Extopy_commonsUser

var body: some View {
ZStack {
ScrollView {
LazyVStack(spacing: 8) {
if let post = viewModel.post {
NavigationLink(destination: PostView(
viewModel: KoinApplication.shared.koin.postViewModel(id: post.id),
viewedBy: viewedBy
)) {
PostCard(
post: post,
viewedBy: viewedBy,
onLikeClicked: { post in
Task {
try await asyncFunction(for: viewModel.onLikeClicked(post: post))
}
},
onRepostClicked: { _ in },
onReplyClicked: { _ in }
)
}
}
ForEach(viewModel.posts ?? [], id: \.namespacedId) { post in
NavigationLink(destination: PostView(
viewModel: KoinApplication.shared.koin.postViewModel(id: post.id),
viewedBy: viewedBy
)) {
PostCard(
post: post,
viewedBy: viewedBy,
onLikeClicked: { post in
Task {
try await asyncFunction(for: viewModel.onLikeClicked(post: post))
}
},
onRepostClicked: { _ in },
onReplyClicked: { _ in }
)
.onAppear {
viewModel.loadMoreIfNeeded(postId: post.id)
}
}
}
}
.padding()
}
}
.navigationTitle("timeline_post_title")
.refreshable {
Task {
try await asyncFunction(for: viewModel.fetchPost())
}
}
.onAppear {
Task {
try await asyncFunction(for: viewModel.fetchPost())
}
}
}

}
Loading

0 comments on commit 1e8ef56

Please sign in to comment.