Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
22e31d6
I added the swipe to refresh view into the layout, and removed the pr…
victorvicari Jul 15, 2019
998b39d
layout reorganization
victorvicari Jul 16, 2019
a7d2d9f
renamed swipeToRefresh view.
victorvicari Jul 16, 2019
fcafff9
Merge pull request #19 from victorvicari/Add_pull_to_refresh_support_…
MostafaGazar Jul 17, 2019
b9b8ad4
First commit. Added layout components and code necessary to upvote/do…
Aug 6, 2019
d344c1c
Cleaning up some left over debugging code
Aug 6, 2019
cdbcc41
Merge branch 'master' of https://github.com/Justin-Terry/software-eng…
Aug 6, 2019
c1b4096
Making requested changes to comment voting.
Aug 10, 2019
f32e486
Making requested changes to comment voting.
Aug 10, 2019
63523ea
Formatted upVoteComment block as requested.
Aug 10, 2019
b6dccf2
Adding .stickler.yml
stickler-ci Aug 16, 2019
a202c57
Update .stickler.yml
MostafaGazar Aug 16, 2019
7935ee0
Merge pull request #32 from SoftwareEngineeringDaily/add-stickler-config
MostafaGazar Aug 16, 2019
2becafa
Making requested changes to upvote/downvote feature.
Aug 19, 2019
18e3cd0
Making requested changes to upvote/downvote feature.
Aug 19, 2019
2b48d1f
Create .stickler.yml
Justin-Terry Aug 19, 2019
ff2e9ea
Fixing Stickler error
Aug 19, 2019
c2767c9
Fixing Stickler error
Aug 19, 2019
1a867e9
Cleaning up an empty line
Aug 19, 2019
3ec81d2
Cleaning up an empty comment line
Aug 19, 2019
d36d86e
Reformat commentVoteLiveData.observe to match addCommentLiveData.observe
Aug 19, 2019
ca1476c
Update CommentEpoxyModelWithHolder.kt
MostafaGazar Aug 24, 2019
e2929fb
Update CommentsEpoxyController.kt
MostafaGazar Aug 24, 2019
9655a89
Update ReplyEpoxyModelWithHolder.kt
MostafaGazar Aug 24, 2019
75c1803
Update CommentEpoxyModelWithHolder.kt
MostafaGazar Aug 24, 2019
be21797
Update upvote_downvote_src.xml
MostafaGazar Aug 24, 2019
9824faf
Update and rename vd_thumb_down_outline.xml to vd_thumb_up.xml
MostafaGazar Aug 24, 2019
219c727
Update vd_thumb_up_outline.xml
MostafaGazar Aug 24, 2019
03492ee
Merge pull request #31 from Justin-Terry/first-pull-request
MostafaGazar Aug 24, 2019
b729bed
add chrome custom tabs
faogustavo Sep 20, 2019
41de1c9
Merge pull request #34 from faogustavo/feature/11-chrome-custom-tabs
MostafaGazar Sep 23, 2019
d5d2706
Merge remote-tracking branch 'upstream/develop' into develop
MostafaGazar Oct 20, 2019
a104d73
Hide blog posts
MostafaGazar Oct 31, 2019
a60c1f1
Show articles and hide unrelated buttons in them (play, download and …
MostafaGazar Nov 8, 2019
8f9736b
Cleanup some issues missed in previous code reviews
MostafaGazar Nov 12, 2019
bf5d65a
Delete unused mentions from the Comment model
MostafaGazar Nov 12, 2019
5256899
Bump app version
MostafaGazar Nov 12, 2019
79fbded
Merge pull request #38 from MostafaGazar/develop
MostafaGazar Nov 12, 2019
ac1e0c2
Fixing style errors.
stickler-ci Nov 12, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .stickler.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
linters:
ktlint:
android: true
fixer: true
fixers:
enable: true
7 changes: 5 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ android {
applicationId "com.koalatea.sedaily"
minSdkVersion 21
targetSdkVersion 29
versionCode 18
versionName "1.0.2"
versionCode 19
versionName "1.0.3"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

Expand Down Expand Up @@ -141,6 +141,9 @@ dependencies {
// Timber
implementation 'com.jakewharton.timber:timber:4.7.1'

// Custom Tabs
implementation 'androidx.browser:browser:1.0.0'

// Testing
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.2.0'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ data class Comment(
val author: Author,
val rootEntity: String,
val content: String,
val mentions: List<String>?,
val deleted: Boolean?,
val dateCreated: String,
val score: Int?,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ class BookmarksFragment : BaseFragment() {
epoxyRecyclerView.setController(this)
}

bookmarksSwipeRefreshLayout.setOnRefreshListener {
viewModel.fetchBookmarks()
}

viewModel.bookmarksResource.observe(this, Observer { resource ->
when (resource) {
is Resource.Loading -> {
Expand Down Expand Up @@ -94,18 +98,18 @@ class BookmarksFragment : BaseFragment() {

private fun showLoading() {
emptyStateContainer.visibility = View.GONE
epoxyRecyclerView.visibility = View.GONE
bookmarksSwipeRefreshLayout.visibility = View.GONE

progressBar.visibility = View.VISIBLE
bookmarksSwipeRefreshLayout.isRefreshing = true
}

private fun hideLoading() {
progressBar.visibility = View.GONE
bookmarksSwipeRefreshLayout.isRefreshing = false
}

private fun showLoginEmptyState() {
epoxyRecyclerView.visibility = View.GONE
progressBar.visibility = View.GONE
bookmarksSwipeRefreshLayout.visibility = View.GONE
bookmarksSwipeRefreshLayout.isRefreshing = false

emptyStateContainer.textView.text = getString(R.string.login_to_manage_bookmarks)
emptyStateContainer.visibility = View.VISIBLE
Expand All @@ -115,9 +119,9 @@ class BookmarksFragment : BaseFragment() {
bookmarksEpoxyController?.setData(episodes)

emptyStateContainer.visibility = View.GONE
progressBar.visibility = View.GONE
bookmarksSwipeRefreshLayout.isRefreshing = false

epoxyRecyclerView.visibility = View.VISIBLE
bookmarksSwipeRefreshLayout.visibility = View.VISIBLE
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ class CommentsFragment : BaseFragment() {
commentsEpoxyController = CommentsEpoxyController(
replyClickListener = { comment ->
viewModel.replyTo(comment)
},
upVoteClickListener = { comment ->
viewModel.upVoteComment(comment)
}
).apply {
epoxyRecyclerView.setController(this)
Expand All @@ -73,6 +76,21 @@ class CommentsFragment : BaseFragment() {
viewModel.cancelReply()
}

viewModel.commentVoteLiveData.observe(this, Observer { it.getContentIfNotHandled()?.let { resource ->
when (resource) {
is Resource.RequireLogin -> showPromptLoginDialog()
is Resource.Success -> {
viewModel.reloadComments(entityId)
}
is Resource.Error -> {
hideLoading()

if (resource.isConnected) acknowledgeGenericError() else acknowledgeConnectionError()
}
}
}
})

viewModel.commentsResource.observe(this, Observer { resource ->
when (resource) {
is Resource.Loading -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ class CommentsViewModel(
val replyToCommentLiveData: LiveData<Comment?>
get() = _replyToCommentLiveData

private val _commentVoteLiveData = MutableLiveData<Event<Resource<Boolean>>>()
val commentVoteLiveData: LiveData<Event<Resource<Boolean>>>
get() = _commentVoteLiveData

private val _addCommentLiveData = MutableLiveData<Event<Resource<Boolean>>>()
val addCommentLiveData: LiveData<Event<Resource<Boolean>>>
get() = _addCommentLiveData
Expand All @@ -42,6 +46,16 @@ class CommentsViewModel(
entityIdLiveData.value = entityId
}

@MainThread
fun upVoteComment(comment: Comment) = viewModelScope.launch {
with(_commentVoteLiveData) {
postValue(Event(Resource.Loading))

val resource = commentsRepository.upVoteComment(comment._id)
postValue(Event(resource))
}
}

@MainThread
fun addComment(comment: String) = viewModelScope.launch {
if (comment.isBlank()) return@launch
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ abstract class BaseCommentEpoxyModelWithHolder<Holder: BaseCommentHolder> : Epox
@EpoxyAttribute lateinit var authorName: String
@EpoxyAttribute lateinit var comment: String
@EpoxyAttribute var date: Date? = null
@EpoxyAttribute var score: Int? = 0
@EpoxyAttribute var upvoted: Boolean = false

@CallSuper
override fun bind(holder: Holder) {
Expand All @@ -43,7 +45,6 @@ abstract class BaseCommentEpoxyModelWithHolder<Holder: BaseCommentHolder> : Epox
holder.dateTextView.visibility = View.GONE
}
}

}

abstract class BaseCommentHolder : KotlinEpoxyHolder() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,21 @@ import com.koalatea.sedaily.R
abstract class CommentEpoxyModelWithHolder : BaseCommentEpoxyModelWithHolder<CommentHolder>() {

@EpoxyAttribute lateinit var replyClickListener: () -> Unit
@EpoxyAttribute lateinit var upVoteClickListener: () -> Unit

override fun bind(holder: CommentHolder) {
super.bind(holder)

holder.replayButton.setOnClickListener { replyClickListener() }
holder.upVoteButton.setOnClickListener { upVoteClickListener() }
holder.upVoteButton.isSelected = upvoted
holder.upVoteButton.text = score?.let {
if (it > 0) { it.toString() } else { "" }
} ?: ""
}

}

class CommentHolder : BaseCommentHolder() {
val replayButton by bind<Button>(R.id.replyButton)
}
val upVoteButton by bind<Button>(R.id.commentUpvoteButton)
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import com.airbnb.epoxy.TypedEpoxyController
import com.koalatea.sedaily.database.model.Comment

class CommentsEpoxyController(
private val replyClickListener: (comment: Comment) -> Unit
private val replyClickListener: (comment: Comment) -> Unit,
private val upVoteClickListener: (comment: Comment) -> Unit
) : TypedEpoxyController<List<Comment>>() {

override fun buildModels(comments: List<Comment>) {
Expand All @@ -17,7 +18,10 @@ class CommentsEpoxyController(
authorName(comment.author.name ?: comment.author.username)
comment(comment.content)
date(comment.utcDateCreated)
score(comment.score)
replyClickListener { replyClickListener(comment) }
upVoteClickListener { upVoteClickListener(comment) }
upvoted(comment?.upvoted ?: false)
}

comment.replies?.forEach { reply ->
Expand All @@ -29,9 +33,12 @@ class CommentsEpoxyController(
authorName(reply.author.name ?: comment.author.username)
comment(reply.content)
date(reply.utcDateCreated)
upVoteClickListener { upVoteClickListener(reply) }
upvoted(reply?.upvoted ?: false)
score(reply.score)
}
}
}
}

}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,26 @@
package com.koalatea.sedaily.feature.commentList.epoxy

import android.widget.Button
import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass
import com.koalatea.sedaily.R

@EpoxyModelClass(layout = R.layout.view_holder_reply)
abstract class ReplyEpoxyModelWithHolder : BaseCommentEpoxyModelWithHolder<ReplyHolder>()
abstract class ReplyEpoxyModelWithHolder : BaseCommentEpoxyModelWithHolder<ReplyHolder>() {

class ReplyHolder : BaseCommentHolder()
@EpoxyAttribute lateinit var upVoteClickListener: () -> Unit

override fun bind(holder: ReplyHolder) {
super.bind(holder)

holder.upVoteButton.setOnClickListener { upVoteClickListener() }
holder.upVoteButton.isSelected = upvoted
holder.upVoteButton.text = score?.let {
if (it > 0) { it.toString() } else { "" }
} ?: ""
}
}

class ReplyHolder : BaseCommentHolder() {
val upVoteButton by bind<Button>(R.id.replyUpvoteButton)
}
Original file line number Diff line number Diff line change
Expand Up @@ -292,8 +292,8 @@ class EpisodeDetailFragment : BaseFragment() {
}

private fun renderPlay(episode: Episode) {
// Playback is not supported
if (playerCallback == null) {
// Playback is not supported or viewing an article
if (playerCallback == null || episode.httpsMp3Url.isNullOrBlank()) {
hidePlayerViews()
} else {
monitorPlayback(episode)
Expand All @@ -313,6 +313,13 @@ class EpisodeDetailFragment : BaseFragment() {
playerCallback?.playerStatusLiveData?.removeObservers(this)
}
}

// Cannot download or view related links for an article
if (episode.httpsMp3Url.isNullOrBlank()) {
hideDownloadViews()

relatedLinksButton.visibility = View.INVISIBLE
}
}

private fun monitorPlayback(episode: Episode) {
Expand All @@ -337,6 +344,12 @@ class EpisodeDetailFragment : BaseFragment() {
downloadProgressBar.visibility = View.INVISIBLE
}

private fun hideDownloadViews() {
deleteButton.visibility = View.GONE
downloadButton.visibility = View.INVISIBLE
downloadProgressBar.visibility = View.INVISIBLE
}

private fun showDeleteViews() {
deleteButton.visibility = View.VISIBLE
downloadButton.visibility = View.INVISIBLE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.koin.android.ext.android.inject
import timber.log.Timber
import java.util.*

private const val PLAYBACK_CHANNEL_ID = "playback_channel"
Expand Down Expand Up @@ -100,14 +101,6 @@ class AudioService : LifecycleService() {
val playerStatusLiveData: LiveData<PlayerStatus>
get() = _playerStatusLiveData

override fun onBind(intent: Intent?): IBinder {
super.onBind(intent)

handleIntent(intent)

return AudioServiceBinder()
}

override fun onCreate() {
super.onCreate()

Expand Down Expand Up @@ -213,6 +206,14 @@ class AudioService : LifecycleService() {
}
}

override fun onBind(intent: Intent?): IBinder {
super.onBind(intent)

handleIntent(intent)

return AudioServiceBinder()
}

override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
handleIntent(intent)

Expand All @@ -233,17 +234,16 @@ class AudioService : LifecycleService() {

@MainThread
private fun handleIntent(intent: Intent?) {
episodeId = intent?.getStringExtra(ARG_EPISODE_ID)
episodeTitle = intent?.getStringExtra(ARG_TITLE)

// Play
intent?.let {
intent.getParcelableExtra<Uri>(ARG_URI)?.also { uri ->
episodeId = intent.getStringExtra(ARG_EPISODE_ID)
episodeTitle = intent.getStringExtra(ARG_TITLE)
val startPosition = intent.getLongExtra(ARG_START_POSITION, C.POSITION_UNSET.toLong())
val playbackSpeed = playbackManager.playbackSpeed

play(uri, startPosition, playbackSpeed)
}
} ?: Timber.w("Playback uri was not set")
}
}

Expand Down
3 changes: 3 additions & 0 deletions app/src/main/java/com/koalatea/sedaily/network/SEDailyApi.kt
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ interface SEDailyApi {
@GET("comments/forEntity/{entity_id}")
fun getEpisodeCommentsAsync(@Path("entity_id") entityId: String): Deferred<Response<CommentsResponse>>

@POST("comments/{entity_id}/upvote")
fun upVoteCommentsAsync(@Path("entity_id") entityId: String): Deferred<Response<GenericResponse>>

@FormUrlEncoded
@POST("comments/forEntity/{entity_id}")
fun addEpisodeCommentAsync(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,16 @@ class CommentsRepository(
}
}

}
suspend fun upVoteComment(entityId: String) = withContext(Dispatchers.IO) {
if (sessionRepository.isLoggedIn) {
val response = safeApiCall { api.upVoteCommentsAsync(entityId).await() }
if (response?.isSuccessful == true) {
Resource.Success(true)
} else {
Resource.Error(response?.errorBody().toException(), networkManager.isConnected)
}
} else {
Resource.RequireLogin
}
}
}
Loading