Update My Stories logic when user has not sent to a distribution list.
This commit is contained in:
parent
19861ef0d1
commit
d9ffd67f36
8 changed files with 51 additions and 38 deletions
|
@ -20,8 +20,7 @@ object MyStoriesItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
class Model(
|
class Model(
|
||||||
val hasOutgoingStories: Boolean,
|
val onClick: () -> Unit,
|
||||||
val onClick: (Boolean) -> Unit,
|
|
||||||
val onClickThumbnail: () -> Unit
|
val onClickThumbnail: () -> Unit
|
||||||
) : PreferenceModel<Model>() {
|
) : PreferenceModel<Model>() {
|
||||||
override fun areItemsTheSame(newItem: Model): Boolean = true
|
override fun areItemsTheSame(newItem: Model): Boolean = true
|
||||||
|
@ -34,7 +33,7 @@ object MyStoriesItem {
|
||||||
private val badgeView: BadgeImageView = itemView.findViewById(R.id.badge)
|
private val badgeView: BadgeImageView = itemView.findViewById(R.id.badge)
|
||||||
|
|
||||||
override fun bind(model: Model) {
|
override fun bind(model: Model) {
|
||||||
itemView.setOnClickListener { model.onClick(model.hasOutgoingStories) }
|
itemView.setOnClickListener { model.onClick() }
|
||||||
thumbnail.setOnClickListener { model.onClickThumbnail() }
|
thumbnail.setOnClickListener { model.onClickThumbnail() }
|
||||||
|
|
||||||
avatarView.displayProfileAvatar(Recipient.self())
|
avatarView.displayProfileAvatar(Recipient.self())
|
||||||
|
|
|
@ -110,13 +110,8 @@ class StoriesLandingFragment : DSLSettingsFragment(layoutId = R.layout.stories_l
|
||||||
if (state.displayMyStoryItem) {
|
if (state.displayMyStoryItem) {
|
||||||
customPref(
|
customPref(
|
||||||
MyStoriesItem.Model(
|
MyStoriesItem.Model(
|
||||||
state.hasOutgoingStories,
|
|
||||||
onClick = {
|
onClick = {
|
||||||
if (it) {
|
startActivity(Intent(requireContext(), MyStoriesActivity::class.java))
|
||||||
startActivity(Intent(requireContext(), MyStoriesActivity::class.java))
|
|
||||||
} else {
|
|
||||||
cameraFab.performClick()
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
onClickThumbnail = {
|
onClickThumbnail = {
|
||||||
cameraFab.performClick()
|
cameraFab.performClick()
|
||||||
|
|
|
@ -27,7 +27,7 @@ class StoriesLandingRepository(context: Context) {
|
||||||
}.subscribeOn(Schedulers.io())
|
}.subscribeOn(Schedulers.io())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getStories(): Observable<StoriesResult> {
|
fun getStories(): Observable<List<StoriesLandingItemData>> {
|
||||||
val storyRecipients: Observable<Map<Recipient, List<StoryResult>>> = Observable.create { emitter ->
|
val storyRecipients: Observable<Map<Recipient, List<StoryResult>>> = Observable.create { emitter ->
|
||||||
fun refresh() {
|
fun refresh() {
|
||||||
val myStoriesId = SignalDatabase.recipients.getOrInsertFromDistributionListId(DistributionListId.MY_STORY)
|
val myStoriesId = SignalDatabase.recipients.getOrInsertFromDistributionListId(DistributionListId.MY_STORY)
|
||||||
|
@ -57,7 +57,7 @@ class StoriesLandingRepository(context: Context) {
|
||||||
refresh()
|
refresh()
|
||||||
}
|
}
|
||||||
|
|
||||||
val storiesLandingItemData = storyRecipients.switchMap { map ->
|
return storyRecipients.switchMap { map ->
|
||||||
val observables = map.map { (recipient, results) ->
|
val observables = map.map { (recipient, results) ->
|
||||||
val messages = results
|
val messages = results
|
||||||
.sortedBy { it.messageSentTimestamp }
|
.sortedBy { it.messageSentTimestamp }
|
||||||
|
@ -74,21 +74,6 @@ class StoriesLandingRepository(context: Context) {
|
||||||
it.toList() as List<StoriesLandingItemData>
|
it.toList() as List<StoriesLandingItemData>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val hasOutgoingStories: Observable<Boolean> = storyRecipients.concatMap {
|
|
||||||
Observable.fromCallable {
|
|
||||||
SignalDatabase.mms.getAllOutgoingStories(false).use {
|
|
||||||
it.next != null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Observable.combineLatest(
|
|
||||||
storiesLandingItemData,
|
|
||||||
hasOutgoingStories
|
|
||||||
) { data, outgoingStories ->
|
|
||||||
StoriesResult(data, outgoingStories)
|
|
||||||
}.observeOn(Schedulers.io())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createStoriesLandingItemData(sender: Recipient, messageRecords: List<MessageRecord>): Observable<StoriesLandingItemData> {
|
private fun createStoriesLandingItemData(sender: Recipient, messageRecords: List<MessageRecord>): Observable<StoriesLandingItemData> {
|
||||||
|
@ -142,9 +127,4 @@ class StoriesLandingRepository(context: Context) {
|
||||||
SignalDatabase.recipients.setHideStory(recipientId, hideStory)
|
SignalDatabase.recipients.setHideStory(recipientId, hideStory)
|
||||||
}.subscribeOn(Schedulers.io())
|
}.subscribeOn(Schedulers.io())
|
||||||
}
|
}
|
||||||
|
|
||||||
data class StoriesResult(
|
|
||||||
val data: List<StoriesLandingItemData>,
|
|
||||||
val hasOutgoingStories: Boolean
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@ data class StoriesLandingState(
|
||||||
val storiesLandingItems: List<StoriesLandingItemData> = emptyList(),
|
val storiesLandingItems: List<StoriesLandingItemData> = emptyList(),
|
||||||
val displayMyStoryItem: Boolean = false,
|
val displayMyStoryItem: Boolean = false,
|
||||||
val isHiddenContentVisible: Boolean = false,
|
val isHiddenContentVisible: Boolean = false,
|
||||||
val hasOutgoingStories: Boolean = false,
|
|
||||||
val loadingState: LoadingState = LoadingState.INIT
|
val loadingState: LoadingState = LoadingState.INIT
|
||||||
) {
|
) {
|
||||||
enum class LoadingState {
|
enum class LoadingState {
|
||||||
|
|
|
@ -17,13 +17,12 @@ class StoriesLandingViewModel(private val storiesLandingRepository: StoriesLandi
|
||||||
val state: LiveData<StoriesLandingState> = store.stateLiveData
|
val state: LiveData<StoriesLandingState> = store.stateLiveData
|
||||||
|
|
||||||
init {
|
init {
|
||||||
disposables += storiesLandingRepository.getStories().subscribe { (stories, hasOutgoingGroupStories) ->
|
disposables += storiesLandingRepository.getStories().subscribe { stories ->
|
||||||
store.update { state ->
|
store.update { state ->
|
||||||
state.copy(
|
state.copy(
|
||||||
loadingState = StoriesLandingState.LoadingState.LOADED,
|
loadingState = StoriesLandingState.LoadingState.LOADED,
|
||||||
storiesLandingItems = stories.sorted(),
|
storiesLandingItems = stories.sorted(),
|
||||||
displayMyStoryItem = stories.isEmpty() || stories.none { it.storyRecipient.isMyStory },
|
displayMyStoryItem = stories.isEmpty() || stories.none { it.storyRecipient.isMyStory }
|
||||||
hasOutgoingStories = hasOutgoingGroupStories
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package org.thoughtcrime.securesms.stories.my
|
package org.thoughtcrime.securesms.stories.my
|
||||||
|
|
||||||
|
import android.view.View
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.activity.OnBackPressedCallback
|
import androidx.activity.OnBackPressedCallback
|
||||||
import androidx.core.app.ActivityOptionsCompat
|
import androidx.core.app.ActivityOptionsCompat
|
||||||
|
@ -19,8 +20,10 @@ import org.thoughtcrime.securesms.stories.dialogs.StoryContextMenu
|
||||||
import org.thoughtcrime.securesms.stories.viewer.StoryViewerActivity
|
import org.thoughtcrime.securesms.stories.viewer.StoryViewerActivity
|
||||||
import org.thoughtcrime.securesms.util.LifecycleDisposable
|
import org.thoughtcrime.securesms.util.LifecycleDisposable
|
||||||
import org.thoughtcrime.securesms.util.Util
|
import org.thoughtcrime.securesms.util.Util
|
||||||
|
import org.thoughtcrime.securesms.util.visible
|
||||||
|
|
||||||
class MyStoriesFragment : DSLSettingsFragment(
|
class MyStoriesFragment : DSLSettingsFragment(
|
||||||
|
layoutId = R.layout.stories_my_stories_fragment,
|
||||||
titleId = R.string.StoriesLandingFragment__my_stories
|
titleId = R.string.StoriesLandingFragment__my_stories
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
@ -44,12 +47,11 @@ class MyStoriesFragment : DSLSettingsFragment(
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val emptyNotice = requireView().findViewById<View>(R.id.empty_notice)
|
||||||
lifecycleDisposable.bindTo(viewLifecycleOwner)
|
lifecycleDisposable.bindTo(viewLifecycleOwner)
|
||||||
viewModel.state.observe(viewLifecycleOwner) {
|
viewModel.state.observe(viewLifecycleOwner) {
|
||||||
adapter.submitList(getConfiguration(it).toMappingModelList())
|
adapter.submitList(getConfiguration(it).toMappingModelList())
|
||||||
if (it.distributionSets.isEmpty()) {
|
emptyNotice.visible = it.distributionSets.isEmpty()
|
||||||
requireActivity().finish()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
37
app/src/main/res/layout/stories_my_stories_fragment.xml
Normal file
37
app/src/main/res/layout/stories_my_stories_fragment.xml
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<include layout="@layout/dsl_settings_toolbar" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/empty_notice"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginHorizontal="68dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="@string/MyStoriesFragment__updates_to_your_story_will_show_up_here"
|
||||||
|
android:textAppearance="@style/Signal.Text.Body"
|
||||||
|
android:textColor="@color/signal_text_secondary"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:layout_constrainedWidth="true"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/toolbar"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/recycler"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:orientation="vertical"
|
||||||
|
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/toolbar" />
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -2230,6 +2230,8 @@
|
||||||
|
|
||||||
<!-- Displayed in a toast when user long presses an item in MyStories -->
|
<!-- Displayed in a toast when user long presses an item in MyStories -->
|
||||||
<string name="MyStoriesFragment__copied_sent_timestamp_to_clipboard">Copied sent timestamp to clipboard.</string>
|
<string name="MyStoriesFragment__copied_sent_timestamp_to_clipboard">Copied sent timestamp to clipboard.</string>
|
||||||
|
<!-- Displayed when there are no outgoing stories -->
|
||||||
|
<string name="MyStoriesFragment__updates_to_your_story_will_show_up_here">Updates to your story will show up here.</string>
|
||||||
|
|
||||||
<!-- GroupUtil -->
|
<!-- GroupUtil -->
|
||||||
<plurals name="GroupUtil_joined_the_group">
|
<plurals name="GroupUtil_joined_the_group">
|
||||||
|
|
Loading…
Add table
Reference in a new issue