mirror of
https://github.com/KokaKiwi/BarInsta
synced 2024-12-23 05:16:58 +00:00
restore marking feed stories as seen
This commit is contained in:
parent
585db4056a
commit
c82080acf4
@ -17,10 +17,9 @@ import androidx.appcompat.view.ContextThemeWrapper
|
||||
import androidx.appcompat.widget.PopupMenu
|
||||
import androidx.core.view.GestureDetectorCompat
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.SavedStateHandle
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.navigation.NavController
|
||||
@ -31,7 +30,6 @@ import awais.instagrabber.R
|
||||
import awais.instagrabber.adapters.StoriesAdapter
|
||||
import awais.instagrabber.customviews.helpers.SwipeGestureListener
|
||||
import awais.instagrabber.databinding.FragmentStoryViewerBinding
|
||||
import awais.instagrabber.fragments.main.ProfileFragment
|
||||
import awais.instagrabber.fragments.settings.PreferenceKeys
|
||||
import awais.instagrabber.interfaces.SwipeEvent
|
||||
import awais.instagrabber.models.Resource
|
||||
@ -41,9 +39,7 @@ import awais.instagrabber.models.enums.StoryPaginationType
|
||||
import awais.instagrabber.repositories.requests.StoryViewerOptions
|
||||
import awais.instagrabber.repositories.responses.directmessages.RankedRecipient
|
||||
import awais.instagrabber.repositories.responses.stories.*
|
||||
import awais.instagrabber.utils.Constants
|
||||
import awais.instagrabber.utils.DownloadUtils.download
|
||||
import awais.instagrabber.utils.TextUtils.epochSecondToString
|
||||
import awais.instagrabber.utils.ResponseBodyUtils
|
||||
import awais.instagrabber.utils.Utils
|
||||
import awais.instagrabber.utils.extensions.TAG
|
||||
@ -79,7 +75,6 @@ class StoryViewerFragment : Fragment() {
|
||||
private var gestureDetector: GestureDetectorCompat? = null
|
||||
private val storiesRepository: StoriesRepository? = null
|
||||
private val mediaRepository: MediaRepository? = null
|
||||
private var live: Broadcast? = null
|
||||
private var menuProfile: MenuItem? = null
|
||||
private var profileVisible: Boolean = false
|
||||
private var player: SimpleExoPlayer? = null
|
||||
@ -218,8 +213,8 @@ class StoryViewerFragment : Fragment() {
|
||||
storiesViewModel.setMedia(position)
|
||||
}
|
||||
binding.storiesList.adapter = storiesAdapter
|
||||
storiesViewModel.getCurrentStory().observe(fragmentActivity, {
|
||||
if (it?.items != null) {
|
||||
storiesViewModel.getCurrentStory().observe(viewLifecycleOwner, {
|
||||
if (it?.items != null && it.items.size > 1) {
|
||||
val storyMedias = it.items.toMutableList()
|
||||
val newItem = storyMedias.get(0)
|
||||
newItem.isCurrentSlide = true
|
||||
@ -231,23 +226,24 @@ class StoryViewerFragment : Fragment() {
|
||||
else View.GONE
|
||||
}
|
||||
else {
|
||||
if (it?.items != null) storiesViewModel.setMedia(0)
|
||||
binding.listToggle.isEnabled = false
|
||||
binding.storiesList.visibility = View.GONE
|
||||
}
|
||||
})
|
||||
storiesViewModel.getDate().observe(fragmentActivity, {
|
||||
storiesViewModel.getDate().observe(viewLifecycleOwner, {
|
||||
val actionBar = fragmentActivity.supportActionBar
|
||||
if (actionBar != null && it != null) actionBar.subtitle = it
|
||||
})
|
||||
storiesViewModel.getTitle().observe(fragmentActivity, {
|
||||
storiesViewModel.getTitle().observe(viewLifecycleOwner, {
|
||||
val actionBar = fragmentActivity.supportActionBar
|
||||
if (actionBar != null && it != null) actionBar.title = it
|
||||
})
|
||||
storiesViewModel.getCurrentMedia().observe(fragmentActivity, { refreshStory(it) })
|
||||
storiesViewModel.getCurrentIndex().observe(fragmentActivity, {
|
||||
storiesViewModel.getCurrentMedia().observe(viewLifecycleOwner, { refreshStory(it) })
|
||||
storiesViewModel.getCurrentIndex().observe(viewLifecycleOwner, {
|
||||
storiesAdapter!!.paginate(it)
|
||||
})
|
||||
storiesViewModel.getOptions().observe(fragmentActivity, {
|
||||
storiesViewModel.getOptions().observe(viewLifecycleOwner, {
|
||||
binding.stickers.isEnabled = it.first.size > 0
|
||||
})
|
||||
}
|
||||
@ -267,65 +263,28 @@ class StoryViewerFragment : Fragment() {
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
private fun setupListeners() {
|
||||
var liveModels: LiveData<List<Story>?>? = null
|
||||
if (currentFeedStoryIndex >= 0) {
|
||||
val type = options!!.type
|
||||
when (type) {
|
||||
StoryViewerOptions.Type.HIGHLIGHT -> {
|
||||
storiesViewModel.fetchHighlights(options!!.id)
|
||||
liveModels = storiesViewModel.getHighlights()
|
||||
storiesViewModel.highlights.observe(viewLifecycleOwner) {
|
||||
setupMultipage(it)
|
||||
}
|
||||
}
|
||||
StoryViewerOptions.Type.FEED_STORY_POSITION -> {
|
||||
val feedStoriesViewModel = listViewModel as FeedStoriesViewModel?
|
||||
liveModels = feedStoriesViewModel!!.list
|
||||
setupMultipage(feedStoriesViewModel!!.list.value)
|
||||
}
|
||||
StoryViewerOptions.Type.STORY_ARCHIVE -> {
|
||||
val archivesViewModel = listViewModel as ArchivesViewModel?
|
||||
liveModels = archivesViewModel!!.list
|
||||
setupMultipage(archivesViewModel!!.list.value)
|
||||
}
|
||||
StoryViewerOptions.Type.USER -> {
|
||||
resetView()
|
||||
}
|
||||
}
|
||||
}
|
||||
if (liveModels != null) liveModels.observe(viewLifecycleOwner, { models ->
|
||||
storiesViewModel.getPagination().observe(fragmentActivity, {
|
||||
if (models != null) {
|
||||
when (it) {
|
||||
StoryPaginationType.FORWARD -> {
|
||||
if (currentFeedStoryIndex == models.size - 1)
|
||||
Toast.makeText(
|
||||
context,
|
||||
R.string.no_more_stories,
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
else paginateStories(false, currentFeedStoryIndex == models.size - 2)
|
||||
}
|
||||
StoryPaginationType.BACKWARD -> {
|
||||
if (currentFeedStoryIndex == 0)
|
||||
Toast.makeText(
|
||||
context,
|
||||
R.string.no_more_stories,
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
else paginateStories(true, false)
|
||||
}
|
||||
StoryPaginationType.ERROR -> {
|
||||
Toast.makeText(
|
||||
context,
|
||||
R.string.downloader_unknown_error,
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
if (models != null && !models.isEmpty()) {
|
||||
binding.btnBackward.isEnabled = currentFeedStoryIndex != 0
|
||||
binding.btnForward.isEnabled = currentFeedStoryIndex != models.size - 1
|
||||
resetView()
|
||||
}
|
||||
})
|
||||
|
||||
val context = context ?: return
|
||||
swipeEvent = SwipeEvent { isRightSwipe: Boolean ->
|
||||
@ -358,9 +317,46 @@ class StoryViewerFragment : Fragment() {
|
||||
binding.imageViewer.setTapListener(simpleOnGestureListener)
|
||||
}
|
||||
|
||||
private fun setupMultipage(models: List<Story>?) {
|
||||
if (models == null) return
|
||||
storiesViewModel.getPagination().observe(viewLifecycleOwner, {
|
||||
when (it) {
|
||||
StoryPaginationType.FORWARD -> {
|
||||
if (currentFeedStoryIndex == models.size - 1)
|
||||
Toast.makeText(
|
||||
context,
|
||||
R.string.no_more_stories,
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
else paginateStories(false, currentFeedStoryIndex == models.size - 2)
|
||||
}
|
||||
StoryPaginationType.BACKWARD -> {
|
||||
if (currentFeedStoryIndex == 0)
|
||||
Toast.makeText(
|
||||
context,
|
||||
R.string.no_more_stories,
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
else paginateStories(true, false)
|
||||
}
|
||||
StoryPaginationType.ERROR -> {
|
||||
Toast.makeText(
|
||||
context,
|
||||
R.string.downloader_unknown_error,
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
})
|
||||
if (!models.isEmpty()) {
|
||||
binding.btnBackward.isEnabled = currentFeedStoryIndex != 0
|
||||
binding.btnForward.isEnabled = currentFeedStoryIndex != models.size - 1
|
||||
resetView()
|
||||
}
|
||||
}
|
||||
|
||||
private fun resetView() {
|
||||
val context = context ?: return
|
||||
live = null
|
||||
if (menuProfile != null) menuProfile!!.isVisible = false
|
||||
binding.imageViewer.controller = null
|
||||
releasePlayer()
|
||||
@ -368,7 +364,7 @@ class StoryViewerFragment : Fragment() {
|
||||
var fetchOptions: StoryViewerOptions? = null
|
||||
when (type) {
|
||||
StoryViewerOptions.Type.HIGHLIGHT -> {
|
||||
val models = storiesViewModel.getHighlights().value
|
||||
val models = storiesViewModel.highlights.value
|
||||
if (models == null || models.isEmpty() || currentFeedStoryIndex >= models.size || currentFeedStoryIndex < 0) {
|
||||
Toast.makeText(context, R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show()
|
||||
return
|
||||
@ -379,10 +375,15 @@ class StoryViewerFragment : Fragment() {
|
||||
val feedStoriesViewModel = listViewModel as FeedStoriesViewModel?
|
||||
val models = feedStoriesViewModel!!.list.value
|
||||
if (models == null || currentFeedStoryIndex >= models.size || currentFeedStoryIndex < 0) return
|
||||
val (_, _, _, _, user, _, _, _, _, _, _, broadcast) = models[currentFeedStoryIndex]
|
||||
currentStoryUsername = user!!.username
|
||||
fetchOptions = StoryViewerOptions.forUser(user.pk, currentStoryUsername)
|
||||
live = broadcast
|
||||
val userStory = models[currentFeedStoryIndex]
|
||||
currentStoryUsername = userStory.user!!.username
|
||||
fetchOptions = StoryViewerOptions.forUser(userStory.user.pk, currentStoryUsername)
|
||||
val live = userStory.broadcast
|
||||
if (live != null) {
|
||||
storiesViewModel.setStory(userStory)
|
||||
refreshLive(live)
|
||||
return
|
||||
}
|
||||
}
|
||||
StoryViewerOptions.Type.STORY_ARCHIVE -> {
|
||||
val archivesViewModel = listViewModel as ArchivesViewModel?
|
||||
@ -405,11 +406,7 @@ class StoryViewerFragment : Fragment() {
|
||||
storiesViewModel.fetchSingleMedia(options!!.id)
|
||||
return
|
||||
}
|
||||
if (live != null) {
|
||||
refreshLive()
|
||||
return
|
||||
}
|
||||
storiesViewModel.fetchStory(fetchOptions).observe(fragmentActivity, {
|
||||
storiesViewModel.fetchStory(fetchOptions).observe(viewLifecycleOwner, {
|
||||
if (it.status == Resource.Status.ERROR) {
|
||||
Toast.makeText(context, "Error: " + it.message, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
@ -417,18 +414,14 @@ class StoryViewerFragment : Fragment() {
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
private fun refreshLive() {
|
||||
private fun refreshLive(live: Broadcast) {
|
||||
binding.btnDownload.isEnabled = false
|
||||
binding.stickers.isEnabled = false
|
||||
binding.listToggle.isEnabled = false
|
||||
binding.btnShare.isEnabled = false
|
||||
binding.btnReply.isEnabled = false
|
||||
releasePlayer()
|
||||
setupLive(live!!.dashPlaybackUrl ?: live!!.dashAbrPlaybackUrl ?: return)
|
||||
val actionBar = fragmentActivity.supportActionBar
|
||||
actionBarSubtitle = epochSecondToString(live!!.publishedTime!!)
|
||||
if (actionBar != null) {
|
||||
try {
|
||||
actionBar.setSubtitle(actionBarSubtitle)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "refreshLive: ", e)
|
||||
}
|
||||
}
|
||||
setupLive(live.dashPlaybackUrl ?: live.dashAbrPlaybackUrl ?: return)
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
@ -447,14 +440,19 @@ class StoryViewerFragment : Fragment() {
|
||||
binding.btnReply.isEnabled = currentStory.canReply
|
||||
if (itemType === MediaItemType.MEDIA_TYPE_VIDEO) setupVideo(url) else setupImage(url)
|
||||
|
||||
// if (Utils.settingsHelper.getBoolean(MARK_AS_SEEN)) storiesRepository!!.seen(
|
||||
// csrfToken,
|
||||
// userId,
|
||||
// deviceId,
|
||||
// currentStory!!.id!!,
|
||||
// currentStory!!.takenAt,
|
||||
// System.currentTimeMillis() / 1000
|
||||
// )
|
||||
if (options!!.type == StoryViewerOptions.Type.FEED_STORY_POSITION
|
||||
&& Utils.settingsHelper.getBoolean(PreferenceKeys.MARK_AS_SEEN)) {
|
||||
val feedStoriesViewModel = listViewModel as FeedStoriesViewModel?
|
||||
storiesViewModel.markAsSeen(currentStory).observe(viewLifecycleOwner) { m ->
|
||||
if (m.status == Resource.Status.SUCCESS && m.data != null) {
|
||||
val liveModels: MutableLiveData<List<Story>> = feedStoriesViewModel!!.list
|
||||
val models = liveModels.value
|
||||
val modelsCopy: MutableList<Story> = models!!.toMutableList()
|
||||
modelsCopy.set(currentFeedStoryIndex, m.data)
|
||||
liveModels.postValue(modelsCopy)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun downloadStory() {
|
||||
|
@ -322,7 +322,9 @@ public class FeedFragment extends Fragment implements SwipeRefreshLayout.OnRefre
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
binding.getRoot().postDelayed(feedStoriesAdapter::notifyDataSetChanged, 1000);
|
||||
// temporary fix
|
||||
feedStoriesViewModel.getList().removeObservers(getViewLifecycleOwner());
|
||||
feedStoriesViewModel.getList().observe(getViewLifecycleOwner(), feedStoriesAdapter::submitList);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -398,8 +400,6 @@ public class FeedFragment extends Fragment implements SwipeRefreshLayout.OnRefre
|
||||
storiesFetching = false;
|
||||
//noinspection unchecked
|
||||
feedStoriesViewModel.getList().postValue((List<Story>) feedStoryModels);
|
||||
//noinspection unchecked
|
||||
feedStoriesAdapter.submitList((List<Story>) feedStoryModels);
|
||||
if (storyListMenu != null) storyListMenu.setVisible(true);
|
||||
updateSwipeRefreshState();
|
||||
}), Dispatchers.getIO())
|
||||
|
@ -11,7 +11,7 @@ data class Story(
|
||||
val latestReelMedia: Long? = null, // = timestamp
|
||||
val mediaCount: Int? = null,
|
||||
// for stories and highlights
|
||||
var seen: Long? = null,
|
||||
val seen: Long? = null,
|
||||
val user: User? = null,
|
||||
// for stories
|
||||
val muted: Boolean? = null,
|
||||
|
@ -60,21 +60,22 @@ class StoryFragmentViewModel : ViewModel() {
|
||||
private val mediaRepository: MediaRepository by lazy { MediaRepository.getInstance() }
|
||||
|
||||
// for highlights ONLY
|
||||
private val highlights = MutableLiveData<List<Story>?>()
|
||||
val highlights = MutableLiveData<List<Story>?>()
|
||||
|
||||
/* set functions */
|
||||
|
||||
fun setStory(story: Story) {
|
||||
if (story.items == null || story.items.size == 0) {
|
||||
pagination.postValue(StoryPaginationType.ERROR)
|
||||
return
|
||||
}
|
||||
currentStory.postValue(story)
|
||||
storyTitle.postValue(story.title ?: story.user?.username)
|
||||
if (story.broadcast != null) {
|
||||
date.postValue(story.dateTime)
|
||||
type.postValue(MediaItemType.MEDIA_TYPE_LIVE)
|
||||
pagination.postValue(StoryPaginationType.DO_NOTHING)
|
||||
return
|
||||
}
|
||||
if (story.items == null || story.items.size == 0) {
|
||||
pagination.postValue(StoryPaginationType.ERROR)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
@ -184,10 +185,6 @@ class StoryFragmentViewModel : ViewModel() {
|
||||
|
||||
/* get functions */
|
||||
|
||||
fun getHighlights(): LiveData<List<Story>?> {
|
||||
return highlights
|
||||
}
|
||||
|
||||
fun getCurrentStory(): LiveData<Story?> {
|
||||
return currentStory
|
||||
}
|
||||
@ -472,4 +469,27 @@ class StoryFragmentViewModel : ViewModel() {
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
fun markAsSeen(storyMedia: StoryMedia): LiveData<Resource<Story?>> {
|
||||
val data = MutableLiveData<Resource<Story?>>()
|
||||
data.postValue(loading(null))
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
try {
|
||||
storiesRepository.seen(
|
||||
csrfToken!!,
|
||||
userId,
|
||||
deviceId,
|
||||
storyMedia.id,
|
||||
storyMedia.takenAt,
|
||||
System.currentTimeMillis() / 1000
|
||||
)
|
||||
val oldStory = currentStory.value!!
|
||||
val newStory = oldStory.copy(seen = storyMedia.takenAt)
|
||||
data.postValue(success(newStory))
|
||||
} catch (e: Exception) {
|
||||
data.postValue(error(e.message, null))
|
||||
}
|
||||
}
|
||||
return data
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user