Skip to content

Commit

Permalink
Merge pull request #41 from Ruang-Opini/039-release
Browse files Browse the repository at this point in the history
039 release
  • Loading branch information
derysudrajat authored Jun 9, 2021
2 parents ea616f3 + 5a04aca commit 330799e
Show file tree
Hide file tree
Showing 19 changed files with 219 additions and 66 deletions.
12 changes: 6 additions & 6 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ plugins {

ext.majorVersion = 0
ext.minorVersion = 3
ext.patchVersion = 4
ext.preRelease = "beta"
ext.patchVersion = 9
ext.preRelease = ""
ext.minSdkVersion = 21

android {
Expand Down Expand Up @@ -77,9 +77,9 @@ dependencies {
implementation 'androidx.appcompat:appcompat:1.3.0'
implementation 'com.google.android.material:material:1.3.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'androidx.recyclerview:recyclerview:1.2.0'
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.0'
implementation 'androidx.navigation:navigation-ui-ktx:2.3.0'
implementation 'androidx.recyclerview:recyclerview:1.2.1'
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.5'
implementation 'androidx.navigation:navigation-ui-ktx:2.3.5'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
Expand All @@ -94,7 +94,7 @@ dependencies {
implementation 'com.google.android.gms:play-services-auth:19.0.0'

// coil
implementation 'io.coil-kt:coil:1.2.1'
implementation 'io.coil-kt:coil:1.2.2'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'

// ktx artifact
Expand Down
Binary file modified app/release/app-release.apk
Binary file not shown.
4 changes: 2 additions & 2 deletions app/release/output-metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
{
"type": "SINGLE",
"filters": [],
"versionCode": 210000304,
"versionName": "0.3.4-beta",
"versionCode": 210000309,
"versionName": "0.3.9",
"outputFile": "app-release.apk"
}
]
Expand Down
12 changes: 6 additions & 6 deletions app/src/main/java/id/ruangopini/data/model/Analytics.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,17 @@ data class CategoryAnalytics(
)

data class DiscussionAnalytics(
val join: Int? = 0,
val comment: Int? = 0,
val post: Int? = 0,
var join: Int? = 0,
var comment: Int? = 0,
var post: Int? = 0,
@DocumentId
val discussionId: String? = null
)

data class PostAnalytics(
val voteUp: Int? = 0,
val voteDown: Int? = 0,
val comment: Int? = 0,
var voteUp: Int? = 0,
var voteDown: Int? = 0,
var comment: Int? = 0,
@DocumentId
val postId: String? = null,
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package id.ruangopini.data.repo.remote.firebase.firestore.analytics

import id.ruangopini.data.model.CategoryAnalytics
import id.ruangopini.data.model.DiscussionAnalytics
import id.ruangopini.data.repo.State
import kotlinx.coroutines.flow.Flow

Expand All @@ -14,6 +15,8 @@ interface FirestoreAnalyticsDataStore {
fun updateCommentDiscussion(discussionId: String): Flow<State<Boolean>>
fun updatePostDiscussion(discussionId: String): Flow<State<Boolean>>

fun getPopularDiscussion(): Flow<State<List<DiscussionAnalytics>>>

fun updateCommentPost(postId: String): Flow<State<Boolean>>
fun updateVoteUpPost(postId: String, vote: Int): Flow<State<Boolean>>
fun updateVoteDownPost(postId: String, vote: Int): Flow<State<Boolean>>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,38 @@ class FirestoreAnalyticsRepository : FirestoreAnalyticsDataStore {
}
}.flowOn(Dispatchers.IO)

override fun getPopularDiscussion() = callbackFlow<State<List<DiscussionAnalytics>>> {
trySend(State.loading()).isSuccess
instance.whereLessThan("createdAt", Timestamp.now())
.whereGreaterThan("createdAt", Helpers.getSevenDayAgo())
.addSnapshotListener { value, error ->
if (error != null) {
trySend(State.failed(error.message ?: "")).isSuccess
close(error)
return@addSnapshotListener
}
if (value != null && !value.isEmpty) value.toObjects(Analytics::class.java)
.forEach { data ->
instance.document(data.time ?: "").collection(COLLECTION.DISCUSSION)
.addSnapshotListener { result, error ->
if (error != null) {
trySend(State.failed(error.message ?: "")).isSuccess
close(error)
}

val discussion = if (result != null && !result.isEmpty)
result.toObjects(DiscussionAnalytics::class.java)
else emptyList()

trySend(State.success(discussion)).isSuccess
}
}
}
awaitClose()
}.catch {
emit(State.failed(it.message ?: ""))
}.flowOn(Dispatchers.IO)

override fun updateJoinDiscussion(discussionId: String, isJoin: Boolean) =
flow<State<Boolean>> {
emit(State.loading())
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package id.ruangopini.data.repo.remote.firebase.firestore.comment

import com.google.firebase.firestore.Query
import com.google.firebase.firestore.ktx.firestore
import com.google.firebase.ktx.Firebase
import id.ruangopini.data.model.Comment
Expand Down Expand Up @@ -30,23 +31,27 @@ class FirestoreCommentRepository : FirestoreCommentDataSource {

override fun loadComment(postId: String) = callbackFlow<State<List<Comment>>> {
trySend(State.loading()).isSuccess
instance.whereEqualTo("postId", postId).addSnapshotListener { value, error ->
if (error != null) trySend(State.failed(error.message ?: "")).isSuccess
if (value != null && !value.isEmpty) trySend(State.success(value.toObjects(Comment::class.java))).isSuccess
else trySend(State.success(emptyList())).isSuccess
}
instance.whereEqualTo("postId", postId)
.orderBy("createdAt", Query.Direction.DESCENDING)
.addSnapshotListener { value, error ->
if (error != null) trySend(State.failed(error.message ?: "")).isSuccess
if (value != null && !value.isEmpty) trySend(State.success(value.toObjects(Comment::class.java))).isSuccess
else trySend(State.success(emptyList())).isSuccess
}
awaitClose()
}.catch {
emit(State.failed(it.message ?: ""))
}.flowOn(Dispatchers.IO)

override fun getCommentByUserId(userId: String) = callbackFlow<State<List<Comment>>> {
trySend(State.loading()).isSuccess
instance.whereEqualTo("userId", userId).addSnapshotListener { value, error ->
if (error != null) trySend(State.failed(error.message ?: "")).isSuccess
if (value != null && !value.isEmpty) trySend(State.success(value.toObjects(Comment::class.java))).isSuccess
else trySend(State.success(emptyList())).isSuccess
}
instance.whereEqualTo("userId", userId)
.orderBy("createdAt", Query.Direction.DESCENDING)
.addSnapshotListener { value, error ->
if (error != null) trySend(State.failed(error.message ?: "")).isSuccess
if (value != null && !value.isEmpty) trySend(State.success(value.toObjects(Comment::class.java))).isSuccess
else trySend(State.success(emptyList())).isSuccess
}
awaitClose()
}.catch {
emit(State.failed(it.message ?: ""))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ import kotlinx.coroutines.flow.Flow

interface FirestoreDiscussionDataSource {
fun getLatestDiscussionRoom(): Flow<State<List<Discussion>>>

// TODO: 5/26/2021 get trending discussion
fun createNewDiscussion(discussion: Discussion): Flow<State<Boolean>>
fun joinDiscussion(discussionId: String, userId: String): Flow<State<Boolean>>
fun leaveDiscussion(discussionId: String, userId: String): Flow<State<Boolean>>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,4 @@ class FirestoreDiscussionRepository : FirestoreDiscussionDataSource {
}.catch {
emit(State.failed(it.message ?: ""))
}.flowOn(Dispatchers.IO)

// TODO: 5/26/2021 get trending discussion
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package id.ruangopini.data.repo.remote.firebase.firestore.post

import com.google.firebase.firestore.FieldValue
import com.google.firebase.firestore.Query
import com.google.firebase.firestore.ktx.firestore
import com.google.firebase.ktx.Firebase
import id.ruangopini.data.model.Post
Expand Down Expand Up @@ -31,23 +32,27 @@ class FirestorePostRepository : FirestorePostDataSource {

override fun getPostByDiscussionId(discussionId: String) = callbackFlow<State<List<Post>>> {
trySend(State.loading()).isSuccess
instance.whereEqualTo("discussionId", discussionId).addSnapshotListener { value, error ->
if (error != null) trySend(State.failed(error.message ?: "")).isSuccess
if (value != null && !value.isEmpty) trySend(State.success(value.toObjects(Post::class.java))).isSuccess
else trySend(State.success(emptyList())).isSuccess
}
instance.whereEqualTo("discussionId", discussionId)
.orderBy("createdAt", Query.Direction.DESCENDING)
.addSnapshotListener { value, error ->
if (error != null) trySend(State.failed(error.message ?: "")).isSuccess
if (value != null && !value.isEmpty) trySend(State.success(value.toObjects(Post::class.java))).isSuccess
else trySend(State.success(emptyList())).isSuccess
}
awaitClose()
}.catch {
emit(State.failed(it.message ?: ""))
}.flowOn(Dispatchers.IO)

override fun getPostByUserId(userId: String) = callbackFlow<State<List<Post>>> {
trySend(State.loading()).isSuccess
instance.whereEqualTo("userId", userId).addSnapshotListener { value, error ->
if (error != null) trySend(State.failed(error.message ?: "")).isSuccess
if (value != null && !value.isEmpty) trySend(State.success(value.toObjects(Post::class.java))).isSuccess
else trySend(State.success(emptyList())).isSuccess
}
instance.whereEqualTo("userId", userId)
.orderBy("createdAt", Query.Direction.DESCENDING)
.addSnapshotListener { value, error ->
if (error != null) trySend(State.failed(error.message ?: "")).isSuccess
if (value != null && !value.isEmpty) trySend(State.success(value.toObjects(Post::class.java))).isSuccess
else trySend(State.success(emptyList())).isSuccess
}
awaitClose()
}.catch {
emit(State.failed(it.message ?: ""))
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/java/id/ruangopini/di/AppModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ val useCaseModule = module {

val viewModelModule = module {
viewModel { ReferenceViewModel(get()) }
viewModel { DiscussionViewModel(get()) }
viewModel { DiscussionViewModel(get(), get()) }
viewModel { CreateAccountViewModel(get(), get()) }
viewModel { UploadPhotoViewModel(get(), get()) }
viewModel { DetailPolicyViewModel(get()) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,14 @@ class ContentDiscussionFragment : Fragment() {
arguments?.getInt(POS_ARG, 1).let {
binding.swipeRefresh.apply {
setOnRefreshListener {
if (it == 1) {
// TODO: 5/26/2021 change to getTrendingDiscussion
model.getLatestDiscussion(requireContext())
} else model.getLatestDiscussion(requireContext())
if (it == 1) model.getPopularDiscussion()
else model.getLatestDiscussion(requireContext())
isRefreshing = false
}
}
if (it == 1) {
// TODO: 5/26/2021 change to getTrendingDiscussion
model.getLatestDiscussion(requireContext())
} else model.getLatestDiscussion(requireContext())

if (it == 1) model.getPopularDiscussion()
else model.getLatestDiscussion(requireContext())
}

model.discussion.observe(viewLifecycleOwner, {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,25 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.google.firebase.firestore.ktx.firestore
import com.google.firebase.ktx.Firebase
import id.ruangopini.data.model.Discussion
import id.ruangopini.data.model.DiscussionAnalytics
import id.ruangopini.data.repo.State
import id.ruangopini.data.repo.remote.firebase.firestore.analytics.FirestoreAnalyticsRepository
import id.ruangopini.data.repo.remote.firebase.firestore.discussion.FirestoreDiscussionRepository
import id.ruangopini.utils.COLLECTION
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch

class DiscussionViewModel(
private val repo: FirestoreDiscussionRepository
private val repo: FirestoreDiscussionRepository,
private val analyticsRepository: FirestoreAnalyticsRepository
) : ViewModel() {

private val currentDiscussion = mutableListOf<Discussion>()
private val currentDiscussionAnalytics = mutableListOf<DiscussionAnalytics>()
private val _discussion = MutableLiveData<List<Discussion>>()
val discussion: LiveData<List<Discussion>> get() = _discussion

Expand All @@ -40,6 +48,66 @@ class DiscussionViewModel(
}
}

fun getPopularDiscussion() = viewModelScope.launch {
currentDiscussion.clear()
analyticsRepository.getPopularDiscussion().collect {
when (it) {
is State.Loading -> _isLoading.value = true
is State.Success -> {
addDataPopular(it.data)
}
is State.Failed -> {
_isLoading.value = false
Log.d("TAG", "getPopularDiscussion: failed = ${it.message}")
}
}
}
}

private fun addDataPopular(data: List<DiscussionAnalytics>) {
data.forEach { discussion ->
val existingData =
currentDiscussionAnalytics.find { it.discussionId == discussion.discussionId }
val isExist = existingData != null
if (isExist) {
currentDiscussionAnalytics[currentDiscussionAnalytics.indexOf(existingData)].apply {
this.comment = this.comment?.plus(discussion.comment ?: 0)
this.join = this.join?.plus(discussion.join ?: 0)
this.post = this.post?.plus(discussion.post ?: 0)
}
} else currentDiscussionAnalytics.add(discussion)
}

val sorted = currentDiscussionAnalytics.sortedByDescending {
it.comment?.plus(it.post ?: 0)?.plus(it.join ?: 0)
}
getDiscussionById(sorted)
}

private fun getDiscussionById(discussion: List<DiscussionAnalytics>) = viewModelScope.launch {
currentDiscussion.clear()
discussion.forEach { discus ->
Firebase.firestore.collection(COLLECTION.DISCUSSION)
.document(discus.discussionId ?: "")
.get().addOnCompleteListener {
it.result?.toObject(Discussion::class.java)?.let { data ->
addDataPopularDiscussion(data, discussion)
}
}
}
}

private fun addDataPopularDiscussion(data: Discussion, discussion: List<DiscussionAnalytics>) {
val isExist = currentDiscussion.find { it.discussionId == data.discussionId } != null
if (!isExist) {
currentDiscussion.add(data)
val orderById = discussion.withIndex().associate { it.value.discussionId to it.index }
val sortedDiscussion = currentDiscussion.sortedBy { orderById[it.discussionId] }
_isLoading.value = false
_discussion.value = sortedDiscussion
}
}

@ExperimentalCoroutinesApi
fun getDiscussionByIssueName(issueName: String) = viewModelScope.launch {
repo.getDiscussionByIssueName(issueName).collect {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,14 @@ class DetailDiscussionRoomActivity : AppCompatActivity() {
private inner class SectionPagerAdapter(
fa: FragmentActivity
) : FragmentStateAdapter(fa) {
override fun getItemCount(): Int = 2
override fun createFragment(position: Int): Fragment = PostFragment.newInstance(
PostFragment.Companion.GetPost.DISCUSSION_ID_NEW, currentDiscussionId
val pageType = listOf(
PostFragment.Companion.GetPost.DISCUSSION_POPULAR,
PostFragment.Companion.GetPost.DISCUSSION_ID_NEW
)

override fun getItemCount(): Int = 2
override fun createFragment(position: Int): Fragment =
PostFragment.newInstance(pageType[position], currentDiscussionId)
}

override fun onOptionsItemSelected(item: MenuItem): Boolean {
Expand Down
Loading

0 comments on commit 330799e

Please sign in to comment.