diff options
author | TAMARA JERINIC <tamara.jerinic@gmail.com> | 2022-12-05 21:33:20 +0100 |
---|---|---|
committer | TAMARA JERINIC <tamara.jerinic@gmail.com> | 2022-12-05 21:33:20 +0100 |
commit | b1e3ebe5dc5a7dbfefeef79924255f1906983181 (patch) | |
tree | a323fe4c2f6c3c10b752594b54c31f3c871d5674 /Client | |
parent | 4eab4ea8df9e3aeb7db8c86fd54a6fa9d59d11a7 (diff) | |
parent | 951b36b54b106178200cfa4fb2bbc499ca1a2de0 (diff) |
Merge branch 'develop' of http://gitlab.pmf.kg.ac.rs/BrzoDoLokacije2022/odyssey/brzodolokacije into develop
# Conflicts:
# Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ActivitySinglePost.kt
# Client/BrzoDoLokacije/app/src/main/res/layout/activity_single_post.xml
Diffstat (limited to 'Client')
30 files changed, 1006 insertions, 339 deletions
diff --git a/Client/BrzoDoLokacije/app/src/main/AndroidManifest.xml b/Client/BrzoDoLokacije/app/src/main/AndroidManifest.xml index 2241c80..4555917 100644 --- a/Client/BrzoDoLokacije/app/src/main/AndroidManifest.xml +++ b/Client/BrzoDoLokacije/app/src/main/AndroidManifest.xml @@ -56,7 +56,7 @@ android:name=".Activities.ChatActivityConversation" android:exported="false" android:screenOrientation="portrait" - android:windowSoftInputMode="stateVisible|adjustPan"> + android:windowSoftInputMode="stateAlwaysHidden|adjustResize"> <meta-data android:name="android.app.lib_name" android:value="" /> diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ActivitySinglePost.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ActivitySinglePost.kt index 5a1e8b1..c5e30d3 100644 --- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ActivitySinglePost.kt +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ActivitySinglePost.kt @@ -1,14 +1,20 @@ package com.example.brzodolokacije.Activities +import android.content.Context import android.content.Intent import android.graphics.Color import android.graphics.drawable.ColorDrawable import android.os.Bundle import android.preference.PreferenceManager import android.util.Log +<<<<<<< HEAD import android.view.ViewGroup import android.view.ViewGroup.LayoutParams import android.widget.Button +======= +import android.view.inputmethod.InputMethodManager +import android.widget.EditText +>>>>>>> 951b36b54b106178200cfa4fb2bbc499ca1a2de0 import android.widget.ImageView import android.widget.TextView import android.widget.Toast @@ -19,6 +25,7 @@ import androidx.core.view.isGone import androidx.core.view.isVisible import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView +import com.auth0.android.jwt.JWT import com.example.brzodolokacije.Adapters.CommentsAdapter import com.example.brzodolokacije.Adapters.PostImageAdapter import com.example.brzodolokacije.Models.* @@ -46,6 +53,7 @@ class ActivitySinglePost : AppCompatActivity() { private var adapterComments: RecyclerView.Adapter<CommentsAdapter.ViewHolder>? = null private var recyclerViewImages: RecyclerView?=null private var recyclerViewComments: RecyclerView?=null + private var favouriteImage:ImageView?=null public lateinit var post:PostPreview private var comments:MutableList<CommentSend>?=mutableListOf() private var starNumber:Number=0 @@ -85,7 +93,7 @@ class ActivitySinglePost : AppCompatActivity() { /* buildRecyclerViewComments() requestGetComments() - + favouriteImage=binding.ivFavourite // set recyclerView attributes recyclerViewImages?.setHasFixedSize(true) recyclerViewImages?.layoutManager = layoutManagerImages @@ -93,7 +101,7 @@ class ActivitySinglePost : AppCompatActivity() { loadTextComponents() setRatingListeners() translateOwnerIdToName(post.ownerId) - + loadFavourite() val alreadyrated= RatingReceive(starNumber.toInt(),post._id) requestAddRating(alreadyrated) */ @@ -108,6 +116,7 @@ class ActivitySinglePost : AppCompatActivity() { } + btnChangeHeightUp.setOnClickListener { btnChangeHeightUp.isVisible=false btnChangeHeightUp.isGone=true @@ -130,6 +139,44 @@ class ActivitySinglePost : AppCompatActivity() { linearLayout2.setMinimumHeight(0); linearLayout2.getLayoutParams().height= ViewGroup.LayoutParams.WRAP_CONTENT; } + + favouriteImage!!.setOnClickListener{ + addRemoveFavourite() + } + } + fun loadFavourite(){ + if(post.favourites!=null){ + var jwtString=SharedPreferencesHelper.getValue("jwt",this) + var jwt: JWT = JWT(jwtString!!) + var userId=jwt.getClaim("id").asString() + if(post.favourites!!.contains(userId)) + { + favouriteImage!!.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.ic_baseline_favorite_24)) + }else{ + favouriteImage!!.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.ic_baseline_favorite_border_24)); + + } + + } + } + fun addRemoveFavourite(){ + var token= SharedPreferencesHelper.getValue("jwt", this).toString() + val Api= RetrofitHelper.getInstance() + val request=Api.addRemoveFavourite("Bearer "+token,post._id) + request.enqueue(object : retrofit2.Callback<Boolean?> { + override fun onResponse(call: Call<Boolean?>, response: Response<Boolean?>) { + if(response.isSuccessful && response.body() == true) + favouriteImage!!.setImageDrawable(ContextCompat.getDrawable(this@ActivitySinglePost, R.drawable.ic_baseline_favorite_24)) + else + favouriteImage!!.setImageDrawable(ContextCompat.getDrawable(this@ActivitySinglePost, R.drawable.ic_baseline_favorite_border_24)); + } + + override fun onFailure(call: Call<Boolean?>, t: Throwable) { + + } + }) + + } fun getMap(){ /*val mapDialogue = BottomSheetDialog(this@ActivitySinglePost, android.R.style.Theme_Black_NoTitleBar) @@ -167,6 +214,10 @@ class ActivitySinglePost : AppCompatActivity() { recyclerViewComments!!.layoutManager=layoutManagerComments recyclerViewComments!!.adapter= adapterComments } + fun hideKeyboard(item: EditText){ + var imm: InputMethodManager =this.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager + imm.hideSoftInputFromWindow(item.windowToken, InputMethodManager.HIDE_NOT_ALWAYS) + } fun setRatingListeners() { val emptyStar = R.drawable.empty_star @@ -267,6 +318,7 @@ class ActivitySinglePost : AppCompatActivity() { var newComment=response.body()!! requestGetComments(newComment) binding.NewComment.text.clear() + hideKeyboard(binding.NewComment) }else{ if(response.errorBody()!=null) Log.d("main1",response.message().toString()) 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 951cbb4..14a4ba5 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 @@ -20,6 +20,7 @@ import com.example.brzodolokacije.Services.SharedPreferencesHelper import com.example.brzodolokacije.chat.SignalRListener import com.example.brzodolokacije.databinding.ActivityChatBinding import retrofit2.Call +import retrofit2.Callback import retrofit2.Response import java.util.* @@ -64,6 +65,9 @@ class ChatActivity : AppCompatActivity(), SwipeRefreshLayout.OnRefreshListener { intent.putExtra("receiverId","") startActivity(intent) } + findViewById<ImageButton>(R.id.btnBack).setOnClickListener { + finish() + } } fun requestForChats(){ @@ -77,7 +81,7 @@ class ChatActivity : AppCompatActivity(), SwipeRefreshLayout.OnRefreshListener { val api=RetrofitHelper.getInstance() val token=SharedPreferencesHelper.getValue("jwt",this@ChatActivity) val request2=api?.getNewMessages("Bearer "+token) - request2?.enqueue(object : retrofit2.Callback<MutableList<MessageReceive>?> { + request2?.enqueue(object : Callback<MutableList<MessageReceive>?> { override fun onResponse(call: Call<MutableList<MessageReceive>?>, response: Response<MutableList<MessageReceive>?>) { if(response.isSuccessful()){ var messages=response.body() 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 19fd836..985735f 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 @@ -1,5 +1,6 @@ package com.example.brzodolokacije.Activities +import android.graphics.Bitmap import android.os.Bundle import android.util.Log import android.view.View @@ -37,6 +38,7 @@ class ChatActivityConversation : AppCompatActivity() { var dbConnection: DBHelper?=null var webSocketConnection:SignalRListener?=null var items:MutableList<Message>?=mutableListOf() + var userImage:Bitmap?=null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -44,6 +46,7 @@ class ChatActivityConversation : AppCompatActivity() { setContentView(binding.root) userId=intent.extras?.get("userId").toString() receiverUsername=intent.extras?.get("username").toString() + userImage=intent.extras?.get("pfp") as Bitmap? dbConnection=DBHelper.getInstance(this@ChatActivityConversation) setHeader() setRecyclerView() @@ -56,85 +59,89 @@ class ChatActivityConversation : AppCompatActivity() { private fun setListeners() { findViewById<ImageButton>(R.id.btnSendMessage).setOnClickListener { var token=SharedPreferencesHelper.getValue("jwt",this@ChatActivityConversation) - var messageContent=findViewById<EditText>(R.id.etNewMessage).text.toString() + var messageContent=findViewById<EditText>(R.id.etNewMessage).text.trim().toString() val Api= RetrofitHelper.getInstance() - if(userId.isNullOrEmpty() || userId.equals("null")){ - //zahtev sa username=om - receiverUsername=findViewById<EditText>(R.id.etReceiverUsername).text.toString() - val request=Api.getProfile("Bearer "+token, - receiverUsername!! - ) - request.enqueue(object : retrofit2.Callback<UserReceive?> { - override fun onResponse(call: Call<UserReceive?>, response: Response<UserReceive?>) { - 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 - ) - request2.enqueue(object : retrofit2.Callback<Message?> { - override fun onResponse(call: Call<Message?>, response: Response<Message?>) { - if(response.isSuccessful()){ - //zahtev da se posalje poruka - var responseMessage=response.body() - var cal: Calendar = Calendar.getInstance() - cal.time=responseMessage?.timestamp - responseMessage?.usableTimeStamp=cal - dbConnection?.addMessage(responseMessage!!) - requestMessages() - binding.etNewMessage.text?.clear() + if(!messageContent.isNullOrEmpty()){ + if(userId.isNullOrEmpty() || userId.equals("null")){ + //zahtev sa username=om + receiverUsername=findViewById<EditText>(R.id.etReceiverUsername).text.toString() + val request=Api.getProfile("Bearer "+token, + receiverUsername!! + ) + request.enqueue(object : retrofit2.Callback<UserReceive?> { + override fun onResponse(call: Call<UserReceive?>, response: Response<UserReceive?>) { + if(response.isSuccessful()){ + //zahtev da se posalje poruka + var user:UserReceive=response.body()!! + userId=user._id + setHeader() + var message= MessageSend(userId!!,messageContent) + val request2=Api.sendMessage("Bearer "+token, + message + ) + request2.enqueue(object : retrofit2.Callback<Message?> { + override fun onResponse(call: Call<Message?>, response: Response<Message?>) { + if(response.isSuccessful()){ + //zahtev da se posalje poruka + var responseMessage=response.body() + var cal: Calendar = Calendar.getInstance() + cal.time=responseMessage?.timestamp + responseMessage?.usableTimeStamp=cal + dbConnection?.addMessage(responseMessage!!,username=user.username) + requestMessages() + binding.etNewMessage.text?.clear() + } + else{ + Toast.makeText(this@ChatActivityConversation,"Pogresno korisnicko ime1.",Toast.LENGTH_LONG).show() + } } - else{ - Toast.makeText(this@ChatActivityConversation,"Pogresno korisnicko ime1.",Toast.LENGTH_LONG).show() + + override fun onFailure(call: Call<Message?>, t: Throwable) { + Toast.makeText(this@ChatActivityConversation,"Pogresno korisnicko ime2.",Toast.LENGTH_LONG).show() } - } + }) + } + else{ + Log.d("main",response.message()) + //Toast.makeText(this@ChatActivityConversation,"Pogresno korisnicko ime3.",Toast.LENGTH_LONG).show() + } + } - override fun onFailure(call: Call<Message?>, t: Throwable) { - Toast.makeText(this@ChatActivityConversation,"Pogresno korisnicko ime2.",Toast.LENGTH_LONG).show() - } - }) + override fun onFailure(call: Call<UserReceive?>, t: Throwable) { + Toast.makeText(this@ChatActivityConversation,"fail.",Toast.LENGTH_LONG).show() } - else{ - Log.d("main",response.message()) - //Toast.makeText(this@ChatActivityConversation,"Pogresno korisnicko ime3.",Toast.LENGTH_LONG).show() + }) + } + else{ + //zahtev da se posalje poruka + var message= MessageSend(userId!!,messageContent) + val request2=Api.sendMessage("Bearer "+token, + message + ) + request2.enqueue(object : retrofit2.Callback<Message?> { + override fun onResponse(call: Call<Message?>, response: Response<Message?>) { + if(response.isSuccessful()){ + //zahtev da se posalje poruka + var responseMessage=response.body() + var cal: Calendar = Calendar.getInstance() + cal.time=responseMessage?.timestamp + responseMessage?.usableTimeStamp=cal + dbConnection?.addMessage(responseMessage!!,username=receiverUsername) + requestMessages() + binding.etNewMessage.text?.clear() + } + else{ + Toast.makeText(this@ChatActivityConversation,"Pogresno korisnicko ime.",Toast.LENGTH_LONG).show() + } } - } - override fun onFailure(call: Call<UserReceive?>, t: Throwable) { - Toast.makeText(this@ChatActivityConversation,"fail.",Toast.LENGTH_LONG).show() - } - }) - } - else{ - //zahtev da se posalje poruka - var message= MessageSend(userId!!,messageContent) - val request2=Api.sendMessage("Bearer "+token, - message - ) - request2.enqueue(object : retrofit2.Callback<Message?> { - override fun onResponse(call: Call<Message?>, response: Response<Message?>) { - if(response.isSuccessful()){ - //zahtev da se posalje poruka - var responseMessage=response.body() - var cal: Calendar = Calendar.getInstance() - cal.time=responseMessage?.timestamp - responseMessage?.usableTimeStamp=cal - dbConnection?.addMessage(responseMessage!!) - requestMessages() - binding.etNewMessage.text?.clear() - } - else{ + override fun onFailure(call: Call<Message?>, t: Throwable) { Toast.makeText(this@ChatActivityConversation,"Pogresno korisnicko ime.",Toast.LENGTH_LONG).show() } - } + }) + } - override fun onFailure(call: Call<Message?>, t: Throwable) { - Toast.makeText(this@ChatActivityConversation,"Pogresno korisnicko ime.",Toast.LENGTH_LONG).show() - } - }) } } @@ -144,19 +151,24 @@ class ChatActivityConversation : AppCompatActivity() { 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() + binding.llHeader.visibility= View.GONE + binding.llHeader.invalidate() + binding.llHeader.forceLayout() } else{ - binding.tvFragmentTitle.visibility= View.VISIBLE - binding.tvFragmentTitle.invalidate() - binding.tvFragmentTitle.forceLayout() + binding.llHeader.visibility= View.VISIBLE + binding.llHeader.invalidate() + binding.llHeader.forceLayout() binding.tvFragmentTitle.text=receiverUsername binding.tvFragmentTitle.invalidate() binding.cvParentUsername.visibility= View.GONE binding.cvParentUsername.forceLayout() } + binding.btnBack.setOnClickListener { + finish() + } + if(userImage!=null) + binding.ivUserImage.setImageBitmap(userImage) } fun setRecyclerView(setParams:Boolean=true){ MainScope().launch { @@ -173,6 +185,7 @@ class ChatActivityConversation : AppCompatActivity() { } catch (e: Exception) { Log.d("error", e.message!!) } + recyclerView?.addOnLayoutChangeListener { _, i, i2, i3, i4, i5, i6, i7, i8 -> recyclerView?.scrollToPosition(items?.size?.minus(1) ?: 0) } recyclerView?.scrollToPosition(items?.size?.minus(1) ?: 0) } } diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/NavigationActivity.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/NavigationActivity.kt index 180b59d..23cbca6 100644 --- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/NavigationActivity.kt +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/NavigationActivity.kt @@ -18,19 +18,20 @@ class NavigationActivity : AppCompatActivity() { //lateinit var openAddPost:Button //lateinit var capturePost:Button - + public lateinit var bottomNav:BottomNavigationView + public lateinit var searchQuery:String + public lateinit var searchId:String override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_navigation) - Toast.makeText( - applicationContext, "Open ", Toast.LENGTH_LONG - ).show(); + searchQuery="" + searchId="" val fragmentHomePage=FragmentHomePage() val fragmentShowPosts=FragmentShowPosts() val browseFragment=FragmentBrowse() val addPostFragment= FragmentAddNew() val profileFragment=FragmentProfile() - val bottomNav=findViewById<View>(R.id.bottomNavigationView) as BottomNavigationView + bottomNav=findViewById<View>(R.id.bottomNavigationView) as BottomNavigationView setCurrentFragment(fragmentHomePage) bottomNav.setOnNavigationItemSelectedListener { when(it.itemId){ @@ -46,6 +47,7 @@ class NavigationActivity : AppCompatActivity() { } + } private fun setCurrentFragment(fragment: Fragment)= supportFragmentManager.beginTransaction().apply { 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 6e62180..be564f4 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 @@ -5,6 +5,8 @@ import android.graphics.Typeface import android.view.LayoutInflater import android.view.ViewGroup import android.widget.Toast +import androidx.core.content.ContextCompat +import androidx.core.graphics.drawable.toBitmap import androidx.recyclerview.widget.RecyclerView import com.bumptech.glide.Glide import com.exam.DBHelper @@ -13,12 +15,14 @@ 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.R 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 +import java.util.* class ChatPreviewsAdapter (val items : MutableList<ChatPreview>,val activity:ChatActivity) : RecyclerView.Adapter<ChatPreviewsAdapter.ViewHolder>(){ @@ -42,6 +46,7 @@ class ChatPreviewsAdapter (val items : MutableList<ChatPreview>,val activity:Cha val intent: Intent = Intent(activity, ChatActivityConversation::class.java) intent.putExtra("userId",items[position].userId) intent.putExtra("username",holder.itemView.tvUsername.text) + intent.putExtra("pfp",holder.itemView.ivUserImage.drawable.toBitmap(200,200)) db.readContact(items[position].userId) items[position].read=true holder.itemView.tvUsername.typeface= Typeface.DEFAULT @@ -61,11 +66,12 @@ class ChatPreviewsAdapter (val items : MutableList<ChatPreview>,val activity:Cha //zahtev da se posalje poruka var user=response.body()!! if(!item.read) - tvUsername.typeface= Typeface.DEFAULT_BOLD + setUnread() tvUsername.text=user.username if(user.pfp!=null) { Glide.with(activity) .load(RetrofitHelper.baseUrl + "/api/post/image/" + user.pfp!!._id) + .circleCrop() .into(ivUserImage) } } @@ -81,7 +87,41 @@ class ChatPreviewsAdapter (val items : MutableList<ChatPreview>,val activity:Cha Toast.LENGTH_LONG).show() } }) + var lastMessage=db.getLastMessage(item.userId) + tvUsername.text=item.username + if(lastMessage!=null){ + tvLastMessage.text=lastMessage.messagge + if(layoutPosition==0 || isDifferentDays(lastMessage.usableTimeStamp,Calendar.getInstance())){ + tvLastMessageDate.text=lastMessage.usableTimeStamp.get(Calendar.HOUR_OF_DAY).toString() + ":" + lastMessage.usableTimeStamp.get( + Calendar.MINUTE).toString() + } + else{ + tvLastMessageDate.text=lastMessage.usableTimeStamp.get(Calendar.DAY_OF_MONTH).toString()+"/"+ + (lastMessage.usableTimeStamp.get(Calendar.MONTH)+1).toString()+"/"+ + lastMessage.usableTimeStamp.get(Calendar.YEAR).toString() + } + + } } } + fun isDifferentDays(c1:Calendar,c2:Calendar):Boolean{ + if(c1.get(Calendar.DAY_OF_YEAR)!=c2.get(Calendar.DAY_OF_YEAR)){ + return true + } + else if(c1.get(Calendar.YEAR)!=c2.get(Calendar.YEAR)){ + return true + } + return false + } + fun setUnread(){ + itemView.tvUsername.typeface= Typeface.DEFAULT_BOLD + itemView.tvUsername.invalidate() + itemView.tvLastMessage.typeface= Typeface.DEFAULT_BOLD + itemView.tvLastMessage.invalidate() + itemView.tvLastMessageDate.typeface= Typeface.DEFAULT_BOLD + itemView.tvLastMessageDate.invalidate() + itemView.readIndicator.background= ContextCompat.getDrawable(activity,R.color.dark_blue_transparent) + itemView.readIndicator.invalidate() + } } }
\ No newline at end of file diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/CommentsAdapter.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/CommentsAdapter.kt index 96e332a..8f737a3 100644 --- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/CommentsAdapter.kt +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/CommentsAdapter.kt @@ -8,15 +8,19 @@ import android.view.View import android.view.ViewGroup import android.view.inputmethod.InputMethodManager import android.widget.EditText +import android.widget.Toast import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView +import com.bumptech.glide.Glide import com.example.brzodolokacije.Activities.ActivitySinglePost +import com.example.brzodolokacije.Interfaces.IBackendApi import com.example.brzodolokacije.Models.CommentReceive import com.example.brzodolokacije.Models.CommentSend -import com.example.brzodolokacije.R +import com.example.brzodolokacije.Models.UserReceive import com.example.brzodolokacije.Services.RetrofitHelper import com.example.brzodolokacije.Services.SharedPreferencesHelper import com.example.brzodolokacije.databinding.SingleCommentBinding +import kotlinx.android.synthetic.main.single_comment.view.* import retrofit2.Call import retrofit2.Response @@ -24,10 +28,14 @@ class CommentsAdapter (val items : MutableList<CommentSend>,val activity: Activi : RecyclerView.Adapter<CommentsAdapter.ViewHolder>(){ //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: SingleCommentBinding override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val inflater = LayoutInflater.from(parent.context) binding=SingleCommentBinding.inflate(inflater,parent,false) + api=RetrofitHelper.getInstance() + token=SharedPreferencesHelper.getValue("jwt",activity) return ViewHolder(binding) } override fun onBindViewHolder(holder: ViewHolder, position: Int){ @@ -46,24 +54,37 @@ class CommentsAdapter (val items : MutableList<CommentSend>,val activity: Activi binding.apply { tvCommentAuthor.text=item.username tvCommentText.text=item.comment - etReply.visibility= View.GONE - etReply.forceLayout() + Log.d("info",tvCommentText.text.toString()+binding.toString()) + requestProfilePic(item) + llReply.visibility=View.GONE + llReply.forceLayout() + if(item.parentId!=""){ + btnReply.visibility=View.GONE + btnReply.forceLayout() + } + else{ + btnReply.setOnClickListener { + llReply.visibility=View.VISIBLE + llReply.forceLayout() + etReply.requestFocus() + } + } etReply.showSoftInputOnFocus=true etReply.setOnFocusChangeListener { _, focused -> if(!focused){ - etReply.visibility= View.GONE - etReply.forceLayout() - btnReply.setImageResource(R.drawable.reply) + llReply.visibility= View.GONE + llReply.forceLayout() + //btnReply.setImageResource(R.drawable.) hideKeyboard(etReply) } else{ showKeyboard(etReply) - btnReply.setImageResource(R.drawable.post_comment) - btnReply.setOnClickListener{ + btnPostReply.setOnClickListener{ if(etReply.text.isNotEmpty()){ val postId=(activity as ActivitySinglePost).post._id + Log.d("main",binding.toString()) val comment= CommentReceive(etReply.text.toString(),item._id) - requestAddComment(binding,comment,postId) + requestAddComment(comment,postId) } else{ Log.d("komentari","greska") @@ -71,14 +92,10 @@ class CommentsAdapter (val items : MutableList<CommentSend>,val activity: Activi } } } - btnReply.setOnClickListener { - etReply.visibility=View.VISIBLE - etReply.forceLayout() - etReply.requestFocus() - } + var rv: RecyclerView = rvReplies - rv.setHasFixedSize(false) + rv.setHasFixedSize(true) rv.layoutManager=LinearLayoutManager(activity,LinearLayoutManager.VERTICAL,false) if(item.replies!=null) rv.adapter=CommentsAdapter(item.replies as MutableList<CommentSend>,activity) @@ -88,14 +105,14 @@ class CommentsAdapter (val items : MutableList<CommentSend>,val activity: Activi } fun showKeyboard(item:EditText){ var imm:InputMethodManager=activity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager - imm.showSoftInput(item,InputMethodManager.SHOW_FORCED) + imm.showSoftInput(item,InputMethodManager.SHOW_IMPLICIT) } fun hideKeyboard(item: EditText){ var imm:InputMethodManager=activity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager - imm.hideSoftInputFromWindow(item.windowToken,InputMethodManager.HIDE_IMPLICIT_ONLY) + imm.hideSoftInputFromWindow(item.windowToken,InputMethodManager.HIDE_NOT_ALWAYS) } - fun requestAddComment(binding:SingleCommentBinding,comment:CommentReceive,postId:String){ + fun requestAddComment(comment:CommentReceive,postId:String){ val postApi= RetrofitHelper.getInstance() val token= SharedPreferencesHelper.getValue("jwt", activity) val request=postApi.addComment("Bearer "+token,postId,comment) @@ -103,9 +120,10 @@ class CommentsAdapter (val items : MutableList<CommentSend>,val activity: Activi override fun onResponse(call: Call<CommentSend?>, response: Response<CommentSend?>) { if(response.isSuccessful){ var newComment=response.body()!! - requestGetComments(binding,newComment) - binding.etReply.text.clear() - hideKeyboard(binding.etReply) + requestGetComments(newComment) + itemView.etReply.text.clear() + hideKeyboard(itemView.etReply) + itemView.etReply.clearFocus() }else{ if(response.errorBody()!=null) Log.d("main1",response.message().toString()) @@ -120,12 +138,47 @@ class CommentsAdapter (val items : MutableList<CommentSend>,val activity: Activi }) } - private fun requestGetComments(binding:SingleCommentBinding,newComment: CommentSend) { - var rv: RecyclerView = binding.rvReplies + private fun requestGetComments(newComment: CommentSend) { + var rv: RecyclerView = itemView.rvReplies var adapter:CommentsAdapter=rv.adapter as CommentsAdapter adapter.items.add(0,newComment) rv.adapter=adapter //(activity as ActivitySinglePost).addedComment() } + + private fun requestProfilePic(item:CommentSend){ + val request2=api?.getProfileFromId("Bearer "+token, + item.userId + ) + request2?.enqueue(object : retrofit2.Callback<UserReceive?> { + override fun onResponse( + call: Call<UserReceive?>, + response: Response<UserReceive?> + ) { + if (response.isSuccessful) { + var user = response.body()!! + if (user.pfp != null) { + Glide.with(activity) + .load(RetrofitHelper.baseUrl + "/api/post/image/compress/" + user.pfp!!._id) + .circleCrop() + .into(itemView.ivPfp) + } + } else { + Toast.makeText( + activity, "los id", + Toast.LENGTH_LONG + ).show() + itemView.tvCommentAuthor.text = "nije nadjen korisnik" + } + } + + override fun onFailure(call: Call<UserReceive?>, t: Throwable) { + Toast.makeText( + activity, "neuspesan zahtev", + Toast.LENGTH_LONG + ).show() + } + }) + } } }
\ No newline at end of file diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentBrowse.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentBrowse.kt index 57e1833..a0d6146 100644 --- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentBrowse.kt +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentBrowse.kt @@ -197,7 +197,6 @@ class FragmentBrowse : Fragment(R.layout.fragment_browse) { } } private fun getMarkers(){ - val startMarker = Marker(map) var api=RetrofitHelper.getInstance() var jwtString= SharedPreferencesHelper.getValue("jwt",requireActivity()) var data=api.getPosts("Bearer "+jwtString) diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentHomePage.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentHomePage.kt index cb48d3e..a26aaba 100644 --- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentHomePage.kt +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentHomePage.kt @@ -2,27 +2,31 @@ package com.example.brzodolokacije.Fragments import android.content.Intent import android.os.Bundle +import android.util.Log +import android.view.KeyEvent import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import android.widget.Button -import android.widget.ImageButton -import android.widget.ImageView -import android.widget.ScrollView -import android.widget.Toast +import android.widget.* import androidx.core.view.isVisible +import androidx.core.widget.addTextChangedListener import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentTransaction import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.example.brzodolokacije.Activities.ChatActivity +import com.example.brzodolokacije.Activities.NavigationActivity import com.example.brzodolokacije.Adapters.ShowPostsHomePageAdapter import com.example.brzodolokacije.Interfaces.IBackendApi +import com.example.brzodolokacije.Models.Location import com.example.brzodolokacije.Models.LocationType import com.example.brzodolokacije.Models.PostPreview +import com.example.brzodolokacije.Models.SearchParams import com.example.brzodolokacije.R +import com.example.brzodolokacije.Services.RetrofitHelper import com.example.brzodolokacije.Services.RetrofitHelper.baseUrl import com.example.brzodolokacije.Services.SharedPreferencesHelper +import com.google.android.material.button.MaterialButton import retrofit2.Call import retrofit2.Callback import retrofit2.Response @@ -34,6 +38,9 @@ class FragmentHomePage : Fragment() { private lateinit var btnChat:ImageView private lateinit var btnBack:ImageView + private lateinit var searchBar:AutoCompleteTextView + private lateinit var searchButton: MaterialButton + var responseLocations:MutableList<com.example.brzodolokacije.Models.Location>?=null /* override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -47,8 +54,10 @@ class FragmentHomePage : Fragment() { var view:View= inflater.inflate(R.layout.fragment_home_page, container, false) btnBack=view.findViewById(R.id.btnFragmentHomePageBack) btnChat=view.findViewById(R.id.ivFragmentHomePageChat) + searchBar=view.findViewById(R.id.etFragmentHomePageSearch) + searchButton=view.findViewById(R.id.mbFragmentHomePageSearchButton) setBtnBackInvisible() - + setUpSpinner() var fm: FragmentTransaction =childFragmentManager.beginTransaction() fm.replace(R.id.flFragmentHomePageMainContent, FragmentHomePageMainScroll()) fm.commit() @@ -62,9 +71,36 @@ class FragmentHomePage : Fragment() { val intent: Intent = Intent(activity, ChatActivity::class.java) requireActivity().startActivity(intent) } + searchButton.setOnClickListener{ + searchText() + } + searchBar.addTextChangedListener{ + onTextEnter() + } + searchBar.setOnKeyListener(View.OnKeyListener { v1, keyCode, event -> // If the event is a key-down event on the "enter" button + if (event.action === KeyEvent.ACTION_DOWN && + keyCode == KeyEvent.KEYCODE_ENTER + ) { + // Perform action on key press + searchText() + return@OnKeyListener true + } + false + }) return view } + + + fun searchText(){ + if(searchBar.text==null || searchBar.text.toString().trim()=="") + return + + var act=requireActivity() as NavigationActivity + act.searchQuery=searchBar.text.toString() + act.searchId="" + act.bottomNav.selectedItemId=R.id.navAllPosts + } fun changeScrollVIewToLocationView(){ var fm: FragmentTransaction =childFragmentManager.beginTransaction() fm.replace(R.id.flFragmentHomePageMainContent, FragmentShowPostsByLocation()) @@ -81,4 +117,59 @@ class FragmentHomePage : Fragment() { fun setBtnBackVisible(){ btnBack.isVisible=true } + fun onTextEnter(){ + var api= RetrofitHelper.getInstance() + var jwtString= SharedPreferencesHelper.getValue("jwt",requireActivity()) + var text=searchBar.text + Log.d("test",text.toString()) + if(text==null ||text.toString().trim()=="") + return + var data=api.searchLocationsQuery("Bearer "+jwtString,text.toString()) + data.enqueue(object : retrofit2.Callback<MutableList<com.example.brzodolokacije.Models.Location>> { + override fun onResponse(call: Call<MutableList<Location>?>, response: Response<MutableList<Location>>) { + if(response.isSuccessful){ + var existingLocation=responseLocations + responseLocations=response.body()!! + if(existingLocation!=null && existingLocation.size>0) + for(loc in existingLocation!!){ + spinnerAdapter!!.remove(loc.name) + } + for(loc in responseLocations!!){ + spinnerAdapter!!.add(loc.name) + } + spinnerAdapter!!.notifyDataSetChanged() + } + } + + override fun onFailure(call: Call<MutableList<Location>>, t: Throwable) { + + } + }) + + + } + var arraySpinner :MutableList<String>?=null + var spinnerAdapter: ArrayAdapter<String>?=null + + fun setUpSpinner() { + arraySpinner=mutableListOf<String>() + spinnerAdapter= ArrayAdapter<String>( + requireContext(), + android.R.layout.simple_list_item_1, arraySpinner!!) + searchBar.threshold=1 + searchBar.setAdapter(spinnerAdapter) + searchBar.setOnItemClickListener(AdapterView.OnItemClickListener { parent, view, position, id -> + val selected = parent.getItemAtPosition(position) as String + var selectedLocation = responseLocations!!.find { location -> location.name == selected } + + var act=requireActivity() as NavigationActivity + act.searchQuery=selectedLocation!!.name + act.searchId=selectedLocation!!._id + act.bottomNav.selectedItemId=R.id.navAllPosts + + + }) + + + } } diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentHomePageMainScroll.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentHomePageMainScroll.kt index 46904d4..82c78a1 100644 --- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentHomePageMainScroll.kt +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentHomePageMainScroll.kt @@ -239,9 +239,6 @@ private lateinit var change:Button // Toast.makeText( // activity, "get all mv ", Toast.LENGTH_LONG // ).show(); - Toast.makeText( - activity," get popular all", Toast.LENGTH_LONG - ).show(); val api = RetrofitHelper.getInstance() val token= SharedPreferencesHelper.getValue("jwt", requireActivity()) val data=api.get10MostViewed("Bearer "+token) diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentShowPosts.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentShowPosts.kt index a840d6b..76fa4e0 100644 --- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentShowPosts.kt +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentShowPosts.kt @@ -3,13 +3,13 @@ package com.example.brzodolokacije.Fragments import android.content.Intent import android.os.Bundle import android.util.Log +import android.view.KeyEvent import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import android.widget.Button -import android.widget.EditText -import android.widget.ImageButton -import android.widget.Toast +import android.widget.* +import androidx.core.content.ContextCompat +import androidx.core.widget.addTextChangedListener import androidx.fragment.app.Fragment import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.lifecycleScope @@ -19,18 +19,27 @@ import androidx.recyclerview.widget.RecyclerView import androidx.swiperefreshlayout.widget.SwipeRefreshLayout import com.example.brzodolokacije.Activities.ActivityAddPost import com.example.brzodolokacije.Activities.ChatActivity +import com.example.brzodolokacije.Activities.NavigationActivity import com.example.brzodolokacije.Adapters.ShowPostsAdapter +import com.example.brzodolokacije.Models.Location import com.example.brzodolokacije.Models.SearchParams import com.example.brzodolokacije.R import com.example.brzodolokacije.Services.RetrofitHelper +import com.example.brzodolokacije.Services.SharedPreferencesHelper import com.example.brzodolokacije.databinding.FragmentShowPostsBinding import com.example.brzodolokacije.paging.SearchPostsViewModel import com.example.brzodolokacije.paging.SearchPostsViewModelFactory import com.google.android.material.bottomsheet.BottomSheetDialog +import com.google.android.material.button.MaterialButton import kotlinx.android.synthetic.main.fragment_show_posts.* import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.launch +import org.osmdroid.util.GeoPoint +import org.osmdroid.views.overlay.ItemizedIconOverlay +import org.osmdroid.views.overlay.OverlayItem +import retrofit2.Call +import retrofit2.Response class FragmentShowPosts : Fragment(), SwipeRefreshLayout.OnRefreshListener { @@ -41,10 +50,14 @@ class FragmentShowPosts : Fragment(), SwipeRefreshLayout.OnRefreshListener { private var recyclerView: RecyclerView?=null private var gridManagerVar: RecyclerView.LayoutManager?=null private var swipeRefreshLayout:SwipeRefreshLayout?=null + private lateinit var searchButton: MaterialButton private lateinit var searchPostsViewModel:SearchPostsViewModel - private var searchParams:SearchParams?= SearchParams("6375784fe84e2d53df32bf03",1,1) + private var searchParams:SearchParams?= SearchParams("Kragujevac",1,1) private lateinit var btnFilter:ImageButton private lateinit var btnSort:ImageButton + private lateinit var searchBar: AutoCompleteTextView + var responseLocations:MutableList<com.example.brzodolokacije.Models.Location>?=null + var selectedLocation:com.example.brzodolokacije.Models.Location?=null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -55,7 +68,69 @@ class FragmentShowPosts : Fragment(), SwipeRefreshLayout.OnRefreshListener { linearManagerVar= LinearLayoutManager(activity) gridManagerVar=GridLayoutManager(activity,2) } + fun searchText(){ + if(searchBar.text==null || searchBar.text.toString().trim()=="") + return + var act=requireActivity() as NavigationActivity + act.searchQuery=searchBar.text.toString() + act.searchId="" + searchParams=SearchParams(searchBar.text.toString(),1,1) + requestToBack(searchParams!!) + } + fun onTextEnter(){ + var api=RetrofitHelper.getInstance() + var jwtString= SharedPreferencesHelper.getValue("jwt",requireActivity()) + var text=searchBar.text + Log.d("test",text.toString()) + if(text==null ||text.toString().trim()=="") + return + var data=api.searchLocationsQuery("Bearer "+jwtString,text.toString()) + data.enqueue(object : retrofit2.Callback<MutableList<com.example.brzodolokacije.Models.Location>> { + override fun onResponse(call: Call<MutableList<Location>?>, response: Response<MutableList<Location>>) { + if(response.isSuccessful){ + var existingLocation=responseLocations + responseLocations=response.body()!! + if(existingLocation!=null && existingLocation.size>0) + for(loc in existingLocation!!){ + spinnerAdapter!!.remove(loc.name) + } + for(loc in responseLocations!!){ + spinnerAdapter!!.add(loc.name) + } + spinnerAdapter!!.notifyDataSetChanged() + } + } + + override fun onFailure(call: Call<MutableList<Location>>, t: Throwable) { + + } + }) + + + } + var arraySpinner :MutableList<String>?=null + var spinnerAdapter: ArrayAdapter<String>?=null + + fun setUpSpinner() { + arraySpinner=mutableListOf<String>() + spinnerAdapter= ArrayAdapter<String>( + requireContext(), + android.R.layout.simple_list_item_1, arraySpinner!!) + searchBar.threshold=1 + searchBar.setAdapter(spinnerAdapter) + searchBar.setOnItemClickListener(AdapterView.OnItemClickListener { parent, view, position, id -> + val selected = parent.getItemAtPosition(position) as String + selectedLocation = responseLocations!!.find { location -> location.name == selected } + var act=requireActivity() as NavigationActivity + act.searchQuery=selectedLocation!!.name + act.searchId=selectedLocation!!._id + searchParams=SearchParams(selectedLocation!!._id,1,1)//to do sort type + requestToBack(searchParams!!) + + }) + + } private fun setUpViewModel() { val factory=SearchPostsViewModelFactory(RetrofitHelper.getInstance(),requireActivity()) searchPostsViewModel=ViewModelProvider(this@FragmentShowPosts,factory).get(SearchPostsViewModel::class.java) @@ -126,11 +201,55 @@ class FragmentShowPosts : Fragment(), SwipeRefreshLayout.OnRefreshListener { btnSort.setOnClickListener{ showBottomSheetSort() } + searchBar=rootView.findViewById(R.id.etFragmentShowPostsSearch) as AutoCompleteTextView + searchButton=rootView.findViewById<View>(R.id.mbFragmentHomePageSearch) as MaterialButton + setUpSpinner() + searchButton.setOnClickListener{ + searchText() + } + searchBar.addTextChangedListener{ + onTextEnter() + } + searchBar.setOnKeyListener(View.OnKeyListener { v1, keyCode, event -> // If the event is a key-down event on the "enter" button + if (event.action === KeyEvent.ACTION_DOWN && + keyCode == KeyEvent.KEYCODE_ENTER + ) { + // Perform action on key press + searchText() + return@OnKeyListener true + } + false + }) + refreshSearch() + + return rootView } override fun onRefresh() { requestToBack(searchParams!!) + refreshSearch() + } + override fun onResume() { + super.onResume() + refreshSearch() + + } + private fun refreshSearch(){ + var act=requireActivity() as NavigationActivity + Log.d("TEST","USAO") + if(act.searchId!=null && act.searchId.trim()!="") + { + searchBar.setText(act.searchQuery,TextView.BufferType.EDITABLE) + searchParams= SearchParams(act.searchId,1,1) + requestToBack(searchParams!!) + }else + if(act.searchQuery!=null && act.searchQuery.trim()!="") + { + searchBar.setText(act.searchQuery,TextView.BufferType.EDITABLE) + searchParams= SearchParams(act.searchQuery,1,1) + requestToBack(searchParams!!) + } } 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 676023f..60f243d 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 @@ -109,5 +109,7 @@ interface IBackendApi { @GET("/api/user/{id}/myFollowers") fun getMyFollowers(@Header("Authorization") authHeader:String):Call <MutableList<UserReceive>> + @GET("/api/Post/favourite/{id}") + fun addRemoveFavourite(@Header("Authorization") authHeader:String,@Path("id") id:String):Call <Boolean> }
\ 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 6725c15..f3af84c 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 @@ -24,5 +24,6 @@ data class Message( data class ChatPreview( var userId:String, - var read:Boolean + var read:Boolean, + var username:String )
\ No newline at end of file diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Models/Post.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Models/Post.kt index f0f67a7..8f07bca 100644 --- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Models/Post.kt +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Models/Post.kt @@ -39,7 +39,8 @@ data class PostPreview ( var ratingscount:Int, var createdAt:Date, var lastViewed: Date?, //samo za istoriju pregleda - var tags:List<String>? + var tags:List<String>?, + var favourites:List<String>? //nedostaju datum i vreme kreiranja diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/UserPostsMapFragment.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/UserPostsMapFragment.kt new file mode 100644 index 0000000..882a1ae --- /dev/null +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/UserPostsMapFragment.kt @@ -0,0 +1,127 @@ +package com.example.brzodolokacije + +import android.content.Context +import android.content.Intent +import android.os.Bundle +import android.preference.PreferenceManager +import android.util.Log +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import com.example.brzodolokacije.Activities.ActivitySinglePost +import com.example.brzodolokacije.Fragments.FragmentProfile +import com.example.brzodolokacije.Models.PostPreview +import com.example.brzodolokacije.Services.RetrofitHelper +import com.example.brzodolokacije.Services.SharedPreferencesHelper +import org.osmdroid.config.Configuration +import org.osmdroid.tileprovider.tilesource.TileSourceFactory +import org.osmdroid.util.GeoPoint +import org.osmdroid.views.MapView +import org.osmdroid.views.overlay.Marker +import retrofit2.Call +import retrofit2.Response + + +class UserPostsMapFragment : Fragment() { + + var map: MapView? = null + var id:String?=null + var backButton:ImageView?=null + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + // Inflate the layout for this fragment + var view=inflater.inflate(R.layout.fragment_user_posts_map, container, false) + val ctx: Context = requireContext() + Configuration.getInstance().load(ctx, PreferenceManager.getDefaultSharedPreferences(ctx)); + map=view.findViewById(R.id.FragmentUserPostsMapMapView) as MapView + backButton=view.findViewById(R.id.btnFragmentUserPostsBack) as ImageView + map!!.setTileSource(TileSourceFactory.MAPNIK); + id=this.requireArguments().getString("id");//https://stackoverflow.com/questions/17436298/how-to-pass-a-variable-from-activity-to-fragment-and-pass-it-back + setUpMap() + backButton!!.setOnClickListener{ + //SUBJECT TO CHANGE + val fragmentProfile = FragmentProfile() + fragmentManager?.beginTransaction() + ?.replace(com.example.brzodolokacije.R.id.flNavigationFragment,fragmentProfile) + ?.commit() +//How to call fragment +// val bundle = Bundle() +// bundle.putString("id",userId ) +// val fragmentFollowers = UserPostsMapFragment() +// fragmentFollowers.setArguments(bundle) +// +// fragmentManager +// ?.beginTransaction() +// ?.replace(com.example.brzodolokacije.R.id.flNavigationFragment,fragmentFollowers) +// ?.commit() + } + return view + } + fun setUpMap(){ + map!!.setBuiltInZoomControls(true); + map!!.setMultiTouchControls(true); + val mapController = map!!.controller + mapController.setZoom(15) + var api= RetrofitHelper.getInstance() + var jwtString= SharedPreferencesHelper.getValue("jwt",requireActivity()) + if(id==null) + return + var data=api.getUsersPosts("Bearer "+jwtString,id!!) + + data.enqueue(object : retrofit2.Callback<MutableList<PostPreview>> { + override fun onResponse(call: Call<MutableList<PostPreview>>, response: Response<MutableList<PostPreview>>) { + if(response.isSuccessful()){ + var postList=response.body() + if (postList != null) { + var flag=true + for(post in postList){ + Log.d("main",post.toString()) + val startMarker = Marker(map) + startMarker.setPosition(GeoPoint(post.location.latitude,post.location.longitude)) + startMarker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM) + if(flag){ + flag=false + map!!.controller.animateTo(GeoPoint(post.location.latitude,post.location.longitude)) + } + + startMarker.setOnMarkerClickListener(object: + Marker.OnMarkerClickListener { + override fun onMarkerClick( + marker: Marker?, + mapView: MapView? + ): Boolean { + val intent: Intent = Intent(activity, ActivitySinglePost::class.java) + var b=Bundle() + b.putParcelable("selectedPost",post) + intent.putExtras(b) + requireActivity().startActivity(intent) + return true + } + + }) + map!!.getOverlays().add(startMarker) + + + } + } + + + + }else { + + } + + + } + + override fun onFailure(call: Call<MutableList<PostPreview>>, t: Throwable) { + } + }) + } + + +}
\ 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 a3d5a13..041eebb 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 @@ -9,6 +9,11 @@ import android.database.sqlite.SQLiteOpenHelper import android.util.Log import com.example.brzodolokacije.Models.ChatPreview import com.example.brzodolokacije.Models.Message +import com.example.brzodolokacije.Models.UserReceive +import com.example.brzodolokacije.Services.RetrofitHelper +import com.example.brzodolokacije.Services.SharedPreferencesHelper +import retrofit2.Call +import retrofit2.Response import java.util.* @@ -17,7 +22,7 @@ class DBHelper : var db:SQLiteDatabase?=null - constructor(context: Context, factory: SQLiteDatabase.CursorFactory?):super(context, DATABASE_NAME, factory,3){ + constructor(context: Context, factory: SQLiteDatabase.CursorFactory?):super(context, DATABASE_NAME, factory,5){ db=readableDatabase } @@ -28,8 +33,10 @@ class DBHelper : //database tables val CONTACTS_TABLE_NAME = "contacts" val MESSAGES_TABLE_NAME = "messages" + var activity:Activity?=null private var instance:DBHelper?=null fun getInstance(activity: Activity):DBHelper{ + this.activity =activity if(instance==null){ instance= DBHelper(activity,null) } @@ -41,7 +48,8 @@ class DBHelper : if(!doesTableExist(CONTACTS_TABLE_NAME,db)){ var sql:String="CREATE TABLE "+ CONTACTS_TABLE_NAME+" (" + "userId " +"TEXT PRIMARY KEY,"+ - "read " +"INTEGER"+ + "read " +"INTEGER,"+ + "username "+"TEXT"+ ")" db?.execSQL(sql) } @@ -77,7 +85,7 @@ class DBHelper : onCreate(db) } - fun addMessage(message: Message, sent:Boolean=true){ + fun addMessage(message: Message, sent:Boolean=true,username:String?=null){ onCreate(db) if(!message._id.isNullOrEmpty() && message.senderId==message.receiverId){ Log.d("main", "ne zapisuje se dupla poruka") @@ -101,9 +109,41 @@ class DBHelper : 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) + if(username==null){ + //request + var api=RetrofitHelper.getInstance() + var token= activity?.let { SharedPreferencesHelper.getValue("jwt", it) } + val request2=api.getProfileFromId("Bearer "+token, + message.senderId + ) + request2?.enqueue(object : retrofit2.Callback<UserReceive?> { + override fun onResponse(call: Call<UserReceive?>, response: Response<UserReceive?>) { + if(response.isSuccessful()){ + var user=response.body()!! + sql="INSERT INTO "+ CONTACTS_TABLE_NAME+"(userId,read,username) VALUES('"+id+"','"+ + read+"','"+user.username+"')" + db?.execSQL(sql) + } + else{ + sql="INSERT INTO "+ CONTACTS_TABLE_NAME+"(userId,read) VALUES('"+id+"','"+ + read+"')" + db?.execSQL(sql) + } + } + + override fun onFailure(call: Call<UserReceive?>, t: Throwable) { + sql="INSERT INTO "+ CONTACTS_TABLE_NAME+"(userId,read) VALUES('"+id+"','"+ + read+"')" + db?.execSQL(sql) + } + }) + } + else{ + sql="INSERT INTO "+ CONTACTS_TABLE_NAME+"(userId,read,username) VALUES('"+id+"','"+ + read+"','"+username+"')" + db?.execSQL(sql) + } + } else{ if(!sent) @@ -111,7 +151,36 @@ class DBHelper : } } } - fun getMessages(userId:String, self:Boolean=false): MutableList<Message>? { + fun getLastMessage(userId:String): Message? { + onCreate(db) + var sql:String = "SELECT * FROM "+ MESSAGES_TABLE_NAME+" WHERE senderId='"+userId+"'"+" OR receiverId='"+userId+"'"+" ORDER BY timestamp DESC LIMIT 1" + var cursor=db?.rawQuery(sql,null) + if(cursor?.count!! >0){ + var msg:Message + 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") + cursor.moveToNext() + var cal:Calendar= Calendar.getInstance() + cal.timeInMillis=cursor.getLong(timestampIndex) + msg=Message( + cursor.getString(idIndex), + cursor.getString(senderIdIndex), + cursor.getString(receiverIdIndex), + cursor.getString(messageIndex), + cal.time, + cal + ) + + Log.d("main",cal.time.toString()) + readContact(userId) + return msg + } + return null + } + fun getMessages(userId:String,self:Boolean=false): MutableList<Message>? { onCreate(db) var sql:String if(!self) @@ -137,8 +206,8 @@ class DBHelper : cursor.getString(messageIndex), cal.time, cal - ) ) + ) Log.d("main",cal.time.toString()) } readContact(userId) @@ -155,8 +224,9 @@ class DBHelper : var contactList:MutableList<ChatPreview> =mutableListOf() var userIdIndex=cursor.getColumnIndexOrThrow("userId") var readIndex=cursor.getColumnIndexOrThrow("read") + var usernameIndex=cursor.getColumnIndexOrThrow("username") while(cursor.moveToNext()){ - contactList.add(ChatPreview(cursor.getString(userIdIndex),cursor.getInt(readIndex)==1)) + contactList.add(ChatPreview(cursor.getString(userIdIndex),cursor.getInt(readIndex)==1,cursor.getString(usernameIndex))) } Log.d("main",contactList.size.toString()) return contactList diff --git a/Client/BrzoDoLokacije/app/src/main/res/drawable/expand.png b/Client/BrzoDoLokacije/app/src/main/res/drawable/expand.png Binary files differnew file mode 100644 index 0000000..2051733 --- /dev/null +++ b/Client/BrzoDoLokacije/app/src/main/res/drawable/expand.png diff --git a/Client/BrzoDoLokacije/app/src/main/res/drawable/ic_baseline_favorite_24.xml b/Client/BrzoDoLokacije/app/src/main/res/drawable/ic_baseline_favorite_24.xml new file mode 100644 index 0000000..84df34b --- /dev/null +++ b/Client/BrzoDoLokacije/app/src/main/res/drawable/ic_baseline_favorite_24.xml @@ -0,0 +1,5 @@ +<vector android:height="24dp" android:tint="#E52121" + android:viewportHeight="24" android:viewportWidth="24" + android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,21.35l-1.45,-1.32C5.4,15.36 2,12.28 2,8.5 2,5.42 4.42,3 7.5,3c1.74,0 3.41,0.81 4.5,2.09C13.09,3.81 14.76,3 16.5,3 19.58,3 22,5.42 22,8.5c0,3.78 -3.4,6.86 -8.55,11.54L12,21.35z"/> +</vector> diff --git a/Client/BrzoDoLokacije/app/src/main/res/drawable/ic_baseline_favorite_border_24.xml b/Client/BrzoDoLokacije/app/src/main/res/drawable/ic_baseline_favorite_border_24.xml new file mode 100644 index 0000000..4c07189 --- /dev/null +++ b/Client/BrzoDoLokacije/app/src/main/res/drawable/ic_baseline_favorite_border_24.xml @@ -0,0 +1,5 @@ +<vector android:height="24dp" android:tint="#3B3737" + android:viewportHeight="24" android:viewportWidth="24" + android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M16.5,3c-1.74,0 -3.41,0.81 -4.5,2.09C10.91,3.81 9.24,3 7.5,3 4.42,3 2,5.42 2,8.5c0,3.78 3.4,6.86 8.55,11.54L12,21.35l1.45,-1.32C18.6,15.36 22,12.28 22,8.5 22,5.42 19.58,3 16.5,3zM12.1,18.55l-0.1,0.1 -0.1,-0.1C7.14,14.24 4,11.39 4,8.5 4,6.5 5.5,5 7.5,5c1.54,0 3.04,0.99 3.57,2.36h1.87C13.46,5.99 14.96,5 16.5,5c2,0 3.5,1.5 3.5,3.5 0,2.89 -3.14,5.74 -7.9,10.05z"/> +</vector> diff --git a/Client/BrzoDoLokacije/app/src/main/res/drawable/shrink.png b/Client/BrzoDoLokacije/app/src/main/res/drawable/shrink.png Binary files differnew file mode 100644 index 0000000..d4c07e1 --- /dev/null +++ b/Client/BrzoDoLokacije/app/src/main/res/drawable/shrink.png 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 680bada..acdab4a 100644 --- a/Client/BrzoDoLokacije/app/src/main/res/layout/activity_chat.xml +++ b/Client/BrzoDoLokacije/app/src/main/res/layout/activity_chat.xml @@ -18,16 +18,20 @@ app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" /> +<androidx.appcompat.widget.LinearLayoutCompat + android:layout_width="match_parent" + android:id="@+id/llHeader" + android:layout_height="50dp" + android:background="@color/unfollow"> - <ImageView - android:id="@+id/btnActivityShowFollowersAndFollowingBackToUser" - android:layout_width="35dp" - android:layout_height="35dp" - android:layout_marginStart="16dp" - android:layout_marginTop="16dp" + <ImageButton + android:id="@+id/btnBack" + android:layout_width="50dp" + android:layout_height="match_parent" + android:layout_gravity="center_vertical" android:clickable="true" android:src="@drawable/ic_baseline_arrow_back" - android:textAllCaps="false" + android:background="@null" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" tools:ignore="SpeakableTextPresentCheck,TouchTargetSizeCheck" /> @@ -36,13 +40,20 @@ android:id="@+id/tvActivityShowFollowersOrFollowingShow" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginTop="16dp" - android:layout_marginEnd="268dp" + android:layout_gravity="center_vertical" + android:layout_weight="1" android:text="Poruke" android:textSize="25dp" android:textStyle="bold" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" /> +<!-- + <ImageButton + android:layout_width="50dp" + android:layout_height="match_parent" + android:layout_gravity="center_vertical"/>--> + +</androidx.appcompat.widget.LinearLayoutCompat> <androidx.swiperefreshlayout.widget.SwipeRefreshLayout android:id="@+id/swipeContainer" @@ -50,7 +61,7 @@ android:layout_height="0dp" android:layout_marginTop="8dp" app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintTop_toBottomOf="@+id/tvActivityShowFollowersOrFollowingShow" + app:layout_constraintTop_toBottomOf="@+id/llHeader" app:layout_constraintVertical_bias="1.0" tools:layout_editor_absoluteX="-27dp"> 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 72060f7..4dcab31 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 @@ -1,69 +1,94 @@ <?xml version="1.0" encoding="utf-8"?> -<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" +<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" + android:orientation="vertical" android:layout_height="match_parent" + android:fitsSystemWindows="true" tools:context=".Activities.ChatActivityConversation"> - <androidx.constraintlayout.widget.ConstraintLayout - android:id="@+id/topBanner" - android:layout_width="match_parent" - android:layout_height="50dp" - android:elevation="5dp" - android:background="@color/dark_blue_transparent" - android:clickable="true" - app:layout_constraintStart_toStartOf="parent"> - - <TextView - android:id="@+id/tvFragmentTitle" - android:layout_width="wrap_content" - android:layout_height="match_parent" - android:text="Chat" - android:textColor="@color/white" - android:textSize="40dp" /> - <androidx.cardview.widget.CardView - android:id="@+id/cvParentUsername" + <androidx.appcompat.widget.LinearLayoutCompat + android:id="@+id/topBanner" android:layout_width="match_parent" - android:layout_height="40dp" - android:layout_marginStart="16dp" - android:layout_marginTop="10dp" - android:layout_marginEnd="16dp" - android:elevation="0dp" - app:cardCornerRadius="20dp" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toTopOf="parent"> - - - <com.google.android.material.textfield.TextInputEditText - android:id="@+id/etReceiverUsername" - android:layout_width="match_parent" + android:elevation="5dp" + android:layout_height="50dp" + android:background="@color/unfollow"> + <ImageButton + android:id="@+id/btnBack" + android:layout_width="50dp" android:layout_height="match_parent" - android:background="@drawable/rounded_white_button_login" - android:hint=" kome slati poruku?" - android:inputType="textPersonName" - android:paddingLeft="15dp" /> + android:layout_gravity="center_vertical" + android:clickable="true" + android:src="@drawable/ic_baseline_arrow_back" + android:background="@null" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" + tools:ignore="SpeakableTextPresentCheck,TouchTargetSizeCheck" /> + + <androidx.appcompat.widget.LinearLayoutCompat + android:layout_width="match_parent" + android:id="@+id/llHeader" + android:layout_height="50dp"> + <ImageView + android:id="@+id/ivUserImage" + android:layout_width="50dp" + android:layout_height="match_parent" + android:layout_gravity="center_vertical" + android:src="@drawable/ic_nav_profile" + android:padding="5dp" + android:scaleType="centerCrop"/> + <TextView + android:id="@+id/tvFragmentTitle" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:gravity="center_vertical" + android:text="Chat" + android:textSize="20dp" /> + </androidx.appcompat.widget.LinearLayoutCompat> + + <androidx.cardview.widget.CardView + android:id="@+id/cvParentUsername" + android:layout_width="wrap_content" + android:layout_height="40dp" + android:layout_gravity="center_vertical" + android:layout_weight="1" + android:elevation="0dp" + app:cardCornerRadius="20dp" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent"> + + + <com.google.android.material.textfield.TextInputEditText + android:id="@+id/etReceiverUsername" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="@drawable/rounded_white_button_login" + android:hint=" kome slati poruku?" + android:inputType="textPersonName" + android:paddingLeft="15dp" /> + + + </androidx.cardview.widget.CardView> + </androidx.appcompat.widget.LinearLayoutCompat> - </androidx.cardview.widget.CardView> - </androidx.constraintlayout.widget.ConstraintLayout> <androidx.constraintlayout.widget.ConstraintLayout android:id="@+id/messagesContainer" android:layout_width="match_parent" android:layout_height="wrap_content" - app:layout_constraintBottom_toTopOf="@id/cvParentMessageEdit" - app:layout_constrainedHeight="true"> + android:animateLayoutChanges="true" + android:layout_weight="1"> <androidx.recyclerview.widget.RecyclerView android:id="@+id/rvMain" android:layout_width="match_parent" android:layout_height="wrap_content" - app:layout_constraintBottom_toBottomOf="parent" - > + app:layout_constraintBottom_toBottomOf="parent"> </androidx.recyclerview.widget.RecyclerView> </androidx.constraintlayout.widget.ConstraintLayout> @@ -72,14 +97,12 @@ android:id="@+id/cvParentMessageEdit" android:layout_width="match_parent" android:layout_height="40dp" + android:layout_marginBottom="5dp" android:layout_marginStart="16dp" android:layout_marginTop="10dp" android:layout_marginEnd="16dp" android:elevation="0dp" - app:cardCornerRadius="20dp" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent"> + app:cardCornerRadius="20dp"> <com.google.android.material.textfield.TextInputEditText @@ -89,16 +112,21 @@ android:background="@drawable/rounded_white_button_login" android:hint=" poruka" android:inputType="textPersonName" - android:paddingLeft="15dp" /> + android:paddingLeft="15dp" + tools:ignore="TouchTargetSizeCheck" + android:autofillHints="emailAddress"/> <ImageButton android:id="@+id/btnSendMessage" - android:layout_width="49dp" - android:layout_height="50dp" - android:layout_gravity="right" + android:layout_width="25dp" + android:layout_height="25dp" + android:layout_gravity="right|center_vertical" android:scaleType="centerCrop" + android:layout_marginEnd="10dp" + android:background="@null" android:src="@drawable/post_comment" - app:cornerRadius="16dp" /> + app:cornerRadius="16dp" + tools:ignore="SpeakableTextPresentCheck" /> </androidx.cardview.widget.CardView> -</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file +</androidx.appcompat.widget.LinearLayoutCompat>
\ 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 index 7858e94..f7ef08c 100644 --- a/Client/BrzoDoLokacije/app/src/main/res/layout/chat_message.xml +++ b/Client/BrzoDoLokacije/app/src/main/res/layout/chat_message.xml @@ -1,42 +1,15 @@ <?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" - android:id="@+id/clMessage" android:layout_margin="@dimen/text_padding" android:layout_height="wrap_content" - android:layout_width="wrap_content" - android:layout_gravity="end"> - - <androidx.cardview.widget.CardView - android:id="@+id/cardView" - android:layout_width="wrap_content" - android:layout_height="30dp" - android:backgroundTint="@color/unfollow" - android:elevation="5dp" - app:cardCornerRadius="15dp" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintTop_toTopOf="parent" /> - - - <com.google.android.material.textview.MaterialTextView - - android:id="@+id/tvMessage" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginEnd="16dp" - android:background="@drawable/view_corner_radius" - android:backgroundTint="@color/unfollow" - android:padding="5dp" - android:text="blabla" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintTop_toTopOf="parent" /> + android:layout_width="match_parent"> <TextView android:id="@+id/tvDate" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginTop="32dp" android:paddingStart="8dp" android:paddingTop="4dp" android:paddingEnd="8dp" @@ -45,23 +18,31 @@ android:textColor="#C0C0C0" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toTopOf="parent" /> + app:layout_constraintTop_toTopOf="parent"/> <androidx.cardview.widget.CardView android:id="@+id/cvContainer" android:layout_width="wrap_content" - android:layout_height="wrap_content" - app:cardBackgroundColor="@color/dark_blue_transparent" - app:cardCornerRadius="12dp" - app:cardElevation="0dp" - app:cardPreventCornerOverlap="false" - app:cardUseCompatPadding="true" + android:minWidth="40dp" + android:layout_height="30dp" + android:layout_marginBottom="10dp" + android:layout_marginLeft="10dp" + android:backgroundTint="@color/unfollow" + app:cardCornerRadius="15dp" + android:background="@drawable/view_corner_radius" app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintTop_toBottomOf="@id/tvDate"> - - - - + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintTop_toBottomOf="@+id/tvDate"> + + <com.google.android.material.textview.MaterialTextView + android:id="@+id/tvMessage" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:backgroundTint="@color/unfollow" + android:padding="5dp" + android:paddingHorizontal="15dp" + android:text="blabla" + app:layout_constraintEnd_toEndOf="parent" /> </androidx.cardview.widget.CardView> <TextView 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 index aaabd86..b076cf8 100644 --- a/Client/BrzoDoLokacije/app/src/main/res/layout/chat_message_other.xml +++ b/Client/BrzoDoLokacije/app/src/main/res/layout/chat_message_other.xml @@ -1,78 +1,58 @@ <?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" - - xmlns:tools="http://schemas.android.com/tools" android:id="@+id/clMessage" - android:layout_width="wrap_content" android:layout_height="wrap_content" - - android:layout_marginStart="8dp" - android:layout_marginTop="16dp"> + android:layout_width="match_parent"> <TextView android:id="@+id/tvDate" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginTop="32dp" - android:elevation="10dp" - + android:paddingStart="8dp" android:paddingTop="4dp" android:paddingEnd="8dp" android:paddingBottom="4dp" android:text="June 10" android:textColor="#C0C0C0" app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintHorizontal_bias="0.0" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toTopOf="parent" /> + app:layout_constraintTop_toTopOf="parent"/> <androidx.cardview.widget.CardView android:id="@+id/cvContainer" android:layout_width="wrap_content" + android:minWidth="40dp" android:layout_height="30dp" - android:layout_margin="5dp" - android:elevation="5dp" - app:cardCornerRadius="10dp" + android:layout_marginBottom="10dp" + android:layout_marginLeft="10dp" + android:backgroundTint="#eef1f6" + android:background="@drawable/view_corner_radius" + app:cardCornerRadius="15dp" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toTopOf="parent"> - - + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintTop_toBottomOf="@+id/tvDate"> - <LinearLayout - android:id="@+id/llContainer" + <com.google.android.material.textview.MaterialTextView + android:id="@+id/tvMessage" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:orientation="vertical"> - <TextView - android:id="@+id/tvMessage" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:padding="5dp" - android:text="blabla" - app:cardBackgroundColor="#eef1f6" - app:cardCornerRadius="12dp" - app:cardElevation="0dp" - app:cardPreventCornerOverlap="false" - app:cardUseCompatPadding="true" - app:layout_constraintTop_toBottomOf="@+id/tvDate"/> - - </LinearLayout> - + android:backgroundTint="#eef1f6" + android:padding="5dp" + android:paddingHorizontal="15dp" + android:text="blabla" + app:layout_constraintEnd_toEndOf="parent" /> </androidx.cardview.widget.CardView> - <TextView android:id="@+id/tvTimestamp" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginStart="4dp" - android:layout_marginTop="-5dp" - android:text="8:00" + android:text="10:00" android:textColor="#C0C0C0" android:textSize="10sp" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@+id/tvDate" /> + app:layout_constraintBottom_toBottomOf="@+id/cvContainer" + app:layout_constraintStart_toEndOf="@+id/cvContainer" /> </androidx.constraintlayout.widget.ConstraintLayout>
\ 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 35431ff..c995b4b 100644 --- a/Client/BrzoDoLokacije/app/src/main/res/layout/chat_preview.xml +++ b/Client/BrzoDoLokacije/app/src/main/res/layout/chat_preview.xml @@ -1,19 +1,54 @@ <?xml version="1.0" encoding="utf-8"?> -<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" +<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" - android:layout_height="wrap_content" + android:layout_height="70dp" + android:padding="5dp" xmlns:app="http://schemas.android.com/apk/res-auto"> - <androidx.appcompat.widget.AppCompatImageView - android:layout_width="50dp" - android:layout_height="50dp" + <androidx.constraintlayout.widget.ConstraintLayout + android:layout_width="5dp" + android:id="@+id/readIndicator" + android:layout_height="5dp" + android:layout_gravity="center_vertical"/> + <ImageView android:id="@+id/ivUserImage" - android:src="@drawable/ic_nav_profile"/> - <TextView + android:layout_width="70dp" + android:layout_height="match_parent" + android:layout_gravity="center_vertical" + android:src="@drawable/ic_nav_profile" + android:padding="5dp" + android:scaleType="centerCrop"/> + <androidx.appcompat.widget.LinearLayoutCompat android:layout_width="wrap_content" android:layout_height="match_parent" - android:id="@+id/tvUsername" - android:textSize="@dimen/header1_size" - android:textColor="@color/black" - app:layout_constraintStart_toEndOf="@id/ivUserImage"/> - -</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file + android:layout_weight="1" + android:orientation="vertical"> + <androidx.appcompat.widget.LinearLayoutCompat + android:layout_width="match_parent" + android:layout_height="wrap_content"> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:id="@+id/tvUsername" + android:layout_weight="1" + android:textSize="@dimen/header1_size" + android:textColor="@color/black"/> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:id="@+id/tvLastMessageDate" + android:text="1/1/1" + android:textSize="@dimen/header2_size" + android:textColor="@color/unfollow"/> + </androidx.appcompat.widget.LinearLayoutCompat> + <TextView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:id="@+id/tvLastMessage" + android:text="hej, sta ima novo?" + android:layout_weight="1" + android:gravity="center_vertical" + android:textAlignment="gravity" + android:textSize="@dimen/header2_size" + android:textColor="@color/unfollow"/> + </androidx.appcompat.widget.LinearLayoutCompat> +</androidx.appcompat.widget.LinearLayoutCompat>
\ No newline at end of file diff --git a/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_home_page.xml b/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_home_page.xml index f39acf2..12c37e8 100644 --- a/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_home_page.xml +++ b/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_home_page.xml @@ -82,7 +82,7 @@ app:layout_constraintTop_toBottomOf="@+id/brzodolokacije"> - <com.google.android.material.textfield.TextInputEditText + <AutoCompleteTextView android:id="@+id/etFragmentHomePageSearch" android:layout_width="match_parent" android:layout_height="match_parent" @@ -92,6 +92,7 @@ android:paddingLeft="15dp" /> <com.google.android.material.button.MaterialButton + android:id="@+id/mbFragmentHomePageSearchButton" android:layout_width="49dp" android:layout_height="match_parent" android:layout_gravity="right" diff --git a/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_show_posts.xml b/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_show_posts.xml index e1effc4..e3db4bc 100644 --- a/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_show_posts.xml +++ b/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_show_posts.xml @@ -21,8 +21,8 @@ app:layout_constraintTop_toBottomOf="@+id/tvFragmentHomePageSearch"> - <com.google.android.material.textfield.TextInputEditText - android:id="@+id/etFragmentHomePageSearch" + <AutoCompleteTextView + android:id="@+id/etFragmentShowPostsSearch" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/rounded_white_button_login" @@ -31,6 +31,7 @@ android:inputType="textPersonName" /> <com.google.android.material.button.MaterialButton + android:id="@+id/mbFragmentHomePageSearch" android:layout_width="49dp" android:layout_height="match_parent" android:layout_gravity="right" diff --git a/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_user_posts_map.xml b/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_user_posts_map.xml new file mode 100644 index 0000000..5ea5c93 --- /dev/null +++ b/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_user_posts_map.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + tools:context=".UserPostsMapFragment"> + + <org.osmdroid.views.MapView + android:id="@+id/FragmentUserPostsMapMapView" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + + <ImageView + android:id="@+id/btnFragmentUserPostsBack" + android:layout_width="30dp" + android:layout_height="30dp" + android:clickable="true" + android:layout_marginTop="5dp" + android:layout_marginLeft="5dp" + android:src="@drawable/ic_baseline_arrow_back_24" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + +</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file diff --git a/Client/BrzoDoLokacije/app/src/main/res/layout/single_comment.xml b/Client/BrzoDoLokacije/app/src/main/res/layout/single_comment.xml index 51d9079..5e0dc03 100644 --- a/Client/BrzoDoLokacije/app/src/main/res/layout/single_comment.xml +++ b/Client/BrzoDoLokacije/app/src/main/res/layout/single_comment.xml @@ -3,66 +3,85 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" + android:orientation="vertical" android:padding="@dimen/component_padding" xmlns:app="http://schemas.android.com/apk/res-auto"> - - <ImageView - android:layout_width="50dp" - android:layout_height="50dp" - android:src="@drawable/ic_nav_profile" - app:layout_constraintEnd_toStartOf="@+id/tvCommentText" - app:layout_constraintHorizontal_bias="0.0" - app:layout_constraintStart_toStartOf="parent" - tools:layout_editor_absoluteY="27dp" /> - <androidx.appcompat.widget.LinearLayoutCompat - android:layout_width="wrap_content" + android:layout_width="match_parent" android:layout_height="wrap_content" - android:orientation="vertical" - android:layout_weight="1"> + android:orientation="horizontal"> - <TextView - android:id="@+id/tvCommentAuthor" + <ImageView + android:id="@+id/ivPfp" + android:layout_width="50dp" + android:layout_height="50dp" + android:src="@drawable/ic_nav_profile" + app:layout_constraintEnd_toStartOf="@+id/tvCommentText" + app:layout_constraintHorizontal_bias="0.0" + app:layout_constraintStart_toStartOf="parent" + android:scaleType="centerCrop" + tools:layout_editor_absoluteY="27dp" /> + <androidx.appcompat.widget.LinearLayoutCompat android:layout_width="wrap_content" android:layout_height="wrap_content" - android:text="autor" - android:textStyle="bold" - android:padding="@dimen/text_padding"/> + android:orientation="vertical" + android:layout_weight="1"> - <TextView - android:id="@+id/tvCommentText" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:padding="@dimen/text_padding" - app:layout_constraintTop_toBottomOf="@id/tvCommentAuthor" - tools:layout_editor_absoluteX="54dp" /> - <androidx.appcompat.widget.LinearLayoutCompat - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="horizontal" - android:layoutDirection="rtl"> - <ImageButton - android:layout_width="50dp" - android:layout_height="50dp" - android:src="@drawable/reply" - android:layout_weight="0" - android:id="@+id/btnReply" - android:layout_gravity="end" - android:backgroundTint="@color/white" - android:scaleType="centerCrop"/> + <TextView + android:id="@+id/tvCommentAuthor" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="autor" + android:textStyle="bold" + android:padding="@dimen/text_padding"/> - <EditText + <TextView + android:id="@+id/tvCommentText" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_weight="1" - android:id="@+id/etReply" - android:layoutDirection="ltr" - android:hint="odgovor na komentar"/> + android:padding="@dimen/text_padding" + app:layout_constraintTop_toBottomOf="@id/tvCommentAuthor" + tools:layout_editor_absoluteX="54dp" /> + </androidx.appcompat.widget.LinearLayoutCompat> - <androidx.recyclerview.widget.RecyclerView + <ImageButton + android:id="@+id/btnReply" + android:layout_width="50dp" + android:layout_height="50dp" + android:layout_gravity="end" + android:layout_weight="0" + android:backgroundTint="@color/white" + android:scaleType="centerCrop" + android:src="@drawable/reply" /> + + + + </androidx.appcompat.widget.LinearLayoutCompat> + <androidx.appcompat.widget.LinearLayoutCompat + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + android:id="@+id/llReply"> + + <EditText android:layout_width="match_parent" android:layout_height="wrap_content" - android:id="@+id/rvReplies"/> + android:layout_weight="1" + android:id="@+id/etReply" + android:hint="odgovor na komentar"/> + <ImageButton + android:id="@+id/btnPostReply" + android:layout_width="50dp" + android:layout_height="50dp" + android:layout_gravity="end" + android:layout_weight="0" + android:backgroundTint="@color/white" + android:scaleType="centerCrop" + android:src="@drawable/post_comment" /> </androidx.appcompat.widget.LinearLayoutCompat> + <androidx.recyclerview.widget.RecyclerView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:id="@+id/rvReplies"/> </androidx.appcompat.widget.LinearLayoutCompat>
\ No newline at end of file diff --git a/Client/BrzoDoLokacije/app/src/main/res/values/dimens.xml b/Client/BrzoDoLokacije/app/src/main/res/values/dimens.xml index 181591b..5f0b4e1 100644 --- a/Client/BrzoDoLokacije/app/src/main/res/values/dimens.xml +++ b/Client/BrzoDoLokacije/app/src/main/res/values/dimens.xml @@ -2,6 +2,7 @@ <dimen name="fab_margin">16dp</dimen> <dimen name="text_padding">5dp</dimen> <dimen name="header1_size">20dp</dimen> + <dimen name="header2_size">18dp</dimen> <dimen name="component_padding">10dp</dimen> <dimen name="list_item_spacing">16dp</dimen> <dimen name="list_item_spacing_half">8dp</dimen> |