Skip to content

Commit b19ce01

Browse files
authored
Merge pull request #61 from JothishKamal/v3
feat: implement pinned friends functionality in ConnectViewModel and UI
2 parents 05b9333 + c7d53fa commit b19ce01

4 files changed

Lines changed: 172 additions & 4 deletions

File tree

app/src/main/java/com/dscvit/vitty/ui/connect/ConnectScreenContent.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ fun ConnectScreenContent(
203203
val username = sharedPreferences.getString(Constants.COMMUNITY_USERNAME, "") ?: ""
204204

205205
if (token.isNotEmpty()) {
206+
connectViewModel.initializePinnedFriends(sharedPreferences)
206207
connectViewModel.getFriendList(token, username)
207208
connectViewModel.getCircleList(token)
208209
connectViewModel.getFriendRequest(token)

app/src/main/java/com/dscvit/vitty/ui/connect/ConnectViewModel.kt

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ class ConnectViewModel : ViewModel() {
5151
private val _circleActionResponse = MutableLiveData<PostResponse?>()
5252
private val _activeFriends = MutableLiveData<List<ActiveFriendItem>??>()
5353
private val _ghostModeResponse = MutableLiveData<GhostModeResponse?>()
54+
private val _pinnedFriends = MutableLiveData<Set<String>>()
5455

5556
val ghostModeResponse: MutableLiveData<GhostModeResponse?> = _ghostModeResponse
5657
val friendList: MutableLiveData<FriendResponse?> = _friendList
@@ -73,6 +74,7 @@ class ConnectViewModel : ViewModel() {
7374
val isCircleRequestsLoading: MutableLiveData<Boolean> = _isCircleRequestsLoading
7475
val circleActionResponse: MutableLiveData<PostResponse?> = _circleActionResponse
7576
val activeFriends: MutableLiveData<List<ActiveFriendItem>??> = _activeFriends
77+
val pinnedFriends: MutableLiveData<Set<String>> = _pinnedFriends
7678

7779
fun getFriendList(
7880
token: String,
@@ -779,6 +781,95 @@ class ConnectViewModel : ViewModel() {
779781
_activeFriends.postValue(data)
780782
}
781783

784+
fun pinFriend(
785+
username: String,
786+
prefs: SharedPreferences,
787+
): Boolean {
788+
val pinnedFriend1 = prefs.getString(Constants.COMMUNITY_PINNED_FRIEND_1, "")
789+
val pinnedFriend2 = prefs.getString(Constants.COMMUNITY_PINNED_FRIEND_2, "")
790+
val pinnedFriend3 = prefs.getString(Constants.COMMUNITY_PINNED_FRIEND_3, "")
791+
792+
val success =
793+
when {
794+
pinnedFriend1.isNullOrEmpty() -> {
795+
prefs.edit { putString(Constants.COMMUNITY_PINNED_FRIEND_1, username) }
796+
true
797+
}
798+
pinnedFriend2.isNullOrEmpty() -> {
799+
prefs.edit { putString(Constants.COMMUNITY_PINNED_FRIEND_2, username) }
800+
true
801+
}
802+
pinnedFriend3.isNullOrEmpty() -> {
803+
prefs.edit { putString(Constants.COMMUNITY_PINNED_FRIEND_3, username) }
804+
true
805+
}
806+
else -> false
807+
}
808+
809+
if (success) {
810+
updatePinnedFriendsState(prefs)
811+
}
812+
return success
813+
}
814+
815+
fun unpinFriend(
816+
username: String,
817+
prefs: SharedPreferences,
818+
) {
819+
val pinnedFriend1 = prefs.getString(Constants.COMMUNITY_PINNED_FRIEND_1, "")
820+
val pinnedFriend2 = prefs.getString(Constants.COMMUNITY_PINNED_FRIEND_2, "")
821+
val pinnedFriend3 = prefs.getString(Constants.COMMUNITY_PINNED_FRIEND_3, "")
822+
823+
when (username) {
824+
pinnedFriend1 -> prefs.edit { putString(Constants.COMMUNITY_PINNED_FRIEND_1, "") }
825+
pinnedFriend2 -> prefs.edit { putString(Constants.COMMUNITY_PINNED_FRIEND_2, "") }
826+
pinnedFriend3 -> prefs.edit { putString(Constants.COMMUNITY_PINNED_FRIEND_3, "") }
827+
}
828+
829+
updatePinnedFriendsState(prefs)
830+
}
831+
832+
fun isFriendPinned(
833+
username: String,
834+
prefs: SharedPreferences,
835+
): Boolean {
836+
val pinnedFriend1 = prefs.getString(Constants.COMMUNITY_PINNED_FRIEND_1, "")
837+
val pinnedFriend2 = prefs.getString(Constants.COMMUNITY_PINNED_FRIEND_2, "")
838+
val pinnedFriend3 = prefs.getString(Constants.COMMUNITY_PINNED_FRIEND_3, "")
839+
840+
return username == pinnedFriend1 || username == pinnedFriend2 || username == pinnedFriend3
841+
}
842+
843+
fun getPinnedFriends(prefs: SharedPreferences): List<String> {
844+
val pinnedFriends = mutableListOf<String>()
845+
val pinnedFriend1 = prefs.getString(Constants.COMMUNITY_PINNED_FRIEND_1, "")
846+
val pinnedFriend2 = prefs.getString(Constants.COMMUNITY_PINNED_FRIEND_2, "")
847+
val pinnedFriend3 = prefs.getString(Constants.COMMUNITY_PINNED_FRIEND_3, "")
848+
849+
if (!pinnedFriend1.isNullOrEmpty()) pinnedFriends.add(pinnedFriend1)
850+
if (!pinnedFriend2.isNullOrEmpty()) pinnedFriends.add(pinnedFriend2)
851+
if (!pinnedFriend3.isNullOrEmpty()) pinnedFriends.add(pinnedFriend3)
852+
853+
return pinnedFriends
854+
}
855+
856+
fun initializePinnedFriends(prefs: SharedPreferences) {
857+
updatePinnedFriendsState(prefs)
858+
}
859+
860+
private fun updatePinnedFriendsState(prefs: SharedPreferences) {
861+
val pinnedFriends = mutableSetOf<String>()
862+
val pinnedFriend1 = prefs.getString(Constants.COMMUNITY_PINNED_FRIEND_1, "")
863+
val pinnedFriend2 = prefs.getString(Constants.COMMUNITY_PINNED_FRIEND_2, "")
864+
val pinnedFriend3 = prefs.getString(Constants.COMMUNITY_PINNED_FRIEND_3, "")
865+
866+
if (!pinnedFriend1.isNullOrEmpty()) pinnedFriends.add(pinnedFriend1)
867+
if (!pinnedFriend2.isNullOrEmpty()) pinnedFriends.add(pinnedFriend2)
868+
if (!pinnedFriend3.isNullOrEmpty()) pinnedFriends.add(pinnedFriend3)
869+
870+
_pinnedFriends.postValue(pinnedFriends)
871+
}
872+
782873
data class GhostModeResponse(
783874
val success: Boolean,
784875
)

app/src/main/java/com/dscvit/vitty/ui/connect/components/ConnectScreenComponents.kt

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.dscvit.vitty.ui.connect.components
22

33
import android.content.Context
4+
import android.widget.Toast
45
import androidx.compose.animation.core.LinearEasing
56
import androidx.compose.animation.core.RepeatMode
67
import androidx.compose.animation.core.animateFloat
@@ -48,6 +49,8 @@ import androidx.compose.runtime.Composable
4849
import androidx.compose.runtime.LaunchedEffect
4950
import androidx.compose.runtime.getValue
5051
import androidx.compose.runtime.livedata.observeAsState
52+
import androidx.compose.runtime.mutableStateOf
53+
import androidx.compose.runtime.remember
5154
import androidx.compose.runtime.setValue
5255
import androidx.compose.ui.Alignment
5356
import androidx.compose.ui.Modifier
@@ -339,9 +342,41 @@ fun ConnectTabContent(
339342
onFriendsRefresh: () -> Unit = {},
340343
onCirclesRefresh: () -> Unit = {},
341344
) {
345+
val context = LocalContext.current
346+
val sharedPreferences = context.getSharedPreferences(Constants.USER_INFO, Context.MODE_PRIVATE)
347+
val pinnedFriends by viewModel.pinnedFriends.observeAsState()
348+
342349
val allFriends = friendList?.data ?: emptyList()
350+
351+
val sortedFriends =
352+
allFriends.sortedWith { friend1, friend2 ->
353+
val currentPinnedFriends = pinnedFriends ?: emptySet()
354+
355+
val getPinPriority = { username: String ->
356+
if (currentPinnedFriends.contains(username)) {
357+
val pinnedFriend1 = sharedPreferences.getString(Constants.COMMUNITY_PINNED_FRIEND_1, "")
358+
val pinnedFriend2 = sharedPreferences.getString(Constants.COMMUNITY_PINNED_FRIEND_2, "")
359+
val pinnedFriend3 = sharedPreferences.getString(Constants.COMMUNITY_PINNED_FRIEND_3, "")
360+
361+
when (username) {
362+
pinnedFriend1 -> 1
363+
pinnedFriend2 -> 2
364+
pinnedFriend3 -> 3
365+
else -> 4
366+
}
367+
} else {
368+
Int.MAX_VALUE
369+
}
370+
}
371+
372+
val priority1 = getPinPriority(friend1.username)
373+
val priority2 = getPinPriority(friend2.username)
374+
375+
priority1.compareTo(priority2)
376+
}
377+
343378
val displayedFriends =
344-
allFriends.filter { friend ->
379+
sortedFriends.filter { friend ->
345380
val matchesSearch =
346381
searchQuery.isBlank() ||
347382
friend.name.contains(searchQuery, ignoreCase = true) ||
@@ -421,6 +456,22 @@ fun ConnectTabContent(
421456
FriendCard(
422457
friend = friend,
423458
onClick = { onFriendClick(friend) },
459+
viewModel = viewModel,
460+
onPinToggle = { username, shouldPin ->
461+
if (shouldPin) {
462+
val success = viewModel.pinFriend(username, sharedPreferences)
463+
if (!success) {
464+
Toast
465+
.makeText(
466+
context,
467+
"Maximum 3 friends can be pinned",
468+
android.widget.Toast.LENGTH_SHORT,
469+
).show()
470+
}
471+
} else {
472+
viewModel.unpinFriend(username, sharedPreferences)
473+
}
474+
},
424475
)
425476
}
426477
}
@@ -532,7 +583,12 @@ fun EmptyStateContent(
532583
fun FriendCard(
533584
friend: UserResponse,
534585
onClick: () -> Unit = {},
586+
viewModel: ConnectViewModel? = null,
587+
onPinToggle: ((String, Boolean) -> Unit)? = null,
535588
) {
589+
val pinnedFriends by viewModel?.pinnedFriends?.observeAsState() ?: remember { mutableStateOf(emptySet<String>()) }
590+
val isPinned = pinnedFriends?.contains(friend.username) ?: false
591+
536592
Box(
537593
modifier =
538594
Modifier
@@ -618,6 +674,25 @@ fun FriendCard(
618674
)
619675
}
620676
}
677+
678+
if (viewModel != null && onPinToggle != null) {
679+
IconButton(
680+
onClick = {
681+
onPinToggle(friend.username, !isPinned)
682+
},
683+
modifier = Modifier.size(40.dp),
684+
) {
685+
Icon(
686+
painter =
687+
painterResource(
688+
id = R.drawable.ic_pin,
689+
),
690+
contentDescription = if (isPinned) "Unpin friend" else "Pin friend",
691+
tint = if (isPinned) Accent else Accent.copy(alpha = 0.3f),
692+
modifier = Modifier.size(20.dp),
693+
)
694+
}
695+
}
621696
}
622697
}
623698
}

app/src/main/java/com/dscvit/vitty/util/LogoutHelper.kt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ object LogoutHelper {
4545
}
4646

4747
logout.setOnClickListener {
48-
prefs.edit().apply {
48+
prefs.edit {
4949
putInt(Constants.TIMETABLE_AVAILABLE, 0)
5050
putInt(Constants.UPDATE, 0)
5151
putString(Constants.UID, "")
@@ -60,8 +60,9 @@ object LogoutHelper {
6060
putString(Constants.CACHE_COMMUNITY_TIMETABLE, null)
6161
putBoolean(Constants.ACTIVE_FRIENDS_FETCHED, false)
6262
putString(Constants.ACTIVE_FRIENDS_FETCHED, null)
63-
64-
apply()
63+
putString(Constants.COMMUNITY_PINNED_FRIEND_1, null)
64+
putString(Constants.COMMUNITY_PINNED_FRIEND_2, null)
65+
putString(Constants.COMMUNITY_PINNED_FRIEND_3, null)
6566
}
6667
prefs.edit { clear() }
6768
FirebaseAuth.getInstance().signOut()

0 commit comments

Comments
 (0)