Skip to content
Snippets Groups Projects
Commit 4ac42664 authored by scimmiamorta's avatar scimmiamorta
Browse files

First Commit

parent 152edc5a
No related branches found
No related tags found
No related merge requests found
Showing
with 159 additions and 87 deletions
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
......
app/src/main/ic_launcher-playstore.png

85.1 KiB

......@@ -6,6 +6,7 @@ import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.example.taskmanagement.R
import com.google.firebase.auth.FirebaseAuth
class ChatViewAdapter(
private val chatList: List<Chat>,
......@@ -24,7 +25,12 @@ class ChatViewAdapter(
override fun onBindViewHolder(holder: ChatViewHolder, position: Int) {
val chat = chatList[position]
holder.chatName.text = chat.participants.joinToString(", ")
val currentUserEmail = FirebaseAuth.getInstance().currentUser?.email
val otherParticipant = chat.participants.firstOrNull { it != currentUserEmail }
holder.chatName.text = otherParticipant ?:
holder.itemView.context.getString(R.string.user_not_authenticated)
holder.lastMessage.text =
chat.lastMessage?.text ?: holder.itemView.context.getString(R.string.no_message)
......@@ -33,5 +39,6 @@ class ChatViewAdapter(
}
}
override fun getItemCount() = chatList.size
}
......@@ -42,28 +42,56 @@ class DialogFragment : DialogFragment() {
private fun loadUsers() {
val currentUser = FirebaseAuth.getInstance().currentUser
if (currentUser == null) {
Toast.makeText(requireContext(), getString(R.string.error_loading_users), Toast.LENGTH_SHORT).show()
return
}
firestore.collection("users")
.document(currentUser.uid)
.get()
.addOnSuccessListener { documents ->
userList.clear()
for (document in documents) {
val user = document.toObject(User::class.java)
if (user.email != FirebaseAuth.getInstance().currentUser?.uid) {
userList.add(user)
}
.addOnSuccessListener { document ->
val currentUserRole = document.getString("role") ?: return@addOnSuccessListener
val rolesToLoad = when (currentUserRole) {
"PM" -> listOf("PL")
"PL" -> listOf("PM", "Dev")
"Dev" -> listOf("PL", "Dev")
else -> emptyList()
}
recyclerViewUsers.adapter?.notifyDataSetChanged()
firestore.collection("users")
.whereIn("role", rolesToLoad)
.get()
.addOnSuccessListener { documents ->
userList.clear()
for (document in documents) {
val user = document.toObject(User::class.java)
if (user.email != currentUser.email) {
userList.add(user)
}
}
recyclerViewUsers.adapter?.notifyDataSetChanged()
}
.addOnFailureListener { e ->
Toast.makeText(
requireContext(),
getString(R.string.error_loading_users, e.message),
Toast.LENGTH_SHORT
).show()
}
}
.addOnFailureListener { e ->
Toast.makeText(
requireContext(),
getString(R.string.error_loading_users, e.message),
getString(R.string.error_loading_chats, e.message),
Toast.LENGTH_SHORT
).show()
}
}
private fun openChat(selectedUser: String) {
val bundle = Bundle()
bundle.putString("selectedUser", selectedUser)
......
......@@ -96,9 +96,34 @@ class UserSelectionFragment : Fragment() {
private fun openChat(chat: Chat) {
val currentUserId = currentUser?.email
val otherParticipant = chat.participants.firstOrNull { it != currentUserId }
if (currentUserId.isNullOrEmpty()) {
if (isAdded) {
Toast.makeText(
requireContext(),
getString(R.string.user_not_authenticated),
Toast.LENGTH_SHORT
).show()
}
return
}
if (otherParticipant == null) {
if (!chat.participants.contains(currentUserId)) {
if (isAdded) {
Toast.makeText(
requireContext(),
getString(R.string.user_not_found),
Toast.LENGTH_SHORT
).show()
}
return
}
val otherParticipant = chat.participants
.filter { it != currentUserId }
.sorted()
.joinToString("_")
if (otherParticipant.isEmpty()) {
if (isAdded) {
Toast.makeText(
requireContext(),
......@@ -112,26 +137,17 @@ class UserSelectionFragment : Fragment() {
firestore.collection("users")
.document(otherParticipant)
.get()
.addOnSuccessListener { document ->
.addOnSuccessListener {
if (isAdded) {
val otherUserRole = document.getString("role")
val currentUserRole = fetchUserRole(currentUserId)
if (canCommunicate(currentUserRole, otherUserRole)) {
val bundle = Bundle().apply {
putString("selectedUser", otherParticipant)
}
findNavController().navigate(
R.id.action_userSelectionFragment_to_chatFragment,
bundle
)
} else {
Toast.makeText(
requireContext(),
getString(R.string.cannot_communicate),
Toast.LENGTH_SHORT
).show()
val chatUser = chat.participants.firstOrNull { it != currentUser?.email }
val bundle = Bundle().apply {
putString("selectedUser", chatUser)
}
findNavController().navigate(
R.id.action_userSelectionFragment_to_chatFragment,
bundle
)
}
}
.addOnFailureListener {
......@@ -145,36 +161,4 @@ class UserSelectionFragment : Fragment() {
}
}
private fun canCommunicate(currentUserRole: String?, otherUserRole: String?): Boolean {
return when (currentUserRole) {
"PM" -> otherUserRole == "PL"
"PL" -> otherUserRole == "PM" || otherUserRole == "DEV"
"DEV" -> otherUserRole == "PL" || otherUserRole == "DEV"
else -> false
}
}
private fun fetchUserRole(userId: String?): String? {
var role: String? = null
if (userId.isNullOrEmpty()) return role
firestore.collection("users")
.document(userId)
.get()
.addOnSuccessListener { document ->
if (isAdded) {
role = document.getString("role")
}
}
.addOnFailureListener {
if (isAdded) {
Toast.makeText(
requireContext(),
getString(R.string.error_retrieving_role),
Toast.LENGTH_SHORT
).show()
}
}
return role
}
}
......@@ -113,18 +113,31 @@ class HomeFragment : Fragment() {
.get()
.await()
val allTasks = mutableListOf<QueryDocumentSnapshot>()
allTasks.addAll(createdByPMResult.documents as List<QueryDocumentSnapshot>)
// Inizializza una lista per i task
val allTasks = mutableListOf<Task>()
for (document in allTasks) {
// Processa i task creati dal Project Manager
createdByPMResult.documents.forEach { document ->
val task = document.toObject(Task::class.java)
taskList.add(task)
taskIdMap[task] = document.id
task?.let {
allTasks.add(it)
taskIdMap[it] = document.id
}
}
// Aggiorna i task aggiuntivi con il calcolo dei subtasks
for (task in allTasks) {
calculateSubTasks(task, taskIdMap[task] ?: return)
}
// Aggiungi i task caricati alla lista principale e aggiorna l'interfaccia utente
taskList.clear()
taskList.addAll(allTasks)
calculateSubTasks(task, document.id)
if (isAdded) {
fabMain.visibility = View.VISIBLE
}
if (isAdded) fabMain.visibility = View.VISIBLE
} catch (e: Exception) {
if (isAdded) {
Toast.makeText(
......@@ -137,6 +150,7 @@ class HomeFragment : Fragment() {
}
private suspend fun loadTasksForPL() {
try {
val currentUserEmail = auth.currentUser?.email ?: return
......@@ -150,23 +164,37 @@ class HomeFragment : Fragment() {
.get()
.await()
val allTasks = mutableListOf<QueryDocumentSnapshot>()
allTasks.addAll(createdByPLResult.documents as List<QueryDocumentSnapshot>)
allTasks.addAll(assignedToPLResult.documents as List<QueryDocumentSnapshot>)
val allTasks = mutableListOf<Task>()
createdByPLResult.documents.forEach { document ->
val task = document.toObject(Task::class.java)
task?.let {
allTasks.add(it)
taskIdMap[it] = document.id
}
}
for (document in allTasks) {
assignedToPLResult.documents.forEach { document ->
val task = document.toObject(Task::class.java)
task?.let {
if (!taskIdMap.containsKey(it)) {
allTasks.add(it)
taskIdMap[it] = document.id
}
}
}
for (task in allTasks) {
calculateSubTasks(task, taskIdMap[task] ?: return)
}
calculateSubTasks(task, document.id)
taskList.clear()
taskList.addAll(allTasks)
if (!taskIdMap.containsKey(task)) {
taskList.add(task)
taskIdMap[task] = document.id
}
if (isAdded) {
fabMain.visibility = View.VISIBLE
}
if (isAdded) fabMain.visibility = View.VISIBLE
} catch (e: Exception) {
if (isAdded) {
Toast.makeText(
......@@ -181,6 +209,7 @@ class HomeFragment : Fragment() {
private suspend fun loadTasksForDev() {
try {
val currentUserEmail = auth.currentUser?.email ?: return
......@@ -189,19 +218,31 @@ class HomeFragment : Fragment() {
.get()
.await()
val allTasks = mutableListOf<QueryDocumentSnapshot>()
allTasks.addAll(assignedToDevResult.documents as List<QueryDocumentSnapshot>)
// Inizializza una lista per i task
val allTasks = mutableListOf<Task>()
for (document in allTasks) {
// Processa i task assegnati al Developer
assignedToDevResult.documents.forEach { document ->
val task = document.toObject(Task::class.java)
task?.let {
allTasks.add(it)
taskIdMap[it] = document.id
}
}
// Aggiorna i task aggiuntivi con il calcolo dei subtasks
for (task in allTasks) {
calculateSubTasks(task, taskIdMap[task] ?: return)
}
calculateSubTasks(task, document.id)
// Aggiungi i task caricati alla lista principale e aggiorna l'interfaccia utente
taskList.clear()
taskList.addAll(allTasks)
taskList.add(task)
taskIdMap[task] = document.id
if (isAdded) {
fabMain.visibility = View.VISIBLE
}
if (isAdded) fabMain.visibility = View.VISIBLE
} catch (e: Exception) {
if (isAdded) {
Toast.makeText(
......@@ -214,6 +255,7 @@ class HomeFragment : Fragment() {
}
private suspend fun calculateSubTasks(task: Task, taskId: String) {
try {
val subTasksResult = firestore.collection("tasks")
......
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>
\ No newline at end of file
app/src/main/res/mipmap-hdpi/ic_launcher.webp

1.37 KiB | W: | H:

app/src/main/res/mipmap-hdpi/ic_launcher.webp

2.44 KiB | W: | H:

app/src/main/res/mipmap-hdpi/ic_launcher.webp
app/src/main/res/mipmap-hdpi/ic_launcher.webp
app/src/main/res/mipmap-hdpi/ic_launcher.webp
app/src/main/res/mipmap-hdpi/ic_launcher.webp
  • 2-up
  • Swipe
  • Onion skin
app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp

5.81 KiB

app/src/main/res/mipmap-hdpi/ic_launcher_round.webp

2.83 KiB | W: | H:

app/src/main/res/mipmap-hdpi/ic_launcher_round.webp

4.28 KiB | W: | H:

app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
  • 2-up
  • Swipe
  • Onion skin
app/src/main/res/mipmap-mdpi/ic_launcher.webp

982 B | W: | H:

app/src/main/res/mipmap-mdpi/ic_launcher.webp

1.48 KiB | W: | H:

app/src/main/res/mipmap-mdpi/ic_launcher.webp
app/src/main/res/mipmap-mdpi/ic_launcher.webp
app/src/main/res/mipmap-mdpi/ic_launcher.webp
app/src/main/res/mipmap-mdpi/ic_launcher.webp
  • 2-up
  • Swipe
  • Onion skin
app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp

3.24 KiB

app/src/main/res/mipmap-mdpi/ic_launcher_round.webp

1.73 KiB | W: | H:

app/src/main/res/mipmap-mdpi/ic_launcher_round.webp

2.55 KiB | W: | H:

app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
  • 2-up
  • Swipe
  • Onion skin
app/src/main/res/mipmap-xhdpi/ic_launcher.webp

1.86 KiB | W: | H:

app/src/main/res/mipmap-xhdpi/ic_launcher.webp

3.6 KiB | W: | H:

app/src/main/res/mipmap-xhdpi/ic_launcher.webp
app/src/main/res/mipmap-xhdpi/ic_launcher.webp
app/src/main/res/mipmap-xhdpi/ic_launcher.webp
app/src/main/res/mipmap-xhdpi/ic_launcher.webp
  • 2-up
  • Swipe
  • Onion skin
app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp

8.77 KiB

app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp

3.83 KiB | W: | H:

app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp

6.39 KiB | W: | H:

app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
  • 2-up
  • Swipe
  • Onion skin
app/src/main/res/mipmap-xxhdpi/ic_launcher.webp

2.82 KiB | W: | H:

app/src/main/res/mipmap-xxhdpi/ic_launcher.webp

5.96 KiB | W: | H:

app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
  • 2-up
  • Swipe
  • Onion skin
app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp

16.2 KiB

app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp

5.78 KiB | W: | H:

app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp

11.2 KiB | W: | H:

app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
  • 2-up
  • Swipe
  • Onion skin
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment