From 9a00d5a73d1854ed496f25a721926be26fc6cc45 Mon Sep 17 00:00:00 2001 From: Jelena Petrovic Date: Tue, 22 Nov 2022 00:00:44 +0100 Subject: prikaz liste cetova i poruka u cetu, slanje i prikaz dobijenih poruka #37 --- .../.idea/deploymentTargetDropDown.xml | 4 +- .../brzodolokacije/Activities/ChatActivity.kt | 34 +++++++++- .../Activities/ChatActivityConversation.kt | 77 +++++++++++++++------- .../brzodolokacije/Adapters/ChatMessagesAdapter.kt | 38 +++++++++++ .../brzodolokacije/Adapters/ChatPreviewsAdapter.kt | 39 +++++++++++ .../java/com/example/brzodolokacije/Models/Chat.kt | 5 ++ .../com/example/brzodolokacije/chat/DBHelper.kt | 66 +++++++++++++++++-- .../example/brzodolokacije/chat/SignalRListener.kt | 8 ++- .../app/src/main/res/layout/activity_chat.xml | 4 +- .../main/res/layout/activity_chat_conversation.xml | 49 ++++++++++---- .../app/src/main/res/layout/chat_message.xml | 17 +++++ 11 files changed, 291 insertions(+), 50 deletions(-) create mode 100644 Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/ChatMessagesAdapter.kt create mode 100644 Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/ChatPreviewsAdapter.kt create mode 100644 Client/BrzoDoLokacije/app/src/main/res/layout/chat_message.xml diff --git a/Client/BrzoDoLokacije/.idea/deploymentTargetDropDown.xml b/Client/BrzoDoLokacije/.idea/deploymentTargetDropDown.xml index d34d986..c73c499 100644 --- a/Client/BrzoDoLokacije/.idea/deploymentTargetDropDown.xml +++ b/Client/BrzoDoLokacije/.idea/deploymentTargetDropDown.xml @@ -7,11 +7,11 @@ - + - + \ No newline at end of file diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ChatActivity.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ChatActivity.kt index 4cc7cc1..992f09f 100644 --- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ChatActivity.kt +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ChatActivity.kt @@ -4,8 +4,12 @@ import android.content.Intent import android.os.Bundle import android.widget.ImageButton import androidx.appcompat.app.AppCompatActivity +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import com.exam.DBHelper +import com.example.brzodolokacije.Adapters.ChatPreviewsAdapter +import com.example.brzodolokacije.Models.ChatPreview import com.example.brzodolokacije.R -import com.example.brzodolokacije.chat.DBHelper import com.example.brzodolokacije.chat.SignalRListener import com.example.brzodolokacije.databinding.ActivityChatBinding @@ -14,14 +18,20 @@ class ChatActivity : AppCompatActivity() { private var dbConnection:DBHelper?=null lateinit var binding: ActivityChatBinding var ws:SignalRListener?=null + var recyclerView:RecyclerView?=null + var adapterVar:ChatPreviewsAdapter?=null + var layoutVar:LinearLayoutManager?=null + var items:MutableList?= mutableListOf() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContentView(R.layout.activity_chat) - binding=ActivityChatBinding.inflate(layoutInflater) + binding= ActivityChatBinding.inflate(layoutInflater) + setContentView(binding.root) dbConnection= DBHelper(this@ChatActivity,null) ws=SignalRListener.getInstance(this@ChatActivity) setListeners() + setRecyclerView() + requestForChats() } fun setListeners(){ @@ -31,4 +41,22 @@ class ChatActivity : AppCompatActivity() { startActivity(intent) } } + + fun requestForChats(){ + var dbHelper= DBHelper.getInstance(this@ChatActivity) + items=dbHelper.getContacts() + adapterVar= items?.let { ChatPreviewsAdapter(it,this@ChatActivity) } + setRecyclerView(setParams = false) + } + + fun setRecyclerView(setParams:Boolean=true){ + if(setParams){ + adapterVar= items?.let { ChatPreviewsAdapter(it,this@ChatActivity) } + layoutVar=LinearLayoutManager(this@ChatActivity) + } + recyclerView=binding.rvMain + recyclerView?.setHasFixedSize(true) + recyclerView?.layoutManager=layoutVar + recyclerView?.adapter=adapterVar + } } \ No newline at end of file diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ChatActivityConversation.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ChatActivityConversation.kt index 715f5f3..d523485 100644 --- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ChatActivityConversation.kt +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ChatActivityConversation.kt @@ -2,43 +2,47 @@ package com.example.brzodolokacije.Activities import android.os.Bundle import android.util.Log +import android.view.View import android.widget.EditText import android.widget.ImageButton import android.widget.Toast import androidx.appcompat.app.AppCompatActivity -import androidx.cardview.widget.CardView -import androidx.core.view.isVisible +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import com.exam.DBHelper +import com.example.brzodolokacije.Adapters.ChatMessagesAdapter import com.example.brzodolokacije.Models.Message import com.example.brzodolokacije.Models.MessageSend import com.example.brzodolokacije.Models.UserReceive import com.example.brzodolokacije.R import com.example.brzodolokacije.Services.RetrofitHelper import com.example.brzodolokacije.Services.SharedPreferencesHelper -import com.example.brzodolokacije.chat.DBHelper import com.example.brzodolokacije.chat.SignalRListener +import com.example.brzodolokacije.databinding.ActivityChatConversationBinding import retrofit2.Call import retrofit2.Response class ChatActivityConversation : AppCompatActivity() { - var receiverId:String?=null + var recyclerView:RecyclerView?=null + var adapterVar: ChatMessagesAdapter?=null + var layoutVar: RecyclerView.LayoutManager?=null + lateinit var binding:ActivityChatConversationBinding + var userId:String?=null var receiverUsername:String?="jelena" - var dbConnection:DBHelper?=null + var dbConnection: DBHelper?=null var webSocketConnection:SignalRListener?=null + var items:MutableList?=mutableListOf() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContentView(R.layout.activity_chat_conversation) - receiverId=intent.extras?.get("receiverId").toString() - if(receiverId.isNullOrEmpty()){ - findViewById(R.id.cvParentMessageEdit).isVisible=true - findViewById(R.id.cvParentMessageEdit).invalidate() - } - else{ - findViewById(R.id.cvParentUsername).isVisible=true - findViewById(R.id.cvParentUsername).invalidate() - } + binding= ActivityChatConversationBinding.inflate(layoutInflater) + setContentView(binding.root) + userId=intent.extras?.get("userId").toString() dbConnection=DBHelper.getInstance(this@ChatActivityConversation) + setHeader() + setRecyclerView() + requestMessages() webSocketConnection=SignalRListener.getInstance(this@ChatActivityConversation) setListeners() } @@ -49,7 +53,7 @@ class ChatActivityConversation : AppCompatActivity() { var messageContent=findViewById(R.id.etNewMessage).text.toString() Log.d("main",token!!) val Api= RetrofitHelper.getInstance() - if(receiverId.isNullOrEmpty()){ + if(userId.isNullOrEmpty() || userId.equals("null")){ //zahtev sa username=om receiverUsername=findViewById(R.id.etReceiverUsername).text.toString() val request=Api.getProfile("Bearer "+token, @@ -59,8 +63,8 @@ class ChatActivityConversation : AppCompatActivity() { override fun onResponse(call: Call, response: Response) { if(response.isSuccessful()){ //zahtev da se posalje poruka - receiverId=response.body()?._id - var message= MessageSend(receiverId!!,messageContent) + userId=response.body()?._id + var message= MessageSend(userId!!,messageContent) val request2=Api.sendMessage("Bearer "+token, message ) @@ -70,8 +74,7 @@ class ChatActivityConversation : AppCompatActivity() { //zahtev da se posalje poruka var responseMessage=response.body() dbConnection?.addMessage(responseMessage!!) - dbConnection?.getMessages() - webSocketConnection?.getConnectionState() + } @@ -98,7 +101,7 @@ class ChatActivityConversation : AppCompatActivity() { } else{ //zahtev da se posalje poruka - var message= MessageSend(receiverId!!,messageContent) + var message= MessageSend(userId!!,messageContent) val request2=Api.sendMessage("Bearer "+token, message ) @@ -108,7 +111,7 @@ class ChatActivityConversation : AppCompatActivity() { //zahtev da se posalje poruka var responseMessage=response.body() dbConnection?.addMessage(responseMessage!!) - dbConnection?.getMessages() + requestMessages() } @@ -125,4 +128,34 @@ class ChatActivityConversation : AppCompatActivity() { } } + + private fun setHeader(){ + if(userId.isNullOrEmpty() || userId.equals("null")){ + binding.tvFragmentTitle.visibility= View.GONE + binding.tvFragmentTitle.invalidate() + binding.tvFragmentTitle.forceLayout() + } + else{ + binding.tvFragmentTitle.text=userId + binding.tvFragmentTitle.invalidate() + binding.cvParentUsername.visibility= View.GONE + binding.cvParentUsername.forceLayout() + } + } + fun setRecyclerView(setParams:Boolean=true){ + if(setParams){ + adapterVar= items?.let { ChatMessagesAdapter(it,this@ChatActivityConversation) } + layoutVar= LinearLayoutManager(this@ChatActivityConversation) + } + recyclerView = binding.rvMain + recyclerView?.setHasFixedSize(true) + recyclerView?.layoutManager=layoutVar + recyclerView?.adapter=adapterVar + } + + fun requestMessages(){ + items=dbConnection?.getMessages(userId!!) + adapterVar= items?.let { ChatMessagesAdapter(it,this@ChatActivityConversation) } + setRecyclerView(setParams = false) + } } \ No newline at end of file diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/ChatMessagesAdapter.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/ChatMessagesAdapter.kt new file mode 100644 index 0000000..4c917f3 --- /dev/null +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/ChatMessagesAdapter.kt @@ -0,0 +1,38 @@ +package com.example.brzodolokacije.Adapters + +import android.app.Activity +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView +import com.example.brzodolokacije.Models.Message +import com.example.brzodolokacije.databinding.ChatMessageBinding + +class ChatMessagesAdapter (val items : MutableList, val activity:Activity) + : RecyclerView.Adapter(){ + //constructer has one argument - list of objects that need to be displayed + //it is bound to xml of single item + private lateinit var binding: ChatMessageBinding + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + val inflater = LayoutInflater.from(parent.context) + binding= ChatMessageBinding.inflate(inflater,parent,false) + return ViewHolder(binding) + } + override fun onBindViewHolder(holder: ViewHolder, position: Int){ + //sets components of particular item + holder.bind(items[position]) +// holder.itemView.setOnClickListener { +// val intent: Intent = Intent(activity, ChatActivityConversation::class.java) +// intent.putExtra("userId",items[position].userId) +// activity.startActivity(intent) +// } + } + override fun getItemCount() = items.size + inner class ViewHolder(itemView : ChatMessageBinding) : RecyclerView.ViewHolder(itemView.root){ + fun bind(item : Message){ + binding.apply { + //clMessage.foregroundGravity=Gravity.END + tvMessage.text=item.messagge + } + } + } +} \ No newline at end of file diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/ChatPreviewsAdapter.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/ChatPreviewsAdapter.kt new file mode 100644 index 0000000..b63cb2f --- /dev/null +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/ChatPreviewsAdapter.kt @@ -0,0 +1,39 @@ +package com.example.brzodolokacije.Adapters + +import android.app.Activity +import android.content.Intent +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView +import com.example.brzodolokacije.Activities.ChatActivityConversation +import com.example.brzodolokacije.Models.ChatPreview +import com.example.brzodolokacije.databinding.ChatPreviewBinding + +class ChatPreviewsAdapter (val items : MutableList,val activity:Activity) + : RecyclerView.Adapter(){ + //constructer has one argument - list of objects that need to be displayed + //it is bound to xml of single item + private lateinit var binding: ChatPreviewBinding + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + val inflater = LayoutInflater.from(parent.context) + binding=ChatPreviewBinding.inflate(inflater,parent,false) + return ViewHolder(binding) + } + override fun onBindViewHolder(holder: ViewHolder, position: Int){ + //sets components of particular item + holder.bind(items[position]) + holder.itemView.setOnClickListener { + val intent: Intent = Intent(activity, ChatActivityConversation::class.java) + intent.putExtra("userId",items[position].userId) + activity.startActivity(intent) + } + } + override fun getItemCount() = items.size + inner class ViewHolder(itemView : ChatPreviewBinding) : RecyclerView.ViewHolder(itemView.root){ + fun bind(item : ChatPreview){ + binding.apply { + tvUsername.text=item.userId + } + } + } +} \ No newline at end of file diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Models/Chat.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Models/Chat.kt index 4b87d51..3404541 100644 --- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Models/Chat.kt +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Models/Chat.kt @@ -19,4 +19,9 @@ data class Message( var receiverId: String, var messagge: String, var timestamp: Date +) + +data class ChatPreview( + var userId:String, + var read:Boolean ) \ No newline at end of file diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/chat/DBHelper.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/chat/DBHelper.kt index d4ee046..d3a95b4 100644 --- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/chat/DBHelper.kt +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/chat/DBHelper.kt @@ -1,4 +1,5 @@ -package com.example.brzodolokacije.chat +package com.exam + import android.app.Activity import android.content.Context @@ -6,7 +7,9 @@ import android.database.Cursor import android.database.sqlite.SQLiteDatabase import android.database.sqlite.SQLiteOpenHelper import android.util.Log +import com.example.brzodolokacije.Models.ChatPreview import com.example.brzodolokacije.Models.Message +import java.util.* class DBHelper : @@ -36,7 +39,7 @@ class DBHelper : override fun onCreate(db: SQLiteDatabase?) { if(!doesTableExist(CONTACTS_TABLE_NAME,db)){ - var sql:String="CREATE TABLE "+ CONTACTS_TABLE_NAME+"(" + + var sql:String="CREATE TABLE "+ CONTACTS_TABLE_NAME+" (" + "userId " +"TEXT PRIMARY KEY,"+ "read " +"INT"+ ")" @@ -74,7 +77,7 @@ class DBHelper : onCreate(db) } - fun addMessage(message: Message){ + fun addMessage(message: Message, sent:Boolean=true){ if(message._id.isNullOrEmpty()){ message._id=message.senderId+message.timestamp } @@ -84,10 +87,61 @@ class DBHelper : message.messagge+ "','"+ message.timestamp+ "')" db?.execSQL(sql) + if(sent) + sql="SELECT * FROM "+ CONTACTS_TABLE_NAME+" WHERE userId='"+message.receiverId+"'" + else + sql="SELECT * FROM "+ CONTACTS_TABLE_NAME+" WHERE userId='"+message.senderId+"'" + var cursor=db?.rawQuery(sql,null) + if(cursor?.count==0){ + //dodati u kontakte + var id:String + id = if(sent) message.receiverId else message.senderId + var read:Int=if(sent) 1 else 0 + sql="INSERT INTO "+ CONTACTS_TABLE_NAME+"(userId,read) VALUES('"+id+"','"+ + read+"')" + db?.execSQL(sql) + } } - fun getMessages(){ - var sql="SELECT * FROM "+ MESSAGES_TABLE_NAME + fun getMessages(userId:String): MutableList? { + var sql="SELECT * FROM "+ MESSAGES_TABLE_NAME+" WHERE senderId='"+userId+"' OR receiverId='"+userId+"'" var cursor=db?.rawQuery(sql,null) - Log.d("main",cursor?.count.toString()) + if(cursor?.count!! >0){ + var messagesList:MutableList =mutableListOf() + var idIndex=cursor.getColumnIndexOrThrow("_id") + var senderIdIndex=cursor.getColumnIndexOrThrow("senderId") + var receiverIdIndex=cursor.getColumnIndexOrThrow("receiverId") + var messageIndex=cursor.getColumnIndexOrThrow("messagge") + var timestampIndex=cursor.getColumnIndexOrThrow("timestamp") + while(cursor.moveToNext()){ + messagesList.add( + Message( + cursor.getString(idIndex), + cursor.getString(senderIdIndex), + cursor.getString(receiverIdIndex), + cursor.getString(messageIndex), + Date() + ) + ) + } + Log.d("main",messagesList.size.toString()) + return messagesList + } + return null + } + + fun getContacts(): MutableList? { + var sql="SELECT * FROM "+ CONTACTS_TABLE_NAME + var cursor=db?.rawQuery(sql,null) + if(cursor?.count!! >0){ + var contactList:MutableList =mutableListOf() + var userIdIndex=cursor.getColumnIndexOrThrow("userId") + var readIndex=cursor.getColumnIndexOrThrow("read") + while(cursor.moveToNext()){ + contactList.add(ChatPreview(cursor.getString(userIdIndex),cursor.getInt(readIndex)==1)) + } + Log.d("main",contactList.size.toString()) + return contactList + } + return null } } \ No newline at end of file diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/chat/SignalRListener.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/chat/SignalRListener.kt index 1aa6afa..07a9d3e 100644 --- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/chat/SignalRListener.kt +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/chat/SignalRListener.kt @@ -2,6 +2,8 @@ package com.example.brzodolokacije.chat import android.app.Activity import android.util.Log +import com.exam.DBHelper +import com.example.brzodolokacije.Models.Message import com.example.brzodolokacije.Models.MessageReceive import com.example.brzodolokacije.Services.RetrofitHelper import com.example.brzodolokacije.Services.SharedPreferencesHelper @@ -13,13 +15,17 @@ import com.microsoft.signalr.HubConnectionState class SignalRListener private constructor(val activity: Activity){ private var hubConnection:HubConnection + private var dbHelper:DBHelper init{ + dbHelper= DBHelper.getInstance(activity) hubConnection=HubConnectionBuilder.create(RetrofitHelper.baseUrl+"/chathub") .withHeader("access_token",SharedPreferencesHelper.getValue("jwt",activity)) .build() hubConnection.keepAliveInterval=120 hubConnection.on("Message", - Action1 {message:MessageReceive->Log.d("main",message.messagge)}, + Action1 { + message:MessageReceive->dbHelper.addMessage(Message(message.senderId+message.timestamp,message.senderId,message.senderId,message.messagge,message.timestamp),false) + }, MessageReceive::class.java ) hubConnection.start().blockingAwait() diff --git a/Client/BrzoDoLokacije/app/src/main/res/layout/activity_chat.xml b/Client/BrzoDoLokacije/app/src/main/res/layout/activity_chat.xml index 694e972..9e28d6d 100644 --- a/Client/BrzoDoLokacije/app/src/main/res/layout/activity_chat.xml +++ b/Client/BrzoDoLokacije/app/src/main/res/layout/activity_chat.xml @@ -32,7 +32,7 @@ - + \ No newline at end of file diff --git a/Client/BrzoDoLokacije/app/src/main/res/layout/activity_chat_conversation.xml b/Client/BrzoDoLokacije/app/src/main/res/layout/activity_chat_conversation.xml index ea7d3e7..5afcd86 100644 --- a/Client/BrzoDoLokacije/app/src/main/res/layout/activity_chat_conversation.xml +++ b/Client/BrzoDoLokacije/app/src/main/res/layout/activity_chat_conversation.xml @@ -5,26 +5,30 @@ android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".Activities.ChatActivityConversation"> + + + android:textColor="@color/white" + android:textSize="40dp" /> + + android:inputType="textPersonName" + android:paddingLeft="15dp" /> + + + + + + + + + app:layout_constraintStart_toStartOf="parent"> + android:inputType="textPersonName" + android:paddingLeft="15dp" /> + android:src="@drawable/post_comment" + app:cornerRadius="16dp" /> \ No newline at end of file diff --git a/Client/BrzoDoLokacije/app/src/main/res/layout/chat_message.xml b/Client/BrzoDoLokacije/app/src/main/res/layout/chat_message.xml new file mode 100644 index 0000000..2210fa0 --- /dev/null +++ b/Client/BrzoDoLokacije/app/src/main/res/layout/chat_message.xml @@ -0,0 +1,17 @@ + + + + + + + \ No newline at end of file -- cgit v1.2.3 From b5128bad1c6ea8c304def4bb2c9d75bc5d74ff5c Mon Sep 17 00:00:00 2001 From: Ognjen Cirkovic Date: Tue, 22 Nov 2022 00:33:43 +0100 Subject: Ispravljen typo. Dodate provere za null. --- Backend/Api/Api/Controllers/UserController.cs | 2 +- Backend/Api/Api/Services/UserService.cs | 14 ++++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/Backend/Api/Api/Controllers/UserController.cs b/Backend/Api/Api/Controllers/UserController.cs index 6cc41ea..7764af1 100644 --- a/Backend/Api/Api/Controllers/UserController.cs +++ b/Backend/Api/Api/Controllers/UserController.cs @@ -89,7 +89,7 @@ namespace Api.Controllers return Ok(await _userService.GetFollowing(id)); } - [HttpGet("{id}/addFollower")] + [HttpGet("addFollower")] [Authorize(Roles = "User")] public async Task>> AddFollower(string userId, string followerId) { diff --git a/Backend/Api/Api/Services/UserService.cs b/Backend/Api/Api/Services/UserService.cs index 64a7f7a..f616d99 100644 --- a/Backend/Api/Api/Services/UserService.cs +++ b/Backend/Api/Api/Services/UserService.cs @@ -382,13 +382,19 @@ namespace Api.Services public async Task AddFollower(string userId,string followerId) { - UserSend u = await _usersSend.Find(user => user._id==userId).FirstOrDefaultAsync(); - UserSend f = await _usersSend.Find(user => user._id == followerId).FirstOrDefaultAsync(); + User u = await _users.Find(user => user._id==userId).FirstOrDefaultAsync(); + User f = await _users.Find(user => user._id == followerId).FirstOrDefaultAsync(); if (userId != null && followerId!=null) { + if (u.followers == null) + u.followers = new List(); u.followers.Add(followerId); + if (f.following == null) + f.following = new List(); f.following.Add(userId); + _users.ReplaceOne(user=>user._id==userId, u); + _users.ReplaceOne(user => user._id == followerId, f); return true; } @@ -403,7 +409,7 @@ namespace Api.Services if (u != null) { //List followers = u.followers; - if (u.followers.Count() > 0) + if (u.followers!=null &&u.followers.Count() > 0) { foreach (string userid in u.followers) { @@ -434,7 +440,7 @@ namespace Api.Services if (u != null) { - if (u.following.Count() > 0) + if (u.following!=null &&u.following.Count() > 0) { foreach (string userid in u.following) { -- cgit v1.2.3 From 9ae6cce32844d3262003cd68bdd10918bcad5601 Mon Sep 17 00:00:00 2001 From: Jelena Petrovic Date: Tue, 22 Nov 2022 00:59:11 +0100 Subject: Sredjena aktivnost liste cetova, prikazuje se korisnicko ime islika svakog kontakta, omogucen refresh, prosledjuje se korisnicko ime i id korisnika pojedinacnom cetu na klik #37 --- .../brzodolokacije/Activities/ChatActivity.kt | 21 ++++++++++- .../Activities/ChatActivityConversation.kt | 5 +-- .../brzodolokacije/Adapters/ChatPreviewsAdapter.kt | 42 +++++++++++++++++++++- .../brzodolokacije/Interfaces/IBackendApi.kt | 2 ++ .../app/src/main/res/layout/chat_preview.xml | 3 +- 5 files changed, 68 insertions(+), 5 deletions(-) diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ChatActivity.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ChatActivity.kt index 992f09f..c824cf3 100644 --- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ChatActivity.kt +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ChatActivity.kt @@ -6,6 +6,7 @@ import android.widget.ImageButton import androidx.appcompat.app.AppCompatActivity import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout import com.exam.DBHelper import com.example.brzodolokacije.Adapters.ChatPreviewsAdapter import com.example.brzodolokacije.Models.ChatPreview @@ -13,7 +14,7 @@ import com.example.brzodolokacije.R import com.example.brzodolokacije.chat.SignalRListener import com.example.brzodolokacije.databinding.ActivityChatBinding -class ChatActivity : AppCompatActivity() { +class ChatActivity : AppCompatActivity(), SwipeRefreshLayout.OnRefreshListener { private var dbConnection:DBHelper?=null lateinit var binding: ActivityChatBinding @@ -22,6 +23,7 @@ class ChatActivity : AppCompatActivity() { var adapterVar:ChatPreviewsAdapter?=null var layoutVar:LinearLayoutManager?=null var items:MutableList?= mutableListOf() + private var swipeRefreshLayout: SwipeRefreshLayout?=null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -32,6 +34,18 @@ class ChatActivity : AppCompatActivity() { setListeners() setRecyclerView() requestForChats() + swipeRefreshLayout = binding.swipeContainer + swipeRefreshLayout?.setOnRefreshListener(this@ChatActivity) + swipeRefreshLayout?.setColorSchemeResources( + R.color.purple_200, + R.color.teal_200, + R.color.dark_blue_transparent, + R.color.purple_700 + ) + swipeRefreshLayout?.post(kotlinx.coroutines.Runnable { + swipeRefreshLayout?.isRefreshing=true + requestForChats() + }) } fun setListeners(){ @@ -58,5 +72,10 @@ class ChatActivity : AppCompatActivity() { recyclerView?.setHasFixedSize(true) recyclerView?.layoutManager=layoutVar recyclerView?.adapter=adapterVar + swipeRefreshLayout?.isRefreshing=false + } + + override fun onRefresh() { + requestForChats() } } \ No newline at end of file diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ChatActivityConversation.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ChatActivityConversation.kt index d523485..84771a8 100644 --- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ChatActivityConversation.kt +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ChatActivityConversation.kt @@ -29,7 +29,7 @@ class ChatActivityConversation : AppCompatActivity() { var layoutVar: RecyclerView.LayoutManager?=null lateinit var binding:ActivityChatConversationBinding var userId:String?=null - var receiverUsername:String?="jelena" + var receiverUsername:String?=null var dbConnection: DBHelper?=null var webSocketConnection:SignalRListener?=null var items:MutableList?=mutableListOf() @@ -39,6 +39,7 @@ class ChatActivityConversation : AppCompatActivity() { binding= ActivityChatConversationBinding.inflate(layoutInflater) setContentView(binding.root) userId=intent.extras?.get("userId").toString() + receiverUsername=intent.extras?.get("username").toString() dbConnection=DBHelper.getInstance(this@ChatActivityConversation) setHeader() setRecyclerView() @@ -136,7 +137,7 @@ class ChatActivityConversation : AppCompatActivity() { binding.tvFragmentTitle.forceLayout() } else{ - binding.tvFragmentTitle.text=userId + binding.tvFragmentTitle.text=receiverUsername binding.tvFragmentTitle.invalidate() binding.cvParentUsername.visibility= View.GONE binding.cvParentUsername.forceLayout() diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/ChatPreviewsAdapter.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/ChatPreviewsAdapter.kt index b63cb2f..94a72f3 100644 --- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/ChatPreviewsAdapter.kt +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/ChatPreviewsAdapter.kt @@ -4,19 +4,32 @@ import android.app.Activity import android.content.Intent import android.view.LayoutInflater import android.view.ViewGroup +import android.widget.Toast import androidx.recyclerview.widget.RecyclerView +import com.bumptech.glide.Glide import com.example.brzodolokacije.Activities.ChatActivityConversation +import com.example.brzodolokacije.Interfaces.IBackendApi import com.example.brzodolokacije.Models.ChatPreview +import com.example.brzodolokacije.Models.UserReceive +import com.example.brzodolokacije.Services.RetrofitHelper +import com.example.brzodolokacije.Services.SharedPreferencesHelper import com.example.brzodolokacije.databinding.ChatPreviewBinding +import kotlinx.android.synthetic.main.chat_preview.view.* +import retrofit2.Call +import retrofit2.Response class ChatPreviewsAdapter (val items : MutableList,val activity:Activity) : RecyclerView.Adapter(){ //constructer has one argument - list of objects that need to be displayed //it is bound to xml of single item + private var api: IBackendApi?=null + private var token:String?=null private lateinit var binding: ChatPreviewBinding override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val inflater = LayoutInflater.from(parent.context) binding=ChatPreviewBinding.inflate(inflater,parent,false) + api=RetrofitHelper.getInstance() + token=SharedPreferencesHelper.getValue("jwt",activity) return ViewHolder(binding) } override fun onBindViewHolder(holder: ViewHolder, position: Int){ @@ -25,6 +38,7 @@ class ChatPreviewsAdapter (val items : MutableList,val activity:Act holder.itemView.setOnClickListener { val intent: Intent = Intent(activity, ChatActivityConversation::class.java) intent.putExtra("userId",items[position].userId) + intent.putExtra("username",holder.itemView.tvUsername.text) activity.startActivity(intent) } } @@ -32,7 +46,33 @@ class ChatPreviewsAdapter (val items : MutableList,val activity:Act inner class ViewHolder(itemView : ChatPreviewBinding) : RecyclerView.ViewHolder(itemView.root){ fun bind(item : ChatPreview){ binding.apply { - tvUsername.text=item.userId + val request2=api?.getProfileFromId("Bearer "+token, + item.userId + ) + request2?.enqueue(object : retrofit2.Callback { + override fun onResponse(call: Call, response: Response) { + if(response.isSuccessful()){ + //zahtev da se posalje poruka + var user=response.body()!! + tvUsername.text=user.username + if(user.pfp!=null) { + Glide.with(activity) + .load(RetrofitHelper.baseUrl + "/api/post/image/" + user.pfp!!._id) + .into(ivUserImage) + } + } + else{ + Toast.makeText(activity,"los id", + Toast.LENGTH_LONG).show() + tvUsername.text="nije nadjen korisnik" + } + } + + override fun onFailure(call: Call, t: Throwable) { + Toast.makeText(activity,"neuspesan zahtev", + Toast.LENGTH_LONG).show() + } + }) } } } diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Interfaces/IBackendApi.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Interfaces/IBackendApi.kt index f7bb9b6..8fb7b4d 100644 --- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Interfaces/IBackendApi.kt +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Interfaces/IBackendApi.kt @@ -78,5 +78,7 @@ interface IBackendApi { @POST("/api/user{id}/addFollower") fun addFollower(@Header("Authorization") authHeader:String,@Path("id") id:String):Call + @GET("/api/user/{id}/id/profile") + fun getProfileFromId(@Header("Authorization") authHeader:String,@Path("id") username:String):Call } \ No newline at end of file diff --git a/Client/BrzoDoLokacije/app/src/main/res/layout/chat_preview.xml b/Client/BrzoDoLokacije/app/src/main/res/layout/chat_preview.xml index 95c036a..35431ff 100644 --- a/Client/BrzoDoLokacije/app/src/main/res/layout/chat_preview.xml +++ b/Client/BrzoDoLokacije/app/src/main/res/layout/chat_preview.xml @@ -6,7 +6,8 @@ + android:id="@+id/ivUserImage" + android:src="@drawable/ic_nav_profile"/> Date: Tue, 22 Nov 2022 01:32:02 +0100 Subject: resen problem duplog id-ja kada se poruka posalje samom sebi #37 --- .../app/src/main/AndroidManifest.xml | 3 +- .../Activities/ChatActivityConversation.kt | 4 +- .../com/example/brzodolokacije/chat/DBHelper.kt | 46 ++++++++++++---------- 3 files changed, 28 insertions(+), 25 deletions(-) diff --git a/Client/BrzoDoLokacije/app/src/main/AndroidManifest.xml b/Client/BrzoDoLokacije/app/src/main/AndroidManifest.xml index 745f813..bb2d712 100644 --- a/Client/BrzoDoLokacije/app/src/main/AndroidManifest.xml +++ b/Client/BrzoDoLokacije/app/src/main/AndroidManifest.xml @@ -38,7 +38,8 @@ tools:targetApi="31"> + android:exported="false" + android:windowSoftInputMode="stateVisible|adjustPan"> diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ChatActivityConversation.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ChatActivityConversation.kt index 84771a8..ab91940 100644 --- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ChatActivityConversation.kt +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ChatActivityConversation.kt @@ -112,9 +112,7 @@ class ChatActivityConversation : AppCompatActivity() { //zahtev da se posalje poruka var responseMessage=response.body() dbConnection?.addMessage(responseMessage!!) - requestMessages() - - + //requestMessages() } else{ Toast.makeText(this@ChatActivityConversation,"Pogresno korisnicko ime.",Toast.LENGTH_LONG).show() diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/chat/DBHelper.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/chat/DBHelper.kt index d3a95b4..be88ad3 100644 --- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/chat/DBHelper.kt +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/chat/DBHelper.kt @@ -78,28 +78,32 @@ class DBHelper : } fun addMessage(message: Message, sent:Boolean=true){ - if(message._id.isNullOrEmpty()){ - message._id=message.senderId+message.timestamp - } - var sql="INSERT INTO "+ MESSAGES_TABLE_NAME+"(_id,senderId,receiverid,messagge,timestamp) VALUES('"+message._id+"','"+ - message.senderId+"','"+ - message.receiverId+"','"+ - message.messagge+ "','"+ - message.timestamp+ "')" - db?.execSQL(sql) - if(sent) - sql="SELECT * FROM "+ CONTACTS_TABLE_NAME+" WHERE userId='"+message.receiverId+"'" - else - sql="SELECT * FROM "+ CONTACTS_TABLE_NAME+" WHERE userId='"+message.senderId+"'" - var cursor=db?.rawQuery(sql,null) - if(cursor?.count==0){ - //dodati u kontakte - var id:String - id = if(sent) message.receiverId else message.senderId - var read:Int=if(sent) 1 else 0 - sql="INSERT INTO "+ CONTACTS_TABLE_NAME+"(userId,read) VALUES('"+id+"','"+ - read+"')" + if(!message._id.isNullOrEmpty() && message.senderId==message.receiverId){ + Log.d("main", "ne zapisuje se dupla poruka") + } else { + if(message._id.isNullOrEmpty()){ + message._id=message.senderId+message.timestamp + } + var sql="INSERT INTO "+ MESSAGES_TABLE_NAME+"(_id,senderId,receiverid,messagge,timestamp) VALUES('"+message._id+"','"+ + message.senderId+"','"+ + message.receiverId+"','"+ + message.messagge+ "','"+ + message.timestamp+ "')" db?.execSQL(sql) + if(sent) + sql="SELECT * FROM "+ CONTACTS_TABLE_NAME+" WHERE userId='"+message.receiverId+"'" + else + sql="SELECT * FROM "+ CONTACTS_TABLE_NAME+" WHERE userId='"+message.senderId+"'" + var cursor=db?.rawQuery(sql,null) + if(cursor?.count==0){ + //dodati u kontakte + var id:String + id = if(sent) message.receiverId else message.senderId + var read:Int=if(sent) 1 else 0 + sql="INSERT INTO "+ CONTACTS_TABLE_NAME+"(userId,read) VALUES('"+id+"','"+ + read+"')" + db?.execSQL(sql) + } } } fun getMessages(userId:String): MutableList? { -- cgit v1.2.3 From e3b16511aba89dd4905c3150e0bcaecd46664215 Mon Sep 17 00:00:00 2001 From: Jelena Petrovic Date: Tue, 22 Nov 2022 03:13:17 +0100 Subject: poslate poruke se odmah vide u cetu, razlikuju se primljene od poslatih poruka #37 --- .../Activities/ChatActivityConversation.kt | 18 ++++-- .../brzodolokacije/Adapters/ChatMessagesAdapter.kt | 67 +++++++++++++++++----- .../main/res/layout/activity_chat_conversation.xml | 3 +- .../app/src/main/res/layout/chat_message.xml | 23 +++++--- .../app/src/main/res/layout/chat_message_other.xml | 23 ++++++++ 5 files changed, 107 insertions(+), 27 deletions(-) create mode 100644 Client/BrzoDoLokacije/app/src/main/res/layout/chat_message_other.xml diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ChatActivityConversation.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ChatActivityConversation.kt index ab91940..98e3208 100644 --- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ChatActivityConversation.kt +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ChatActivityConversation.kt @@ -65,6 +65,7 @@ class ChatActivityConversation : AppCompatActivity() { if(response.isSuccessful()){ //zahtev da se posalje poruka userId=response.body()?._id + setHeader() var message= MessageSend(userId!!,messageContent) val request2=Api.sendMessage("Bearer "+token, message @@ -75,8 +76,8 @@ class ChatActivityConversation : AppCompatActivity() { //zahtev da se posalje poruka var responseMessage=response.body() dbConnection?.addMessage(responseMessage!!) - - + requestMessages() + binding.etNewMessage.text?.clear() } else{ @@ -112,7 +113,8 @@ class ChatActivityConversation : AppCompatActivity() { //zahtev da se posalje poruka var responseMessage=response.body() dbConnection?.addMessage(responseMessage!!) - //requestMessages() + requestMessages() + binding.etNewMessage.text?.clear() } else{ Toast.makeText(this@ChatActivityConversation,"Pogresno korisnicko ime.",Toast.LENGTH_LONG).show() @@ -130,11 +132,16 @@ class ChatActivityConversation : AppCompatActivity() { private fun setHeader(){ if(userId.isNullOrEmpty() || userId.equals("null")){ + binding.cvParentUsername.visibility= View.VISIBLE + binding.cvParentUsername.forceLayout() binding.tvFragmentTitle.visibility= View.GONE binding.tvFragmentTitle.invalidate() binding.tvFragmentTitle.forceLayout() } else{ + binding.tvFragmentTitle.visibility= View.VISIBLE + binding.tvFragmentTitle.invalidate() + binding.tvFragmentTitle.forceLayout() binding.tvFragmentTitle.text=receiverUsername binding.tvFragmentTitle.invalidate() binding.cvParentUsername.visibility= View.GONE @@ -150,11 +157,14 @@ class ChatActivityConversation : AppCompatActivity() { recyclerView?.setHasFixedSize(true) recyclerView?.layoutManager=layoutVar recyclerView?.adapter=adapterVar + recyclerView?.scrollToPosition(items?.size?.minus(1) ?: 0) } fun requestMessages(){ - items=dbConnection?.getMessages(userId!!) + if(!userId.isNullOrEmpty() && !userId.equals("null")) + items=dbConnection?.getMessages(userId!!) adapterVar= items?.let { ChatMessagesAdapter(it,this@ChatActivityConversation) } setRecyclerView(setParams = false) + } } \ No newline at end of file diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/ChatMessagesAdapter.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/ChatMessagesAdapter.kt index 4c917f3..c3c8a8a 100644 --- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/ChatMessagesAdapter.kt +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/ChatMessagesAdapter.kt @@ -4,35 +4,72 @@ import android.app.Activity import android.view.LayoutInflater import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView +import com.auth0.android.jwt.JWT import com.example.brzodolokacije.Models.Message +import com.example.brzodolokacije.Services.SharedPreferencesHelper import com.example.brzodolokacije.databinding.ChatMessageBinding +import com.example.brzodolokacije.databinding.ChatMessageOtherBinding class ChatMessagesAdapter (val items : MutableList, val activity:Activity) - : RecyclerView.Adapter(){ + : RecyclerView.Adapter(){ //constructer has one argument - list of objects that need to be displayed //it is bound to xml of single item - private lateinit var binding: ChatMessageBinding - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + private val VIEW_TYPE_MESSAGE_SENT: Int = 1 + private val VIEW_TYPE_MESSAGE_RECEIVED:Int = 2 + private var binding: ChatMessageBinding?=null + private var bindingOther: ChatMessageOtherBinding?=null + + private var currentUser:String?=null + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { val inflater = LayoutInflater.from(parent.context) - binding= ChatMessageBinding.inflate(inflater,parent,false) - return ViewHolder(binding) + var token=SharedPreferencesHelper.getValue("jwt",activity) + var jwt= JWT(token.toString()) + currentUser= jwt.getClaim("id").toString() + + if(viewType==VIEW_TYPE_MESSAGE_RECEIVED){ + bindingOther= ChatMessageOtherBinding.inflate(inflater,parent,false) + return ReceivedViewHolder(bindingOther!!) + } + else{ + binding= ChatMessageBinding.inflate(inflater,parent,false) + return SentViewHolder(binding!!) + } + } - override fun onBindViewHolder(holder: ViewHolder, position: Int){ + override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int){ //sets components of particular item - holder.bind(items[position]) -// holder.itemView.setOnClickListener { -// val intent: Intent = Intent(activity, ChatActivityConversation::class.java) -// intent.putExtra("userId",items[position].userId) -// activity.startActivity(intent) -// } + if(holder is ReceivedViewHolder){ + holder.bind(items[position]) + } + else if(holder is SentViewHolder){ + holder.bind(items[position]) + } } override fun getItemCount() = items.size - inner class ViewHolder(itemView : ChatMessageBinding) : RecyclerView.ViewHolder(itemView.root){ + inner class ReceivedViewHolder(itemView : ChatMessageOtherBinding) : RecyclerView.ViewHolder(itemView.root){ fun bind(item : Message){ - binding.apply { - //clMessage.foregroundGravity=Gravity.END + bindingOther?.apply { + tvMessage?.text=item.messagge + } + } + } + inner class SentViewHolder(itemView : ChatMessageBinding) : RecyclerView.ViewHolder(itemView.root){ + fun bind(item : Message){ + binding?.apply { tvMessage.text=item.messagge } } } + + + override fun getItemViewType(position: Int): Int { + var sender=items.get(position).senderId + if(sender==currentUser){ + return VIEW_TYPE_MESSAGE_SENT + } + else{ + return VIEW_TYPE_MESSAGE_RECEIVED + } + } } \ No newline at end of file diff --git a/Client/BrzoDoLokacije/app/src/main/res/layout/activity_chat_conversation.xml b/Client/BrzoDoLokacije/app/src/main/res/layout/activity_chat_conversation.xml index 5afcd86..72060f7 100644 --- a/Client/BrzoDoLokacije/app/src/main/res/layout/activity_chat_conversation.xml +++ b/Client/BrzoDoLokacije/app/src/main/res/layout/activity_chat_conversation.xml @@ -62,7 +62,8 @@ android:id="@+id/rvMain" android:layout_width="match_parent" android:layout_height="wrap_content" - app:layout_constraintBottom_toBottomOf="parent"> + app:layout_constraintBottom_toBottomOf="parent" + > diff --git a/Client/BrzoDoLokacije/app/src/main/res/layout/chat_message.xml b/Client/BrzoDoLokacije/app/src/main/res/layout/chat_message.xml index 2210fa0..2342779 100644 --- a/Client/BrzoDoLokacije/app/src/main/res/layout/chat_message.xml +++ b/Client/BrzoDoLokacije/app/src/main/res/layout/chat_message.xml @@ -2,16 +2,25 @@ - - + + app:layout_constraintEnd_toEndOf="parent" + app:cardBackgroundColor="@color/cardview_dark_background"> + + \ No newline at end of file diff --git a/Client/BrzoDoLokacije/app/src/main/res/layout/chat_message_other.xml b/Client/BrzoDoLokacije/app/src/main/res/layout/chat_message_other.xml new file mode 100644 index 0000000..647127c --- /dev/null +++ b/Client/BrzoDoLokacije/app/src/main/res/layout/chat_message_other.xml @@ -0,0 +1,23 @@ + + + + + + + \ No newline at end of file -- cgit v1.2.3 From f290638ea36f9fb23de3745b2508aefdcad6cf31 Mon Sep 17 00:00:00 2001 From: Jelena Petrovic Date: Tue, 22 Nov 2022 04:41:58 +0100 Subject: omoguceno slanje poruka sebi, traze se nove poruke od kontrolera na ucitavanju i refresh-u, ispravljen izgled poruka- sada se vidi ko je slao po boji #37 --- .../brzodolokacije/Activities/ChatActivity.kt | 48 ++++++++++++++++++++-- .../Activities/ChatActivityConversation.kt | 9 +++- .../brzodolokacije/Adapters/ChatMessagesAdapter.kt | 8 ++-- .../brzodolokacije/Interfaces/IBackendApi.kt | 2 + .../com/example/brzodolokacije/chat/DBHelper.kt | 8 +++- .../example/brzodolokacije/chat/SignalRListener.kt | 4 +- 6 files changed, 68 insertions(+), 11 deletions(-) diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ChatActivity.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ChatActivity.kt index c824cf3..e99142a 100644 --- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ChatActivity.kt +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ChatActivity.kt @@ -3,16 +3,24 @@ package com.example.brzodolokacije.Activities import android.content.Intent import android.os.Bundle import android.widget.ImageButton +import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import androidx.swiperefreshlayout.widget.SwipeRefreshLayout +import com.auth0.android.jwt.JWT import com.exam.DBHelper import com.example.brzodolokacije.Adapters.ChatPreviewsAdapter import com.example.brzodolokacije.Models.ChatPreview +import com.example.brzodolokacije.Models.Message +import com.example.brzodolokacije.Models.MessageReceive import com.example.brzodolokacije.R +import com.example.brzodolokacije.Services.RetrofitHelper +import com.example.brzodolokacije.Services.SharedPreferencesHelper import com.example.brzodolokacije.chat.SignalRListener import com.example.brzodolokacije.databinding.ActivityChatBinding +import retrofit2.Call +import retrofit2.Response class ChatActivity : AppCompatActivity(), SwipeRefreshLayout.OnRefreshListener { @@ -33,7 +41,7 @@ class ChatActivity : AppCompatActivity(), SwipeRefreshLayout.OnRefreshListener { ws=SignalRListener.getInstance(this@ChatActivity) setListeners() setRecyclerView() - requestForChats() + requestNewMessages() swipeRefreshLayout = binding.swipeContainer swipeRefreshLayout?.setOnRefreshListener(this@ChatActivity) swipeRefreshLayout?.setColorSchemeResources( @@ -44,7 +52,7 @@ class ChatActivity : AppCompatActivity(), SwipeRefreshLayout.OnRefreshListener { ) swipeRefreshLayout?.post(kotlinx.coroutines.Runnable { swipeRefreshLayout?.isRefreshing=true - requestForChats() + requestNewMessages() }) } @@ -63,6 +71,40 @@ class ChatActivity : AppCompatActivity(), SwipeRefreshLayout.OnRefreshListener { setRecyclerView(setParams = false) } + fun requestNewMessages(){ + val api=RetrofitHelper.getInstance() + val token=SharedPreferencesHelper.getValue("jwt",this@ChatActivity) + val request2=api?.getNewMessages("Bearer "+token) + request2?.enqueue(object : retrofit2.Callback?> { + override fun onResponse(call: Call?>, response: Response?>) { + if(response.isSuccessful()){ + var messages=response.body() + if(!messages.isNullOrEmpty()){ + var dbHelper= DBHelper.getInstance(this@ChatActivity) + for( message in messages){ + dbHelper.addMessage( + Message(message.senderId+message.timestamp,message.senderId, + JWT(SharedPreferencesHelper.getValue("jwt",this@ChatActivity)!!).claims["id"]?.asString()!!,message.messagge,message.timestamp),false) + } + } + requestForChats() + } + else{ + Toast.makeText(this@ChatActivity,"los id", + Toast.LENGTH_LONG).show() + requestForChats() + } + } + + override fun onFailure(call: Call?>, t: Throwable) { + Toast.makeText(this@ChatActivity,"neuspesan zahtev", + Toast.LENGTH_LONG).show() + requestForChats() + } + }) + + } + fun setRecyclerView(setParams:Boolean=true){ if(setParams){ adapterVar= items?.let { ChatPreviewsAdapter(it,this@ChatActivity) } @@ -76,6 +118,6 @@ class ChatActivity : AppCompatActivity(), SwipeRefreshLayout.OnRefreshListener { } override fun onRefresh() { - requestForChats() + requestNewMessages() } } \ No newline at end of file diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ChatActivityConversation.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ChatActivityConversation.kt index 98e3208..4bd72bc 100644 --- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ChatActivityConversation.kt +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ChatActivityConversation.kt @@ -9,6 +9,7 @@ import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView +import com.auth0.android.jwt.JWT import com.exam.DBHelper import com.example.brzodolokacije.Adapters.ChatMessagesAdapter import com.example.brzodolokacije.Models.Message @@ -161,8 +162,12 @@ class ChatActivityConversation : AppCompatActivity() { } fun requestMessages(){ - if(!userId.isNullOrEmpty() && !userId.equals("null")) - items=dbConnection?.getMessages(userId!!) + if(!userId.isNullOrEmpty() && !userId.equals("null")){ + if(userId!= JWT(SharedPreferencesHelper.getValue("jwt",this@ChatActivityConversation)!!).claims["id"]?.asString()) + items=dbConnection?.getMessages(userId!!) + else + items=dbConnection?.getMessages(userId!!,self = true) + } adapterVar= items?.let { ChatMessagesAdapter(it,this@ChatActivityConversation) } setRecyclerView(setParams = false) diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/ChatMessagesAdapter.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/ChatMessagesAdapter.kt index c3c8a8a..45ffbf0 100644 --- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/ChatMessagesAdapter.kt +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/ChatMessagesAdapter.kt @@ -23,9 +23,7 @@ class ChatMessagesAdapter (val items : MutableList, val activity:Activi override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { val inflater = LayoutInflater.from(parent.context) - var token=SharedPreferencesHelper.getValue("jwt",activity) - var jwt= JWT(token.toString()) - currentUser= jwt.getClaim("id").toString() + if(viewType==VIEW_TYPE_MESSAGE_RECEIVED){ bindingOther= ChatMessageOtherBinding.inflate(inflater,parent,false) @@ -65,6 +63,10 @@ class ChatMessagesAdapter (val items : MutableList, val activity:Activi override fun getItemViewType(position: Int): Int { var sender=items.get(position).senderId + var token= SharedPreferencesHelper.getValue("jwt",activity) + var jwt= JWT(token.toString()) + var claim=jwt.getClaim("id") + currentUser= claim.asString()!! if(sender==currentUser){ return VIEW_TYPE_MESSAGE_SENT } diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Interfaces/IBackendApi.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Interfaces/IBackendApi.kt index 8fb7b4d..cb51627 100644 --- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Interfaces/IBackendApi.kt +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Interfaces/IBackendApi.kt @@ -65,6 +65,8 @@ interface IBackendApi { ):PagedPosts @POST("/api/message/add") fun sendMessage(@Header("Authorization") authHeader:String,@Body message:MessageSend):Call + @GET("/api/message/myMessages") + fun getNewMessages(@Header("Authorization") authHeader:String):Call?> @GET("/api/user/history") fun getMyHistory(@Header("Authorization") authHeader:String):Call> //@POST("putanja") diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/chat/DBHelper.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/chat/DBHelper.kt index be88ad3..479b9cb 100644 --- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/chat/DBHelper.kt +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/chat/DBHelper.kt @@ -106,8 +106,12 @@ class DBHelper : } } } - fun getMessages(userId:String): MutableList? { - var sql="SELECT * FROM "+ MESSAGES_TABLE_NAME+" WHERE senderId='"+userId+"' OR receiverId='"+userId+"'" + fun getMessages(userId:String, self:Boolean=false): MutableList? { + var sql:String + if(!self) + sql="SELECT * FROM "+ MESSAGES_TABLE_NAME+" WHERE senderId='"+userId+"' OR receiverId='"+userId+"'" + else + sql="SELECT * FROM "+ MESSAGES_TABLE_NAME+" WHERE senderId='"+userId+"' AND receiverId='"+userId+"'" var cursor=db?.rawQuery(sql,null) if(cursor?.count!! >0){ var messagesList:MutableList =mutableListOf() diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/chat/SignalRListener.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/chat/SignalRListener.kt index 07a9d3e..d091c5d 100644 --- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/chat/SignalRListener.kt +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/chat/SignalRListener.kt @@ -2,6 +2,7 @@ package com.example.brzodolokacije.chat import android.app.Activity import android.util.Log +import com.auth0.android.jwt.JWT import com.exam.DBHelper import com.example.brzodolokacije.Models.Message import com.example.brzodolokacije.Models.MessageReceive @@ -24,7 +25,8 @@ class SignalRListener private constructor(val activity: Activity){ hubConnection.keepAliveInterval=120 hubConnection.on("Message", Action1 { - message:MessageReceive->dbHelper.addMessage(Message(message.senderId+message.timestamp,message.senderId,message.senderId,message.messagge,message.timestamp),false) + message:MessageReceive->dbHelper.addMessage(Message(message.senderId+message.timestamp,message.senderId, + JWT(SharedPreferencesHelper.getValue("jwt",activity)!!).claims["id"]?.asString()!!,message.messagge,message.timestamp),false) }, MessageReceive::class.java ) -- cgit v1.2.3