Skip to content

Commit a1fdbe5

Browse files
committed
1.0.5
1 parent 7c64cc6 commit a1fdbe5

34 files changed

+965
-310
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@
1414
.cxx
1515
local.properties
1616
app/google-services.json
17+
app/release

app/.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
/build
1+
/build
2+
/release

app/build.gradle.kts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@ android {
1414
applicationId = "com.troplo.privateuploader"
1515
minSdk = 28
1616
targetSdk = 34
17-
versionCode = 4
18-
versionName = "1.0.4"
17+
versionCode = 5
18+
versionName = "1.0.5"
1919
multiDexEnabled = true
2020
buildConfigField("String", "SERVER_URL", "\"https://privateuploader.com\"")
2121
buildConfigField("String", "BUILD_TIME", "\"${System.currentTimeMillis()}\"")
22-
buildConfigField("Integer", "BETA_VERSION", "4")
22+
buildConfigField("Integer", "BETA_VERSION", "5")
2323

2424
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
2525
vectorDrawables {

app/src/main/java/com/troplo/privateuploader/MainScreen.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,9 @@ fun MainScreen() {
9999
}
100100

101101
if(user.value?.emailVerified == false) {
102-
EmailVerificationDialog()
102+
EmailVerificationDialog(navigate = { subItem ->
103+
navController.navigate(subItem)
104+
})
103105
}
104106

105107
Scaffold(

app/src/main/java/com/troplo/privateuploader/api/ApiService.kt

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import com.troplo.privateuploader.data.model.CreateCollectionRequest
1515
import com.troplo.privateuploader.data.model.EditRequest
1616
import com.troplo.privateuploader.data.model.FCMTokenRequest
1717
import com.troplo.privateuploader.data.model.Friend
18+
import com.troplo.privateuploader.data.model.FriendNicknameRequest
1819
import com.troplo.privateuploader.data.model.Gallery
1920
import com.troplo.privateuploader.data.model.LoginRequest
2021
import com.troplo.privateuploader.data.model.LoginResponse
@@ -111,13 +112,18 @@ object TpuApi {
111112

112113
if (!response.isSuccessful) {
113114
val error: JSONObject = JSONObject(response.body?.string() ?: "{}")
114-
val errorType = error.getJSONArray("errors").getJSONObject(0).getString("name")
115-
if (errorType == "INVALID_TOKEN") {
116-
UserStore.logout(context)
117-
} else {
118-
val errorMessage =
119-
error.getJSONArray("errors").getJSONObject(0).getString("message")
120-
showToast(errorMessage)
115+
when (error.getJSONArray("errors").getJSONObject(0).getString("name")) {
116+
"INVALID_TOKEN" -> {
117+
UserStore.logout(context)
118+
}
119+
"EMAIL_NOT_VERIFIED" -> {
120+
// do nothing
121+
}
122+
else -> {
123+
val errorMessage =
124+
error.getJSONArray("errors").getJSONObject(0).getString("message")
125+
showToast(errorMessage)
126+
}
121127
}
122128
return Response.Builder()
123129
.request(request)
@@ -346,6 +352,20 @@ object TpuApi {
346352

347353
@POST("user/verification/send")
348354
fun sendVerificationEmail(): Call<Unit>
355+
356+
@DELETE("gallery/{attachmentId}")
357+
fun deleteUpload(
358+
@Path("attachmentId") attachmentId: Int
359+
): Call<Unit>
360+
361+
@PATCH("user/notifications")
362+
fun markNotificationsAsRead(): Call<Unit>
363+
364+
@PATCH("user/nickname/{userId}")
365+
fun updateNickname(
366+
@Path("userId") userId: Int,
367+
@Body friendNicknameRequest: FriendNicknameRequest
368+
): Call<Unit>
349369
}
350370

351371
val retrofitService: TpuApiService by lazy {

app/src/main/java/com/troplo/privateuploader/api/Functions.kt

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ package com.troplo.privateuploader.api
33
import android.content.Context
44
import android.net.Uri
55
import android.util.Log
6+
import com.troplo.privateuploader.api.stores.FriendStore
67
import com.troplo.privateuploader.data.model.Chat
8+
import com.troplo.privateuploader.data.model.PartialUser
79
import com.troplo.privateuploader.data.model.User
810
import java.io.File
911
import java.io.FileInputStream
@@ -39,12 +41,35 @@ object TpuFunctions {
3941
return "Communications"
4042
}
4143
return if (chat.type == "direct") {
42-
chat.recipient?.username ?: "Deleted User"
44+
getName(chat.recipient)
4345
} else {
4446
chat.name
4547
}
4648
}
4749

50+
fun getName(user: Any?): String {
51+
when (user) {
52+
is PartialUser -> {
53+
val friend = FriendStore.friends.value.find { it.otherUser?.id == user.id }
54+
if (friend?.otherUser?.nickname?.nickname != null) {
55+
return friend.otherUser.nickname.nickname
56+
}
57+
return user?.username ?: "Deleted User"
58+
}
59+
60+
is User -> {
61+
val friend = FriendStore.friends.value.find { it.otherUser?.id == user.id }
62+
if (friend?.otherUser?.nickname?.nickname != null) {
63+
return friend.otherUser.nickname.nickname
64+
}
65+
return user?.username ?: "Deleted User"
66+
}
67+
68+
else -> {
69+
return "Deleted User"
70+
}
71+
}
72+
}
4873

4974
fun formatDate(date: String?): CharSequence {
5075
try {
@@ -53,7 +78,7 @@ object TpuFunctions {
5378
val currentDate = LocalDate.now()
5479

5580
val formatter = if (localDateTime.toLocalDate() == currentDate) {
56-
DateTimeFormatter.ofPattern("hh:mm:ss a")
81+
DateTimeFormatter.ofPattern("'Today at' hh:mm:ss a")
5782
} else {
5883
DateTimeFormatter.ofPattern("dd/MM/yyyy hh:mm:ss a")
5984
}

app/src/main/java/com/troplo/privateuploader/api/SessionManager.kt

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,15 @@ class SessionManager(context: Context) {
5555
}
5656

5757
fun getUserCache(): User? {
58-
val user = prefs.getString("user", null)
59-
return if (user != null) {
60-
Gson().fromJson(user, User::class.java)
61-
} else {
58+
// Can crash if the backend schema has changed, this will be refreshed with new data provided the app is updated
59+
return try {
60+
val user = prefs.getString("user", null)
61+
if (user != null) {
62+
Gson().fromJson(user, User::class.java)
63+
} else {
64+
null
65+
}
66+
} catch (e: Exception) {
6267
null
6368
}
6469
}

app/src/main/java/com/troplo/privateuploader/api/stores/FriendStore.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,4 +83,14 @@ object FriendStore {
8383
e.printStackTrace()
8484
}
8585
}
86+
87+
fun updateFriendNickname(name: String, userId: Int) {
88+
friends.value = friends.value.map {
89+
if (it.otherUser?.id == userId) {
90+
it.copy(otherUser = it.otherUser?.copy(nickname = it.otherUser?.nickname?.copy(nickname = name)))
91+
} else {
92+
it
93+
}
94+
}
95+
}
8696
}

app/src/main/java/com/troplo/privateuploader/api/stores/UserStore.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import com.troplo.privateuploader.api.SessionManager
99
import com.troplo.privateuploader.api.SocketHandler
1010
import com.troplo.privateuploader.api.TpuApi
1111
import com.troplo.privateuploader.data.model.FCMTokenRequest
12+
import com.troplo.privateuploader.data.model.Notification
1213
import com.troplo.privateuploader.data.model.SettingsPayload
1314
import com.troplo.privateuploader.data.model.User
1415
import kotlinx.coroutines.CoroutineScope
@@ -85,6 +86,14 @@ object UserStore {
8586
insights = settings.insights ?: user.value?.insights ?: "friends"
8687
)
8788
}
89+
90+
socket?.on("notification") {
91+
val jsonArray = it[0] as JSONObject
92+
val payload = jsonArray.toString()
93+
val notification = SocketHandler.gson.fromJson(payload, Notification::class.java)
94+
Log.d("UserStore", "Notification received: $notification")
95+
user.value?.notifications = user.value?.notifications?.plus(notification) ?: listOf(notification)
96+
}
8897
} catch (e: URISyntaxException) {
8998
e.printStackTrace()
9099
}
@@ -98,6 +107,7 @@ object UserStore {
98107
user.value = null
99108
val socket = SocketHandler.getSocket()
100109
socket?.off("userSettingsUpdate")
110+
socket?.off("notification")
101111
SessionManager(context).setUserCache(null)
102112
SessionManager(context).setFCMToken(null)
103113
SessionManager(context).saveAuthToken(null)

app/src/main/java/com/troplo/privateuploader/components/chat/MemberSidebar.kt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ import androidx.compose.runtime.derivedStateOf
1111
import androidx.compose.runtime.mutableStateOf
1212
import androidx.compose.runtime.remember
1313
import com.troplo.privateuploader.api.ChatStore
14+
import com.troplo.privateuploader.api.TpuFunctions
1415
import com.troplo.privateuploader.components.core.UserAvatar
16+
import com.troplo.privateuploader.components.user.PopupRequiredUser
1517
import com.troplo.privateuploader.components.user.UserPopup
1618
import com.troplo.privateuploader.data.model.User
1719

@@ -25,7 +27,7 @@ fun MemberSidebar() {
2527
val chats = ChatStore.chats.collectAsState()
2628
val chat =
2729
remember { derivedStateOf { chats.value.find { it.association?.id == chatId.value } } }
28-
val user: MutableState<User?> = remember { mutableStateOf(null) }
30+
val user: MutableState<PopupRequiredUser?> = remember { mutableStateOf(null) }
2931
val popup = remember { mutableStateOf(false) }
3032

3133
if (popup.value) {
@@ -41,10 +43,10 @@ fun MemberSidebar() {
4143
username = association.user.username
4244
)
4345
},
44-
label = { Text(association.user.username) },
46+
label = { Text(TpuFunctions.getName(association.user)) },
4547
onClick = {
4648
if (association.legacyUser == null) {
47-
user.value = association.user
49+
user.value = PopupRequiredUser(association.user.username)
4850
popup.value = true
4951
}
5052
},

0 commit comments

Comments
 (0)