Add Self view for stories
This commit is contained in:
parent
0290e6f8d5
commit
bb3c9afb13
|
@ -1,7 +1,6 @@
|
||||||
package org.pixeldroid.app.stories
|
package org.pixeldroid.app.stories
|
||||||
|
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import android.os.Build
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.MotionEvent
|
import android.view.MotionEvent
|
||||||
import android.view.View.OnClickListener
|
import android.view.View.OnClickListener
|
||||||
|
@ -26,6 +25,7 @@ import org.pixeldroid.app.databinding.ActivityStoriesBinding
|
||||||
import org.pixeldroid.app.posts.setTextViewFromISO8601
|
import org.pixeldroid.app.posts.setTextViewFromISO8601
|
||||||
import org.pixeldroid.app.utils.BaseActivity
|
import org.pixeldroid.app.utils.BaseActivity
|
||||||
import org.pixeldroid.app.utils.api.objects.Account
|
import org.pixeldroid.app.utils.api.objects.Account
|
||||||
|
import org.pixeldroid.app.utils.api.objects.Story
|
||||||
import org.pixeldroid.app.utils.api.objects.StoryCarousel
|
import org.pixeldroid.app.utils.api.objects.StoryCarousel
|
||||||
|
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@ class StoriesActivity: BaseActivity() {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val STORY_CAROUSEL = "LaunchStoryCarousel"
|
const val STORY_CAROUSEL = "LaunchStoryCarousel"
|
||||||
|
const val STORY_CAROUSEL_SELF = "LaunchStoryCarouselSelf"
|
||||||
const val STORY_CAROUSEL_USER_ID = "LaunchStoryUserId"
|
const val STORY_CAROUSEL_USER_ID = "LaunchStoryUserId"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,14 +50,15 @@ class StoriesActivity: BaseActivity() {
|
||||||
|
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
val carousel = intent.getSerializableExtra(STORY_CAROUSEL) as StoryCarousel
|
val carousel = intent.getSerializableExtra(STORY_CAROUSEL) as? StoryCarousel
|
||||||
val userId = intent.getStringExtra(STORY_CAROUSEL_USER_ID)
|
val userId = intent.getStringExtra(STORY_CAROUSEL_USER_ID)
|
||||||
|
val selfCarousel: Array<Story>? = intent.getSerializableExtra(STORY_CAROUSEL_SELF) as? Array<Story>
|
||||||
|
|
||||||
binding = ActivityStoriesBinding.inflate(layoutInflater)
|
binding = ActivityStoriesBinding.inflate(layoutInflater)
|
||||||
setContentView(binding.root)
|
setContentView(binding.root)
|
||||||
|
|
||||||
val _model: StoriesViewModel by viewModels {
|
val _model: StoriesViewModel by viewModels {
|
||||||
StoriesViewModelFactory(application, carousel, userId)
|
StoriesViewModelFactory(application, carousel, userId, selfCarousel?.asList())
|
||||||
}
|
}
|
||||||
model = _model
|
model = _model
|
||||||
|
|
||||||
|
|
|
@ -4,21 +4,21 @@ import android.app.Application
|
||||||
import android.os.CountDownTimer
|
import android.os.CountDownTimer
|
||||||
import android.text.Editable
|
import android.text.Editable
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import androidx.appcompat.app.AppCompatDelegate
|
|
||||||
import androidx.core.os.LocaleListCompat
|
|
||||||
import androidx.lifecycle.AndroidViewModel
|
import androidx.lifecycle.AndroidViewModel
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import kotlinx.coroutines.flow.update
|
import kotlinx.coroutines.flow.update
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.pixeldroid.app.R
|
import org.pixeldroid.app.R
|
||||||
import org.pixeldroid.app.utils.PixelDroidApplication
|
import org.pixeldroid.app.utils.PixelDroidApplication
|
||||||
|
import org.pixeldroid.app.utils.api.objects.CarouselUserContainer
|
||||||
|
import org.pixeldroid.app.utils.api.objects.Story
|
||||||
import org.pixeldroid.app.utils.api.objects.StoryCarousel
|
import org.pixeldroid.app.utils.api.objects.StoryCarousel
|
||||||
|
import org.pixeldroid.app.utils.db.AppDatabase
|
||||||
import org.pixeldroid.app.utils.di.PixelfedAPIHolder
|
import org.pixeldroid.app.utils.di.PixelfedAPIHolder
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
@ -40,20 +40,21 @@ data class StoriesUiState(
|
||||||
|
|
||||||
class StoriesViewModel(
|
class StoriesViewModel(
|
||||||
application: Application,
|
application: Application,
|
||||||
val carousel: StoryCarousel,
|
val carousel: StoryCarousel?,
|
||||||
userId: String?
|
userId: String?,
|
||||||
|
val selfCarousel: List<Story>?
|
||||||
) : AndroidViewModel(application) {
|
) : AndroidViewModel(application) {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var apiHolder: PixelfedAPIHolder
|
lateinit var apiHolder: PixelfedAPIHolder
|
||||||
|
@Inject
|
||||||
|
lateinit var db: AppDatabase
|
||||||
|
|
||||||
private var currentAccount = carousel.nodes?.firstOrNull { it?.user?.id == userId }
|
private var currentAccount: CarouselUserContainer?
|
||||||
|
|
||||||
private val _uiState: MutableStateFlow<StoriesUiState> = MutableStateFlow(
|
private val _uiState: MutableStateFlow<StoriesUiState>
|
||||||
newUiStateFromCurrentAccount()
|
|
||||||
)
|
|
||||||
|
|
||||||
val uiState: StateFlow<StoriesUiState> = _uiState
|
val uiState: StateFlow<StoriesUiState>
|
||||||
|
|
||||||
val count = MutableLiveData<Float>()
|
val count = MutableLiveData<Float>()
|
||||||
|
|
||||||
|
@ -61,12 +62,20 @@ class StoriesViewModel(
|
||||||
|
|
||||||
init {
|
init {
|
||||||
(application as PixelDroidApplication).getAppComponent().inject(this)
|
(application as PixelDroidApplication).getAppComponent().inject(this)
|
||||||
|
currentAccount =
|
||||||
|
if (selfCarousel != null) {
|
||||||
|
db.userDao().getActiveUser()?.let { CarouselUserContainer(it, selfCarousel) }
|
||||||
|
} else carousel?.nodes?.firstOrNull { it?.user?.id == userId }
|
||||||
|
|
||||||
|
_uiState = MutableStateFlow(newUiStateFromCurrentAccount())
|
||||||
|
uiState = _uiState
|
||||||
|
|
||||||
startTimerForCurrent()
|
startTimerForCurrent()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setTimer(timerLength: Float) {
|
private fun setTimer(timerLength: Float) {
|
||||||
count.value = timerLength
|
count.value = timerLength
|
||||||
timer = object: CountDownTimer((timerLength * 1000).toLong(), 100){
|
timer = object: CountDownTimer((timerLength * 1000).toLong(), 50){
|
||||||
|
|
||||||
override fun onTick(millisUntilFinished: Long) {
|
override fun onTick(millisUntilFinished: Long) {
|
||||||
count.value = millisUntilFinished.toFloat() / 1000
|
count.value = millisUntilFinished.toFloat() / 1000
|
||||||
|
@ -98,8 +107,9 @@ class StoriesViewModel(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if(selfCarousel != null) return
|
||||||
val currentUserId = currentAccount?.user?.id
|
val currentUserId = currentAccount?.user?.id
|
||||||
val currentAccountIndex = carousel.nodes?.indexOfFirst { it?.user?.id == currentUserId } ?: return
|
val currentAccountIndex = carousel?.nodes?.indexOfFirst { it?.user?.id == currentUserId } ?: return
|
||||||
currentAccount = when (index) {
|
currentAccount = when (index) {
|
||||||
uiState.value.imageList.size -> {
|
uiState.value.imageList.size -> {
|
||||||
// Go to next user
|
// Go to next user
|
||||||
|
@ -209,10 +219,11 @@ class StoriesViewModel(
|
||||||
|
|
||||||
class StoriesViewModelFactory(
|
class StoriesViewModelFactory(
|
||||||
val application: Application,
|
val application: Application,
|
||||||
val carousel: StoryCarousel,
|
val carousel: StoryCarousel?,
|
||||||
val userId: String?
|
val userId: String?,
|
||||||
|
val selfCarousel: List<Story>?
|
||||||
) : ViewModelProvider.Factory {
|
) : ViewModelProvider.Factory {
|
||||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||||
return modelClass.getConstructor(Application::class.java, StoryCarousel::class.java, String::class.java).newInstance(application, carousel, userId)
|
return modelClass.getConstructor(Application::class.java, StoryCarousel::class.java, String::class.java, List::class.java).newInstance(application, carousel, userId, selfCarousel)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,26 +2,33 @@ package org.pixeldroid.app.stories
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import android.graphics.Color
|
||||||
|
import android.graphics.PorterDuff
|
||||||
|
import android.graphics.PorterDuffColorFilter
|
||||||
|
import android.graphics.RenderEffect
|
||||||
|
import android.graphics.Shader
|
||||||
|
import android.os.Build
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.lifecycle.LifecycleCoroutineScope
|
import androidx.lifecycle.LifecycleCoroutineScope
|
||||||
import androidx.paging.LoadState
|
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.pixeldroid.app.R
|
import org.pixeldroid.app.R
|
||||||
import org.pixeldroid.app.databinding.StoryCarouselAddStoryBinding
|
|
||||||
import org.pixeldroid.app.databinding.StoryCarouselBinding
|
import org.pixeldroid.app.databinding.StoryCarouselBinding
|
||||||
import org.pixeldroid.app.databinding.StoryCarouselItemBinding
|
import org.pixeldroid.app.databinding.StoryCarouselItemBinding
|
||||||
|
import org.pixeldroid.app.databinding.StoryCarouselSelfBinding
|
||||||
import org.pixeldroid.app.postCreation.camera.CameraActivity
|
import org.pixeldroid.app.postCreation.camera.CameraActivity
|
||||||
import org.pixeldroid.app.postCreation.camera.CameraFragment
|
import org.pixeldroid.app.postCreation.camera.CameraFragment
|
||||||
import org.pixeldroid.app.utils.api.objects.CarouselUserContainer
|
import org.pixeldroid.app.utils.api.objects.CarouselUserContainer
|
||||||
|
import org.pixeldroid.app.utils.api.objects.Story
|
||||||
import org.pixeldroid.app.utils.api.objects.StoryCarousel
|
import org.pixeldroid.app.utils.api.objects.StoryCarousel
|
||||||
import org.pixeldroid.app.utils.di.PixelfedAPIHolder
|
import org.pixeldroid.app.utils.di.PixelfedAPIHolder
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adapter to the show the a [RecyclerView] item for a [LoadState]
|
* Adapter that has either 1 or 0 items, to show stories widget or not
|
||||||
*/
|
*/
|
||||||
class StoriesAdapter(val lifecycleScope: LifecycleCoroutineScope, val apiHolder: PixelfedAPIHolder) : RecyclerView.Adapter<StoryCarouselViewHolder>() {
|
class StoriesAdapter(val lifecycleScope: LifecycleCoroutineScope, val apiHolder: PixelfedAPIHolder) : RecyclerView.Adapter<StoryCarouselViewHolder>() {
|
||||||
var carousel: StoryCarousel? = null
|
var carousel: StoryCarousel? = null
|
||||||
|
@ -74,7 +81,8 @@ class StoriesAdapter(val lifecycleScope: LifecycleCoroutineScope, val apiHolder:
|
||||||
val api = apiHolder.api ?: apiHolder.setToCurrentUser()
|
val api = apiHolder.api ?: apiHolder.setToCurrentUser()
|
||||||
val carousel = api.carousel()
|
val carousel = api.carousel()
|
||||||
|
|
||||||
if (carousel.nodes?.isEmpty() != true) {
|
// If there are stories from someone else or our stories to show, show them
|
||||||
|
if (carousel.nodes?.isEmpty() == false || carousel.self?.nodes?.isEmpty() == false) {
|
||||||
// Pass carousel to adapter
|
// Pass carousel to adapter
|
||||||
gotStories(carousel)
|
gotStories(carousel)
|
||||||
} else {
|
} else {
|
||||||
|
@ -113,8 +121,12 @@ class StoriesListAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||||
private var storyCarousel: StoryCarousel? = null
|
private var storyCarousel: StoryCarousel? = null
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||||
return if(viewType == R.layout.story_carousel_add_story){
|
return if(viewType == R.layout.story_carousel_self){
|
||||||
val v = StoryCarouselAddStoryBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
val v = StoryCarouselSelfBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
||||||
|
v.myStory.visibility =
|
||||||
|
if (storyCarousel?.self?.nodes?.isEmpty() == false) View.VISIBLE
|
||||||
|
else View.GONE
|
||||||
|
|
||||||
AddViewHolder(v)
|
AddViewHolder(v)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -124,7 +136,7 @@ class StoriesListAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemViewType(position: Int): Int {
|
override fun getItemViewType(position: Int): Int {
|
||||||
return if(position == 0) R.layout.story_carousel_add_story
|
return if(position == 0) R.layout.story_carousel_self
|
||||||
else R.layout.story_carousel_item
|
else R.layout.story_carousel_item
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,21 +145,15 @@ class StoriesListAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||||
val carouselPosition = position - 1
|
val carouselPosition = position - 1
|
||||||
storyCarousel?.nodes?.get(carouselPosition)?.let { (holder as ViewHolder).bindItem(it) }
|
storyCarousel?.nodes?.get(carouselPosition)?.let { (holder as ViewHolder).bindItem(it) }
|
||||||
holder.itemView.setOnClickListener {
|
holder.itemView.setOnClickListener {
|
||||||
storyCarousel?.let { carousel ->
|
|
||||||
storyCarousel?.nodes?.get(carouselPosition)?.user?.id?.let { userId ->
|
storyCarousel?.nodes?.get(carouselPosition)?.user?.id?.let { userId ->
|
||||||
val intent = Intent(holder.itemView.context, StoriesActivity::class.java)
|
val intent = Intent(holder.itemView.context, StoriesActivity::class.java)
|
||||||
intent.putExtra(StoriesActivity.STORY_CAROUSEL, carousel)
|
intent.putExtra(StoriesActivity.STORY_CAROUSEL, storyCarousel)
|
||||||
intent.putExtra(StoriesActivity.STORY_CAROUSEL_USER_ID, userId)
|
intent.putExtra(StoriesActivity.STORY_CAROUSEL_USER_ID, userId)
|
||||||
holder.itemView.context.startActivity(intent)
|
holder.itemView.context.startActivity(intent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
holder.itemView.setOnClickListener {
|
storyCarousel?.self?.nodes?.let { (holder as? AddViewHolder)?.bindItem(it.filterNotNull()) }
|
||||||
val intent = Intent(holder.itemView.context, CameraActivity::class.java)
|
|
||||||
intent.putExtra(CameraFragment.CAMERA_ACTIVITY_STORY, true)
|
|
||||||
holder.itemView.context.startActivity(intent)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,7 +168,35 @@ class StoriesListAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||||
notifyDataSetChanged()
|
notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
class AddViewHolder(itemBinding: StoryCarouselAddStoryBinding) : RecyclerView.ViewHolder(itemBinding.root)
|
class AddViewHolder(private val itemBinding: StoryCarouselSelfBinding) : RecyclerView.ViewHolder(itemBinding.root) {
|
||||||
|
fun bindItem(nodes: List<Story>) {
|
||||||
|
itemBinding.addStory.setOnClickListener {
|
||||||
|
val intent = Intent(itemView.context, CameraActivity::class.java)
|
||||||
|
intent.putExtra(CameraFragment.CAMERA_ACTIVITY_STORY, true)
|
||||||
|
itemView.context.startActivity(intent)
|
||||||
|
}
|
||||||
|
itemBinding.myStory.setOnClickListener {
|
||||||
|
val intent = Intent(itemView.context, StoriesActivity::class.java)
|
||||||
|
intent.putExtra(StoriesActivity.STORY_CAROUSEL_SELF, nodes.toTypedArray())
|
||||||
|
itemView.context.startActivity(intent)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only show image on new Android versions, because the transformations need it and the
|
||||||
|
// text is not legible without the transformations
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||||
|
Glide.with(itemBinding.root).load(nodes.firstOrNull()?.src).into(itemBinding.carouselImageView)
|
||||||
|
val value = 70 * 255 / 100
|
||||||
|
val darkFilterRenderEffect = PorterDuffColorFilter(Color.argb(value, 0, 0, 0), PorterDuff.Mode.SRC_ATOP)
|
||||||
|
val blurRenderEffect =
|
||||||
|
RenderEffect.createBlurEffect(
|
||||||
|
4f, 4f, Shader.TileMode.MIRROR
|
||||||
|
)
|
||||||
|
val combinedEffect = RenderEffect.createColorFilterEffect(darkFilterRenderEffect, blurRenderEffect)
|
||||||
|
itemBinding.carouselImageView.setRenderEffect(combinedEffect)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class ViewHolder(private val itemBinding: StoryCarouselItemBinding) :
|
class ViewHolder(private val itemBinding: StoryCarouselItemBinding) :
|
||||||
RecyclerView.ViewHolder(itemBinding.root) {
|
RecyclerView.ViewHolder(itemBinding.root) {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package org.pixeldroid.app.utils.api.objects
|
package org.pixeldroid.app.utils.api.objects
|
||||||
|
|
||||||
|
import org.pixeldroid.app.utils.db.entities.UserDatabaseEntity
|
||||||
import java.io.Serializable
|
import java.io.Serializable
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
|
|
||||||
|
@ -23,7 +24,13 @@ data class CarouselUser(
|
||||||
data class CarouselUserContainer(
|
data class CarouselUserContainer(
|
||||||
val user: CarouselUser?,
|
val user: CarouselUser?,
|
||||||
val nodes: List<Story?>?,
|
val nodes: List<Story?>?,
|
||||||
): Serializable
|
): Serializable {
|
||||||
|
constructor(user: UserDatabaseEntity, nodes: List<Story?>?) : this(
|
||||||
|
CarouselUser(user.user_id, user.username, null, user.avatar_static,
|
||||||
|
local = true,
|
||||||
|
is_author = true
|
||||||
|
), nodes)
|
||||||
|
}
|
||||||
|
|
||||||
data class Story(
|
data class Story(
|
||||||
val id: String?,
|
val id: String?,
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
<vector android:height="24dp" android:tint="#FFFFFF"
|
||||||
|
android:viewportHeight="24" android:viewportWidth="24"
|
||||||
|
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<path android:fillColor="@android:color/white" android:pathData="M4,6L2,6v14c0,1.1 0.9,2 2,2h14v-2L4,20L4,6zM20,2L8,2c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L22,4c0,-1.1 -0.9,-2 -2,-2zM12,14.5v-9l6,4.5 -6,4.5z"/>
|
||||||
|
</vector>
|
|
@ -1,46 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<com.google.android.material.carousel.MaskableFrameLayout
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:id="@+id/carousel_add_story"
|
|
||||||
android:layout_width="120dp"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:layout_marginStart="4dp"
|
|
||||||
tools:context="androidx.recyclerview.widget.RecyclerView"
|
|
||||||
android:layout_marginEnd="4dp"
|
|
||||||
android:background="?attr/colorSecondaryContainer"
|
|
||||||
android:foreground="?attr/selectableItemBackground"
|
|
||||||
app:shapeAppearance="?attr/shapeAppearanceCornerExtraLarge">
|
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/carousel_image_view"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="40dp"
|
|
||||||
android:contentDescription="@string/story_image"
|
|
||||||
android:scaleType="fitCenter"
|
|
||||||
android:src="@drawable/collection_add"
|
|
||||||
app:layout_constraintBottom_toTopOf="@id/textView"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
app:tint="?attr/colorOnSecondaryContainer" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/textView"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/add_story"
|
|
||||||
android:textColor="?attr/colorOnSecondaryContainer"
|
|
||||||
android:textStyle="bold"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/carousel_image_view" />
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
</com.google.android.material.carousel.MaskableFrameLayout>
|
|
|
@ -0,0 +1,102 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<com.google.android.material.carousel.MaskableFrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/carousel_add_story"
|
||||||
|
android:layout_width="120dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_marginStart="4dp"
|
||||||
|
android:layout_marginEnd="4dp"
|
||||||
|
android:background="?attr/colorStoryImage"
|
||||||
|
app:shapeAppearance="?attr/shapeAppearanceCornerExtraLarge"
|
||||||
|
tools:context="androidx.recyclerview.widget.RecyclerView">
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/carousel_image_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:contentDescription="@string/story_image"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
|
tools:srcCompat="@tools:sample/backgrounds/scenic" />
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:id="@+id/add_story"
|
||||||
|
android:foreground="?attr/selectableItemBackground"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/my_story"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/carousel_add_story_icon"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="40dp"
|
||||||
|
android:contentDescription="@string/add_story"
|
||||||
|
android:scaleType="fitCenter"
|
||||||
|
android:src="@drawable/collection_add"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/textView"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:tint="?attr/colorOnStoryImage" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/textView"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/add_story"
|
||||||
|
android:textColor="?attr/colorOnStoryImage"
|
||||||
|
android:textStyle="bold"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/carousel_add_story_icon" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:id="@+id/my_story"
|
||||||
|
android:foreground="?attr/selectableItemBackground"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/add_story"
|
||||||
|
tools:visibility="visible">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/my_story_icon"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="40dp"
|
||||||
|
android:contentDescription="@string/my_story"
|
||||||
|
android:scaleType="fitCenter"
|
||||||
|
android:src="@drawable/story_play"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/my_story_text"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:tint="?attr/colorOnStoryImage" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/my_story_text"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/my_story"
|
||||||
|
android:textColor="?attr/colorOnStoryImage"
|
||||||
|
android:textStyle="bold"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/my_story_icon" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
</com.google.android.material.carousel.MaskableFrameLayout>
|
|
@ -338,4 +338,12 @@ For more info about Pixelfed, you can check here: https://pixelfed.org"</string>
|
||||||
<string name="add_story">Add Story</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_could_not_see">Error: could not mark story as seen</string>
|
||||||
<string name="story_pause">Start or pause the stories</string>
|
<string name="story_pause">Start or pause the stories</string>
|
||||||
|
<string name="my_story">My story</string>
|
||||||
|
<!-- Type of new publication that is being created (as opposed to a traditional post, if this is chosen it would be a story) -->
|
||||||
|
<string name="type_story">Story</string>
|
||||||
|
<!-- Type of new publication that is being created (as opposed to a story, if this is chosen it would be a traditional post) -->
|
||||||
|
<string name="type_post">Post</string>
|
||||||
|
<string name="continue_post_creation">Continue</string>
|
||||||
|
<string name="extraneous_pictures_stories">Pictures after the first were removed but can be restored by switching back to creating a Post</string>
|
||||||
|
<string name="story_duration">Story Duration</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
Loading…
Reference in New Issue