Allow user to launch directly to a specific story, fix story chronology.

fork-5.53.8
Alex Hart 2022-03-16 14:22:11 -03:00 zatwierdzone przez Cody Henthorne
rodzic 8bb27b60fa
commit 63e48efdfe
13 zmienionych plików z 55 dodań i 25 usunięć

Wyświetl plik

@ -183,7 +183,7 @@ public abstract class MessageDatabase extends Database implements MmsSmsColumns
public abstract boolean isStory(long messageId);
public abstract @NonNull Reader getOutgoingStoriesTo(@NonNull RecipientId recipientId);
public abstract @NonNull Reader getAllOutgoingStories();
public abstract @NonNull Reader getAllOutgoingStories(boolean reverse);
public abstract @NonNull Reader getAllStories();
public abstract @NonNull List<RecipientId> getAllStoriesRecipientsList();
public abstract @NonNull Reader getAllStoriesFor(@NonNull RecipientId recipientId);

Wyświetl plik

@ -571,10 +571,10 @@ public class MmsDatabase extends MessageDatabase {
}
@Override
public @NonNull MessageDatabase.Reader getAllOutgoingStories() {
public @NonNull MessageDatabase.Reader getAllOutgoingStories(boolean reverse) {
String where = IS_STORY_CLAUSE + " AND (" + getOutgoingTypeClause() + ")";
return new Reader(rawQuery(where, null, true, -1L));
return new Reader(rawQuery(where, null, reverse, -1L));
}
@Override
@ -587,7 +587,7 @@ public class MmsDatabase extends MessageDatabase {
long threadId = SignalDatabase.threads().getThreadIdIfExistsFor(recipientId);
String where = IS_STORY_CLAUSE + " AND " + THREAD_ID_WHERE;
String[] whereArgs = SqlUtil.buildArgs(threadId);
Cursor cursor = rawQuery(where, whereArgs, true, -1L);
Cursor cursor = rawQuery(where, whereArgs, false, -1L);
return new Reader(cursor);
}

Wyświetl plik

@ -1395,7 +1395,7 @@ public class SmsDatabase extends MessageDatabase {
}
@Override
public @NonNull MessageDatabase.Reader getAllOutgoingStories() {
public @NonNull MessageDatabase.Reader getAllOutgoingStories(boolean reverse) {
throw new UnsupportedOperationException();
}

Wyświetl plik

@ -61,8 +61,13 @@ class MyStoriesFragment : DSLSettingsFragment(
lifecycleDisposable += viewModel.resend(it.distributionStory.messageRecord).subscribe()
Toast.makeText(requireContext(), R.string.message_recipients_list_item__resend, Toast.LENGTH_SHORT).show()
} else {
// TODO [stories] pass in something more specific to start with the correct progress
startActivity(StoryViewerActivity.createIntent(requireContext(), Recipient.self().id))
val recipientId = if (it.distributionStory.messageRecord.recipient.isGroup) {
it.distributionStory.messageRecord.recipient.id
} else {
Recipient.self().id
}
startActivity(StoryViewerActivity.createIntent(requireContext(), recipientId, conversationMessage.messageRecord.id))
}
},
onSaveClick = {

Wyświetl plik

@ -82,6 +82,7 @@ object MyStoriesItem {
private val errorIndicator: View = itemView.findViewById(R.id.error_indicator)
override fun bind(model: Model) {
storyPreview.isClickable = false
itemView.setOnClickListener { model.onClick(model) }
downloadTarget.setOnClickListener { model.onSaveClick(model) }
moreTarget.setOnClickListener { showContextMenu(model) }

Wyświetl plik

@ -26,7 +26,7 @@ class MyStoriesRepository(context: Context) {
return Observable.create { emitter ->
fun refresh() {
val storiesMap = mutableMapOf<Recipient, List<MessageRecord>>()
SignalDatabase.mms.allOutgoingStories.use {
SignalDatabase.mms.getAllOutgoingStories(true).use {
while (it.next != null) {
val messageRecord = it.current
val currentList = storiesMap[messageRecord.recipient] ?: emptyList()

Wyświetl plik

@ -21,17 +21,22 @@ class StoryViewerActivity : PassphraseRequiredActivity() {
if (savedInstanceState == null) {
supportFragmentManager.beginTransaction()
.replace(R.id.fragment_container, StoryViewerFragment.create(intent.getParcelableExtra(ARG_START_RECIPIENT_ID)!!))
.replace(R.id.fragment_container, StoryViewerFragment.create(
intent.getParcelableExtra(ARG_START_RECIPIENT_ID)!!,
intent.getLongExtra(ARG_START_STORY_ID, -1L)
))
.commit()
}
}
companion object {
private const val ARG_START_RECIPIENT_ID = "start.recipient.id"
private const val ARG_START_STORY_ID = "start.story.id"
fun createIntent(context: Context, storyId: RecipientId): Intent {
fun createIntent(context: Context, recipientId: RecipientId, storyId: Long = -1L): Intent {
return Intent(context, StoryViewerActivity::class.java)
.putExtra(ARG_START_RECIPIENT_ID, storyId)
.putExtra(ARG_START_RECIPIENT_ID, recipientId)
.putExtra(ARG_START_STORY_ID, storyId)
}
}
}

Wyświetl plik

@ -27,10 +27,13 @@ class StoryViewerFragment : Fragment(R.layout.stories_viewer_fragment), StoryVie
private val storyRecipientId: RecipientId
get() = requireArguments().getParcelable(ARG_START_RECIPIENT_ID)!!
private val storyId: Long
get() = requireArguments().getLong(ARG_START_STORY_ID, -1L)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
storyPager = view.findViewById(R.id.story_item_pager)
val adapter = StoryViewerPagerAdapter(this)
val adapter = StoryViewerPagerAdapter(this, storyId)
storyPager.adapter = adapter
viewModel.state.observe(viewLifecycleOwner) { state ->
@ -77,11 +80,13 @@ class StoryViewerFragment : Fragment(R.layout.stories_viewer_fragment), StoryVie
companion object {
private const val ARG_START_RECIPIENT_ID = "start.recipient.id"
private const val ARG_START_STORY_ID = "start.story.id"
fun create(storyRecipientId: RecipientId): Fragment {
fun create(storyRecipientId: RecipientId, storyId: Long): Fragment {
return StoryViewerFragment().apply {
arguments = Bundle().apply {
putParcelable(ARG_START_RECIPIENT_ID, storyRecipientId)
putLong(ARG_START_STORY_ID, storyId)
}
}
}

Wyświetl plik

@ -6,7 +6,7 @@ import androidx.viewpager2.adapter.FragmentStateAdapter
import org.thoughtcrime.securesms.recipients.RecipientId
import org.thoughtcrime.securesms.stories.viewer.page.StoryViewerPageFragment
class StoryViewerPagerAdapter(fragment: Fragment) : FragmentStateAdapter(fragment) {
class StoryViewerPagerAdapter(fragment: Fragment, private val initialStoryId: Long) : FragmentStateAdapter(fragment) {
private var pages: List<RecipientId> = emptyList()
@ -21,7 +21,7 @@ class StoryViewerPagerAdapter(fragment: Fragment) : FragmentStateAdapter(fragmen
override fun getItemCount(): Int = pages.size
override fun createFragment(position: Int): Fragment {
return StoryViewerPageFragment.create(pages[position])
return StoryViewerPageFragment.create(pages[position], initialStoryId)
}
private class Callback(

Wyświetl plik

@ -19,7 +19,7 @@ class StoryViewerRepository {
val myStory: RecipientId = SignalDatabase.recipients.getOrInsertFromDistributionListId(DistributionListId.MY_STORY)
val myStoriesCount = SignalDatabase.mms.allOutgoingStories.use {
val myStoriesCount = SignalDatabase.mms.getAllOutgoingStories(true).use {
var count = 0
while (it.next != null) {
if (!it.current.recipient.isGroup) {

Wyświetl plik

@ -77,7 +77,7 @@ class StoryViewerPageFragment :
private val viewModel: StoryViewerPageViewModel by viewModels(
factoryProducer = {
StoryViewerPageViewModel.Factory(storyRecipientId, StoryViewerPageRepository(requireContext()))
StoryViewerPageViewModel.Factory(storyRecipientId, initialStoryId, StoryViewerPageRepository(requireContext()))
}
)
@ -93,6 +93,9 @@ class StoryViewerPageFragment :
private val storyRecipientId: RecipientId
get() = requireArguments().getParcelable(ARG_STORY_RECIPIENT_ID)!!
private val initialStoryId: Long
get() = requireArguments().getLong(ARG_STORY_ID, -1L)
@SuppressLint("ClickableViewAccessibility")
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
callback = requireListener()
@ -624,11 +627,13 @@ class StoryViewerPageFragment :
companion object {
private const val ARG_STORY_RECIPIENT_ID = "arg.story.recipient.id"
private const val ARG_STORY_ID = "arg.story.id"
fun create(recipientId: RecipientId): Fragment {
fun create(recipientId: RecipientId, initialStoryId: Long): Fragment {
return StoryViewerPageFragment().apply {
arguments = Bundle().apply {
putParcelable(ARG_STORY_RECIPIENT_ID, recipientId)
putLong(ARG_STORY_ID, initialStoryId)
}
}
}

Wyświetl plik

@ -31,7 +31,7 @@ class StoryViewerPageRepository(context: Context) {
fun refresh() {
val stories = if (recipient.isMyStory) {
SignalDatabase.mms.allOutgoingStories
SignalDatabase.mms.getAllOutgoingStories(false)
} else {
SignalDatabase.mms.getAllStoriesFor(recipientId)
}

Wyświetl plik

@ -20,6 +20,7 @@ import kotlin.math.min
*/
class StoryViewerPageViewModel(
private val recipientId: RecipientId,
private val initialStoryId: Long,
private val repository: StoryViewerPageRepository
) : ViewModel() {
@ -44,10 +45,18 @@ class StoryViewerPageViewModel(
fun refresh() {
disposables.clear()
disposables += repository.getStoryPostsFor(recipientId).subscribe { posts ->
store.update {
it.copy(
store.update { state ->
val startIndex = if (state.posts.isEmpty() && initialStoryId > 0) {
val initialIndex = posts.indexOfFirst { it.id == initialStoryId }
initialIndex.takeIf { it > -1 } ?: state.selectedPostIndex
} else {
state.selectedPostIndex
}
state.copy(
posts = posts,
replyState = resolveSwipeToReplyState(it)
replyState = resolveSwipeToReplyState(state, startIndex),
selectedPostIndex = startIndex
)
}
}
@ -162,7 +171,7 @@ class StoryViewerPageViewModel(
storyViewerPlaybackStore.update { it.copy(isDisplayingLinkPreviewTooltip = isDisplayingLinkPreviewTooltip) }
}
private fun resolveSwipeToReplyState(state: StoryViewerPageState, index: Int = state.selectedPostIndex): StoryViewerPageState.ReplyState {
private fun resolveSwipeToReplyState(state: StoryViewerPageState, index: Int): StoryViewerPageState.ReplyState {
if (index !in state.posts.indices) {
return StoryViewerPageState.ReplyState.NONE
}
@ -182,9 +191,9 @@ class StoryViewerPageViewModel(
return store.state.posts.getOrNull(index)
}
class Factory(private val recipientId: RecipientId, private val repository: StoryViewerPageRepository) : ViewModelProvider.Factory {
class Factory(private val recipientId: RecipientId, private val initialStoryId: Long, private val repository: StoryViewerPageRepository) : ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
return modelClass.cast(StoryViewerPageViewModel(recipientId, repository)) as T
return modelClass.cast(StoryViewerPageViewModel(recipientId, initialStoryId, repository)) as T
}
}
}