mirror of https://github.com/KokaKiwi/BarInsta
632 lines
26 KiB
Kotlin
632 lines
26 KiB
Kotlin
package awais.instagrabber.viewmodels
|
|
|
|
import android.os.Bundle
|
|
import android.util.Log
|
|
import androidx.lifecycle.*
|
|
import androidx.savedstate.SavedStateRegistryOwner
|
|
import awais.instagrabber.db.entities.Favorite
|
|
import awais.instagrabber.db.repositories.AccountRepository
|
|
import awais.instagrabber.db.repositories.FavoriteRepository
|
|
import awais.instagrabber.managers.DirectMessagesManager
|
|
import awais.instagrabber.models.Resource
|
|
import awais.instagrabber.models.StoryModel
|
|
import awais.instagrabber.models.enums.BroadcastItemType
|
|
import awais.instagrabber.models.enums.FavoriteType
|
|
import awais.instagrabber.repositories.requests.StoryViewerOptions
|
|
import awais.instagrabber.repositories.responses.FriendshipStatus
|
|
import awais.instagrabber.repositories.responses.User
|
|
import awais.instagrabber.repositories.responses.UserProfileContextLink
|
|
import awais.instagrabber.repositories.responses.directmessages.RankedRecipient
|
|
import awais.instagrabber.repositories.responses.stories.Story
|
|
import awais.instagrabber.utils.ControlledRunner
|
|
import awais.instagrabber.utils.Event
|
|
import awais.instagrabber.utils.SingleRunner
|
|
import awais.instagrabber.utils.extensions.TAG
|
|
import awais.instagrabber.utils.extensions.isReallyPrivate
|
|
import awais.instagrabber.viewmodels.ProfileFragmentViewModel.ProfileAction.*
|
|
import awais.instagrabber.viewmodels.ProfileFragmentViewModel.ProfileEvent.*
|
|
import awais.instagrabber.webservices.*
|
|
import kotlinx.coroutines.CoroutineDispatcher
|
|
import kotlinx.coroutines.Dispatchers
|
|
import kotlinx.coroutines.launch
|
|
import java.time.LocalDateTime
|
|
|
|
class ProfileFragmentViewModel(
|
|
private val state: SavedStateHandle,
|
|
private val csrfToken: String?,
|
|
private val deviceUuid: String?,
|
|
private val userRepository: UserRepository,
|
|
private val friendshipRepository: FriendshipRepository,
|
|
private val storiesRepository: StoriesRepository,
|
|
private val mediaRepository: MediaRepository,
|
|
private val graphQLRepository: GraphQLRepository,
|
|
private val favoriteRepository: FavoriteRepository,
|
|
private val directMessagesRepository: DirectMessagesRepository,
|
|
private val messageManager: DirectMessagesManager?,
|
|
ioDispatcher: CoroutineDispatcher,
|
|
) : ViewModel() {
|
|
private val _currentUser = MutableLiveData<Resource<User?>>(Resource.loading(null))
|
|
private val _isFavorite = MutableLiveData(false)
|
|
private val profileAction = MutableLiveData(INIT)
|
|
private val _eventLiveData = MutableLiveData<Event<ProfileEvent>?>()
|
|
|
|
enum class ProfileAction {
|
|
INIT,
|
|
REFRESH,
|
|
REFRESH_FRIENDSHIP,
|
|
}
|
|
|
|
sealed class ProfileEvent {
|
|
object ShowConfirmUnfollowDialog : ProfileEvent()
|
|
class DMButtonState(val disabled: Boolean) : ProfileEvent()
|
|
class NavigateToThread(val threadId: String, val username: String) : ProfileEvent()
|
|
class ShowTranslation(val result: String) : ProfileEvent()
|
|
}
|
|
|
|
val currentUser: LiveData<Resource<User?>> = _currentUser
|
|
val isLoggedIn: LiveData<Boolean> = currentUser.map { it.data != null }
|
|
val isFavorite: LiveData<Boolean> = _isFavorite
|
|
val eventLiveData: LiveData<Event<ProfileEvent>?> = _eventLiveData
|
|
|
|
private val currentUserStateUsernameActionLiveData: LiveData<Triple<Resource<User?>, Resource<String?>, ProfileAction>> =
|
|
object : MediatorLiveData<Triple<Resource<User?>, Resource<String?>, ProfileAction>>() {
|
|
var user: Resource<User?> = Resource.loading(null)
|
|
var stateUsername: Resource<String?> = Resource.loading(null)
|
|
var action: ProfileAction = INIT
|
|
|
|
init {
|
|
addSource(currentUser) { currentUser ->
|
|
this.user = currentUser
|
|
value = Triple(currentUser, stateUsername, action)
|
|
}
|
|
addSource(state.getLiveData<String?>("username")) { username ->
|
|
this.stateUsername = Resource.success(username.substringAfter('@'))
|
|
value = Triple(user, this.stateUsername, action)
|
|
}
|
|
addSource(profileAction) { action ->
|
|
this.action = action
|
|
value = Triple(user, stateUsername, action)
|
|
}
|
|
// trigger currentUserStateUsernameActionLiveData switch map with a state username success resource
|
|
if (!state.contains("username")) {
|
|
this.stateUsername = Resource.success(null)
|
|
value = Triple(user, this.stateUsername, action)
|
|
}
|
|
}
|
|
}
|
|
|
|
private val profileFetchControlledRunner = ControlledRunner<User?>()
|
|
val profile: LiveData<Resource<User?>> = currentUserStateUsernameActionLiveData.switchMap {
|
|
val (currentUserResource, stateUsernameResource, action) = it
|
|
liveData<Resource<User?>>(context = viewModelScope.coroutineContext + ioDispatcher) {
|
|
if (currentUserResource.status == Resource.Status.LOADING || stateUsernameResource.status == Resource.Status.LOADING) {
|
|
emit(Resource.loading(null))
|
|
return@liveData
|
|
}
|
|
val currentUser = currentUserResource.data
|
|
val stateUsername = stateUsernameResource.data
|
|
if (stateUsername.isNullOrBlank()) {
|
|
emit(Resource.success(currentUser))
|
|
return@liveData
|
|
}
|
|
try {
|
|
when (action) {
|
|
INIT, REFRESH -> {
|
|
val fetchedUser = profileFetchControlledRunner.cancelPreviousThenRun { fetchUser(currentUser, stateUsername) }
|
|
emit(Resource.success(fetchedUser))
|
|
if (fetchedUser != null) {
|
|
checkAndUpdateFavorite(fetchedUser)
|
|
}
|
|
}
|
|
REFRESH_FRIENDSHIP -> {
|
|
var profile = profileCopy.value?.data ?: return@liveData
|
|
profile = profile.copy(friendshipStatus = userRepository.getUserFriendship(profile.pk))
|
|
emit(Resource.success(profile))
|
|
}
|
|
}
|
|
} catch (e: Exception) {
|
|
emit(Resource.error(e.message, profileCopy.value?.data))
|
|
Log.e(TAG, "fetching user: ", e)
|
|
}
|
|
}
|
|
}
|
|
val profileCopy = profile
|
|
|
|
val currentUserProfileActionLiveData: LiveData<Triple<Resource<User?>, Resource<User?>, ProfileAction>> =
|
|
object : MediatorLiveData<Triple<Resource<User?>, Resource<User?>, ProfileAction>>() {
|
|
var currentUser: Resource<User?> = Resource.loading(null)
|
|
var profile: Resource<User?> = Resource.loading(null)
|
|
var action: ProfileAction = INIT
|
|
|
|
init {
|
|
addSource(this@ProfileFragmentViewModel.currentUser) { currentUser ->
|
|
this.currentUser = currentUser
|
|
value = Triple(currentUser, profile, action)
|
|
}
|
|
addSource(this@ProfileFragmentViewModel.profile) { profile ->
|
|
this.profile = profile
|
|
value = Triple(currentUser, this.profile, action)
|
|
}
|
|
addSource(profileAction) { action ->
|
|
this.action = action
|
|
value = Triple(currentUser, this.profile, action)
|
|
}
|
|
}
|
|
}
|
|
|
|
private val storyFetchControlledRunner = ControlledRunner<List<StoryModel>?>()
|
|
val userStories: LiveData<Resource<List<StoryModel>?>> = currentUserProfileActionLiveData.switchMap { currentUserAndProfilePair ->
|
|
liveData<Resource<List<StoryModel>?>>(context = viewModelScope.coroutineContext + ioDispatcher) {
|
|
val (currentUserResource, profileResource, action) = currentUserAndProfilePair
|
|
if (action != INIT && action != REFRESH) {
|
|
return@liveData
|
|
}
|
|
// don't fetch if not logged in
|
|
if (currentUserResource.data == null) {
|
|
emit(Resource.success(null))
|
|
return@liveData
|
|
}
|
|
if (currentUserResource.status == Resource.Status.LOADING || profileResource.status == Resource.Status.LOADING) {
|
|
emit(Resource.loading(null))
|
|
return@liveData
|
|
}
|
|
val user = profileResource.data
|
|
if (user == null) {
|
|
emit(Resource.success(null))
|
|
return@liveData
|
|
}
|
|
try {
|
|
val fetchedStories = storyFetchControlledRunner.cancelPreviousThenRun { fetchUserStory(user) }
|
|
emit(Resource.success(fetchedStories))
|
|
} catch (e: Exception) {
|
|
emit(Resource.error(e.message, null))
|
|
Log.e(TAG, "fetching story: ", e)
|
|
}
|
|
}
|
|
}
|
|
|
|
private val highlightsFetchControlledRunner = ControlledRunner<List<Story>?>()
|
|
val userHighlights: LiveData<Resource<List<Story>?>> = currentUserProfileActionLiveData.switchMap { currentUserAndProfilePair ->
|
|
liveData<Resource<List<Story>?>>(context = viewModelScope.coroutineContext + ioDispatcher) {
|
|
val (currentUserResource, profileResource, action) = currentUserAndProfilePair
|
|
if (action != INIT && action != REFRESH) {
|
|
return@liveData
|
|
}
|
|
// don't fetch if not logged in
|
|
if (currentUserResource.data == null) {
|
|
emit(Resource.success(null))
|
|
return@liveData
|
|
}
|
|
if (currentUserResource.status == Resource.Status.LOADING || profileResource.status == Resource.Status.LOADING) {
|
|
emit(Resource.loading(null))
|
|
return@liveData
|
|
}
|
|
val user = profileResource.data
|
|
if (user == null) {
|
|
emit(Resource.success(null))
|
|
return@liveData
|
|
}
|
|
try {
|
|
val fetchedHighlights = highlightsFetchControlledRunner.cancelPreviousThenRun { fetchUserHighlights(user) }
|
|
emit(Resource.success(fetchedHighlights))
|
|
} catch (e: Exception) {
|
|
emit(Resource.error(e.message, null))
|
|
Log.e(TAG, "fetching highlights: ", e)
|
|
}
|
|
}
|
|
}
|
|
|
|
private suspend fun fetchUser(
|
|
currentUser: User?,
|
|
stateUsername: String,
|
|
): User {
|
|
if (currentUser != null) {
|
|
// logged in
|
|
val tempUser = userRepository.getUsernameInfo(stateUsername)
|
|
if (!tempUser.isReallyPrivate(currentUser)) {
|
|
tempUser.friendshipStatus = userRepository.getUserFriendship(tempUser.pk)
|
|
}
|
|
return tempUser
|
|
}
|
|
// anonymous
|
|
return graphQLRepository.fetchUser(stateUsername)
|
|
}
|
|
|
|
private suspend fun fetchUserStory(fetchedUser: User): List<StoryModel> = storiesRepository.getUserStory(
|
|
StoryViewerOptions.forUser(fetchedUser.pk, fetchedUser.fullName)
|
|
)
|
|
|
|
private suspend fun fetchUserHighlights(fetchedUser: User): List<Story> = storiesRepository.fetchHighlights(fetchedUser.pk)
|
|
|
|
private suspend fun checkAndUpdateFavorite(fetchedUser: User) {
|
|
try {
|
|
val favorite = favoriteRepository.getFavorite(fetchedUser.username, FavoriteType.USER)
|
|
if (favorite == null) {
|
|
_isFavorite.postValue(false)
|
|
return
|
|
}
|
|
_isFavorite.postValue(true)
|
|
favoriteRepository.insertOrUpdateFavorite(
|
|
Favorite(
|
|
favorite.id,
|
|
fetchedUser.username,
|
|
FavoriteType.USER,
|
|
fetchedUser.fullName,
|
|
fetchedUser.profilePicUrl,
|
|
favorite.dateAdded
|
|
)
|
|
)
|
|
} catch (e: Exception) {
|
|
_isFavorite.postValue(false)
|
|
Log.e(TAG, "checkAndUpdateFavorite: ", e)
|
|
}
|
|
}
|
|
|
|
fun setCurrentUser(currentUser: Resource<User?>) {
|
|
_currentUser.postValue(currentUser)
|
|
}
|
|
|
|
fun shareDm(result: RankedRecipient) {
|
|
val mediaId = profile.value?.data?.pk ?: return
|
|
messageManager?.sendMedia(result, mediaId.toString(10), null, BroadcastItemType.PROFILE, viewModelScope)
|
|
}
|
|
|
|
fun shareDm(recipients: Set<RankedRecipient>) {
|
|
val mediaId = profile.value?.data?.pk ?: return
|
|
messageManager?.sendMedia(recipients, mediaId.toString(10), null, BroadcastItemType.PROFILE, viewModelScope)
|
|
}
|
|
|
|
fun refresh() {
|
|
profileAction.postValue(REFRESH)
|
|
}
|
|
|
|
private val toggleFavoriteControlledRunner = SingleRunner()
|
|
fun toggleFavorite() {
|
|
val username = profile.value?.data?.username ?: return
|
|
val fullName = profile.value?.data?.fullName ?: return
|
|
val profilePicUrl = profile.value?.data?.profilePicUrl ?: return
|
|
viewModelScope.launch(Dispatchers.IO) {
|
|
toggleFavoriteControlledRunner.afterPrevious {
|
|
try {
|
|
val favorite = favoriteRepository.getFavorite(username, FavoriteType.USER)
|
|
if (favorite == null) {
|
|
// insert
|
|
favoriteRepository.insertOrUpdateFavorite(
|
|
Favorite(
|
|
0,
|
|
username,
|
|
FavoriteType.USER,
|
|
fullName,
|
|
profilePicUrl,
|
|
LocalDateTime.now()
|
|
)
|
|
)
|
|
_isFavorite.postValue(true)
|
|
return@afterPrevious
|
|
}
|
|
// delete
|
|
favoriteRepository.deleteFavorite(username, FavoriteType.USER)
|
|
_isFavorite.postValue(false)
|
|
} catch (e: Exception) {
|
|
Log.e(TAG, "checkAndUpdateFavorite: ", e)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private val toggleFollowSingleRunner = SingleRunner()
|
|
fun toggleFollow(confirmed: Boolean) {
|
|
viewModelScope.launch(Dispatchers.IO) {
|
|
toggleFollowSingleRunner.afterPrevious {
|
|
try {
|
|
val following = profile.value?.data?.friendshipStatus?.following ?: false
|
|
val currentUserId = currentUser.value?.data?.pk ?: return@afterPrevious
|
|
val targetUserId = profile.value?.data?.pk ?: return@afterPrevious
|
|
val csrfToken = csrfToken ?: return@afterPrevious
|
|
val deviceUuid = deviceUuid ?: return@afterPrevious
|
|
if (following) {
|
|
if (!confirmed) {
|
|
_eventLiveData.postValue(Event(ShowConfirmUnfollowDialog))
|
|
return@afterPrevious
|
|
}
|
|
// unfollow
|
|
friendshipRepository.unfollow(
|
|
csrfToken,
|
|
currentUserId,
|
|
deviceUuid,
|
|
targetUserId
|
|
)
|
|
profileAction.postValue(REFRESH_FRIENDSHIP)
|
|
return@afterPrevious
|
|
}
|
|
friendshipRepository.follow(
|
|
csrfToken,
|
|
currentUserId,
|
|
deviceUuid,
|
|
targetUserId
|
|
)
|
|
profileAction.postValue(REFRESH_FRIENDSHIP)
|
|
} catch (e: Exception) {
|
|
Log.e(TAG, "toggleFollow: ", e)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private val sendDmSingleRunner = SingleRunner()
|
|
fun sendDm() {
|
|
viewModelScope.launch(Dispatchers.IO) {
|
|
sendDmSingleRunner.afterPrevious {
|
|
_eventLiveData.postValue(Event(DMButtonState(true)))
|
|
try {
|
|
val currentUserId = currentUser.value?.data?.pk ?: return@afterPrevious
|
|
val targetUserId = profile.value?.data?.pk ?: return@afterPrevious
|
|
val csrfToken = csrfToken ?: return@afterPrevious
|
|
val deviceUuid = deviceUuid ?: return@afterPrevious
|
|
val username = profile.value?.data?.username ?: return@afterPrevious
|
|
val thread = directMessagesRepository.createThread(
|
|
csrfToken,
|
|
currentUserId,
|
|
deviceUuid,
|
|
listOf(targetUserId),
|
|
null,
|
|
)
|
|
val inboxManager = DirectMessagesManager.inboxManager
|
|
if (!inboxManager.containsThread(thread.threadId)) {
|
|
thread.isTemp = true
|
|
inboxManager.addThread(thread, 0)
|
|
}
|
|
val threadId = thread.threadId ?: return@afterPrevious
|
|
_eventLiveData.postValue(Event(NavigateToThread(threadId, username)))
|
|
} catch (e: Exception) {
|
|
Log.e(TAG, "sendDm: ", e)
|
|
} finally {
|
|
_eventLiveData.postValue(Event(DMButtonState(false)))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private val restrictUserSingleRunner = SingleRunner()
|
|
fun restrictUser() {
|
|
if (isLoggedIn.value == false) return
|
|
viewModelScope.launch(Dispatchers.IO) {
|
|
restrictUserSingleRunner.afterPrevious {
|
|
try {
|
|
val profile = profile.value?.data ?: return@afterPrevious
|
|
friendshipRepository.toggleRestrict(
|
|
csrfToken ?: return@afterPrevious,
|
|
deviceUuid ?: return@afterPrevious,
|
|
profile.pk,
|
|
!(profile.friendshipStatus?.isRestricted ?: false),
|
|
)
|
|
profileAction.postValue(REFRESH_FRIENDSHIP)
|
|
} catch (e: Exception) {
|
|
Log.e(TAG, "restrictUser: ", e)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private val blockUserSingleRunner = SingleRunner()
|
|
fun blockUser() {
|
|
if (isLoggedIn.value == false) return
|
|
viewModelScope.launch(Dispatchers.IO) {
|
|
blockUserSingleRunner.afterPrevious {
|
|
try {
|
|
val profile = profile.value?.data ?: return@afterPrevious
|
|
friendshipRepository.changeBlock(
|
|
csrfToken ?: return@afterPrevious,
|
|
currentUser.value?.data?.pk ?: return@afterPrevious,
|
|
deviceUuid ?: return@afterPrevious,
|
|
profile.friendshipStatus?.blocking ?: return@afterPrevious,
|
|
profile.pk
|
|
)
|
|
profileAction.postValue(REFRESH_FRIENDSHIP)
|
|
} catch (e: Exception) {
|
|
Log.e(TAG, "blockUser: ", e)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private val muteStoriesSingleRunner = SingleRunner()
|
|
fun muteStories() {
|
|
if (isLoggedIn.value == false) return
|
|
viewModelScope.launch(Dispatchers.IO) {
|
|
muteStoriesSingleRunner.afterPrevious {
|
|
try {
|
|
val profile = profile.value?.data ?: return@afterPrevious
|
|
friendshipRepository.changeMute(
|
|
csrfToken ?: return@afterPrevious,
|
|
currentUser.value?.data?.pk ?: return@afterPrevious,
|
|
deviceUuid ?: return@afterPrevious,
|
|
profile.friendshipStatus?.isMutingReel ?: return@afterPrevious,
|
|
profile.pk,
|
|
true
|
|
)
|
|
profileAction.postValue(REFRESH_FRIENDSHIP)
|
|
} catch (e: Exception) {
|
|
Log.e(TAG, "muteStories: ", e)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private val mutePostsSingleRunner = SingleRunner()
|
|
fun mutePosts() {
|
|
if (isLoggedIn.value == false) return
|
|
viewModelScope.launch(Dispatchers.IO) {
|
|
mutePostsSingleRunner.afterPrevious {
|
|
try {
|
|
val profile = profile.value?.data ?: return@afterPrevious
|
|
friendshipRepository.changeMute(
|
|
csrfToken ?: return@afterPrevious,
|
|
currentUser.value?.data?.pk ?: return@afterPrevious,
|
|
deviceUuid ?: return@afterPrevious,
|
|
profile.friendshipStatus?.muting ?: return@afterPrevious,
|
|
profile.pk,
|
|
false
|
|
)
|
|
profileAction.postValue(REFRESH_FRIENDSHIP)
|
|
} catch (e: Exception) {
|
|
Log.e(TAG, "mutePosts: ", e)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private val removeFollowerSingleRunner = SingleRunner()
|
|
fun removeFollower() {
|
|
if (isLoggedIn.value == false) return
|
|
viewModelScope.launch(Dispatchers.IO) {
|
|
removeFollowerSingleRunner.afterPrevious {
|
|
try {
|
|
friendshipRepository.removeFollower(
|
|
csrfToken ?: return@afterPrevious,
|
|
currentUser.value?.data?.pk ?: return@afterPrevious,
|
|
deviceUuid ?: return@afterPrevious,
|
|
profile.value?.data?.pk ?: return@afterPrevious
|
|
)
|
|
profileAction.postValue(REFRESH_FRIENDSHIP)
|
|
} catch (e: Exception) {
|
|
Log.e(TAG, "removeFollower: ", e)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private val translateBioSingleRunner = SingleRunner()
|
|
fun translateBio() {
|
|
if (isLoggedIn.value == false) return
|
|
viewModelScope.launch(Dispatchers.IO) {
|
|
translateBioSingleRunner.afterPrevious {
|
|
try {
|
|
val result = mediaRepository.translate(
|
|
profile.value?.data?.pk?.toString() ?: return@afterPrevious,
|
|
"3"
|
|
)
|
|
if (result.isNullOrBlank()) return@afterPrevious
|
|
_eventLiveData.postValue(Event(ShowTranslation(result)))
|
|
} catch (e: Exception) {
|
|
Log.e(TAG, "translateBio: ", e)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Username of profile without '`@`'
|
|
*/
|
|
val username: LiveData<String> = Transformations.map(profile) {
|
|
return@map when (it.status) {
|
|
Resource.Status.ERROR -> ""
|
|
Resource.Status.LOADING, Resource.Status.SUCCESS -> it.data?.username ?: ""
|
|
}
|
|
}
|
|
val profilePicUrl: LiveData<String?> = Transformations.map(profile) {
|
|
return@map when (it.status) {
|
|
Resource.Status.ERROR -> null
|
|
Resource.Status.LOADING, Resource.Status.SUCCESS -> it.data?.profilePicUrl
|
|
}
|
|
}
|
|
val fullName: LiveData<String?> = Transformations.map(profile) {
|
|
return@map when (it.status) {
|
|
Resource.Status.ERROR -> ""
|
|
Resource.Status.LOADING, Resource.Status.SUCCESS -> it.data?.fullName
|
|
}
|
|
}
|
|
val biography: LiveData<String?> = Transformations.map(profile) {
|
|
return@map when (it.status) {
|
|
Resource.Status.ERROR -> ""
|
|
Resource.Status.LOADING, Resource.Status.SUCCESS -> it.data?.biography
|
|
}
|
|
}
|
|
val url: LiveData<String?> = Transformations.map(profile) {
|
|
return@map when (it.status) {
|
|
Resource.Status.ERROR -> ""
|
|
Resource.Status.LOADING, Resource.Status.SUCCESS -> it.data?.externalUrl
|
|
}
|
|
}
|
|
val followersCount: LiveData<Long?> = Transformations.map(profile) {
|
|
return@map when (it.status) {
|
|
Resource.Status.ERROR -> null
|
|
Resource.Status.LOADING, Resource.Status.SUCCESS -> it.data?.followerCount
|
|
}
|
|
}
|
|
val followingCount: LiveData<Long?> = Transformations.map(profile) {
|
|
return@map when (it.status) {
|
|
Resource.Status.ERROR -> null
|
|
Resource.Status.LOADING, Resource.Status.SUCCESS -> it.data?.followingCount
|
|
}
|
|
}
|
|
val postCount: LiveData<Long?> = Transformations.map(profile) {
|
|
return@map when (it.status) {
|
|
Resource.Status.ERROR -> null
|
|
Resource.Status.LOADING, Resource.Status.SUCCESS -> it.data?.mediaCount
|
|
}
|
|
}
|
|
val isPrivate: LiveData<Boolean?> = Transformations.map(profile) {
|
|
return@map when (it.status) {
|
|
Resource.Status.ERROR -> null
|
|
Resource.Status.LOADING, Resource.Status.SUCCESS -> it.data?.isPrivate
|
|
}
|
|
}
|
|
val isVerified: LiveData<Boolean?> = Transformations.map(profile) {
|
|
return@map when (it.status) {
|
|
Resource.Status.ERROR -> null
|
|
Resource.Status.LOADING, Resource.Status.SUCCESS -> it.data?.isVerified
|
|
}
|
|
}
|
|
val friendshipStatus: LiveData<FriendshipStatus?> = Transformations.map(profile) {
|
|
return@map when (it.status) {
|
|
Resource.Status.ERROR -> null
|
|
Resource.Status.LOADING, Resource.Status.SUCCESS -> it.data?.friendshipStatus
|
|
}
|
|
}
|
|
val profileContext: LiveData<Pair<String?, List<UserProfileContextLink>?>> = Transformations.map(profile) {
|
|
return@map when (it.status) {
|
|
Resource.Status.ERROR -> null to null
|
|
Resource.Status.LOADING, Resource.Status.SUCCESS -> it.data?.profileContext to it.data?.profileContextLinksWithUserIds
|
|
}
|
|
}
|
|
}
|
|
|
|
@Suppress("UNCHECKED_CAST")
|
|
class ProfileFragmentViewModelFactory(
|
|
private val csrfToken: String?,
|
|
private val deviceUuid: String?,
|
|
private val userRepository: UserRepository,
|
|
private val friendshipRepository: FriendshipRepository,
|
|
private val storiesRepository: StoriesRepository,
|
|
private val mediaRepository: MediaRepository,
|
|
private val graphQLRepository: GraphQLRepository,
|
|
private val accountRepository: AccountRepository,
|
|
private val favoriteRepository: FavoriteRepository,
|
|
private val directMessagesRepository: DirectMessagesRepository,
|
|
private val messageManager: DirectMessagesManager?,
|
|
owner: SavedStateRegistryOwner,
|
|
defaultArgs: Bundle? = null,
|
|
) : AbstractSavedStateViewModelFactory(owner, defaultArgs) {
|
|
override fun <T : ViewModel> create(
|
|
key: String,
|
|
modelClass: Class<T>,
|
|
handle: SavedStateHandle,
|
|
): T {
|
|
return ProfileFragmentViewModel(
|
|
handle,
|
|
csrfToken,
|
|
deviceUuid,
|
|
userRepository,
|
|
friendshipRepository,
|
|
storiesRepository,
|
|
mediaRepository,
|
|
graphQLRepository,
|
|
favoriteRepository,
|
|
directMessagesRepository,
|
|
messageManager,
|
|
Dispatchers.IO,
|
|
) as T
|
|
}
|
|
}
|