implement story creation
This commit is contained in:
parent
ae54b83ec7
commit
db3da57b7b
@ -1,6 +1,7 @@
|
||||
package org.pixeldroid.app.postCreation
|
||||
|
||||
import android.os.*
|
||||
import androidx.core.view.WindowCompat
|
||||
import androidx.navigation.NavController
|
||||
import androidx.navigation.fragment.NavHostFragment
|
||||
import org.pixeldroid.app.R
|
||||
|
@ -33,6 +33,7 @@ import kotlinx.coroutines.launch
|
||||
import org.pixeldroid.app.R
|
||||
import org.pixeldroid.app.databinding.FragmentPostCreationBinding
|
||||
import org.pixeldroid.app.postCreation.camera.CameraActivity
|
||||
import org.pixeldroid.app.postCreation.camera.CameraFragment
|
||||
import org.pixeldroid.app.postCreation.carousel.CarouselItem
|
||||
import org.pixeldroid.app.utils.BaseFragment
|
||||
import org.pixeldroid.app.utils.db.entities.InstanceDatabaseEntity
|
||||
@ -83,11 +84,16 @@ class PostCreationFragment : BaseFragment() {
|
||||
requireActivity().intent.clipData!!,
|
||||
instance,
|
||||
requireActivity().intent.getStringExtra(PostCreationActivity.PICTURE_DESCRIPTION),
|
||||
requireActivity().intent.getBooleanExtra(PostCreationActivity.POST_NSFW, false)
|
||||
requireActivity().intent.getBooleanExtra(PostCreationActivity.POST_NSFW, false),
|
||||
requireActivity().intent.getBooleanExtra(CameraFragment.CAMERA_ACTIVITY_STORY, false),
|
||||
)
|
||||
}
|
||||
model = _model
|
||||
|
||||
if(model.storyCreation){
|
||||
binding.carousel.showCaption = false
|
||||
}
|
||||
|
||||
model.getPhotoData().observe(viewLifecycleOwner) { newPhotoData ->
|
||||
// update UI
|
||||
binding.carousel.addData(
|
||||
|
@ -22,6 +22,7 @@ import androidx.preference.PreferenceManager
|
||||
import com.jarsilio.android.scrambler.exceptions.UnsupportedFileFormatException
|
||||
import com.jarsilio.android.scrambler.stripMetadata
|
||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.rxjava3.core.Observable
|
||||
import io.reactivex.rxjava3.disposables.Disposable
|
||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
@ -107,7 +108,8 @@ class PostCreationViewModel(
|
||||
clipdata: ClipData? = null,
|
||||
val instance: InstanceDatabaseEntity? = null,
|
||||
existingDescription: String? = null,
|
||||
existingNSFW: Boolean = false
|
||||
existingNSFW: Boolean = false,
|
||||
val storyCreation: Boolean = false,
|
||||
) : AndroidViewModel(application) {
|
||||
private val photoData: MutableLiveData<MutableList<PhotoData>> by lazy {
|
||||
MutableLiveData<MutableList<PhotoData>>().also {
|
||||
@ -444,7 +446,11 @@ class PostCreationViewModel(
|
||||
apiHolder.setToCurrentUser(it)
|
||||
} ?: apiHolder.api ?: apiHolder.setToCurrentUser()
|
||||
|
||||
val inter = api.mediaUpload(description, requestBody.parts[0])
|
||||
val inter: Observable<Attachment> =
|
||||
//TODO specify story duration
|
||||
//TODO validate that image is correct (?) aspect ratio
|
||||
if (storyCreation) api.storyUpload(requestBody.parts[0])
|
||||
else api.mediaUpload(description, requestBody.parts[0])
|
||||
|
||||
apiHolder.api = null
|
||||
postSub = inter
|
||||
@ -453,7 +459,11 @@ class PostCreationViewModel(
|
||||
.subscribe(
|
||||
{ attachment: Attachment ->
|
||||
data.progress = 0
|
||||
data.uploadId = attachment.id!!
|
||||
data.uploadId = if(storyCreation){
|
||||
attachment.media_id!!
|
||||
} else {
|
||||
attachment.id!!
|
||||
}
|
||||
},
|
||||
{ e: Throwable ->
|
||||
_uiState.update { currentUiState ->
|
||||
@ -509,11 +519,19 @@ class PostCreationViewModel(
|
||||
apiHolder.setToCurrentUser(it)
|
||||
} ?: apiHolder.api ?: apiHolder.setToCurrentUser()
|
||||
|
||||
api.postStatus(
|
||||
statusText = description,
|
||||
media_ids = getPhotoData().value!!.mapNotNull { it.uploadId }.toList(),
|
||||
sensitive = nsfw
|
||||
)
|
||||
if(storyCreation){
|
||||
api.storyPublish(
|
||||
media_id = getPhotoData().value!!.firstNotNullOf { it.uploadId },
|
||||
can_react = "1", can_reply = "1",
|
||||
duration = 10
|
||||
)
|
||||
} else{
|
||||
api.postStatus(
|
||||
statusText = description,
|
||||
media_ids = getPhotoData().value!!.mapNotNull { it.uploadId }.toList(),
|
||||
sensitive = nsfw
|
||||
)
|
||||
}
|
||||
Toast.makeText(getApplication(), getApplication<PixelDroidApplication>().getString(R.string.upload_post_success),
|
||||
Toast.LENGTH_SHORT).show()
|
||||
val intent = Intent(getApplication(), MainActivity::class.java)
|
||||
@ -555,8 +573,8 @@ class PostCreationViewModel(
|
||||
}
|
||||
}
|
||||
|
||||
class PostCreationViewModelFactory(val application: Application, val clipdata: ClipData, val instance: InstanceDatabaseEntity, val existingDescription: String?, val existingNSFW: Boolean) : ViewModelProvider.Factory {
|
||||
class PostCreationViewModelFactory(val application: Application, val clipdata: ClipData, val instance: InstanceDatabaseEntity, val existingDescription: String?, val existingNSFW: Boolean, val storyCreation: Boolean) : ViewModelProvider.Factory {
|
||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||
return modelClass.getConstructor(Application::class.java, ClipData::class.java, InstanceDatabaseEntity::class.java, String::class.java, Boolean::class.java).newInstance(application, clipdata, instance, existingDescription, existingNSFW)
|
||||
return modelClass.getConstructor(Application::class.java, ClipData::class.java, InstanceDatabaseEntity::class.java, String::class.java, Boolean::class.java, Boolean::class.java).newInstance(application, clipdata, instance, existingDescription, existingNSFW, storyCreation)
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import kotlinx.coroutines.launch
|
||||
import org.pixeldroid.app.R
|
||||
import org.pixeldroid.app.databinding.FragmentPostSubmissionBinding
|
||||
import org.pixeldroid.app.postCreation.camera.CameraFragment
|
||||
import org.pixeldroid.app.utils.BaseFragment
|
||||
import org.pixeldroid.app.utils.db.entities.InstanceDatabaseEntity
|
||||
import org.pixeldroid.app.utils.db.entities.UserDatabaseEntity
|
||||
@ -68,7 +69,8 @@ class PostSubmissionFragment : BaseFragment() {
|
||||
requireActivity().intent.clipData!!,
|
||||
instance,
|
||||
requireActivity().intent.getStringExtra(PostCreationActivity.PICTURE_DESCRIPTION),
|
||||
requireActivity().intent.getBooleanExtra(PostCreationActivity.POST_NSFW, false)
|
||||
requireActivity().intent.getBooleanExtra(PostCreationActivity.POST_NSFW, false),
|
||||
requireActivity().intent.getBooleanExtra(CameraFragment.CAMERA_ACTIVITY_STORY, false)
|
||||
)
|
||||
}
|
||||
model = _model
|
||||
@ -77,6 +79,14 @@ class PostSubmissionFragment : BaseFragment() {
|
||||
binding.nsfwSwitch.isChecked = model.uiState.value.nsfw
|
||||
binding.newPostDescriptionInputField.setText(model.uiState.value.newPostDescriptionText)
|
||||
|
||||
if(model.storyCreation){
|
||||
binding.nsfwSwitch.visibility = View.GONE
|
||||
binding.postTextInputLayout.visibility = View.GONE
|
||||
binding.privateTitle.visibility = View.GONE
|
||||
binding.postPreview.visibility = View.GONE
|
||||
//TODO show story specific stuff here
|
||||
}
|
||||
|
||||
lifecycleScope.launch {
|
||||
viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
|
||||
model.uiState.collect { uiState ->
|
||||
|
@ -5,6 +5,8 @@ import android.os.Bundle
|
||||
import android.view.MenuItem
|
||||
import org.pixeldroid.app.MainActivity
|
||||
import org.pixeldroid.app.R
|
||||
import org.pixeldroid.app.postCreation.camera.CameraFragment.Companion.CAMERA_ACTIVITY
|
||||
import org.pixeldroid.app.postCreation.camera.CameraFragment.Companion.CAMERA_ACTIVITY_STORY
|
||||
import org.pixeldroid.app.utils.BaseThemedWithBarActivity
|
||||
|
||||
|
||||
@ -13,12 +15,17 @@ class CameraActivity : BaseThemedWithBarActivity() {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_camera)
|
||||
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||
supportActionBar?.setTitle(R.string.add_photo)
|
||||
|
||||
val cameraFragment = CameraFragment()
|
||||
|
||||
val story: Boolean = intent.getBooleanExtra(CAMERA_ACTIVITY_STORY, false)
|
||||
|
||||
if(story) supportActionBar?.setTitle(R.string.add_story)
|
||||
else supportActionBar?.setTitle(R.string.add_photo)
|
||||
|
||||
val arguments = Bundle()
|
||||
arguments.putBoolean("CameraActivity", true)
|
||||
arguments.putBoolean(CAMERA_ACTIVITY, true)
|
||||
arguments.putBoolean(CAMERA_ACTIVITY_STORY, story)
|
||||
cameraFragment.arguments = arguments
|
||||
|
||||
supportFragmentManager.beginTransaction()
|
||||
|
@ -70,6 +70,7 @@ class CameraFragment : BaseFragment() {
|
||||
private var camera: Camera? = null
|
||||
|
||||
private var inActivity by Delegates.notNull<Boolean>()
|
||||
private var addToStory by Delegates.notNull<Boolean>()
|
||||
|
||||
private var filePermissionDialogLaunched: Boolean = false
|
||||
|
||||
@ -89,7 +90,8 @@ class CameraFragment : BaseFragment() {
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
super.onCreateView(inflater, container, savedInstanceState)
|
||||
inActivity = arguments?.getBoolean("CameraActivity") ?: false
|
||||
inActivity = arguments?.getBoolean(CAMERA_ACTIVITY) ?: false
|
||||
addToStory = arguments?.getBoolean(CAMERA_ACTIVITY_STORY) ?: false
|
||||
|
||||
binding = FragmentCameraBinding.inflate(layoutInflater)
|
||||
|
||||
@ -464,15 +466,20 @@ class CameraFragment : BaseFragment() {
|
||||
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||
}
|
||||
|
||||
if(inActivity){
|
||||
if(inActivity && !addToStory){
|
||||
requireActivity().setResult(Activity.RESULT_OK, intent)
|
||||
requireActivity().finish()
|
||||
} else {
|
||||
if(addToStory){
|
||||
intent.putExtra(CAMERA_ACTIVITY_STORY, addToStory)
|
||||
}
|
||||
startActivity(intent)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val CAMERA_ACTIVITY = "CameraActivity"
|
||||
const val CAMERA_ACTIVITY_STORY = "CameraActivityStory"
|
||||
|
||||
private const val TAG = "CameraFragment"
|
||||
private const val RATIO_4_3_VALUE = 4.0 / 3.0
|
||||
|
@ -40,7 +40,6 @@ class ImageCarousel(
|
||||
)
|
||||
|
||||
private lateinit var recyclerView: RecyclerView
|
||||
private lateinit var tvCaption: TextView
|
||||
private var snapHelper: SnapHelper = PagerSnapHelper()
|
||||
|
||||
var indicator: CircleIndicator2? = null
|
||||
@ -103,11 +102,12 @@ class ImageCarousel(
|
||||
* ****************************************************************
|
||||
*/
|
||||
|
||||
//FIXME this is modified a bunch of times all over the place, so it can't be set to false and stay there
|
||||
var showCaption = false
|
||||
set(value) {
|
||||
field = value
|
||||
|
||||
tvCaption.visibility = if (showCaption) View.VISIBLE else View.GONE
|
||||
binding.tvCaption.visibility = if (showCaption) View.VISIBLE else View.GONE
|
||||
}
|
||||
|
||||
@Dimension(unit = Dimension.PX)
|
||||
@ -115,7 +115,7 @@ class ImageCarousel(
|
||||
set(value) {
|
||||
field = value
|
||||
|
||||
tvCaption.setTextSize(TypedValue.COMPLEX_UNIT_PX, captionTextSize.toFloat())
|
||||
binding.tvCaption.setTextSize(TypedValue.COMPLEX_UNIT_PX, captionTextSize.toFloat())
|
||||
}
|
||||
|
||||
var showIndicator = false
|
||||
@ -245,14 +245,14 @@ class ImageCarousel(
|
||||
showNavigationButtons = showNavigationButtons
|
||||
|
||||
binding.editMediaDescriptionLayout.visibility = if(editingMediaDescription) VISIBLE else INVISIBLE
|
||||
tvCaption.visibility = if(editingMediaDescription) INVISIBLE else VISIBLE
|
||||
showCaption = !editingMediaDescription
|
||||
} else {
|
||||
recyclerView.layoutManager = GridLayoutManager(context, 3)
|
||||
binding.btnNext.visibility = GONE
|
||||
binding.btnPrevious.visibility = GONE
|
||||
|
||||
binding.editMediaDescriptionLayout.visibility = INVISIBLE
|
||||
tvCaption.visibility = INVISIBLE
|
||||
showCaption = false
|
||||
}
|
||||
showIndicator = value
|
||||
|
||||
@ -279,7 +279,7 @@ class ImageCarousel(
|
||||
updateDescriptionCallback?.invoke(currentPosition, description)
|
||||
}
|
||||
binding.editMediaDescriptionLayout.visibility = if(value) VISIBLE else INVISIBLE
|
||||
tvCaption.visibility = if(value) INVISIBLE else VISIBLE
|
||||
showCaption = !value
|
||||
|
||||
}
|
||||
|
||||
@ -289,10 +289,10 @@ class ImageCarousel(
|
||||
set(value) {
|
||||
if(!value.isNullOrEmpty()) {
|
||||
field = value
|
||||
tvCaption.text = value
|
||||
binding.tvCaption.text = value
|
||||
} else {
|
||||
field = null
|
||||
tvCaption.text = context.getText(R.string.no_media_description)
|
||||
binding.tvCaption.text = context.getText(R.string.no_media_description)
|
||||
}
|
||||
|
||||
}
|
||||
@ -317,12 +317,11 @@ class ImageCarousel(
|
||||
binding = ImageCarouselBinding.inflate(LayoutInflater.from(context),this, true)
|
||||
|
||||
recyclerView = binding.recyclerView
|
||||
tvCaption = binding.tvCaption
|
||||
|
||||
recyclerView.setHasFixedSize(true)
|
||||
|
||||
// For marquee effect
|
||||
tvCaption.isSelected = true
|
||||
binding.tvCaption.isSelected = true
|
||||
}
|
||||
|
||||
|
||||
@ -441,7 +440,7 @@ class ImageCarousel(
|
||||
caption.apply {
|
||||
if(layoutCarousel){
|
||||
binding.editMediaDescriptionLayout.visibility = INVISIBLE
|
||||
tvCaption.visibility = VISIBLE
|
||||
showCaption = true
|
||||
}
|
||||
currentDescription = this
|
||||
}
|
||||
@ -472,7 +471,7 @@ class ImageCarousel(
|
||||
}
|
||||
})
|
||||
|
||||
tvCaption.setOnClickListener {
|
||||
binding.tvCaption.setOnClickListener {
|
||||
editingMediaDescription = true
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@ import android.view.MotionEvent
|
||||
import android.view.View.OnClickListener
|
||||
import android.view.View.OnTouchListener
|
||||
import androidx.activity.viewModels
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.core.widget.doAfterTextChanged
|
||||
import androidx.lifecycle.Lifecycle
|
||||
@ -41,6 +42,9 @@ class StoriesActivity: BaseThemedWithoutBarActivity() {
|
||||
private lateinit var model: StoriesViewModel
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
//force night mode always
|
||||
delegate.localNightMode = AppCompatDelegate.MODE_NIGHT_YES
|
||||
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
val carousel = intent.getSerializableExtra(STORY_CAROUSEL) as StoryCarousel
|
||||
@ -213,8 +217,6 @@ class StoriesActivity: BaseThemedWithoutBarActivity() {
|
||||
binding.viewLeft.setOnTouchListener(onTouchListener)
|
||||
binding.viewRight.setOnTouchListener(onTouchListener)
|
||||
|
||||
//TODO implement hold to pause
|
||||
|
||||
binding.viewRight.setOnClickListener {
|
||||
model.goToNext()
|
||||
}
|
||||
|
@ -4,11 +4,14 @@ import android.app.Application
|
||||
import android.os.CountDownTimer
|
||||
import android.text.Editable
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import androidx.core.os.LocaleListCompat
|
||||
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.dialog.MaterialAlertDialogBuilder
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.update
|
||||
@ -119,7 +122,20 @@ class StoriesViewModel(
|
||||
startTimerForCurrent()
|
||||
}
|
||||
|
||||
fun goToNext() = goTo(uiState.value.currentImage + 1)
|
||||
fun goToNext() {
|
||||
viewModelScope.launch {
|
||||
try {
|
||||
val api = apiHolder.api ?: apiHolder.setToCurrentUser()
|
||||
currentStoryId()?.let { api.storySeen(it) }
|
||||
} catch (exception: Exception){
|
||||
_uiState.update { currentUiState ->
|
||||
currentUiState.copy(errorMessage = R.string.story_could_not_see)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
goTo(uiState.value.currentImage + 1)
|
||||
}
|
||||
|
||||
fun goToPrevious() = goTo(uiState.value.currentImage - 1)
|
||||
|
||||
@ -148,8 +164,7 @@ class StoriesViewModel(
|
||||
viewModelScope.launch {
|
||||
try {
|
||||
val api = apiHolder.api ?: apiHolder.setToCurrentUser()
|
||||
val id = currentAccount?.nodes?.getOrNull(uiState.value.currentImage)?.id
|
||||
id?.let { api.storyComment(it, text.toString()) }
|
||||
currentStoryId()?.let { api.storyComment(it, text.toString()) }
|
||||
|
||||
_uiState.update { currentUiState ->
|
||||
currentUiState.copy(snackBar = R.string.sent_reply_story)
|
||||
@ -163,6 +178,8 @@ class StoriesViewModel(
|
||||
}
|
||||
}
|
||||
|
||||
private fun currentStoryId(): String? = currentAccount?.nodes?.getOrNull(uiState.value.currentImage)?.id
|
||||
|
||||
fun replyChanged(text: String) {
|
||||
_uiState.update { currentUiState ->
|
||||
currentUiState.copy(reply = text)
|
||||
|
@ -13,6 +13,8 @@ import org.pixeldroid.app.R
|
||||
import org.pixeldroid.app.databinding.StoryCarouselAddStoryBinding
|
||||
import org.pixeldroid.app.databinding.StoryCarouselBinding
|
||||
import org.pixeldroid.app.databinding.StoryCarouselItemBinding
|
||||
import org.pixeldroid.app.postCreation.camera.CameraActivity
|
||||
import org.pixeldroid.app.postCreation.camera.CameraFragment
|
||||
import org.pixeldroid.app.postCreation.carousel.dpToPx
|
||||
import org.pixeldroid.app.utils.api.objects.CarouselUserContainer
|
||||
import org.pixeldroid.app.utils.api.objects.StoryCarousel
|
||||
@ -103,7 +105,9 @@ class StoriesListAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||
}
|
||||
} else {
|
||||
holder.itemView.setOnClickListener {
|
||||
//TODO support for adding a story
|
||||
val intent = Intent(holder.itemView.context, CameraActivity::class.java)
|
||||
intent.putExtra(CameraFragment.CAMERA_ACTIVITY_STORY, true)
|
||||
holder.itemView.context.startActivity(intent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -236,12 +236,11 @@ interface PixelfedAPI {
|
||||
)
|
||||
|
||||
@GET("/api/v1.1/stories/carousel")
|
||||
suspend fun carousel(
|
||||
): StoryCarousel
|
||||
suspend fun carousel(): StoryCarousel
|
||||
|
||||
@POST("/api/v1.1/stories/seen")
|
||||
suspend fun storySeen(
|
||||
@Query("id") id: String //TODO figure out if this is the id of post or of user?
|
||||
@Query("id") id: String
|
||||
)
|
||||
|
||||
@POST("/api/v1.1/stories/comment")
|
||||
@ -250,6 +249,24 @@ interface PixelfedAPI {
|
||||
@Query("caption") caption: String
|
||||
)
|
||||
|
||||
@Multipart
|
||||
@POST("/api/v1.1/stories/add")
|
||||
fun storyUpload(
|
||||
@Part file: MultipartBody.Part,
|
||||
@Part duration: MultipartBody.Part? = null,
|
||||
): Observable<Attachment>
|
||||
|
||||
@POST("/api/v1.1/stories/publish")
|
||||
suspend fun storyPublish(
|
||||
@Query("media_id") media_id: String,
|
||||
//From 0 to 30
|
||||
//TODO figure out what this duration means
|
||||
@Query("duration") duration: Int = 10,
|
||||
//FIXME this should be able to take a boolean or at least "true"/"false" but only "0"/"1" works. Same issue as sensitive boolean in postStatus
|
||||
@Query("can_reply") can_reply: String,
|
||||
@Query("can_react") can_react: String,
|
||||
)
|
||||
|
||||
@POST("/api/v1.1/stories/self-expire/{id}")
|
||||
suspend fun deleteCarousel(
|
||||
@Path("id") storyId: String
|
||||
|
@ -18,6 +18,12 @@ data class Attachment(
|
||||
|
||||
//Deprecated attributes
|
||||
val text_url: String? = null, //URL
|
||||
|
||||
//Pixelfed's Story upload response... TODO make the server return a regular Attachment?
|
||||
val msg: String?,
|
||||
val media_id: String?,
|
||||
val media_url: String?,
|
||||
val media_type: String?,
|
||||
) : Serializable {
|
||||
enum class AttachmentType: Serializable {
|
||||
unknown, image, gifv, video, audio
|
||||
|
@ -3,8 +3,8 @@
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:background="@color/black"
|
||||
android:layout_height="match_parent">
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/black">
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/storyErrorCard"
|
||||
@ -22,8 +22,8 @@
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:minHeight="48dp"
|
||||
android:layout_marginEnd="8dp">
|
||||
android:layout_marginEnd="8dp"
|
||||
android:minHeight="48dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/storyErrorIcon"
|
||||
@ -65,39 +65,39 @@
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/pause"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_margin="12dp"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:contentDescription="@string/play_video"
|
||||
android:contentDescription="@string/story_pause"
|
||||
android:src="@drawable/play_pause"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/storyAuthorProfilePicture"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/storyAuthor"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@+id/storyAuthorProfilePicture"
|
||||
app:layout_constraintTop_toTopOf="@+id/carouselProgress"
|
||||
tools:visibility="visible" />
|
||||
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progressBarStory"
|
||||
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
|
||||
android:progress="0"
|
||||
tools:progress="56"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:progress="0"
|
||||
android:visibility="visible"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:progress="56" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/storyAuthorProfilePicture"
|
||||
android:layout_margin="12dp"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_margin="12dp"
|
||||
android:contentDescription="@string/profile_picture"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/progressBarStory"
|
||||
tools:srcCompat="@tools:sample/avatars"
|
||||
android:contentDescription="@string/profile_picture" />
|
||||
tools:srcCompat="@tools:sample/avatars" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/storyAuthor"
|
||||
@ -105,7 +105,6 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/storyAuthorProfilePicture"
|
||||
app:layout_constraintStart_toEndOf="@+id/storyAuthorProfilePicture"
|
||||
app:layout_constraintTop_toTopOf="@+id/storyAuthorProfilePicture"
|
||||
tools:text="username" />
|
||||
@ -115,20 +114,20 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/storyAuthorProfilePicture"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/storyAuthor"
|
||||
app:layout_constraintStart_toEndOf="@+id/storyAuthor"
|
||||
app:layout_constraintTop_toTopOf="@+id/storyAuthorProfilePicture"
|
||||
tools:text="48m" />
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/storyReplyField"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
tools:hint="Reply to PixelDroid"
|
||||
app:endIconMode="custom"
|
||||
app:endIconContentDescription="TODO"
|
||||
app:endIconDrawable="@drawable/ic_send_blue"
|
||||
app:endIconContentDescription="TODO">
|
||||
app:endIconMode="custom"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
tools:hint="Reply to PixelDroid">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:layout_width="match_parent"
|
||||
@ -141,18 +140,18 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="24dp"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/pause"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/storyAuthor"
|
||||
app:layout_constraintEnd_toStartOf="@+id/pause"
|
||||
app:layout_constraintTop_toTopOf="@+id/pause"
|
||||
app:layout_constraintTop_toTopOf="@+id/storyAge"
|
||||
tools:text="2/3" />
|
||||
|
||||
<View
|
||||
android:id="@+id/viewRight"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintBottom_toTopOf="@id/storyReplyField"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/viewMiddle"
|
||||
app:layout_constraintBottom_toTopOf="@id/storyReplyField"
|
||||
app:layout_constraintTop_toBottomOf="@+id/storyAuthorProfilePicture" />
|
||||
|
||||
|
||||
@ -160,9 +159,9 @@
|
||||
android:id="@+id/viewMiddle"
|
||||
android:layout_width="80dp"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintBottom_toTopOf="@id/storyReplyField"
|
||||
app:layout_constraintEnd_toStartOf="@id/viewRight"
|
||||
app:layout_constraintStart_toEndOf="@id/viewLeft"
|
||||
app:layout_constraintBottom_toTopOf="@id/storyReplyField"
|
||||
app:layout_constraintTop_toBottomOf="@+id/storyAuthorProfilePicture" />
|
||||
|
||||
|
||||
@ -170,11 +169,10 @@
|
||||
android:id="@+id/viewLeft"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/viewMiddle"
|
||||
app:layout_constraintBottom_toTopOf="@id/storyReplyField"
|
||||
app:layout_constraintEnd_toStartOf="@id/viewMiddle"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/storyAuthorProfilePicture" />
|
||||
|
||||
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -11,7 +11,7 @@
|
||||
android:id="@+id/carousel"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
app:showCaption="true"
|
||||
app:showCaption="false"
|
||||
app:layout_constraintBottom_toTopOf="@+id/buttonConstraints"
|
||||
app:layout_constraintTop_toTopOf="parent"/>
|
||||
|
||||
|
@ -337,4 +337,6 @@ For more info about Pixelfed, you can check here: https://pixelfed.org"</string>
|
||||
<string name="error_fetch_story">Something went wrong fetching the carousel</string>
|
||||
<string name="sent_reply_story">Sent reply</string>
|
||||
<string name="add_story">Add Story</string>
|
||||
<string name="story_could_not_see">Error: could not mark story as seen</string>
|
||||
<string name="story_pause">Start or pause the stories</string>
|
||||
</resources>
|
||||
|
@ -23,6 +23,7 @@
|
||||
<style name="AppTheme.PopupOverlay" parent="Theme.Material3.Light" />
|
||||
|
||||
<style name="AppTheme.ActionBar.Transparent" parent="Theme.Material3.Dark">
|
||||
<item name="android:windowLayoutInDisplayCutoutMode" tools:targetApi="o_mr1">always</item>
|
||||
<item name="colorPrimary">@android:color/transparent</item>
|
||||
<item name="colorPrimaryDark">@android:color/transparent</item>
|
||||
<item name="colorPrimaryVariant">@android:color/transparent</item>
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user