kopia lustrzana https://github.com/ryukoposting/Signal-Android
Allow user to launch directly to a specific story, fix story chronology.
rodzic
8bb27b60fa
commit
63e48efdfe
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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) }
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue