diff --git a/app/src/main/java/org/pixeldroid/app/stories/StoriesActivity.kt b/app/src/main/java/org/pixeldroid/app/stories/StoriesActivity.kt index 8a6e90d6..3a85dfac 100644 --- a/app/src/main/java/org/pixeldroid/app/stories/StoriesActivity.kt +++ b/app/src/main/java/org/pixeldroid/app/stories/StoriesActivity.kt @@ -4,6 +4,8 @@ import android.graphics.drawable.Drawable import android.os.Build import android.os.Bundle import androidx.activity.viewModels +import androidx.core.view.isVisible +import androidx.core.widget.doAfterTextChanged import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle @@ -13,7 +15,9 @@ import com.bumptech.glide.load.engine.GlideException import com.bumptech.glide.request.RequestListener import com.bumptech.glide.request.RequestOptions import com.bumptech.glide.request.target.Target +import com.google.android.material.snackbar.Snackbar import kotlinx.coroutines.launch +import org.pixeldroid.app.R import org.pixeldroid.app.databinding.ActivityStoriesBinding import org.pixeldroid.app.posts.setTextViewFromISO8601 import org.pixeldroid.app.utils.BaseThemedWithoutBarActivity @@ -43,6 +47,23 @@ class StoriesActivity: BaseThemedWithoutBarActivity() { uiState.age?.let { setTextViewFromISO8601(it, binding.storyAge, false) } + if (uiState.errorMessage != null) { + binding.storyErrorText.text = uiState.errorMessage + binding.storyErrorCard.isVisible = true + } else binding.storyErrorCard.isVisible = false + + if (uiState.snackBar != null) { + Snackbar.make( + binding.root, uiState.snackBar, + Snackbar.LENGTH_SHORT + ).setAnchorView(binding.storyReplyField).show() + model.shownSnackbar() + } + + if (uiState.username != null) { + binding.storyReplyField.hint = getString(R.string.replyToStory).format(uiState.username) + } else binding.storyReplyField.hint = null + uiState.profilePicture?.let { Glide.with(binding.storyAuthorProfilePicture) .load(it) @@ -79,6 +100,22 @@ class StoriesActivity: BaseThemedWithoutBarActivity() { } } } + binding.storyReplyField.editText?.doAfterTextChanged { + it?.let { text -> + val string = text.toString() + if(string != model.uiState.value.reply) model.replyChanged(string) + } + } + + binding.storyReplyField.setEndIconOnClickListener { + binding.storyReplyField.editText?.text?.let { text -> + model.sendReply(text) + } + } + + binding.storyErrorCard.setOnClickListener{ + model.dismissError() + } model.count.observe(this) { state -> // Render state in UI @@ -96,11 +133,7 @@ class StoriesActivity: BaseThemedWithoutBarActivity() { binding.pause.setOnClickListener { //Set the button's appearance it.isSelected = !it.isSelected - if (it.isSelected) { - //Handle selected state change - } else { - //Handle de-select state change - } + model.pause() } binding.storyImage.setOnClickListener { diff --git a/app/src/main/java/org/pixeldroid/app/stories/StoriesViewModel.kt b/app/src/main/java/org/pixeldroid/app/stories/StoriesViewModel.kt index 18382e18..bf81567c 100644 --- a/app/src/main/java/org/pixeldroid/app/stories/StoriesViewModel.kt +++ b/app/src/main/java/org/pixeldroid/app/stories/StoriesViewModel.kt @@ -2,16 +2,19 @@ package org.pixeldroid.app.stories import android.app.Application import android.os.CountDownTimer +import android.text.Editable import android.util.Log import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.viewModelScope +import com.google.android.material.snackbar.Snackbar import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch +import org.pixeldroid.app.R import org.pixeldroid.app.utils.PixelDroidApplication import org.pixeldroid.app.utils.api.objects.StoryCarousel import org.pixeldroid.app.utils.di.PixelfedAPIHolder @@ -27,6 +30,8 @@ data class StoriesUiState( val durationList: List = emptyList(), val paused: Boolean = false, val errorMessage: String? = null, + val snackBar: String? = null, + val reply: String = "" ) class StoriesViewModel( @@ -134,6 +139,44 @@ class StoriesViewModel( currentUiState.copy(paused = !currentUiState.paused) } } + + fun sendReply(text: Editable) { + viewModelScope.launch { + try { + val api = apiHolder.api ?: apiHolder.setToCurrentUser() + //TODO don't just take the first here, choose from activity input somehow? + val id = carousel?.nodes?.firstOrNull()?.nodes?.getOrNull(uiState.value.currentImage)?.id + id?.let { api.storyComment(it, text.toString()) } + + _uiState.update { currentUiState -> + currentUiState.copy(snackBar = "Sent reply") + } + } catch (exception: Exception){ + _uiState.update { currentUiState -> + currentUiState.copy(errorMessage = "Something went wrong sending reply") + } + } + + } + } + + fun replyChanged(text: String) { + _uiState.update { currentUiState -> + currentUiState.copy(reply = text) + } + } + + fun dismissError() { + _uiState.update { currentUiState -> + currentUiState.copy(errorMessage = null) + } + } + + fun shownSnackbar() { + _uiState.update { currentUiState -> + currentUiState.copy(snackBar = null) + } + } } class StoriesViewModelFactory(val application: Application) : ViewModelProvider.Factory { diff --git a/app/src/main/java/org/pixeldroid/app/utils/api/PixelfedAPI.kt b/app/src/main/java/org/pixeldroid/app/utils/api/PixelfedAPI.kt index f008e992..6750dfef 100644 --- a/app/src/main/java/org/pixeldroid/app/utils/api/PixelfedAPI.kt +++ b/app/src/main/java/org/pixeldroid/app/utils/api/PixelfedAPI.kt @@ -236,10 +236,16 @@ interface PixelfedAPI { ): StoryCarousel @POST("/api/v1.1/stories/seen") - suspend fun carouselSeen( + suspend fun storySeen( @Query("id") id: String //TODO figure out if this is the id of post or of user? ) + @POST("/api/v1.1/stories/comment") + suspend fun storyComment( + @Query("sid") sid: String, + @Query("caption") caption: String + ) + @POST("/api/v1.1/stories/self-expire/{id}") suspend fun deleteCarousel( @Path("id") storyId: String diff --git a/app/src/main/res/layout/activity_stories.xml b/app/src/main/res/layout/activity_stories.xml index b61152df..8f733c90 100644 --- a/app/src/main/res/layout/activity_stories.xml +++ b/app/src/main/res/layout/activity_stories.xml @@ -6,16 +6,59 @@ android:background="@color/black" android:layout_height="match_parent"> + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e47bf398..acabe04e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -331,4 +331,5 @@ For more info about Pixelfed, you can check here: https://pixelfed.org" Switch accounts NSFW/CW posts will not be blurred, and will be shown by default. Story image + Reply to %1$s