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