aboutsummaryrefslogtreecommitdiff
path: root/Client
diff options
context:
space:
mode:
Diffstat (limited to 'Client')
-rw-r--r--Client/BrzoDoLokacije/app/build.gradle4
-rw-r--r--Client/BrzoDoLokacije/app/libs/signalr-client-sdk-android.jarbin0 -> 57824 bytes
-rw-r--r--Client/BrzoDoLokacije/app/libs/signalr-client-sdk.jarbin0 -> 497821 bytes
-rw-r--r--Client/BrzoDoLokacije/app/src/main/AndroidManifest.xml70
-rw-r--r--Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ActivityAddPost.kt130
-rw-r--r--Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ActivityCapturePost.kt138
-rw-r--r--Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ActivitySinglePost.kt57
-rw-r--r--Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ActivityUserProfile.kt49
-rw-r--r--Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ChatActivity.kt123
-rw-r--r--Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ChatActivityConversation.kt175
-rw-r--r--Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/MapsActivity.kt397
-rw-r--r--Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/NavigationActivity.kt2
-rw-r--r--Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/SplashPage.kt2
-rw-r--r--Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/ChatMessagesAdapter.kt77
-rw-r--r--Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/ChatPreviewsAdapter.kt79
-rw-r--r--Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/FollowersAdapter.kt42
-rw-r--r--Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/MyPostsAdapter.kt75
-rw-r--r--Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/PostHistoryAdapter.kt61
-rw-r--r--Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/ShowPostsAdapter.kt32
-rw-r--r--Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/ShowPostsHomePageAdapter.kt13
-rw-r--r--Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentBrowse.kt11
-rw-r--r--Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentFollowers.kt84
-rw-r--r--Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentFollowing.kt78
-rw-r--r--Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentHomePageMainScroll.kt3
-rw-r--r--Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentMyRecensions.kt81
-rw-r--r--Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentProfile.kt70
-rw-r--r--Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentShowPosts.kt118
-rw-r--r--Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentUserPosts.kt3
-rw-r--r--Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentUserProfile.kt26
-rw-r--r--Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Interfaces/IBackendApi.kt29
-rw-r--r--Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/MainActivity.kt4
-rw-r--r--Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Models/Chat.kt27
-rw-r--r--Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Models/Post.kt17
-rw-r--r--Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Models/User.kt12
-rw-r--r--Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/chat/DBHelper.kt155
-rw-r--r--Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/chat/SignalRListener.kt63
-rw-r--r--Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/paging/SearchPostsPagingSource.kt38
-rw-r--r--Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/paging/SearchPostsRepository.kt31
-rw-r--r--Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/paging/SearchPostsViewModel.kt22
-rw-r--r--Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/paging/SearchPostsViewModelFactory.kt15
-rw-r--r--Client/BrzoDoLokacije/app/src/main/res/drawable/button_chat.xml22
-rw-r--r--Client/BrzoDoLokacije/app/src/main/res/drawable/button_filter.xml10
-rw-r--r--Client/BrzoDoLokacije/app/src/main/res/drawable/button_find_on_map.xml25
-rw-r--r--Client/BrzoDoLokacije/app/src/main/res/drawable/button_follow.xml18
-rw-r--r--Client/BrzoDoLokacije/app/src/main/res/drawable/button_sort.xml13
-rw-r--r--Client/BrzoDoLokacije/app/src/main/res/drawable/button_unfollow.xml22
-rw-r--r--Client/BrzoDoLokacije/app/src/main/res/drawable/ic_baseline_add_location_24.xml5
-rw-r--r--Client/BrzoDoLokacije/app/src/main/res/drawable/ic_baseline_check_24.xml5
-rw-r--r--Client/BrzoDoLokacije/app/src/main/res/drawable/ic_baseline_close_24.xml5
-rw-r--r--Client/BrzoDoLokacije/app/src/main/res/drawable/profile_view_background.xml15
-rw-r--r--Client/BrzoDoLokacije/app/src/main/res/layout/activity_add_post.xml62
-rw-r--r--Client/BrzoDoLokacije/app/src/main/res/layout/activity_capture_post.xml78
-rw-r--r--Client/BrzoDoLokacije/app/src/main/res/layout/activity_chat.xml51
-rw-r--r--Client/BrzoDoLokacije/app/src/main/res/layout/activity_chat_conversation.xml104
-rw-r--r--Client/BrzoDoLokacije/app/src/main/res/layout/activity_maps.xml90
-rw-r--r--Client/BrzoDoLokacije/app/src/main/res/layout/activity_single_post.xml72
-rw-r--r--Client/BrzoDoLokacije/app/src/main/res/layout/activity_user_profile.xml252
-rw-r--r--Client/BrzoDoLokacije/app/src/main/res/layout/bottom_sheet_filter.xml147
-rw-r--r--Client/BrzoDoLokacije/app/src/main/res/layout/bottom_sheet_sort.xml67
-rw-r--r--Client/BrzoDoLokacije/app/src/main/res/layout/chat_message.xml26
-rw-r--r--Client/BrzoDoLokacije/app/src/main/res/layout/chat_message_other.xml23
-rw-r--r--Client/BrzoDoLokacije/app/src/main/res/layout/chat_preview.xml19
-rw-r--r--Client/BrzoDoLokacije/app/src/main/res/layout/follower_item.xml87
-rw-r--r--Client/BrzoDoLokacije/app/src/main/res/layout/fragment_followers.xml37
-rw-r--r--Client/BrzoDoLokacije/app/src/main/res/layout/fragment_following.xml37
-rw-r--r--Client/BrzoDoLokacije/app/src/main/res/layout/fragment_my_recensions.xml26
-rw-r--r--Client/BrzoDoLokacije/app/src/main/res/layout/fragment_profile.xml3
-rw-r--r--Client/BrzoDoLokacije/app/src/main/res/layout/fragment_show_posts.xml21
-rw-r--r--Client/BrzoDoLokacije/app/src/main/res/layout/fragment_user_profile.xml248
-rw-r--r--Client/BrzoDoLokacije/app/src/main/res/layout/single_post_history.xml75
-rw-r--r--Client/BrzoDoLokacije/app/src/main/res/values/strings.xml44
71 files changed, 3857 insertions, 265 deletions
diff --git a/Client/BrzoDoLokacije/app/build.gradle b/Client/BrzoDoLokacije/app/build.gradle
index db4ed1b..f81ba4b 100644
--- a/Client/BrzoDoLokacije/app/build.gradle
+++ b/Client/BrzoDoLokacije/app/build.gradle
@@ -52,6 +52,10 @@ dependencies {
implementation 'com.google.android.gms:play-services-location:21.0.1'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.recyclerview:recyclerview:1.2.1'
+ implementation "androidx.paging:paging-runtime:3.0.0-alpha03"
+ implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1"
+ implementation 'com.microsoft.signalr:signalr:6.0.8'
+
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
diff --git a/Client/BrzoDoLokacije/app/libs/signalr-client-sdk-android.jar b/Client/BrzoDoLokacije/app/libs/signalr-client-sdk-android.jar
new file mode 100644
index 0000000..967d741
--- /dev/null
+++ b/Client/BrzoDoLokacije/app/libs/signalr-client-sdk-android.jar
Binary files differ
diff --git a/Client/BrzoDoLokacije/app/libs/signalr-client-sdk.jar b/Client/BrzoDoLokacije/app/libs/signalr-client-sdk.jar
new file mode 100644
index 0000000..f736f64
--- /dev/null
+++ b/Client/BrzoDoLokacije/app/libs/signalr-client-sdk.jar
Binary files differ
diff --git a/Client/BrzoDoLokacije/app/src/main/AndroidManifest.xml b/Client/BrzoDoLokacije/app/src/main/AndroidManifest.xml
index 56bdb58..0c412d8 100644
--- a/Client/BrzoDoLokacije/app/src/main/AndroidManifest.xml
+++ b/Client/BrzoDoLokacije/app/src/main/AndroidManifest.xml
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
-
<!-- DOZVOLE -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
@@ -15,9 +14,7 @@
android:name="android.permission.CAMERA"
android:required="true"
android:requiredFeature="true" />
- <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
-
- <!-- SVOJSTVA -->
+ <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!-- SVOJSTVA -->
<uses-feature
android:name="android.hardware.camera"
android:required="true" />
@@ -39,19 +36,53 @@
android:theme="@style/Theme.BrzoDoLokacije"
android:usesCleartextTraffic="true"
tools:targetApi="31">
+ <activity
+ android:name=".Activities.ActivityUserProfile"
+ android:exported="false"
+ android:screenOrientation="portrait" >
+ <meta-data
+ android:name="android.app.lib_name"
+ android:value="" />
+ </activity>
+ <activity
+ android:name=".Activities.ChatActivityConversation"
+ android:exported="false"
+ android:windowSoftInputMode="stateVisible|adjustPan"
+ android:screenOrientation="portrait" >
+ <meta-data
+ android:name="android.app.lib_name"
+ android:value="" />
+ </activity>
+ <activity
+ android:name=".Activities.ChatActivity"
+ android:exported="true"
+ android:screenOrientation="portrait" >
+ <meta-data
+ android:name="android.app.lib_name"
+ android:value="" />
+
+ </activity>
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="YOUR_API_KEY" />
- <activity android:name=".Activities.MapsActivity" android:screenOrientation="portrait" />
- <activity android:name=".Activities.ActivityCapturePost" android:screenOrientation="portrait" />
- <activity android:name=".Activities.ActivitySinglePost" android:screenOrientation="portrait" />
- <activity android:name=".Activities.ActivityAddPost" android:screenOrientation="portrait" />
+ <activity
+ android:name=".Activities.MapsActivity"
+ android:screenOrientation="portrait" />
+ <activity
+ android:name=".Activities.ActivityCapturePost"
+ android:screenOrientation="portrait" />
+ <activity
+ android:name=".Activities.ActivitySinglePost"
+ android:screenOrientation="portrait" />
+ <activity
+ android:name=".Activities.ActivityAddPost"
+ android:screenOrientation="portrait" />
<activity
android:name=".Activities.SplashPage"
android:exported="true"
- android:screenOrientation="portrait" >
+ android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
@@ -62,12 +93,21 @@
android:name="android.app.lib_name"
android:value="" />
</activity>
- <activity android:name=".Activities.ActivityForgottenPasswordVerify" android:screenOrientation="portrait" />
- <activity android:name=".Activities.ActivityForgottenPassword" android:screenOrientation="portrait" />
- <activity android:name=".Activities.ActivityLoginRegister" android:screenOrientation="portrait" />
- <activity android:name=".Activities.NavigationActivity" android:screenOrientation="portrait" />
- <activity android:name=".MainActivity" android:screenOrientation="portrait" />
-
+ <activity
+ android:name=".Activities.ActivityForgottenPasswordVerify"
+ android:screenOrientation="portrait" />
+ <activity
+ android:name=".Activities.ActivityForgottenPassword"
+ android:screenOrientation="portrait" />
+ <activity
+ android:name=".Activities.ActivityLoginRegister"
+ android:screenOrientation="portrait" />
+ <activity
+ android:name=".Activities.NavigationActivity"
+ android:screenOrientation="portrait" />
+ <activity
+ android:name=".MainActivity"
+ android:screenOrientation="portrait" />
<provider
android:name="androidx.core.content.FileProvider"
diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ActivityAddPost.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ActivityAddPost.kt
index b9e4fd7..2d305a6 100644
--- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ActivityAddPost.kt
+++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ActivityAddPost.kt
@@ -1,32 +1,35 @@
package com.example.brzodolokacije.Activities
import android.Manifest
+import android.app.ProgressDialog
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Color
import android.net.Uri
import android.os.Bundle
import android.util.Log
+import android.util.TypedValue
import android.view.View
import android.widget.*
import androidx.appcompat.app.AppCompatActivity
+import androidx.appcompat.widget.AppCompatImageView
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.core.view.isVisible
+import androidx.core.view.setMargins
import com.example.brzodolokacije.Models.Location
import com.example.brzodolokacije.Models.LocationType
import com.example.brzodolokacije.Models.PostPreview
import com.example.brzodolokacije.R
+import com.example.brzodolokacije.Services.GeocoderHelper
import com.example.brzodolokacije.Services.RetrofitHelper
import com.example.brzodolokacije.Services.SharedPreferencesHelper
-import okhttp3.MediaType
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.MultipartBody
import okhttp3.RequestBody
import retrofit2.Call
import retrofit2.Response
import java.io.File
-import java.io.IOException
class ActivityAddPost : AppCompatActivity() {
@@ -42,6 +45,18 @@ class ActivityAddPost : AppCompatActivity() {
private lateinit var locationString:String
private lateinit var descriptionString:String
private lateinit var post:Button
+ private lateinit var addLocation:Button
+ private lateinit var tagLayout:LinearLayout
+ private lateinit var tagButtons:MutableList<Button>
+ private lateinit var tagText: EditText
+ private lateinit var tagButtonAdd:Button
+ private lateinit var tagList: MutableList<String>
+ private var tagidcounter:Int = 0
+ val incorectCoord:Double=1000.0
+ val LOCATIONREQCODE=123
+ var longitude:Double=incorectCoord
+ var latitude:Double=incorectCoord
+ var progressDialog:ProgressDialog?=null
//private var paths :ArrayList<String?>?=null
private var place=0;
override fun onCreate(savedInstanceState: Bundle?) {
@@ -51,7 +66,9 @@ class ActivityAddPost : AppCompatActivity() {
// applicationContext, "Add new ", Toast.LENGTH_LONG
// ).show();
uploadedImages= ArrayList()
-
+ tagList = mutableListOf()
+ tagButtons= mutableListOf()
+ tagidcounter = 0
//paths= ArrayList()
uploadFromGallery=findViewById<View>(R.id.btnActivityAddPostUploadFromGalleryVisible) as Button
@@ -61,6 +78,15 @@ class ActivityAddPost : AppCompatActivity() {
location=findViewById<View>(R.id.etActivityAddPostLocation) as EditText
description=findViewById<View>(R.id.etActivityAddPostDescription) as EditText
post=findViewById<View>(R.id.btnActivityAddPostPost) as Button
+ addLocation=findViewById<View>(R.id.btnActivityAddPostAddLocation) as Button
+ tagText =findViewById<View>(R.id.acTags) as EditText
+ tagButtonAdd = findViewById<View>(R.id.btnActivityAddPostAddTag) as Button
+ tagLayout = findViewById<View>(R.id.llTags) as LinearLayout
+
+ progressDialog= ProgressDialog(this)
+ progressDialog!!.setMessage("Molimo sacekajte!!!")
+ progressDialog!!.setCancelable(false)
+ progressDialog!!.setCanceledOnTouchOutside(false)
switcher?.setFactory{
@@ -68,6 +94,47 @@ class ActivityAddPost : AppCompatActivity() {
imgView.scaleType = ImageView.ScaleType.CENTER_CROP
imgView.setPadding(8, 8, 8, 8)
imgView}
+ addLocation.setOnClickListener {
+ val myIntent = Intent(this, MapsActivity::class.java)
+ if(location.text!=null && !location.text.trim().equals(""))
+ myIntent.putExtra("search",location.text.toString())
+ startActivityForResult(myIntent,LOCATIONREQCODE)
+ }
+
+ //dodavanje i brisanje tagova
+ tagButtonAdd.setOnClickListener {
+ if(tagList.count()<5) {
+ var tagstr = tagText.text.toString()
+ var newbtn = Button(this)
+ newbtn.setId(tagidcounter)
+ newbtn.text = tagstr
+ var layoutParams = LinearLayout.LayoutParams(
+ LinearLayout.LayoutParams.WRAP_CONTENT,
+ 50
+ )
+ layoutParams.setMargins(3)
+ newbtn.layoutParams=layoutParams
+ newbtn.setBackgroundColor(Color.parseColor("#1C789A"))
+ newbtn.setTextColor(Color.WHITE)
+ newbtn.setTextSize(TypedValue.COMPLEX_UNIT_SP, 10F)
+ newbtn.setPadding(3,1,3,1)
+
+ newbtn.setOnClickListener {
+ var btntext = newbtn.text.toString()
+ tagList.remove(btntext)
+ tagButtons.remove(newbtn)
+ tagLayout.removeView(newbtn)
+ }
+
+ tagList.add(tagstr)
+ tagButtons.add(newbtn)
+ tagLayout.addView(newbtn)
+ tagText.text.clear()
+ }
+ else{
+ Toast.makeText(this,"Maksimalno 5 tagova",Toast.LENGTH_LONG)
+ }
+ }
//dodavanje iz galerije
uploadFromGallery.setOnClickListener{
@@ -116,15 +183,18 @@ class ActivityAddPost : AppCompatActivity() {
descriptionString=description.text.toString().trim()
//prazan unos?
if(locationString.isEmpty()) {
- location.hint="Unesite lokaciju"
+ location.hint="Unesite naziv lokaciju"
location.setHintTextColor(Color.RED)
}
if(descriptionString.isEmpty()) {
description.hint="Unesite lokaciju"
description.setHintTextColor(Color.RED)
}
+ if(longitude!=incorectCoord && latitude!=incorectCoord){
+ Toast.makeText(this,"Unesite lokaciju klikom na dugme",Toast.LENGTH_LONG)
+ }
- if(!locationString.isEmpty() && !descriptionString.isEmpty()){
+ if(!locationString.isEmpty() && !descriptionString.isEmpty() && longitude!=incorectCoord && latitude!=incorectCoord && uploadedImages!!.size>0){
sendPost()
}
}
@@ -162,35 +232,57 @@ class ActivityAddPost : AppCompatActivity() {
uploadFromGallery.isVisible=false
}
}
+ if(requestCode==LOCATIONREQCODE && resultCode== RESULT_OK){
+ var bundle=data!!.extras
+ longitude=bundle!!.getDouble("longitude",incorectCoord)
+ latitude=bundle!!.getDouble("latitude",incorectCoord)
+ var locName=bundle!!.getString("name")
+ if(location.text.toString().trim().equals("") && locName!=null && !locName.toString().trim().equals(""))
+ location.setText(locName,TextView.BufferType.EDITABLE)
+ }
}
private fun sendPost(){
uploadLocation()
}
fun uploadLocation() {
+ //TO DO SEARCH EXISTING LOCATION FROM DB
+ //IF NOT EXISTS ADD NEW LOCATION
+ progressDialog!!.show()
val api =RetrofitHelper.getInstance()
- var loc:Location=Location("",locationString,"","","",0.0,0.0,LocationType.GRAD)
+ var geocoder=GeocoderHelper.getInstance()
+ var loc1=geocoder!!.getFromLocation(latitude,longitude,1)
+ if(loc1==null ||loc1.size<=0)
+ {
+ progressDialog!!.dismiss()
+ Toast.makeText(this,"Lokacija ne postoji",Toast.LENGTH_LONG);
+ return
+ }
+ var countryName=loc1[0].countryName
+ var address="todo not possible in query"
+ var city="its null"
+ if(loc1[0].adminArea!=null)
+ city=loc1[0].adminArea//not possible
+ var loc:Location=Location("",locationString,city,countryName,address,latitude,longitude,LocationType.GRAD)
var jwtString= SharedPreferencesHelper.getValue("jwt",this)
var data=api.addLocation("Bearer "+jwtString,loc)
-
data.enqueue(object : retrofit2.Callback<Location?> {
override fun onResponse(call: Call<Location?>, response: Response<Location?>) {
if(response.isSuccessful()){
+
+ uploadPost(response.body()!!._id)
Toast.makeText(
applicationContext, "USPEH", Toast.LENGTH_LONG
).show();
- uploadPost(response.body()!!._id)
- Log.d("MAIN","RADI")
- Log.d("MAIN","RADI")
}else {
+ progressDialog!!.dismiss()
if (response.errorBody() != null) {
Log.d("Main",response.errorBody()!!.string())
Log.d("Main",response.message())
}
- Log.d("Main","sadadsa")
Log.d("Main",response.errorBody()!!.string())
Log.d("Main",response.message())
}
@@ -203,6 +295,7 @@ class ActivityAddPost : AppCompatActivity() {
applicationContext, t.toString(), Toast.LENGTH_LONG
).show();
Log.d("Main",t.toString())
+ progressDialog!!.dismiss()
}
})
}
@@ -215,6 +308,13 @@ class ActivityAddPost : AppCompatActivity() {
var locReq=RequestBody.create("text/plain".toMediaTypeOrNull(),loc)
var descReq=RequestBody.create("text/plain".toMediaTypeOrNull(),desc)
var idReq=RequestBody.create("text/plain".toMediaTypeOrNull(),"dsa")
+
+ var tagliststring=""
+ for(tag in tagList){
+ tagliststring=tagliststring+tag+"|"
+ }
+ var tagReq=RequestBody.create("text/plain".toMediaTypeOrNull(),tagliststring)
+
val imagesParts = arrayOfNulls<MultipartBody.Part>(
uploadedImages!!.size
)
@@ -233,11 +333,12 @@ class ActivityAddPost : AppCompatActivity() {
imagesParts[i]=MultipartBody.Part.createFormData("images",file.name,imageBody)
}
var jwtString= SharedPreferencesHelper.getValue("jwt",this)
- var data=api.addPost("Bearer "+jwtString,imagesParts,idReq,descReq,locReq)
-
+ var data=api.addPost("Bearer "+jwtString,imagesParts,idReq,descReq,locReq,tagReq)
+ //multipart formdata : images , _id , description , locationId , tags
data.enqueue(object : retrofit2.Callback<PostPreview?> {
override fun onResponse(call: Call<PostPreview?>, response: Response<PostPreview?>) {
+ progressDialog!!.dismiss()
if(response.isSuccessful()){
Toast.makeText(
applicationContext, "USPEH", Toast.LENGTH_LONG
@@ -260,7 +361,8 @@ class ActivityAddPost : AppCompatActivity() {
override fun onFailure(call: Call<PostPreview?>, t: Throwable) {
Toast.makeText(
applicationContext, t.toString(), Toast.LENGTH_LONG
- ).show();
+ ).show()
+ progressDialog!!.dismiss()
Log.d("Main",t.toString())
}
})
diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ActivityCapturePost.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ActivityCapturePost.kt
index e2dbb7c..b02abad 100644
--- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ActivityCapturePost.kt
+++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ActivityCapturePost.kt
@@ -1,6 +1,7 @@
package com.example.brzodolokacije.Activities
import android.Manifest
+import android.app.ProgressDialog
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Bitmap
@@ -9,20 +10,20 @@ import android.net.Uri
import android.os.Bundle
import android.provider.MediaStore
import android.util.Log
+import android.util.TypedValue
import android.view.View
-import android.widget.Button
-import android.widget.EditText
-import android.widget.ImageView
-import android.widget.Toast
+import android.widget.*
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.core.view.isVisible
+import androidx.core.view.setMargins
import com.example.brzodolokacije.Models.Location
import com.example.brzodolokacije.Models.LocationType
import com.example.brzodolokacije.Models.PostPreview
import com.example.brzodolokacije.R
+import com.example.brzodolokacije.Services.GeocoderHelper
import com.example.brzodolokacije.Services.RetrofitHelper
import com.example.brzodolokacije.Services.SharedPreferencesHelper
import okhttp3.MediaType.Companion.toMediaTypeOrNull
@@ -46,15 +47,78 @@ class ActivityCapturePost : AppCompatActivity() {
private lateinit var post: Button
private lateinit var showImage: ImageView
private var uploadedImages: Uri? = null
+ private lateinit var addLocation:Button
+ private lateinit var tagLayout:LinearLayout
+ private lateinit var tagButtons:MutableList<Button>
+ private lateinit var tagText: EditText
+ private lateinit var tagButtonAdd:Button
+ private lateinit var tagList: MutableList<String>
+ private var tagidcounter:Int = 0
+
+ val incorectCoord:Double=1000.0
+ val LOCATIONREQCODE=123
+ var longitude:Double=incorectCoord
+ var latitude:Double=incorectCoord
+ var progressDialog: ProgressDialog?=null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_capture_post)
+ tagList = mutableListOf()
+ tagButtons= mutableListOf()
+ tagidcounter = 0
+
location = findViewById<View>(R.id.etActivityCapturePostLocation) as EditText
description = findViewById<View>(R.id.etActivityCapturePostDescription) as EditText
post = findViewById<View>(R.id.btnActivityCapturePostPost) as Button
showImage = findViewById<View>(R.id.ivActivityCapturePostImage) as ImageView
takePhoto = findViewById<View>(R.id.btnActivityCapturePostCaptureVisible) as Button
+ addLocation=findViewById<View>(R.id.btnActivityCapturePostAddLocation) as Button
+ tagText =findViewById<View>(R.id.acTagsCap) as EditText
+ tagButtonAdd = findViewById<View>(R.id.btnActivityAddPostAddTagCap) as Button
+ tagLayout = findViewById<View>(R.id.llTagsCap) as LinearLayout
+
+ progressDialog= ProgressDialog(this)
+ progressDialog!!.setMessage("Molimo sacekajte!!!")
+ progressDialog!!.setCancelable(false)
+ progressDialog!!.setCanceledOnTouchOutside(false)
+
+
+ //dodavanje i brisanje tagova
+ tagButtonAdd.setOnClickListener {
+ if(tagList.count()<5) {
+ var tagstr = tagText.text.toString()
+ var newbtn = Button(this)
+ newbtn.setId(tagidcounter)
+ newbtn.text = tagstr
+ var layoutParams = LinearLayout.LayoutParams(
+ LinearLayout.LayoutParams.WRAP_CONTENT,
+ 50
+ )
+ layoutParams.setMargins(3)
+ newbtn.layoutParams=layoutParams
+ newbtn.setBackgroundColor(Color.parseColor("#1C789A"))
+ newbtn.setTextColor(Color.WHITE)
+ newbtn.setTextSize(TypedValue.COMPLEX_UNIT_SP, 10F)
+ newbtn.setPadding(3,1,3,1)
+
+ newbtn.setOnClickListener {
+ var btntext = newbtn.text.toString()
+ tagList.remove(btntext)
+ tagButtons.remove(newbtn)
+ tagLayout.removeView(newbtn)
+ }
+
+ tagList.add(tagstr)
+ tagButtons.add(newbtn)
+ tagLayout.addView(newbtn)
+ tagText.text.clear()
+ }
+ else{
+ Toast.makeText(this,"Maksimalno 5 tagova",Toast.LENGTH_LONG)
+ }
+ }
+
//dodavanje sa kamere
@@ -101,6 +165,14 @@ class ActivityCapturePost : AppCompatActivity() {
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ addLocation.setOnClickListener {
+ val myIntent = Intent(this, MapsActivity::class.java)
+ if(location.text!=null && !location.text.trim().equals(""))
+ myIntent.putExtra("search",location.text.toString())
+ startActivityForResult(myIntent,LOCATIONREQCODE)
+ }
+
takePhoto.setOnClickListener {
val APP_TAG = "BrzoDoLokacije"
@@ -136,7 +208,7 @@ class ActivityCapturePost : AppCompatActivity() {
if (descriptionString.isEmpty()) {
description.hint = "Unesite opis"
description.setHintTextColor(Color.RED)
- }else if(f!=null){
+ }else if(f!=null && longitude!=incorectCoord && latitude!=incorectCoord){
uploadLocation()
}
@@ -145,7 +217,17 @@ class ActivityCapturePost : AppCompatActivity() {
}
}
-
+ override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+ super.onActivityResult(requestCode, resultCode, data)
+ if(requestCode==LOCATIONREQCODE && resultCode== RESULT_OK){
+ var bundle=data!!.extras
+ longitude=bundle!!.getDouble("longitude",incorectCoord)
+ latitude=bundle!!.getDouble("latitude",incorectCoord)
+ var locName=bundle!!.getString("name")
+ if(location.text.toString().trim().equals("") && locName!=null && !locName.toString().trim().equals(""))
+ location.setText(locName, TextView.BufferType.EDITABLE)
+ }
+ }
var f:File?=null
private val cameraActivityResultLauncher =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
@@ -168,27 +250,43 @@ class ActivityCapturePost : AppCompatActivity() {
}
fun uploadLocation() {
- val api = RetrofitHelper.getInstance()
- var loc: Location = Location("",locationString,"","","",0.0,0.0, LocationType.GRAD)
+ //TO DO SEARCH EXISTING LOCATION FROM DB
+ //IF NOT EXISTS ADD NEW LOCATION
+ progressDialog!!.show()
+ val api =RetrofitHelper.getInstance()
+ var geocoder= GeocoderHelper.getInstance()
+ var loc1=geocoder!!.getFromLocation(latitude,longitude,1)
+ if(loc1==null ||loc1.size<=0)
+ {
+ progressDialog!!.dismiss()
+ Toast.makeText(this,"Lokacija ne postoji",Toast.LENGTH_LONG);
+ return
+ }
+ var countryName=loc1[0].countryName
+ var address="todo not possible in query"
+ var city=loc1[0].adminArea//not possible
+ //var address=loc1[0].subAdminArea
+ var loc:Location=Location("",locationString,city,countryName,address,latitude,longitude,LocationType.GRAD)
var jwtString= SharedPreferencesHelper.getValue("jwt",this)
var data=api.addLocation("Bearer "+jwtString,loc)
-
data.enqueue(object : retrofit2.Callback<Location?> {
override fun onResponse(call: Call<Location?>, response: Response<Location?>) {
if(response.isSuccessful()){
+
+ uploadPost(response.body()!!._id)
Toast.makeText(
applicationContext, "USPEH", Toast.LENGTH_LONG
).show();
- uploadPost(response.body()!!._id)
- Log.d("MAIN","RADI")
- Log.d("MAIN","RADI")
}else {
+ progressDialog!!.dismiss()
if (response.errorBody() != null) {
Log.d("Main",response.errorBody()!!.string())
+ Log.d("Main",response.message())
}
+ Log.d("Main",response.errorBody()!!.string())
Log.d("Main",response.message())
}
@@ -196,7 +294,11 @@ class ActivityCapturePost : AppCompatActivity() {
}
override fun onFailure(call: Call<Location?>, t: Throwable) {
+ Toast.makeText(
+ applicationContext, t.toString(), Toast.LENGTH_LONG
+ ).show();
Log.d("Main",t.toString())
+ progressDialog!!.dismiss()
}
})
}
@@ -209,6 +311,13 @@ class ActivityCapturePost : AppCompatActivity() {
var locReq= RequestBody.create("text/plain".toMediaTypeOrNull(),loc)
var descReq= RequestBody.create("text/plain".toMediaTypeOrNull(),desc)
var idReq= RequestBody.create("text/plain".toMediaTypeOrNull(),"dsa")
+
+ var tagliststring=""
+ for(tag in tagList){
+ tagliststring=tagliststring+tag+"|"
+ }
+ var tagReq=RequestBody.create("text/plain".toMediaTypeOrNull(),tagliststring)
+
val imagesParts = arrayOfNulls<MultipartBody.Part>(
1
)
@@ -217,16 +326,18 @@ class ActivityCapturePost : AppCompatActivity() {
imagesParts[0]= MultipartBody.Part.createFormData("images",f!!.name,imageBody)
var jwtString= SharedPreferencesHelper.getValue("jwt",this)
- var data=api.addPost("Bearer "+jwtString,imagesParts,idReq,descReq,locReq)
+ var data=api.addPost("Bearer "+jwtString,imagesParts,idReq,descReq,locReq,tagReq)
data.enqueue(object : retrofit2.Callback<PostPreview?> {
override fun onResponse(call: Call<PostPreview?>, response: Response<PostPreview?>) {
if(response.isSuccessful()){
+ progressDialog!!.dismiss()
Toast.makeText(
applicationContext, "USPEH", Toast.LENGTH_LONG
).show();
}else {
+ progressDialog!!.dismiss()
if (response.errorBody() != null) {
Toast.makeText(
@@ -242,6 +353,7 @@ class ActivityCapturePost : AppCompatActivity() {
}
override fun onFailure(call: Call<PostPreview?>, t: Throwable) {
+ progressDialog!!.dismiss()
Toast.makeText(
applicationContext, t.toString(), Toast.LENGTH_LONG
).show();
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 ea82cda..f969669 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,11 +1,11 @@
package com.example.brzodolokacije.Activities
+import android.content.Intent
import android.os.Bundle
import android.util.Log
-import android.widget.Adapter
+import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
-import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.brzodolokacije.Adapters.CommentsAdapter
@@ -15,8 +15,9 @@ import com.example.brzodolokacije.R
import com.example.brzodolokacije.Services.RetrofitHelper
import com.example.brzodolokacije.Services.SharedPreferencesHelper
import com.example.brzodolokacije.databinding.ActivitySinglePostBinding
+import com.google.gson.Gson
+import kotlinx.android.synthetic.main.activity_single_post.*
import okhttp3.ResponseBody
-import okhttp3.internal.notifyAll
import retrofit2.Call
import retrofit2.Response
@@ -32,6 +33,8 @@ class ActivitySinglePost : AppCompatActivity() {
private lateinit var post:PostPreview
private var comments:MutableList<CommentSend>?=mutableListOf()
private var starNumber:Number=0
+ private lateinit var userData:UserReceive
+ private lateinit var user:TextView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -52,6 +55,14 @@ class ActivitySinglePost : AppCompatActivity() {
recyclerViewImages?.adapter = adapterImages
loadTextComponents()
setRatingListeners()
+ translateOwnerIdToName(post.ownerId)
+
+ binding.tvUser.setOnClickListener {
+ val intent: Intent = Intent(this@ActivitySinglePost,ActivityUserProfile::class.java)
+ var b= Bundle()
+ intent.putExtra("user", Gson().toJson(userData))
+ this.startActivity(intent)
+ }
}
fun buildRecyclerViewComments(){
@@ -131,6 +142,7 @@ class ActivitySinglePost : AppCompatActivity() {
Toast.makeText(this@ActivitySinglePost,"Unesite tekst komentara.",Toast.LENGTH_LONG).show()
}
}
+ addView()
}
@@ -192,6 +204,9 @@ class ActivitySinglePost : AppCompatActivity() {
request.enqueue(object : retrofit2.Callback<ResponseBody?> {
override fun onResponse(call: Call<ResponseBody?>, response: Response<ResponseBody?>) {
if(response.isSuccessful){
+ //zasad hardkodovano, zameniti te vrednosti sa brojem ocena kada se doda
+ post.ratings=((post.ratings)*10+rating.rating)/11
+ binding.tvRating.text=String.format("%.2f",post.ratings)
Toast.makeText(
this@ActivitySinglePost, "prosao zahtev", Toast.LENGTH_LONG
).show()
@@ -223,7 +238,43 @@ class ActivitySinglePost : AppCompatActivity() {
tvNumberOfRatings.invalidate()
tvDescription.text=post.description
tvDescription.invalidate()
+
}
+
+ }
+ fun addView() {
+ var token= SharedPreferencesHelper.getValue("jwt", this).toString()
+ val Api= RetrofitHelper.getInstance()
+ val request=Api.addView("Bearer "+token,post._id)
+ request.enqueue(object : retrofit2.Callback<PostPreview?> {
+ override fun onResponse(call: Call<PostPreview?>, response: Response<PostPreview?>) {
+
+ }
+
+ override fun onFailure(call: Call<PostPreview?>, t: Throwable) {
+
+ }
+ })
+ }
+
+ fun translateOwnerIdToName(id:String) {
+ var token= SharedPreferencesHelper.getValue("jwt", this).toString()
+ val api= RetrofitHelper.getInstance()
+ val request= api.getProfileFromId("Bearer " + token, id)
+ request.enqueue(object : retrofit2.Callback<UserReceive> {
+ override fun onResponse(call: Call<UserReceive>,
+ response: Response<UserReceive>) {
+ if (response.body() == null) {
+ return
+ }
+ userData = response.body()!!
+ binding.tvUser.text= userData!!.username.toString()
+ }
+
+ override fun onFailure(call: Call<UserReceive>, t: Throwable) {
+
+ }
+ })
}
}
diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ActivityUserProfile.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ActivityUserProfile.kt
new file mode 100644
index 0000000..50c2b0e
--- /dev/null
+++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ActivityUserProfile.kt
@@ -0,0 +1,49 @@
+package com.example.brzodolokacije.Activities
+
+import android.os.Bundle
+import android.widget.ImageView
+import android.widget.TextView
+import androidx.appcompat.app.AppCompatActivity
+import com.bumptech.glide.Glide
+import com.example.brzodolokacije.Models.UserReceive
+import com.example.brzodolokacije.R
+import com.example.brzodolokacije.Services.RetrofitHelper
+import com.google.gson.Gson
+
+class ActivityUserProfile : AppCompatActivity() {
+ private lateinit var name:TextView
+ private lateinit var postsNumber:TextView
+ private lateinit var followersNumber:TextView
+ private lateinit var followingNumber:TextView
+ private lateinit var profilePicture:ImageView
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_user_profile)
+
+ name=findViewById(R.id.tvActivityUserProfileName)
+ postsNumber=findViewById(R.id.tvActivityUserProfilePostsNo)
+ followersNumber=findViewById(R.id.tvActivityUserProfileFollowersNo)
+ followingNumber=findViewById(R.id.tvActivityUserProfileFollowNo)
+ profilePicture=findViewById(R.id.tvActivityProfileProfilePicture)
+ val jsonMyObject: String
+ val extras = intent.extras
+ if (extras != null) {
+ jsonMyObject = extras.getString("user")!!
+ val myObject: UserReceive = Gson().fromJson(jsonMyObject, UserReceive::class.java)
+
+ name.text=myObject.name
+ postsNumber.text=myObject.postNumber.toString()
+ followersNumber.text="0"
+ followingNumber.text="0"
+
+ if(myObject.pfp!=null) {
+ Glide.with(this)
+ .load(RetrofitHelper.baseUrl + "/api/post/image/" + myObject.pfp!!._id)
+ .circleCrop()//Round image
+ .into(profilePicture)
+ }
+ }
+
+ }
+} \ 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
new file mode 100644
index 0000000..e99142a
--- /dev/null
+++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ChatActivity.kt
@@ -0,0 +1,123 @@
+package com.example.brzodolokacije.Activities
+
+import android.content.Intent
+import android.os.Bundle
+import android.widget.ImageButton
+import android.widget.Toast
+import androidx.appcompat.app.AppCompatActivity
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
+import com.auth0.android.jwt.JWT
+import com.exam.DBHelper
+import com.example.brzodolokacije.Adapters.ChatPreviewsAdapter
+import com.example.brzodolokacije.Models.ChatPreview
+import com.example.brzodolokacije.Models.Message
+import com.example.brzodolokacije.Models.MessageReceive
+import com.example.brzodolokacije.R
+import com.example.brzodolokacije.Services.RetrofitHelper
+import com.example.brzodolokacije.Services.SharedPreferencesHelper
+import com.example.brzodolokacije.chat.SignalRListener
+import com.example.brzodolokacije.databinding.ActivityChatBinding
+import retrofit2.Call
+import retrofit2.Response
+
+class ChatActivity : AppCompatActivity(), SwipeRefreshLayout.OnRefreshListener {
+
+ 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<ChatPreview>?= mutableListOf()
+ private var swipeRefreshLayout: SwipeRefreshLayout?=null
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ binding= ActivityChatBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+ dbConnection= DBHelper(this@ChatActivity,null)
+ ws=SignalRListener.getInstance(this@ChatActivity)
+ setListeners()
+ setRecyclerView()
+ requestNewMessages()
+ swipeRefreshLayout = binding.swipeContainer
+ swipeRefreshLayout?.setOnRefreshListener(this@ChatActivity)
+ swipeRefreshLayout?.setColorSchemeResources(
+ R.color.purple_200,
+ R.color.teal_200,
+ R.color.dark_blue_transparent,
+ R.color.purple_700
+ )
+ swipeRefreshLayout?.post(kotlinx.coroutines.Runnable {
+ swipeRefreshLayout?.isRefreshing=true
+ requestNewMessages()
+ })
+
+ }
+ fun setListeners(){
+ findViewById<ImageButton>(R.id.addNewMessage).setOnClickListener {
+ val intent: Intent = Intent(this@ChatActivity,ChatActivityConversation::class.java)
+ intent.putExtra("receiverId","")
+ startActivity(intent)
+ }
+ }
+
+ fun requestForChats(){
+ var dbHelper= DBHelper.getInstance(this@ChatActivity)
+ items=dbHelper.getContacts()
+ adapterVar= items?.let { ChatPreviewsAdapter(it,this@ChatActivity) }
+ setRecyclerView(setParams = false)
+ }
+
+ fun requestNewMessages(){
+ val api=RetrofitHelper.getInstance()
+ val token=SharedPreferencesHelper.getValue("jwt",this@ChatActivity)
+ val request2=api?.getNewMessages("Bearer "+token)
+ request2?.enqueue(object : retrofit2.Callback<MutableList<MessageReceive>?> {
+ override fun onResponse(call: Call<MutableList<MessageReceive>?>, response: Response<MutableList<MessageReceive>?>) {
+ if(response.isSuccessful()){
+ var messages=response.body()
+ if(!messages.isNullOrEmpty()){
+ var dbHelper= DBHelper.getInstance(this@ChatActivity)
+ for( message in messages){
+ dbHelper.addMessage(
+ Message(message.senderId+message.timestamp,message.senderId,
+ JWT(SharedPreferencesHelper.getValue("jwt",this@ChatActivity)!!).claims["id"]?.asString()!!,message.messagge,message.timestamp),false)
+ }
+ }
+ requestForChats()
+ }
+ else{
+ Toast.makeText(this@ChatActivity,"los id",
+ Toast.LENGTH_LONG).show()
+ requestForChats()
+ }
+ }
+
+ override fun onFailure(call: Call<MutableList<MessageReceive>?>, t: Throwable) {
+ Toast.makeText(this@ChatActivity,"neuspesan zahtev",
+ Toast.LENGTH_LONG).show()
+ requestForChats()
+ }
+ })
+
+ }
+
+ fun setRecyclerView(setParams:Boolean=true){
+ if(setParams){
+ adapterVar= items?.let { ChatPreviewsAdapter(it,this@ChatActivity) }
+ layoutVar=LinearLayoutManager(this@ChatActivity)
+ }
+ recyclerView=binding.rvMain
+ recyclerView?.setHasFixedSize(true)
+ recyclerView?.layoutManager=layoutVar
+ recyclerView?.adapter=adapterVar
+ swipeRefreshLayout?.isRefreshing=false
+ }
+
+ override fun onRefresh() {
+ requestNewMessages()
+ }
+} \ No newline at end of file
diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ChatActivityConversation.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ChatActivityConversation.kt
new file mode 100644
index 0000000..4bd72bc
--- /dev/null
+++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ChatActivityConversation.kt
@@ -0,0 +1,175 @@
+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.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import com.auth0.android.jwt.JWT
+import com.exam.DBHelper
+import com.example.brzodolokacije.Adapters.ChatMessagesAdapter
+import com.example.brzodolokacije.Models.Message
+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.SignalRListener
+import com.example.brzodolokacije.databinding.ActivityChatConversationBinding
+import retrofit2.Call
+import retrofit2.Response
+
+class ChatActivityConversation : AppCompatActivity() {
+
+ var recyclerView:RecyclerView?=null
+ var adapterVar: ChatMessagesAdapter?=null
+ var layoutVar: RecyclerView.LayoutManager?=null
+ lateinit var binding:ActivityChatConversationBinding
+ var userId:String?=null
+ var receiverUsername:String?=null
+ var dbConnection: DBHelper?=null
+ var webSocketConnection:SignalRListener?=null
+ var items:MutableList<Message>?=mutableListOf()
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ binding= ActivityChatConversationBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+ userId=intent.extras?.get("userId").toString()
+ receiverUsername=intent.extras?.get("username").toString()
+ dbConnection=DBHelper.getInstance(this@ChatActivityConversation)
+ setHeader()
+ setRecyclerView()
+ requestMessages()
+ webSocketConnection=SignalRListener.getInstance(this@ChatActivityConversation)
+ setListeners()
+ }
+
+ 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()
+ Log.d("main",token!!)
+ 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()
+ dbConnection?.addMessage(responseMessage!!)
+ requestMessages()
+ binding.etNewMessage.text?.clear()
+
+ }
+ 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<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()
+ dbConnection?.addMessage(responseMessage!!)
+ requestMessages()
+ binding.etNewMessage.text?.clear()
+ }
+ else{
+ 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()
+ }
+ })
+ }
+ }
+
+ }
+
+ private fun setHeader(){
+ if(userId.isNullOrEmpty() || userId.equals("null")){
+ binding.cvParentUsername.visibility= View.VISIBLE
+ binding.cvParentUsername.forceLayout()
+ binding.tvFragmentTitle.visibility= View.GONE
+ binding.tvFragmentTitle.invalidate()
+ binding.tvFragmentTitle.forceLayout()
+ }
+ else{
+ binding.tvFragmentTitle.visibility= View.VISIBLE
+ binding.tvFragmentTitle.invalidate()
+ binding.tvFragmentTitle.forceLayout()
+ binding.tvFragmentTitle.text=receiverUsername
+ binding.tvFragmentTitle.invalidate()
+ binding.cvParentUsername.visibility= View.GONE
+ 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
+ recyclerView?.scrollToPosition(items?.size?.minus(1) ?: 0)
+ }
+
+ fun requestMessages(){
+ if(!userId.isNullOrEmpty() && !userId.equals("null")){
+ if(userId!= JWT(SharedPreferencesHelper.getValue("jwt",this@ChatActivityConversation)!!).claims["id"]?.asString())
+ items=dbConnection?.getMessages(userId!!)
+ else
+ items=dbConnection?.getMessages(userId!!,self = true)
+ }
+ adapterVar= items?.let { ChatMessagesAdapter(it,this@ChatActivityConversation) }
+ setRecyclerView(setParams = false)
+
+ }
+} \ No newline at end of file
diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/MapsActivity.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/MapsActivity.kt
index b9205f6..1ff07f6 100644
--- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/MapsActivity.kt
+++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/MapsActivity.kt
@@ -1,49 +1,370 @@
package com.example.brzodolokacije.Activities
-import androidx.appcompat.app.AppCompatActivity
+import android.Manifest
+import android.content.Context
+import android.content.pm.PackageManager
+import android.location.Location
+import android.location.LocationManager
+import android.os.Build
import android.os.Bundle
-
-import com.google.android.gms.maps.CameraUpdateFactory
-import com.google.android.gms.maps.GoogleMap
-import com.google.android.gms.maps.OnMapReadyCallback
-import com.google.android.gms.maps.SupportMapFragment
-import com.google.android.gms.maps.model.LatLng
-import com.google.android.gms.maps.model.MarkerOptions
+import android.os.Looper
+import android.os.StrictMode
+import android.preference.PreferenceManager
+import android.util.DisplayMetrics
+import android.util.Log
+import android.view.KeyEvent
+import android.view.MotionEvent
+import android.view.View
+import android.widget.TextView
+import android.widget.Toast
+import androidx.appcompat.app.AppCompatActivity
+import androidx.core.app.ActivityCompat
+import androidx.core.content.ContextCompat
import com.example.brzodolokacije.R
-import com.example.brzodolokacije.databinding.ActivityMapsBinding
+import com.example.brzodolokacije.Services.GeocoderHelper
+import com.google.android.gms.location.*
+import com.google.android.material.button.MaterialButton
+import com.google.android.material.floatingactionbutton.FloatingActionButton
+import com.google.android.material.textfield.TextInputEditText
+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.Projection
+import org.osmdroid.views.overlay.ItemizedIconOverlay
+import org.osmdroid.views.overlay.Overlay
+import org.osmdroid.views.overlay.OverlayItem
+import org.osmdroid.views.overlay.ScaleBarOverlay
+import org.osmdroid.views.overlay.compass.CompassOverlay
+import org.osmdroid.views.overlay.compass.InternalCompassOrientationProvider
+import org.osmdroid.views.overlay.gestures.RotationGestureOverlay
+import org.osmdroid.views.overlay.mylocation.GpsMyLocationProvider
+import org.osmdroid.views.overlay.mylocation.MyLocationNewOverlay
-class MapsActivity : AppCompatActivity(), OnMapReadyCallback {
-
- private lateinit var mMap: GoogleMap
- private lateinit var binding: ActivityMapsBinding
+class MapsActivity : AppCompatActivity() {
+ var map: MapView? = null
+ var mLocationOverlay: MyLocationNewOverlay?=null
+ var mRotationGestureOverlay: RotationGestureOverlay?=null
+ var mScaleBarOverlay: ScaleBarOverlay?=null
+ var mCompassOverlay: CompassOverlay?=null
+ private lateinit var locationManager: LocationManager
+ private lateinit var searchButton: MaterialButton
+ private lateinit var gpsButton: FloatingActionButton
+ private lateinit var confirmButton: FloatingActionButton
+ private lateinit var searchBar: TextInputEditText
+ var client: FusedLocationProviderClient? = null
+ var locLongitude:Double?=null
+ var locLatitude:Double?=null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_maps)
+
+ val ctx: Context = this
+ Configuration.getInstance().load(ctx, PreferenceManager.getDefaultSharedPreferences(ctx));
+ map= findViewById<MapView>(R.id.ActivityMapsMapView)
+ map!!.setTileSource(TileSourceFactory.MAPNIK);
+ setUpMap()
+ searchButton=findViewById<View>(R.id.ActivityMapsSearchButton) as MaterialButton
+ gpsButton=findViewById<View>(R.id.ActivityMapsMyLocation) as FloatingActionButton
+ confirmButton=findViewById<View>(R.id.ActivityMapsConfirmLocation) as FloatingActionButton
+ searchBar=findViewById<View>(R.id.ActivityMapsSearchBar) as TextInputEditText
+ client= LocationServices.getFusedLocationProviderClient(this)
+ searchButton.setOnClickListener{
+ searchMap()
+
+ }
+ gpsButton.setOnClickListener{
+ getLocation()
+ }
+ confirmButton.setOnClickListener{
+ if(locLatitude!=null && locLatitude!=null)
+ returnValue()
+ }
+ 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
+ searchMap()
+ return@OnKeyListener true
+ }
+ false
+ })
+ val extras = intent.extras
+ if (extras != null) {
+ val value = extras.getString("search")
+ Log.d("Main",value!!)
+ searchBar.setText(value,TextView.BufferType.EDITABLE)
+ searchMap()
+ }
+
+
+
+ }
+ fun returnValue(){
+ val intent = intent
+ val bundle = Bundle()
+ bundle.putDouble("longitude", locLongitude!!)
+ bundle.putDouble("latitude", locLatitude!!)
+ if(searchBar.text!=null && !searchBar.text.toString().equals(""))
+ bundle.putString("name", searchBar.text.toString())
+ intent.putExtras(bundle)
+ setResult(RESULT_OK, intent)
+ finish()
+ }
+
+ override fun onResume() {
+ super.onResume()
+ map!!.onResume()
+ }
+ override fun onPause() {
+ super.onPause()
+ map!!.onPause()
+ }
+ fun setUpMap(){
+ //Set up controlls and startPoint
+ map!!.setBuiltInZoomControls(true);
+ map!!.setMultiTouchControls(true);
+ val mapController = map!!.controller
+ mapController.setZoom(15)
+ fixNetworkPolicy()
+
+ //my location
+ //checkLocPerm()
+ mLocationOverlay = MyLocationNewOverlay(GpsMyLocationProvider(this), map)
+ mLocationOverlay!!.enableMyLocation()
+ map!!.getOverlays().add(this.mLocationOverlay)
+
+ //start point
+ val startPoint = GeoPoint(44.0107,20.9181)//dodati nasu lokaciju TODO
+ mapController.setCenter(startPoint)
+
+ //rotation gestures
+ mRotationGestureOverlay = RotationGestureOverlay(this, map)
+ mRotationGestureOverlay!!.setEnabled(true)
+ map!!.setMultiTouchControls(true)
+ map!!.getOverlays().add(this.mRotationGestureOverlay)
+ //Map scale bar
+ val dm: DisplayMetrics =this.resources.displayMetrics
+ mScaleBarOverlay = ScaleBarOverlay(map);
+ mScaleBarOverlay!!.setCentred(true);
+ mScaleBarOverlay!!.setScaleBarOffset(dm.widthPixels / 2, 10);
+ map!!.getOverlays().add(this.mScaleBarOverlay);
+
+ //Compass
+ this.mCompassOverlay =
+ CompassOverlay(this, InternalCompassOrientationProvider(this), map)
+ mCompassOverlay!!.enableCompass()
+ map!!.getOverlays().add(this.mCompassOverlay)
- binding = ActivityMapsBinding.inflate(layoutInflater)
- setContentView(binding.root)
-
- // Obtain the SupportMapFragment and get notified when the map is ready to be used.
- val mapFragment = supportFragmentManager
- .findFragmentById(R.id.map) as SupportMapFragment
- mapFragment.getMapAsync(this)
- }
-
- /**
- * Manipulates the map once available.
- * This callback is triggered when the map is ready to be used.
- * This is where we can add markers or lines, add listeners or move the camera. In this case,
- * we just add a marker near Sydney, Australia.
- * If Google Play services is not installed on the device, the user will be prompted to install
- * it inside the SupportMapFragment. This method will only be triggered once the user has
- * installed Google Play services and returned to the app.
- */
- override fun onMapReady(googleMap: GoogleMap) {
- mMap = googleMap
-
- // Add a marker in Sydney and move the camera
- val sydney = LatLng(-34.0, 151.0)
- mMap.addMarker(MarkerOptions().position(sydney).title("Marker in Sydney"))
- mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney))
+
+ val touchOverlay: Overlay = object : Overlay(this) {
+ var anotherItemizedIconOverlay: ItemizedIconOverlay<OverlayItem>? = null
+ override fun onSingleTapConfirmed(e: MotionEvent, mapView: MapView): Boolean {
+ val marker = ContextCompat.getDrawable(this@MapsActivity, R.drawable.ic_baseline_add_location_24);
+ val proj: Projection = mapView.projection
+ val loc = proj.fromPixels(e.x.toInt(), e.y.toInt())
+ val longitude = java.lang.Double.toString(loc.longitudeE6.toDouble() / 1000000)
+ val latitude = java.lang.Double.toString(loc.latitudeE6.toDouble() / 1000000)
+ locLongitude=loc.longitude
+ locLatitude=loc.latitude
+ Log.d("main"," "+locLongitude)
+ Log.d("main"," "+locLatitude)
+ val overlayArray = ArrayList<OverlayItem>()
+ val mapItem = OverlayItem(
+ "", "", GeoPoint(
+ loc.latitudeE6.toDouble() / 1000000,
+ loc.longitudeE6.toDouble() / 1000000
+ )
+ )
+ mapItem.setMarker(marker)
+ overlayArray.add(mapItem)
+ if (anotherItemizedIconOverlay == null) {
+ anotherItemizedIconOverlay =
+ ItemizedIconOverlay(applicationContext, overlayArray, null)
+ mapView.overlays.add(anotherItemizedIconOverlay)
+ mapView.invalidate()
+ } else {
+ mapView.overlays.remove(anotherItemizedIconOverlay)
+ mapView.invalidate()
+ anotherItemizedIconOverlay =
+ ItemizedIconOverlay(applicationContext, overlayArray, null)
+ mapView.overlays.add(anotherItemizedIconOverlay)
+ }
+ // dlgThread();
+ confirmButton.visibility=View.VISIBLE
+ return true
+ }
+ }
+ map!!.getOverlays().add(touchOverlay)
+ }
+ fun checkLocPerm(){
+ if (ContextCompat.checkSelfPermission(
+ this,
+ Manifest.permission.ACCESS_FINE_LOCATION
+ )
+ != PackageManager.PERMISSION_GRANTED
+ ) {
+ ActivityCompat.requestPermissions(
+ this,
+ arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
+ 101
+ )
+ }
+ }
+
+ fun fixNetworkPolicy(){
+ val SDK_INT = Build.VERSION.SDK_INT
+ if (SDK_INT > 8) {
+ val policy = StrictMode.ThreadPolicy.Builder()
+ .permitAll().build()
+ StrictMode.setThreadPolicy(policy)
+ //your codes here
+ }
+ }
+ fun searchMap(){
+ var geocoder= GeocoderHelper.getInstance()
+ //Log.d("Main",geocoder!!.getFromLocationName("Paris",1)[0].countryName)
+ var locString=searchBar.text.toString().trim()
+ if(locString==null || locString=="")
+ Toast.makeText(this,"Unesite naziv lokacije", Toast.LENGTH_LONG)
+ else{
+ var temp=geocoder!!.getFromLocationName(locString,1)
+ if(temp.size<=0) {
+ Toast.makeText(this,"Nepostojeca lokacija",Toast.LENGTH_LONG)
+ return
+ }
+ var result=temp[0]
+ if(result==null)
+ Toast.makeText(this,"Nepostojeca lokacija", Toast.LENGTH_LONG)
+ else{
+ //Move to spot
+ val searchPoint = GeoPoint(result.latitude,result.longitude)
+ map!!.controller.animateTo(searchPoint)
+
+
+ }
+ }
+ }
+ private fun getLocation() {
+ if (ContextCompat.checkSelfPermission(
+ this,
+ Manifest.permission
+ .ACCESS_FINE_LOCATION)
+ == PackageManager
+ .PERMISSION_GRANTED
+ && ContextCompat.checkSelfPermission(
+ this,
+ Manifest.permission
+ .ACCESS_COARSE_LOCATION)
+ == PackageManager
+ .PERMISSION_GRANTED) {
+ // When permission is granted
+ // Call method
+ getCurrentLocation()
+ }
+ else {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+ requestPermissions(
+ arrayOf(
+ Manifest.permission.ACCESS_FINE_LOCATION,
+ Manifest.permission.ACCESS_COARSE_LOCATION
+ ),
+ 111
+ )
+ }
+
+ }
+ }
+ override fun onRequestPermissionsResult(
+ requestCode: Int, permissions: Array<String?>,
+ grantResults: IntArray
+ ) {
+ super.onRequestPermissionsResult(
+ requestCode, permissions, grantResults
+ )
+ // Check condition
+ if (requestCode == 111 && grantResults.size > 0
+ && (grantResults[0] + grantResults[1]
+ == PackageManager.PERMISSION_GRANTED)
+ ) {
+ // When permission are granted
+ // Call method
+ getCurrentLocation()
+ } else {
+ // When permission are denied
+ // Display toast
+ Toast
+ .makeText(
+ this,
+ "Permission denied",
+ Toast.LENGTH_SHORT
+ )
+ .show()
+ }
+ }
+ @Suppress("MissingPermission")
+ private fun getCurrentLocation() {
+ val locationManager = this
+ .getSystemService(
+ Context.LOCATION_SERVICE
+ ) as LocationManager
+ checkLocPerm()
+ if (locationManager.isProviderEnabled(
+ LocationManager.GPS_PROVIDER
+ )
+ || locationManager.isProviderEnabled(
+ LocationManager.NETWORK_PROVIDER
+ )
+ ) {
+
+ client!!.getLastLocation().addOnCompleteListener { task ->
+ var location = task.result
+ if (location == null) {
+ val locationRequest: LocationRequest = LocationRequest()
+ .setPriority(
+ LocationRequest.PRIORITY_HIGH_ACCURACY
+ )
+ .setInterval(10000)
+ .setFastestInterval(
+ 1000
+ )
+ .setNumUpdates(1)
+
+ val locationCallback: LocationCallback = object : LocationCallback() {
+ override fun onLocationResult(
+ locationResult: LocationResult
+ ) {
+ // Initialize
+ // location
+ val location1: Location? = locationResult
+ .lastLocation
+ // Set latitude
+ map!!.controller.animateTo(
+ GeoPoint(
+ location1!!.latitude,
+ location1!!.longitude
+ )
+ )
+
+ }
+ }
+ client!!.requestLocationUpdates(
+ locationRequest,
+ locationCallback,
+ Looper.myLooper()
+ );
+ } else {
+ map!!.controller.animateTo(GeoPoint(location!!.latitude, location!!.longitude))
+ }
+
+
+ }
+ }
+ }
+ override fun onBackPressed() {
+ super.onBackPressed()
+ finish()
}
} \ No newline at end of file
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 604b373..180b59d 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
@@ -37,7 +37,7 @@ class NavigationActivity : AppCompatActivity() {
R.id.navHomePage->setCurrentFragment(fragmentHomePage)
R.id.navAllPosts->setCurrentFragment(fragmentShowPosts)
//R.id.navAddPost->setCurrentFragment(addPostFragment)
- R.id.navAddPost->showBottomSheetAddNew()
+ R.id.navAddPost->showBottomSheetAddPost()
R.id.navBrowse->setCurrentFragment(browseFragment)
R.id.navProfile->setCurrentFragment(profileFragment)
diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/SplashPage.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/SplashPage.kt
index 3d2f923..4faf067 100644
--- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/SplashPage.kt
+++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/SplashPage.kt
@@ -8,7 +8,7 @@ import com.example.brzodolokacije.MainActivity
import com.example.brzodolokacije.R
class SplashPage : AppCompatActivity() {
- private val time:Long = 4000
+ private val time:Long = 2000
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
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..45ffbf0
--- /dev/null
+++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/ChatMessagesAdapter.kt
@@ -0,0 +1,77 @@
+package com.example.brzodolokacije.Adapters
+
+import android.app.Activity
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.auth0.android.jwt.JWT
+import com.example.brzodolokacije.Models.Message
+import com.example.brzodolokacije.Services.SharedPreferencesHelper
+import com.example.brzodolokacije.databinding.ChatMessageBinding
+import com.example.brzodolokacije.databinding.ChatMessageOtherBinding
+
+class ChatMessagesAdapter (val items : MutableList<Message>, val activity:Activity)
+ : RecyclerView.Adapter<RecyclerView.ViewHolder>(){
+ //constructer has one argument - list of objects that need to be displayed
+ //it is bound to xml of single item
+ private val VIEW_TYPE_MESSAGE_SENT: Int = 1
+ private val VIEW_TYPE_MESSAGE_RECEIVED:Int = 2
+ private var binding: ChatMessageBinding?=null
+ private var bindingOther: ChatMessageOtherBinding?=null
+
+ private var currentUser:String?=null
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
+ val inflater = LayoutInflater.from(parent.context)
+
+
+ if(viewType==VIEW_TYPE_MESSAGE_RECEIVED){
+ bindingOther= ChatMessageOtherBinding.inflate(inflater,parent,false)
+ return ReceivedViewHolder(bindingOther!!)
+ }
+ else{
+ binding= ChatMessageBinding.inflate(inflater,parent,false)
+ return SentViewHolder(binding!!)
+ }
+
+ }
+ override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int){
+ //sets components of particular item
+ if(holder is ReceivedViewHolder){
+ holder.bind(items[position])
+ }
+ else if(holder is SentViewHolder){
+ holder.bind(items[position])
+ }
+ }
+ override fun getItemCount() = items.size
+ inner class ReceivedViewHolder(itemView : ChatMessageOtherBinding) : RecyclerView.ViewHolder(itemView.root){
+ fun bind(item : Message){
+ bindingOther?.apply {
+ tvMessage?.text=item.messagge
+ }
+ }
+ }
+ inner class SentViewHolder(itemView : ChatMessageBinding) : RecyclerView.ViewHolder(itemView.root){
+ fun bind(item : Message){
+ binding?.apply {
+ tvMessage.text=item.messagge
+ }
+ }
+ }
+
+
+ override fun getItemViewType(position: Int): Int {
+ var sender=items.get(position).senderId
+ var token= SharedPreferencesHelper.getValue("jwt",activity)
+ var jwt= JWT(token.toString())
+ var claim=jwt.getClaim("id")
+ currentUser= claim.asString()!!
+ if(sender==currentUser){
+ return VIEW_TYPE_MESSAGE_SENT
+ }
+ else{
+ return VIEW_TYPE_MESSAGE_RECEIVED
+ }
+ }
+} \ 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..94a72f3
--- /dev/null
+++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/ChatPreviewsAdapter.kt
@@ -0,0 +1,79 @@
+package com.example.brzodolokacije.Adapters
+
+import android.app.Activity
+import android.content.Intent
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import android.widget.Toast
+import androidx.recyclerview.widget.RecyclerView
+import com.bumptech.glide.Glide
+import com.example.brzodolokacije.Activities.ChatActivityConversation
+import com.example.brzodolokacije.Interfaces.IBackendApi
+import com.example.brzodolokacije.Models.ChatPreview
+import com.example.brzodolokacije.Models.UserReceive
+import com.example.brzodolokacije.Services.RetrofitHelper
+import com.example.brzodolokacije.Services.SharedPreferencesHelper
+import com.example.brzodolokacije.databinding.ChatPreviewBinding
+import kotlinx.android.synthetic.main.chat_preview.view.*
+import retrofit2.Call
+import retrofit2.Response
+
+class ChatPreviewsAdapter (val items : MutableList<ChatPreview>,val activity:Activity)
+ : RecyclerView.Adapter<ChatPreviewsAdapter.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: ChatPreviewBinding
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ val inflater = LayoutInflater.from(parent.context)
+ binding=ChatPreviewBinding.inflate(inflater,parent,false)
+ api=RetrofitHelper.getInstance()
+ token=SharedPreferencesHelper.getValue("jwt",activity)
+ return ViewHolder(binding)
+ }
+ override fun onBindViewHolder(holder: ViewHolder, position: Int){
+ //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)
+ intent.putExtra("username",holder.itemView.tvUsername.text)
+ activity.startActivity(intent)
+ }
+ }
+ override fun getItemCount() = items.size
+ inner class ViewHolder(itemView : ChatPreviewBinding) : RecyclerView.ViewHolder(itemView.root){
+ fun bind(item : ChatPreview){
+ binding.apply {
+ 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()){
+ //zahtev da se posalje poruka
+ var user=response.body()!!
+ tvUsername.text=user.username
+ if(user.pfp!=null) {
+ Glide.with(activity)
+ .load(RetrofitHelper.baseUrl + "/api/post/image/" + user.pfp!!._id)
+ .into(ivUserImage)
+ }
+ }
+ else{
+ Toast.makeText(activity,"los id",
+ Toast.LENGTH_LONG).show()
+ tvUsername.text="nije nadjen korisnik"
+ }
+ }
+
+ override fun onFailure(call: Call<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/Adapters/FollowersAdapter.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/FollowersAdapter.kt
new file mode 100644
index 0000000..e439d0e
--- /dev/null
+++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/FollowersAdapter.kt
@@ -0,0 +1,42 @@
+package com.example.brzodolokacije.Adapters
+
+import android.app.Activity
+import android.util.Log
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.TextView
+import androidx.recyclerview.widget.RecyclerView
+import com.bumptech.glide.Glide
+import com.example.brzodolokacije.Models.PostPreview
+import com.example.brzodolokacije.Models.User
+import com.example.brzodolokacije.Models.UserReceive
+import com.example.brzodolokacije.R
+import com.example.brzodolokacije.Services.RetrofitHelper
+
+class FollowersAdapter (var followers:MutableList<UserReceive>, val activity: Activity):
+ RecyclerView.Adapter<FollowersAdapter.FollowerViewHolder>() {
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FollowersAdapter.FollowerViewHolder {
+ val view= LayoutInflater.from(parent.context).inflate(R.layout.follower_item,parent,false)
+ return FollowerViewHolder(view)
+ }
+
+ override fun onBindViewHolder(holder: FollowersAdapter.FollowerViewHolder, position: Int) {
+ return holder.bindView(followers[position] )
+ }
+
+ override fun getItemCount(): Int {
+ return followers.size
+ }
+
+
+ inner class FollowerViewHolder(view: View): RecyclerView.ViewHolder(view){
+
+ private val name: TextView =view.findViewById(R.id.tvFollowerItemName)
+ private val username:TextView=view.findViewById(R.id.tvFolloewItemUsername)
+ fun bindView(follower: UserReceive){
+ name.text=follower.name
+ username.text=follower.username
+ }
+ }
+} \ No newline at end of file
diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/MyPostsAdapter.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/MyPostsAdapter.kt
new file mode 100644
index 0000000..1b57e5b
--- /dev/null
+++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/MyPostsAdapter.kt
@@ -0,0 +1,75 @@
+package com.example.brzodolokacije.Adapters
+
+import android.app.Activity
+import android.content.Intent
+import android.graphics.BitmapFactory
+import android.os.AsyncTask
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import android.widget.Toast
+import androidx.recyclerview.widget.RecyclerView
+import com.bumptech.glide.Glide
+import com.example.brzodolokacije.Activities.ActivitySinglePost
+import com.example.brzodolokacije.Interfaces.IBackendApi
+import com.example.brzodolokacije.Models.LocationType
+import com.example.brzodolokacije.Models.PostPreview
+import com.example.brzodolokacije.Services.RetrofitHelper
+import com.example.brzodolokacije.Services.SharedPreferencesHelper
+import com.example.brzodolokacije.databinding.PostPreviewBinding
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
+import okhttp3.ResponseBody
+import retrofit2.Call
+import retrofit2.Response
+
+
+class MyPostsAdapter (val activity:Activity,val items : MutableList<PostPreview>)
+ : RecyclerView.Adapter<MyPostsAdapter.ViewHolder>() {
+ private lateinit var token: String
+ private lateinit var imageApi: IBackendApi
+
+ //constructer has one argument - list of objects that need to be displayed
+ //it is bound to xml of single item
+ private lateinit var binding: PostPreviewBinding
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ val inflater = LayoutInflater.from(parent.context)
+ imageApi= RetrofitHelper.getInstance()
+ token= SharedPreferencesHelper.getValue("jwt", activity).toString()
+ binding = PostPreviewBinding.inflate(inflater, parent, false)
+ return ViewHolder(binding)
+ }
+
+
+
+
+ override fun getItemCount() = items.size
+ inner class ViewHolder(itemView: PostPreviewBinding) : RecyclerView.ViewHolder(itemView.root) {
+ fun bind(item: PostPreview) {
+ binding.apply {
+ tvTitle.text = item.location.name
+ tvLocationParent.text = item.location.country
+ tvLocationType.text = "TODO"
+ if(item.images.isNotEmpty()) {
+ Glide.with(activity)
+ .load(RetrofitHelper.baseUrl + "/api/post/image/" + item.images[0]._id)
+ .into(locationImage)
+ }
+
+ }
+ }
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+ holder.bind(items[position])
+ holder.itemView.setOnClickListener {
+ //Toast.makeText(activity,item._id,Toast.LENGTH_LONG).show()
+ val intent:Intent = Intent(activity,ActivitySinglePost::class.java)
+ var b=Bundle()
+ items[position].location.type=LocationType.ADA
+ b.putParcelable("selectedPost", items[position])
+ intent.putExtras(b)
+ activity.startActivity(intent)
+ }
+ }
+}
diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/PostHistoryAdapter.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/PostHistoryAdapter.kt
new file mode 100644
index 0000000..db3fc2e
--- /dev/null
+++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/PostHistoryAdapter.kt
@@ -0,0 +1,61 @@
+package com.example.brzodolokacije.Adapters
+
+import android.app.Activity
+import android.content.Intent
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.example.brzodolokacije.Activities.ActivitySinglePost
+import com.example.brzodolokacije.Interfaces.IBackendApi
+import com.example.brzodolokacije.Models.LocationType
+import com.example.brzodolokacije.Models.PostPreview
+import com.example.brzodolokacije.Services.RetrofitHelper
+import com.example.brzodolokacije.Services.SharedPreferencesHelper
+import com.example.brzodolokacije.databinding.SinglePostHistoryBinding
+
+
+class PostHistoryAdapter (val activity:Activity,val items : MutableList<PostPreview>)
+ : RecyclerView.Adapter<PostHistoryAdapter.ViewHolder>() {
+ private lateinit var token: String
+ private lateinit var imageApi: IBackendApi
+
+ //constructer has one argument - list of objects that need to be displayed
+ //it is bound to xml of single item
+ private lateinit var binding: SinglePostHistoryBinding
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ val inflater = LayoutInflater.from(parent.context)
+ imageApi= RetrofitHelper.getInstance()
+ token= SharedPreferencesHelper.getValue("jwt", activity).toString()
+ binding = SinglePostHistoryBinding.inflate(inflater, parent, false)
+ return ViewHolder(binding)
+ }
+
+
+
+
+ override fun getItemCount() = items.size
+ inner class ViewHolder(itemView: SinglePostHistoryBinding) : RecyclerView.ViewHolder(itemView.root) {
+ fun bind(item: PostPreview) {
+ binding.apply {
+ tvTitleSinglePostHistory.text = item.location.name
+ tvLocationParentSinglePostHistory.text = "22.11.2022"
+ tvLocationTypeSinglePostHistory.text = item.location.country
+
+ }
+ }
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+ holder.bind(items[position])
+ holder.itemView.setOnClickListener {
+ //Toast.makeText(activity,item._id,Toast.LENGTH_LONG).show()
+ val intent:Intent = Intent(activity,ActivitySinglePost::class.java)
+ var b=Bundle()
+ items[position].location.type=LocationType.ADA
+ b.putParcelable("selectedPost", items[position])
+ intent.putExtras(b)
+ activity.startActivity(intent)
+ }
+ }
+}
diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/ShowPostsAdapter.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/ShowPostsAdapter.kt
index bbcf9e4..0bd625f 100644
--- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/ShowPostsAdapter.kt
+++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/ShowPostsAdapter.kt
@@ -8,9 +8,12 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.Toast
+import androidx.paging.PagingDataAdapter
+import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.example.brzodolokacije.Activities.ActivitySinglePost
+import com.example.brzodolokacije.Activities.NavigationActivity
import com.example.brzodolokacije.Interfaces.IBackendApi
import com.example.brzodolokacije.Models.LocationType
import com.example.brzodolokacije.Models.PostPreview
@@ -24,11 +27,24 @@ import retrofit2.Call
import retrofit2.Response
-class ShowPostsAdapter (val activity:Activity,val items : MutableList<PostPreview>)
- : RecyclerView.Adapter<ShowPostsAdapter.ViewHolder>() {
+class ShowPostsAdapter (val activity:Activity,val items : MutableList<PostPreview>?=null)
+ : PagingDataAdapter<PostPreview, ShowPostsAdapter.ViewHolder>(REPO_COMPARATOR) {
private lateinit var token: String
private lateinit var imageApi: IBackendApi
+ companion object{
+ private val REPO_COMPARATOR=object:DiffUtil.ItemCallback<PostPreview>(){
+ override fun areContentsTheSame(oldItem: PostPreview, newItem: PostPreview): Boolean {
+ return oldItem._id==newItem._id
+ }
+
+ override fun areItemsTheSame(oldItem: PostPreview, newItem: PostPreview): Boolean {
+ return oldItem._id==newItem._id
+ }
+ }
+ }
+
+
//constructer has one argument - list of objects that need to be displayed
//it is bound to xml of single item
private lateinit var binding: PostPreviewBinding
@@ -42,20 +58,20 @@ class ShowPostsAdapter (val activity:Activity,val items : MutableList<PostPrevie
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
//sets components of particular item
- holder.bind(items[position])
+ holder.bind(getItem(position)!!)
holder.itemView.setOnClickListener {
- //Toast.makeText(activity,item._id,Toast.LENGTH_LONG).show()
+ Toast.makeText(activity,getItem(position)!!._id,Toast.LENGTH_LONG).show()
val intent:Intent = Intent(activity,ActivitySinglePost::class.java)
var b=Bundle()
- items[position].location.type=LocationType.ADA
- b.putParcelable("selectedPost", items[position])
+ //getItem(position)!!.location.type=LocationType.ADA
+ //--------------------------------------------------------------- call back to add view tick
+ //---------------------------------------------------------------
+ b.putParcelable("selectedPost",getItem(position)!!)
intent.putExtras(b)
activity.startActivity(intent)
}
}
-
- override fun getItemCount() = items.size
inner class ViewHolder(itemView: PostPreviewBinding) : RecyclerView.ViewHolder(itemView.root) {
fun bind(item: PostPreview) {
binding.apply {
diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/ShowPostsHomePageAdapter.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/ShowPostsHomePageAdapter.kt
index c382cf7..3391355 100644
--- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/ShowPostsHomePageAdapter.kt
+++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/ShowPostsHomePageAdapter.kt
@@ -1,6 +1,8 @@
package com.example.brzodolokacije.Adapters
import android.app.Activity
+import android.content.Intent
+import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
@@ -9,6 +11,8 @@ import android.widget.TextView
import androidx.core.net.toUri
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
+import com.example.brzodolokacije.Activities.ActivitySinglePost
+import com.example.brzodolokacije.Models.LocationType
import com.example.brzodolokacije.Models.PostPreview
import com.example.brzodolokacije.R
import com.example.brzodolokacije.Services.RetrofitHelper
@@ -23,6 +27,15 @@ class ShowPostsHomePageAdapter(var postPreview:MutableList<PostPreview>,val acti
}
override fun onBindViewHolder(holder: PostViewHolder, position: Int) {
+ holder.itemView.setOnClickListener {
+ //Toast.makeText(activity,item._id,Toast.LENGTH_LONG).show()
+ val intent: Intent = Intent(activity, ActivitySinglePost::class.java)
+ var b= Bundle()
+ postPreview[position].location.type= LocationType.ADA
+ b.putParcelable("selectedPost", postPreview[position])
+ intent.putExtras(b)
+ activity.startActivity(intent)
+ }
return holder.bindView(postPreview[position] )
}
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 5ba3785..a21ffe0 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
@@ -166,11 +166,16 @@ class FragmentBrowse : Fragment(R.layout.fragment_browse) {
//Log.d("Main",geocoder!!.getFromLocationName("Paris",1)[0].countryName)
var locString=searchBar.text.toString().trim()
if(locString==null || locString=="")
- Toast.makeText(requireContext(),"Unesite naziv lokacije",Toast.LENGTH_SHORT)
+ Toast.makeText(requireContext(),"Unesite naziv lokacije",Toast.LENGTH_LONG)
else{
- var result=geocoder!!.getFromLocationName(locString,1)[0]
+ var temp=geocoder!!.getFromLocationName(locString,1)
+ if(temp.size<=0) {
+ Toast.makeText(requireContext(),"Nepostojeca lokacija",Toast.LENGTH_LONG)
+ return
+ }
+ var result=temp[0]
if(result==null)
- Toast.makeText(requireContext(),"Nepostojeca lokacija",Toast.LENGTH_SHORT)
+ Toast.makeText(requireContext(),"Nepostojeca lokacija",Toast.LENGTH_LONG)
else{
//move to spot
val searchPoint = GeoPoint(result.latitude,result.longitude)
diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentFollowers.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentFollowers.kt
new file mode 100644
index 0000000..f1d9321
--- /dev/null
+++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentFollowers.kt
@@ -0,0 +1,84 @@
+package com.example.brzodolokacije.Fragments
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import android.widget.Toast
+import androidx.fragment.app.Fragment
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import com.example.brzodolokacije.Adapters.FollowersAdapter
+import com.example.brzodolokacije.Adapters.ShowPostsHomePageAdapter
+import com.example.brzodolokacije.Interfaces.IBackendApi
+import com.example.brzodolokacije.Models.PostPreview
+import com.example.brzodolokacije.Models.UserReceive
+import com.example.brzodolokacije.R
+import com.example.brzodolokacije.Services.RetrofitHelper
+import com.example.brzodolokacije.Services.SharedPreferencesHelper
+import retrofit2.Call
+import retrofit2.Callback
+import retrofit2.Response
+import retrofit2.Retrofit
+import retrofit2.converter.gson.GsonConverterFactory
+
+class FragmentFollowers : Fragment() {
+ private lateinit var userId:String
+ private lateinit var followers: MutableList<UserReceive>
+ private lateinit var followersRv:RecyclerView
+ private lateinit var btnBack:ImageView
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ val view= inflater.inflate(R.layout.fragment_followers, container, false)
+ btnBack=view.findViewById(R.id.btnFragmentFollowersBack)
+ followersRv=view.findViewById(R.id.rvFragmentShowFollowers)
+
+ val bundle = this.arguments
+ if (bundle != null) {
+ userId= bundle.getString("userId").toString()
+ Toast.makeText(
+ activity, bundle.getString("userId"), Toast.LENGTH_LONG
+ ).show();
+ }
+
+ getFollowers()
+
+ btnBack.setOnClickListener {
+ val fragmentProfile = FragmentProfile()
+ fragmentManager?.beginTransaction()
+ ?.replace(com.example.brzodolokacije.R.id.flNavigationFragment,fragmentProfile)
+ ?.commit()
+ }
+
+ return view
+ }
+
+ fun getFollowers(){
+ val api = RetrofitHelper.getInstance()
+ val data=api.getFollowers(userId)
+ data.enqueue(object : Callback<MutableList<UserReceive>> {
+ override fun onResponse(
+ call: Call<MutableList<UserReceive>>,
+ response: Response<MutableList<UserReceive>>
+ ) {
+ if (response.body() == null) {
+ return
+ }
+ followers = response.body()!!.toMutableList<UserReceive>()
+ followersRv.apply {
+ layoutManager= LinearLayoutManager(activity, LinearLayoutManager.HORIZONTAL,false)
+ adapter= FollowersAdapter(followers,requireActivity())
+
+ }
+ }
+ override fun onFailure(call: Call<MutableList<UserReceive>>, t: Throwable) {
+ Toast.makeText(
+ activity,"nema pratilaca", Toast.LENGTH_LONG
+ ).show();
+ }
+ })
+ }
+} \ No newline at end of file
diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentFollowing.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentFollowing.kt
new file mode 100644
index 0000000..b7a40dc
--- /dev/null
+++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentFollowing.kt
@@ -0,0 +1,78 @@
+package com.example.brzodolokacije.Fragments
+
+import android.os.Bundle
+import androidx.fragment.app.Fragment
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import android.widget.Toast
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import com.example.brzodolokacije.Adapters.FollowersAdapter
+import com.example.brzodolokacije.Models.UserReceive
+import com.example.brzodolokacije.R
+import com.example.brzodolokacije.Services.RetrofitHelper
+import retrofit2.Call
+import retrofit2.Callback
+import retrofit2.Response
+
+class FragmentFollowing : Fragment() {
+ private lateinit var userId:String
+ private lateinit var following: MutableList<UserReceive>
+ private lateinit var followingRv: RecyclerView
+ private lateinit var back:ImageView
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ val view= inflater.inflate(R.layout.fragment_following, container, false)
+
+ followingRv=view.findViewById(R.id.rvFragmentShowFollowing)
+ back=view.findViewById(R.id.btnFragmentFollowingBack)
+ val bundle = this.arguments
+ if (bundle != null) {
+ userId= bundle.getString("userId").toString()
+ Toast.makeText(
+ activity, bundle.getString("userId"), Toast.LENGTH_LONG
+ ).show();
+ }
+
+ getFollowing()
+
+ back.setOnClickListener {
+ val fragmentProfile = FragmentProfile()
+ fragmentManager
+ ?.beginTransaction()
+ ?.replace(com.example.brzodolokacije.R.id.flNavigationFragment,fragmentProfile)
+ ?.commit()
+ }
+ return view
+ }
+
+ fun getFollowing(){
+ val api = RetrofitHelper.getInstance()
+ val data=api.getFollowers(userId)
+ data.enqueue(object : Callback<MutableList<UserReceive>> {
+ override fun onResponse(
+ call: Call<MutableList<UserReceive>>,
+ response: Response<MutableList<UserReceive>>
+ ) {
+ if (response.body() == null) {
+ return
+ }
+ following = response.body()!!.toMutableList<UserReceive>()
+ followingRv.apply {
+ layoutManager= LinearLayoutManager(activity, LinearLayoutManager.HORIZONTAL,false)
+ adapter= FollowersAdapter(following,requireActivity())
+
+ }
+ }
+ override fun onFailure(call: Call<MutableList<UserReceive>>, t: Throwable) {
+ Toast.makeText(
+ activity,"nema pracenja", Toast.LENGTH_LONG
+ ).show();
+ }
+ })
+ }
+} \ No newline at end of file
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 bde4dd2..cf811df 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
@@ -77,9 +77,6 @@ class FragmentHomePageMainScroll : Fragment() {
var fragment=FragmentShowPostsByLocation()
location_spa.setOnClickListener {
- Toast.makeText(
- activity, "BANJAAAAAAAAAAAAAAA", Toast.LENGTH_LONG
- ).show();
filter=LocationType.BANJA
filterString=filter.toString()
bundle.putString("data",filterString)
diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentMyRecensions.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentMyRecensions.kt
index ce8679a..c5fa6ec 100644
--- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentMyRecensions.kt
+++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentMyRecensions.kt
@@ -5,56 +5,69 @@ import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
+import androidx.recyclerview.widget.GridLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import com.example.brzodolokacije.Adapters.MyPostsAdapter
+import com.example.brzodolokacije.Adapters.PostHistoryAdapter
+import com.example.brzodolokacije.Models.PostPreview
import com.example.brzodolokacije.R
+import com.example.brzodolokacije.Services.RetrofitHelper
+import com.example.brzodolokacije.Services.SharedPreferencesHelper
+import retrofit2.Call
+import retrofit2.Callback
+import retrofit2.Response
-// TODO: Rename parameter arguments, choose names that match
-// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
-private const val ARG_PARAM1 = "param1"
-private const val ARG_PARAM2 = "param2"
-/**
- * A simple [Fragment] subclass.
- * Use the [FragmentMyRecensions.newInstance] factory method to
- * create an instance of this fragment.
- */
class FragmentMyRecensions : Fragment() {
- // TODO: Rename and change types of parameters
- private var param1: String? = null
- private var param2: String? = null
+
+ private lateinit var posts : MutableList<PostPreview>
+ private lateinit var rvPosts: RecyclerView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- arguments?.let {
- param1 = it.getString(ARG_PARAM1)
- param2 = it.getString(ARG_PARAM2)
- }
+
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
- // Inflate the layout for this fragment
- return inflater.inflate(R.layout.fragment_my_recensions, container, false)
+
+ val view =inflater.inflate(R.layout.fragment_my_recensions, container, false)
+
+ rvPosts=view.findViewById(R.id.rvFragmentMyRecensionPostHistory) as RecyclerView
+ getPosts()
+
+ return view
+
}
+ fun getPosts(){
+ val api = RetrofitHelper.getInstance()
+ val token= SharedPreferencesHelper.getValue("jwt", requireActivity())
+ val data=api.getMyHistory("Bearer "+token)
- companion object {
- /**
- * Use this factory method to create a new instance of
- * this fragment using the provided parameters.
- *
- * @param param1 Parameter 1.
- * @param param2 Parameter 2.
- * @return A new instance of fragment FragmentMyRecensions.
- */
- // TODO: Rename and change types and number of parameters
- @JvmStatic
- fun newInstance(param1: String, param2: String) =
- FragmentMyRecensions().apply {
- arguments = Bundle().apply {
- putString(ARG_PARAM1, param1)
- putString(ARG_PARAM2, param2)
+ data.enqueue(object : Callback<MutableList<PostPreview>> {
+ override fun onResponse(
+ call: Call<MutableList<PostPreview>>,
+ response: Response<MutableList<PostPreview>>
+ ) {
+ if (response.body() == null) {
+ return
}
+ posts = response.body()!!.toMutableList<PostPreview>()
+ loadPosts()
+ }
+ override fun onFailure(call: Call<MutableList<PostPreview>>, t: Throwable) {
+
}
+ })
}
+ private fun loadPosts(){//most viewed
+ rvPosts.apply {
+ layoutManager= GridLayoutManager(requireContext(),1, GridLayoutManager.VERTICAL,false)
+ adapter= PostHistoryAdapter(requireActivity(),posts)
+
+ }
+
+}
} \ No newline at end of file
diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentProfile.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentProfile.kt
index a792598..7c6d998 100644
--- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentProfile.kt
+++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentProfile.kt
@@ -1,5 +1,6 @@
package com.example.brzodolokacije.Fragments
+
import android.content.Intent
import android.net.Uri
import android.os.Bundle
@@ -19,7 +20,6 @@ import com.example.brzodolokacije.R
import com.example.brzodolokacije.Services.RetrofitHelper
import com.example.brzodolokacije.Services.SharedPreferencesHelper
import com.google.android.material.button.MaterialButton
-import com.google.android.material.imageview.ShapeableImageView
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.MultipartBody
import okhttp3.RequestBody
@@ -28,6 +28,7 @@ import retrofit2.Call
import retrofit2.Response
import java.io.File
+
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private const val ARG_PARAM1 = "param1"
@@ -38,7 +39,7 @@ private const val ARG_PARAM2 = "param2"
* Use the [FragmentProfile.newInstance] factory method to
* create an instance of this fragment.
*/
-class FragmentProfile : Fragment(R.layout.fragment_profile) {
+class FragmentProfile : Fragment(com.example.brzodolokacije.R.layout.fragment_profile) {
// TODO: Rename and change types of parameters
private lateinit var username: TextView
private lateinit var name: TextView
@@ -55,22 +56,33 @@ class FragmentProfile : Fragment(R.layout.fragment_profile) {
private lateinit var showMyRecensions: Button
private lateinit var profilePicture: ImageView
private lateinit var profilePicturePlus: MaterialButton
+ private lateinit var showFollowers: TextView
+ private lateinit var showFollowing: TextView
+
+ var userId:String = "1"
+
+
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
+// Toast.makeText(
+// activity, "MOJ PROFILLLLLLLLLLLLLLL", Toast.LENGTH_LONG
+// ).show();
// Inflate the layout for this fragment
- val view:View= inflater.inflate(R.layout.fragment_profile, container, false)
- name = view.findViewById<View>(R.id.tvFragmentProfileName) as TextView
- username = view.findViewById<View>(R.id.tvFragmentProfileUserName) as TextView
- postsCount = view.findViewById<View>(R.id.tvFragmentProfilePostsNo) as TextView
- followersCount = view.findViewById<View>(R.id.tvFragmentProfileFollowersNo) as TextView
- followingCount = view.findViewById<View>(R.id.tvFragmentProfileFollowNo) as TextView
- showMyPosts=view.findViewById<View>(R.id.btnFragmentProfileShowMyPosts) as Button
- showMyData=view.findViewById<View>(R.id.btnFragmentProfileShowMyData) as Button
- showMyRecensions=view.findViewById<View>(R.id.btnFragmentProfileShowMyRecensions) as Button
- profilePicture=view.findViewById<View>(R.id.tvFragmentProfileProfilePicture) as ImageView
- profilePicturePlus=view.findViewById<View>(R.id.btnFragmentProfileProfilePicturePlus) as MaterialButton
+ val view:View= inflater.inflate(com.example.brzodolokacije.R.layout.fragment_profile, container, false)
+ name = view.findViewById<View>(com.example.brzodolokacije.R.id.tvFragmentProfileName) as TextView
+ username = view.findViewById<View>(com.example.brzodolokacije.R.id.tvFragmentProfileUserName) as TextView
+ postsCount = view.findViewById<View>(com.example.brzodolokacije.R.id.tvFragmentProfilePostsNo) as TextView
+ followersCount = view.findViewById<View>(com.example.brzodolokacije.R.id.tvFragmentProfileFollowersNo) as TextView
+ followingCount = view.findViewById<View>(com.example.brzodolokacije.R.id.tvFragmentProfileFollowNo) as TextView
+ showMyPosts=view.findViewById<View>(com.example.brzodolokacije.R.id.btnFragmentProfileShowMyPosts) as Button
+ showMyData=view.findViewById<View>(com.example.brzodolokacije.R.id.btnFragmentProfileShowMyData) as Button
+ showMyRecensions=view.findViewById<View>(com.example.brzodolokacije.R.id.btnFragmentProfileShowMyRecensions) as Button
+ profilePicture=view.findViewById<View>(com.example.brzodolokacije.R.id.tvFragmentProfileProfilePicture) as ImageView
+ profilePicturePlus=view.findViewById<View>(com.example.brzodolokacije.R.id.btnFragmentProfileProfilePicturePlus) as MaterialButton
+ showFollowers=view.findViewById(com.example.brzodolokacije.R.id.tvFragmentProfileFollowers)
+ showFollowing=view.findViewById(com.example.brzodolokacije.R.id.tvFragmentProfileFollow)
//podaci iz baze
@@ -85,7 +97,7 @@ class FragmentProfile : Fragment(R.layout.fragment_profile) {
var fm: FragmentTransaction =childFragmentManager.beginTransaction()
- fm.replace(R.id.flFragmentProfileFragmentContainer, FragmentMyProfileInfo())
+ fm.replace(com.example.brzodolokacije.R.id.flFragmentProfileFragmentContainer, FragmentMyProfileInfo())
fm.commit()
}
@@ -93,12 +105,36 @@ class FragmentProfile : Fragment(R.layout.fragment_profile) {
getProfileInfo()
var fm: FragmentTransaction =childFragmentManager.beginTransaction()
- fm.replace(R.id.flFragmentProfileFragmentContainer, FragmentMyRecensions())
+ fm.replace(com.example.brzodolokacije.R.id.flFragmentProfileFragmentContainer, FragmentMyRecensions())
fm.commit()
}
profilePicturePlus.setOnClickListener{
addProfilePicture()
}
+
+ showFollowers.setOnClickListener {
+ val bundle = Bundle()
+ bundle.putString("userId",userId )
+ val fragmentFollowers = FragmentFollowers()
+ fragmentFollowers.setArguments(bundle)
+
+ fragmentManager
+ ?.beginTransaction()
+ ?.replace(com.example.brzodolokacije.R.id.flNavigationFragment,fragmentFollowers)
+ ?.commit()
+ }
+
+ showFollowing.setOnClickListener {
+ val bundle = Bundle()
+ bundle.putString("userId",userId)
+ val fragmentFollowing = FragmentFollowing()
+ fragmentFollowing.setArguments(bundle)
+
+ fragmentManager
+ ?.beginTransaction()
+ ?.replace(com.example.brzodolokacije.R.id.flNavigationFragment,fragmentFollowing)
+ ?.commit()
+ }
getProfileInfo()
openMyPosts()
return view
@@ -106,7 +142,7 @@ class FragmentProfile : Fragment(R.layout.fragment_profile) {
fun openMyPosts(){
var fm: FragmentTransaction =childFragmentManager.beginTransaction()
- fm.replace(R.id.flFragmentProfileFragmentContainer, FragmentUserPosts())
+ fm.replace(com.example.brzodolokacije.R.id.flFragmentProfileFragmentContainer, FragmentUserPosts())
fm.commit()
}
@@ -181,6 +217,8 @@ class FragmentProfile : Fragment(R.layout.fragment_profile) {
followersCount.setText("to do")
followingCount.setText("to do")
+ userId=user._id
+
//Add Profile image
if(user.pfp!=null) {
Glide.with(requireActivity())
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 83f6429..a840d6b 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
@@ -1,54 +1,66 @@
package com.example.brzodolokacije.Fragments
-import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.util.Log
-import androidx.fragment.app.Fragment
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 androidx.fragment.app.Fragment
+import androidx.lifecycle.ViewModelProvider
+import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
-import com.example.brzodolokacije.Activities.NavigationActivity
-import com.example.brzodolokacije.Adapters.SampleAdapter
+import com.example.brzodolokacije.Activities.ActivityAddPost
+import com.example.brzodolokacije.Activities.ChatActivity
import com.example.brzodolokacije.Adapters.ShowPostsAdapter
-import com.example.brzodolokacije.Models.*
+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.FragmentHomeBinding
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 kotlinx.android.synthetic.main.fragment_show_posts.*
-import kotlinx.android.synthetic.main.fragment_show_posts.view.*
-import okhttp3.ResponseBody
-import retrofit2.Call
-import retrofit2.Response
+import kotlinx.coroutines.flow.collectLatest
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.launch
class FragmentShowPosts : Fragment(), SwipeRefreshLayout.OnRefreshListener {
private lateinit var binding: FragmentShowPostsBinding
- private var posts : MutableList<PostPreview> = mutableListOf()
private var linearManagerVar: RecyclerView.LayoutManager? = null
- private var adapterVar: RecyclerView.Adapter<ShowPostsAdapter.ViewHolder>? = null
+ private var adapterVar: ShowPostsAdapter? = null
private var recyclerView: RecyclerView?=null
private var gridManagerVar: RecyclerView.LayoutManager?=null
private var swipeRefreshLayout:SwipeRefreshLayout?=null
+ private lateinit var searchPostsViewModel:SearchPostsViewModel
+ private var searchParams:SearchParams?= SearchParams("6375784fe84e2d53df32bf03",1,1)
+ private lateinit var btnFilter:ImageButton
+ private lateinit var btnSort:ImageButton
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
+ setUpViewModel()
binding=FragmentShowPostsBinding.inflate(layoutInflater)
//instantiate adapter and linearLayout
- adapterVar=ShowPostsAdapter(requireActivity(),posts)
+ adapterVar=ShowPostsAdapter(requireActivity())
linearManagerVar= LinearLayoutManager(activity)
gridManagerVar=GridLayoutManager(activity,2)
}
+ private fun setUpViewModel() {
+ val factory=SearchPostsViewModelFactory(RetrofitHelper.getInstance(),requireActivity())
+ searchPostsViewModel=ViewModelProvider(this@FragmentShowPosts,factory).get(SearchPostsViewModel::class.java)
+ }
+
fun setUpListeners(rootView: View?){
rootView?.findViewById<ImageButton>(R.id.btnGridLayout)?.setOnClickListener() {
if(recyclerView?.layoutManager!=gridManagerVar){
@@ -63,35 +75,20 @@ class FragmentShowPosts : Fragment(), SwipeRefreshLayout.OnRefreshListener {
}
Log.d("main","klik")
}
- }
-
- fun requestToBack(){
- val postApi= RetrofitHelper.getInstance()
- val token=SharedPreferencesHelper.getValue("jwt", requireActivity())
- val request=postApi.getPosts("Bearer "+token)
- request.enqueue(object : retrofit2.Callback<MutableList<PostPreview>?> {
- override fun onResponse(call: Call<MutableList<PostPreview>?>, response: Response<MutableList<PostPreview>?>) {
- if(response.isSuccessful){
- posts=response.body()!!
- recyclerView?.adapter=ShowPostsAdapter(requireActivity(),posts)
- Toast.makeText(
- activity, "prosao zahtev", Toast.LENGTH_LONG
- ).show()
- swipeRefreshLayout?.isRefreshing=false
- }else{
- if(response.errorBody()!=null)
- Toast.makeText(activity, response.errorBody()!!.string(), Toast.LENGTH_LONG).show();
- }
-
- }
+ rootView?.findViewById<ImageButton>(R.id.btnChat)?.setOnClickListener() {
+ val intent: Intent = Intent(activity, ChatActivity::class.java)
+ requireActivity().startActivity(intent)
+ }
+ }
- override fun onFailure(call: Call<MutableList<PostPreview>?>, t: Throwable) {
- Toast.makeText(
- activity, t.toString(), Toast.LENGTH_LONG
- ).show();
+ fun requestToBack(searchParams: SearchParams){
+ lifecycleScope.launch{
+ searchPostsViewModel.fetchPosts(searchParams).distinctUntilChanged().collectLatest {
+ adapterVar?.submitData(lifecycle,it)
+ swipeRefreshLayout?.isRefreshing=false
}
- })
+ }
}
override fun onCreateView(
@@ -116,13 +113,50 @@ class FragmentShowPosts : Fragment(), SwipeRefreshLayout.OnRefreshListener {
)
swipeRefreshLayout?.post(kotlinx.coroutines.Runnable {
swipeRefreshLayout?.isRefreshing=true
- requestToBack()
+ requestToBack(searchParams!!)
})
+
+ btnFilter=rootView.findViewById(R.id.btnSortType)
+ btnSort=rootView.findViewById(R.id.btnSortDirection)
+
+ btnFilter.setOnClickListener{
+ showBottomSheetFilter()
+ }
+
+ btnSort.setOnClickListener{
+ showBottomSheetSort()
+ }
return rootView
}
override fun onRefresh() {
- requestToBack()
+ requestToBack(searchParams!!)
}
+
+ private fun showBottomSheetFilter() {
+ var bottomSheetDialog: BottomSheetDialog
+ bottomSheetDialog = BottomSheetDialog(requireContext())
+ bottomSheetDialog.setContentView(R.layout.bottom_sheet_filter)
+ bottomSheetDialog.show()
+
+ var dateFrom=bottomSheetDialog.findViewById<View>(R.id.dateFromBSF)as EditText
+ var dateTo=bottomSheetDialog.findViewById<View>(R.id.dateToBSF) as EditText
+ var location=bottomSheetDialog.findViewById<View>(R.id.locationBSF) as EditText
+ var filter = bottomSheetDialog.findViewById<View>(R.id.btnBSFFilter) as Button
+
+
+ filter.setOnClickListener {
+ //povezati sa back-om
+
+
+ }
+ }
+ private fun showBottomSheetSort() {
+ var bottomSheetDialogSort: BottomSheetDialog
+ bottomSheetDialogSort = BottomSheetDialog(requireContext())
+ bottomSheetDialogSort.setContentView(R.layout.bottom_sheet_sort)
+ bottomSheetDialogSort.show()
+
+ }
} \ No newline at end of file
diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentUserPosts.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentUserPosts.kt
index f1f2257..d69a40c 100644
--- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentUserPosts.kt
+++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentUserPosts.kt
@@ -34,6 +34,7 @@ import android.widget.TextView
import com.example.brzodolokacije.Activities.ActivityAddPost
import com.example.brzodolokacije.Activities.ActivityCapturePost
import com.example.brzodolokacije.Activities.ActivityForgottenPassword
+import com.example.brzodolokacije.Adapters.MyPostsAdapter
import com.google.android.material.bottomsheet.BottomSheetDialog
@@ -107,7 +108,7 @@ class FragmentUserPosts : Fragment() {
private fun loadPosts(){//most viewed
rvPosts.apply {
layoutManager= GridLayoutManager(requireContext(),2,GridLayoutManager.VERTICAL,false)
- adapter= ShowPostsAdapter(requireActivity(),posts)
+ adapter= MyPostsAdapter(requireActivity(),posts)
}
}
diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentUserProfile.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentUserProfile.kt
new file mode 100644
index 0000000..2635adb
--- /dev/null
+++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentUserProfile.kt
@@ -0,0 +1,26 @@
+package com.example.brzodolokacije.Fragments
+
+import android.os.Bundle
+import androidx.fragment.app.Fragment
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import com.example.brzodolokacije.R
+
+class FragmentUserProfile : Fragment() {
+
+
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+
+ val view= inflater.inflate(R.layout.fragment_user_profile, container, false)
+
+
+
+ return view
+ }
+
+
+} \ No newline at end of file
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 2f5cff1..cb51627 100644
--- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Interfaces/IBackendApi.kt
+++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Interfaces/IBackendApi.kt
@@ -6,7 +6,6 @@ import com.example.brzodolokacije.Models.Auth.Login
import com.example.brzodolokacije.Models.Auth.Register
import com.example.brzodolokacije.Models.Auth.ResetPass
import okhttp3.MultipartBody
-import okhttp3.Request
import okhttp3.RequestBody
import okhttp3.ResponseBody
import retrofit2.Call
@@ -26,6 +25,8 @@ interface IBackendApi {
fun resetpass(@Body obj:ResetPass):Call<ResponseBody>
@GET("/api/post")
fun getPosts(@Header("Authorization") authHeader:String):Call<MutableList<PostPreview>>
+ @GET("/api/Post/posts/{id}")
+ fun addView(@Header("Authorization") authHeader:String,@Path("id") id:String):Call<PostPreview>
@POST("/api/Location/add")
fun addLocation(@Header("Authorization") authHeader:String,@Body obj: Location ):Call<Location>
@Multipart
@@ -34,6 +35,7 @@ interface IBackendApi {
,@Part("_id") _id:RequestBody
,@Part("description") description:RequestBody
,@Part("locationId") locationId:RequestBody
+ ,@Part("tags") tags:RequestBody
):Call<PostPreview>
@POST("api/Post/posts/{id}/addrating")
fun addRating(@Header("Authorization") authHeader:String,@Path("id") id:String,@Body rating: RatingReceive):Call<ResponseBody>
@@ -54,6 +56,31 @@ interface IBackendApi {
@GET("/api/user/posts")
fun getMyPosts(@Header("Authorization") authHeader:String):Call<MutableList<PostPreview>>
+ @GET("/api/post/locations/{id}/posts")
+ suspend fun getPagedPosts(@Header("Authorization") authHeader: String,
+ @Path("id") locationId:String,
+ @Query("page") page:Int,
+ @Query("sorttype") sorttype:Int,
+ @Query("filterdate") filterdate:Int
+ ):PagedPosts
+ @POST("/api/message/add")
+ fun sendMessage(@Header("Authorization") authHeader:String,@Body message:MessageSend):Call<Message>
+ @GET("/api/message/myMessages")
+ fun getNewMessages(@Header("Authorization") authHeader:String):Call<MutableList<MessageReceive>?>
+ @GET("/api/user/history")
+ fun getMyHistory(@Header("Authorization") authHeader:String):Call<MutableList<PostPreview>>
//@POST("putanja")
//fun add(@Body obj:Post,@Header("Authorization") authHeader:String):Call<Post>
+
+ @POST("/api/user/{id}/followers")
+ fun getFollowers(@Path("id") id:String):Call <MutableList<UserReceive>>
+
+ @POST("/api/user{id}/following")
+ fun getFollowing(@Path("id") id:String):Call <MutableList<UserReceive>>
+
+ @POST("/api/user{id}/addFollower")
+ fun addFollower(@Header("Authorization") authHeader:String,@Path("id") id:String):Call<UserReceive>
+ @GET("/api/user/{id}/id/profile")
+ fun getProfileFromId(@Header("Authorization") authHeader:String,@Path("id") username:String):Call<UserReceive>
+
} \ No newline at end of file
diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/MainActivity.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/MainActivity.kt
index 0c43088..b3183b8 100644
--- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/MainActivity.kt
+++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/MainActivity.kt
@@ -1,16 +1,14 @@
package com.example.brzodolokacije
import android.content.Intent
-import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
-import android.util.Log
import android.widget.Toast
+import androidx.appcompat.app.AppCompatActivity
import com.auth0.android.jwt.JWT
import com.example.brzodolokacije.Activities.ActivityLoginRegister
import com.example.brzodolokacije.Activities.NavigationActivity
import com.example.brzodolokacije.Services.RetrofitHelper
import com.example.brzodolokacije.Services.SharedPreferencesHelper
-import com.example.brzodolokacije.Services.authCheck
import retrofit2.Call
import retrofit2.Response
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
new file mode 100644
index 0000000..3404541
--- /dev/null
+++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Models/Chat.kt
@@ -0,0 +1,27 @@
+package com.example.brzodolokacije.Models
+
+import java.util.*
+
+data class MessageReceive(
+ var senderId:String,
+ var messagge:String,
+ var timestamp:Date
+)
+
+data class MessageSend(
+ var receiverId:String,
+ var messagge:String
+)
+
+data class Message(
+ var _id:String,
+ var senderId: String,
+ 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/Models/Post.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Models/Post.kt
index 3bbcc0c..e2e9209 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
@@ -34,7 +34,8 @@ data class PostPreview (
var views:Int,
var ratings:Float,
var comments:List<CommentSend>?,
- var images:List<PostImage>
+ var images:List<PostImage>,
+ var tags:List<String>?
//nedostaju datum i vreme kreiranja
):Parcelable
@@ -71,4 +72,18 @@ data class Rating(
data class RatingReceive(
var rating:Int,
var postId:String
+)
+
+data class PagedPosts(
+ var page:Int,
+ var index:Int,
+ var totalpages:Int,
+ var totalposts:Int,
+ var posts:MutableList<PostPreview>
+)
+
+data class SearchParams(
+ var locationId: String,
+ var sorttype:Int,
+ var filterdate:Int
) \ No newline at end of file
diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Models/User.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Models/User.kt
index c726978..46338b3 100644
--- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Models/User.kt
+++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Models/User.kt
@@ -14,9 +14,9 @@ data class User (
//profil
var followers:List<User>,
- var followersNumber:Int,
+ var followersCount:Int,
var following:List<User>,
- var followingNumber:Int,
+ var followingCount:Int,
var postIds:List<Int>,
var postNumber:Int
@@ -28,5 +28,11 @@ data class UserReceive(
var email:String,
var creationDate: Date,
var pfp:PostImage?,
- var postcount:Int
+ var postcount:Int,
+ var followers:List<User>,
+ var followersNumber:Int,
+ var following:List<User>,
+ var followingNumber:Int,
+ var postIds:List<Int>,
+ var postNumber:Int
) \ 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
new file mode 100644
index 0000000..479b9cb
--- /dev/null
+++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/chat/DBHelper.kt
@@ -0,0 +1,155 @@
+package com.exam
+
+
+import android.app.Activity
+import android.content.Context
+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 :
+ SQLiteOpenHelper{
+
+ var db:SQLiteDatabase?=null
+
+ constructor(context: Context, factory: SQLiteDatabase.CursorFactory?):super(context, DATABASE_NAME, factory,3){
+ db=readableDatabase
+ }
+
+
+ companion object{
+ //database name
+ private val DATABASE_NAME = "chatHistory"
+ //database tables
+ val CONTACTS_TABLE_NAME = "contacts"
+ val MESSAGES_TABLE_NAME = "messages"
+ private var instance:DBHelper?=null
+ fun getInstance(activity: Activity):DBHelper{
+ if(instance==null){
+ instance= DBHelper(activity,null)
+ }
+ return instance as DBHelper
+ }
+ }
+
+ override fun onCreate(db: SQLiteDatabase?) {
+ if(!doesTableExist(CONTACTS_TABLE_NAME,db)){
+ var sql:String="CREATE TABLE "+ CONTACTS_TABLE_NAME+" (" +
+ "userId " +"TEXT PRIMARY KEY,"+
+ "read " +"INT"+
+ ")"
+ db?.execSQL(sql)
+ }
+ if(!doesTableExist(MESSAGES_TABLE_NAME,db)){
+ var sql:String="CREATE TABLE "+ MESSAGES_TABLE_NAME+"(" +
+ "_id "+"TEXT PRIMARY KEY,"+
+ "senderId " +"TEXT,"+
+ "receiverId "+"TEXT,"+
+ "messagge " +"TEXT,"+
+ "timestamp "+"TEXT"+
+ ")"
+ db?.execSQL(sql)
+ }
+ }
+
+ fun doesTableExist(tableName:String,db: SQLiteDatabase?):Boolean{
+ if(db!=null){
+ var sqlString:String="select DISTINCT tbl_name from sqlite_master where tbl_name = '\"+tableName+\"'"
+ var cursor: Cursor=db.rawQuery(sqlString,null)
+ if(cursor!=null){
+ if(cursor.count>0){
+ return true
+ }
+ return false
+ }
+ }
+ return false
+ }
+
+ override fun onUpgrade(db: SQLiteDatabase?, p1: Int, p2: Int) {
+ db?.execSQL("DROP TABLE IF EXISTS " + CONTACTS_TABLE_NAME)
+ db?.execSQL("DROP TABLE IF EXISTS " + MESSAGES_TABLE_NAME)
+ onCreate(db)
+ }
+
+ fun addMessage(message: Message, sent:Boolean=true){
+ if(!message._id.isNullOrEmpty() && message.senderId==message.receiverId){
+ Log.d("main", "ne zapisuje se dupla poruka")
+ } else {
+ if(message._id.isNullOrEmpty()){
+ message._id=message.senderId+message.timestamp
+ }
+ var sql="INSERT INTO "+ MESSAGES_TABLE_NAME+"(_id,senderId,receiverid,messagge,timestamp) VALUES('"+message._id+"','"+
+ message.senderId+"','"+
+ message.receiverId+"','"+
+ message.messagge+ "','"+
+ message.timestamp+ "')"
+ db?.execSQL(sql)
+ if(sent)
+ sql="SELECT * FROM "+ CONTACTS_TABLE_NAME+" WHERE userId='"+message.receiverId+"'"
+ else
+ sql="SELECT * FROM "+ CONTACTS_TABLE_NAME+" WHERE userId='"+message.senderId+"'"
+ var cursor=db?.rawQuery(sql,null)
+ if(cursor?.count==0){
+ //dodati u kontakte
+ var id:String
+ id = if(sent) message.receiverId else message.senderId
+ var read:Int=if(sent) 1 else 0
+ sql="INSERT INTO "+ CONTACTS_TABLE_NAME+"(userId,read) VALUES('"+id+"','"+
+ read+"')"
+ db?.execSQL(sql)
+ }
+ }
+ }
+ fun getMessages(userId:String, self:Boolean=false): MutableList<Message>? {
+ var sql:String
+ if(!self)
+ sql="SELECT * FROM "+ MESSAGES_TABLE_NAME+" WHERE senderId='"+userId+"' OR receiverId='"+userId+"'"
+ else
+ sql="SELECT * FROM "+ MESSAGES_TABLE_NAME+" WHERE senderId='"+userId+"' AND receiverId='"+userId+"'"
+ var cursor=db?.rawQuery(sql,null)
+ if(cursor?.count!! >0){
+ var messagesList:MutableList<Message> =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<ChatPreview>? {
+ var sql="SELECT * FROM "+ CONTACTS_TABLE_NAME
+ var cursor=db?.rawQuery(sql,null)
+ if(cursor?.count!! >0){
+ var contactList:MutableList<ChatPreview> =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
new file mode 100644
index 0000000..d091c5d
--- /dev/null
+++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/chat/SignalRListener.kt
@@ -0,0 +1,63 @@
+package com.example.brzodolokacije.chat
+
+import android.app.Activity
+import android.util.Log
+import com.auth0.android.jwt.JWT
+import com.exam.DBHelper
+import com.example.brzodolokacije.Models.Message
+import com.example.brzodolokacije.Models.MessageReceive
+import com.example.brzodolokacije.Services.RetrofitHelper
+import com.example.brzodolokacije.Services.SharedPreferencesHelper
+import com.microsoft.signalr.Action1
+import com.microsoft.signalr.HubConnection
+import com.microsoft.signalr.HubConnectionBuilder
+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->dbHelper.addMessage(Message(message.senderId+message.timestamp,message.senderId,
+ JWT(SharedPreferencesHelper.getValue("jwt",activity)!!).claims["id"]?.asString()!!,message.messagge,message.timestamp),false)
+ },
+ MessageReceive::class.java
+ )
+ hubConnection.start().blockingAwait()
+
+ Log.d("main", hubConnection.connectionState.toString())
+ }
+
+
+ companion object{
+ private var instance:SignalRListener?=null
+ fun getInstance(activity: Activity):SignalRListener{
+ if(instance==null){
+ instance= SignalRListener(activity)
+ }
+ return instance as SignalRListener
+ }
+
+ }
+ fun stopHubConnection(){
+ if(hubConnection.connectionState == HubConnectionState.CONNECTED){
+ hubConnection.stop()
+ }
+ }
+
+ fun getConnectionState(){
+ Log.d("main",hubConnection.connectionState.toString())
+ }
+
+ fun log(){
+ Log.d("Debug infor siganlR ", hubConnection.connectionId)
+ }
+
+} \ No newline at end of file
diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/paging/SearchPostsPagingSource.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/paging/SearchPostsPagingSource.kt
new file mode 100644
index 0000000..b1c89db
--- /dev/null
+++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/paging/SearchPostsPagingSource.kt
@@ -0,0 +1,38 @@
+package com.example.brzodolokacije.paging
+
+import android.app.Activity
+import android.util.Log
+import androidx.paging.PagingSource
+import com.example.brzodolokacije.Interfaces.IBackendApi
+import com.example.brzodolokacije.Models.PagedPosts
+import com.example.brzodolokacije.Models.PostPreview
+import com.example.brzodolokacije.Models.SearchParams
+import com.example.brzodolokacije.Services.SharedPreferencesHelper
+import retrofit2.HttpException
+import java.io.IOException
+
+class SearchPostsPagingSource(
+ val backend: IBackendApi,
+ val activity: Activity,
+ val searchParams:SearchParams
+):PagingSource<Int,PostPreview>() {
+ override suspend fun load(params: LoadParams<Int>): LoadResult<Int, PostPreview> {
+ val page=params.key?:0
+ val token=SharedPreferencesHelper.getValue("jwt", activity)
+ return try{
+ val response=backend.getPagedPosts("Bearer "+token,searchParams.locationId,
+ page,searchParams.sorttype,searchParams.filterdate
+ )
+ Log.d("main",page.toString())
+ LoadResult.Page(
+ response.posts,prevKey=if(page==0) null else page-1,
+ nextKey=if(response.posts.isEmpty()) null else page+1
+ )
+ }catch(exception:IOException){
+ return LoadResult.Error(exception)
+ }catch(exception:HttpException){
+ return LoadResult.Error(exception)
+ }
+ }
+
+} \ No newline at end of file
diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/paging/SearchPostsRepository.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/paging/SearchPostsRepository.kt
new file mode 100644
index 0000000..4eeb85b
--- /dev/null
+++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/paging/SearchPostsRepository.kt
@@ -0,0 +1,31 @@
+package com.example.brzodolokacije.paging
+
+import android.app.Activity
+import androidx.paging.Pager
+import androidx.paging.PagingConfig
+import androidx.paging.PagingData
+import androidx.paging.cachedIn
+import com.example.brzodolokacije.Models.PostPreview
+import com.example.brzodolokacije.Models.SearchParams
+import com.example.brzodolokacije.Services.RetrofitHelper
+import kotlinx.coroutines.flow.Flow
+
+class SearchPostsRepository(val activity: Activity,val searchParams: SearchParams) {
+ companion object{
+ const val DEFAULT_PAGE_SIZE=20
+ const val DEFAULT_PAGE_INDEX=1
+
+ fun getInstance(activity: Activity,searchParams: SearchParams)=SearchPostsRepository(activity,searchParams)
+ }
+
+ fun letSearchedPostsFlow(pagingConfig: PagingConfig=getDefaultPageConfig()): Flow<PagingData<PostPreview>> {
+ return Pager(
+ config=pagingConfig,
+ pagingSourceFactory = {SearchPostsPagingSource(RetrofitHelper.getInstance(),activity,searchParams)}
+ ).flow
+ }
+
+ private fun getDefaultPageConfig(): PagingConfig {
+ return PagingConfig(pageSize= DEFAULT_PAGE_SIZE, enablePlaceholders = false)
+ }
+} \ No newline at end of file
diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/paging/SearchPostsViewModel.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/paging/SearchPostsViewModel.kt
new file mode 100644
index 0000000..cee1a34
--- /dev/null
+++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/paging/SearchPostsViewModel.kt
@@ -0,0 +1,22 @@
+package com.example.brzodolokacije.paging
+
+import android.app.Activity
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.viewModelScope
+import androidx.paging.Pager
+import androidx.paging.PagingConfig
+import androidx.paging.PagingData
+import androidx.paging.cachedIn
+import com.example.brzodolokacije.Interfaces.IBackendApi
+import com.example.brzodolokacije.Models.PostPreview
+import com.example.brzodolokacije.Models.SearchParams
+import kotlinx.coroutines.flow.Flow
+
+class SearchPostsViewModel(
+ private val api:IBackendApi,
+ val activity:Activity
+): ViewModel() {
+ fun fetchPosts(searchParams: SearchParams): Flow<PagingData<PostPreview>>{
+ return SearchPostsRepository.getInstance(activity,searchParams).letSearchedPostsFlow().cachedIn(viewModelScope)
+ }
+} \ No newline at end of file
diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/paging/SearchPostsViewModelFactory.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/paging/SearchPostsViewModelFactory.kt
new file mode 100644
index 0000000..cddea54
--- /dev/null
+++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/paging/SearchPostsViewModelFactory.kt
@@ -0,0 +1,15 @@
+package com.example.brzodolokacije.paging
+
+import android.app.Activity
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.ViewModelProvider
+import com.example.brzodolokacije.Interfaces.IBackendApi
+
+class SearchPostsViewModelFactory(
+ val api:IBackendApi,
+ val activity: Activity
+):ViewModelProvider.NewInstanceFactory() {
+ override fun <T : ViewModel> create(modelClass: Class<T>): T {
+ return SearchPostsViewModel(api,activity) as T
+ }
+} \ No newline at end of file
diff --git a/Client/BrzoDoLokacije/app/src/main/res/drawable/button_chat.xml b/Client/BrzoDoLokacije/app/src/main/res/drawable/button_chat.xml
new file mode 100644
index 0000000..86bfbd5
--- /dev/null
+++ b/Client/BrzoDoLokacije/app/src/main/res/drawable/button_chat.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="119dp"
+ android:height="45dp"
+ android:viewportWidth="119"
+ android:viewportHeight="45">
+ <group>
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M4 18.5c0-10.22 8.28-18.5 18.5-18.5h74c10.22 0 18.5 8.28 18.5 18.5v0c0 10.22-8.28 18.5-18.5 18.5h-74c-10.22 0-18.5-8.28-18.5-18.5z"/>
+ <path
+ android:strokeColor="#FF093A4C"
+ android:strokeWidth="1"
+ android:pathData="M4.5 18.5c0-9.94 8.06-18 18-18h74c9.94 0 18 8.06 18 18v0c0 9.94-8.06 18-18 18h-74c-9.94 0-18-8.06-18-18z"/>
+ </group>
+ <path
+ android:fillColor="#FF093A4C"
+ android:pathData="M53.32 24V13.1h3.69c0.85 0 1.55 0.15 2.1 0.45 0.54 0.31 0.95 0.72 1.21 1.25 0.26 0.52 0.4 1.1 0.4 1.74 0 0.65-0.14 1.23-0.4 1.76-0.26 0.52-0.66 0.94-1.2 1.25-0.55 0.31-1.24 0.47-2.1 0.47H54.4v-1.18h2.6c0.58 0 1.05-0.1 1.4-0.3 0.36-0.2 0.62-0.48 0.78-0.82 0.16-0.35 0.24-0.74 0.24-1.18 0-0.43-0.08-0.82-0.24-1.17-0.16-0.34-0.42-0.61-0.78-0.8-0.36-0.2-0.83-0.3-1.43-0.3h-2.32V24h-1.32Zm12.59 0.17c-0.74 0-1.39-0.18-1.95-0.53-0.55-0.35-0.98-0.84-1.3-1.47-0.3-0.63-0.46-1.37-0.46-2.22 0-0.85 0.16-1.6 0.46-2.23 0.32-0.64 0.75-1.13 1.3-1.48 0.56-0.35 1.2-0.53 1.95-0.53 0.74 0 1.38 0.18 1.94 0.53 0.55 0.35 0.99 0.84 1.3 1.48 0.3 0.64 0.47 1.38 0.47 2.23 0 0.85-0.16 1.59-0.47 2.22-0.31 0.63-0.75 1.12-1.3 1.47-0.56 0.35-1.2 0.53-1.94 0.53Zm0-1.13c0.56 0 1.02-0.14 1.38-0.43 0.37-0.29 0.63-0.67 0.8-1.13 0.18-0.47 0.27-0.98 0.27-1.53s-0.09-1.05-0.26-1.53c-0.18-0.47-0.44-0.85-0.8-1.14-0.37-0.3-0.83-0.44-1.4-0.44-0.55 0-1.01 0.15-1.38 0.44-0.36 0.29-0.63 0.67-0.8 1.14-0.18 0.48-0.26 0.98-0.26 1.53s0.08 1.06 0.26 1.53c0.17 0.46 0.44 0.84 0.8 1.13 0.37 0.29 0.83 0.43 1.39 0.43ZM71.53 24v-8.18h1.22v1.23h0.08c0.15-0.4 0.42-0.73 0.81-0.98 0.4-0.25 0.83-0.38 1.32-0.38h0.35l0.32 0.02V17l-0.3-0.05c-0.15-0.02-0.3-0.04-0.47-0.04-0.4 0-0.75 0.09-1.07 0.26-0.3 0.16-0.55 0.39-0.73 0.68-0.18 0.28-0.27 0.61-0.27 0.98V24h-1.26Zm10.74-3.35v-4.83h1.26V24h-1.26v-1.38H82.2c-0.2 0.41-0.5 0.76-0.9 1.06-0.4 0.28-0.91 0.43-1.53 0.43-0.51 0-0.97-0.12-1.37-0.34-0.4-0.23-0.7-0.57-0.93-1.02-0.23-0.46-0.34-1.04-0.34-1.73v-5.2h1.25v5.11c0 0.6 0.17 1.07 0.5 1.43 0.34 0.35 0.77 0.53 1.3 0.53 0.3 0 0.62-0.08 0.95-0.24 0.32-0.16 0.6-0.4 0.82-0.73 0.22-0.33 0.33-0.75 0.33-1.27ZM87 21.02l-0.02-1.56h0.26l3.58-3.64h1.55l-3.81 3.85h-0.1L87 21.02ZM85.83 24V13.1h1.26V24h-1.26Zm5.2 0l-3.2-4.05 0.9-0.87 3.9 4.92h-1.6Zm5.37 0.2c-0.52 0-1-0.1-1.41-0.3-0.43-0.2-0.76-0.49-1.01-0.86-0.25-0.38-0.37-0.83-0.37-1.36 0-0.47 0.09-0.85 0.27-1.14 0.19-0.3 0.44-0.53 0.74-0.7 0.31-0.16 0.65-0.29 1.03-0.37 0.37-0.08 0.75-0.15 1.13-0.2L98 19.13c0.31-0.04 0.54-0.1 0.68-0.18 0.15-0.08 0.22-0.22 0.22-0.43v-0.04c0-0.52-0.14-0.93-0.43-1.22-0.28-0.3-0.72-0.44-1.3-0.44-0.6 0-1.07 0.13-1.4 0.4-0.35 0.26-0.59 0.54-0.73 0.84l-1.19-0.43c0.21-0.5 0.5-0.88 0.85-1.16 0.36-0.28 0.75-0.48 1.18-0.59 0.42-0.11 0.84-0.17 1.25-0.17 0.27 0 0.57 0.03 0.9 0.1 0.35 0.06 0.68 0.18 1 0.38 0.33 0.19 0.6 0.48 0.8 0.86 0.22 0.4 0.33 0.9 0.33 1.56V24h-1.26v-1.1h-0.06c-0.09 0.17-0.23 0.36-0.43 0.56-0.2 0.2-0.46 0.38-0.8 0.52-0.32 0.14-0.73 0.21-1.2 0.21Zm0.19-1.14c0.5 0 0.92-0.1 1.26-0.29 0.34-0.2 0.6-0.45 0.77-0.76 0.18-0.3 0.27-0.63 0.27-0.97v-1.15c-0.05 0.06-0.17 0.12-0.35 0.17-0.18 0.05-0.38 0.1-0.62 0.14l-0.67 0.1-0.53 0.06c-0.33 0.04-0.63 0.1-0.92 0.2-0.28 0.1-0.5 0.24-0.68 0.43-0.17 0.18-0.26 0.43-0.26 0.75 0 0.44 0.17 0.77 0.49 1 0.33 0.21 0.74 0.32 1.24 0.32Z"/>
+ <path
+ android:fillColor="#FF093A4C"
+ android:pathData="M39 11H23c-1.1 0-1.99 0.9-1.99 2L21 31l4-4h14c1.1 0 2-0.9 2-2V13c0-1.1-0.9-2-2-2Zm-3 12H26c-0.55 0-1-0.45-1-1s0.45-1 1-1h10c0.55 0 1 0.45 1 1s-0.45 1-1 1Zm0-3H26c-0.55 0-1-0.45-1-1s0.45-1 1-1h10c0.55 0 1 0.45 1 1s-0.45 1-1 1Zm0-3H26c-0.55 0-1-0.45-1-1s0.45-1 1-1h10c0.55 0 1 0.45 1 1s-0.45 1-1 1Z"/>
+</vector> \ No newline at end of file
diff --git a/Client/BrzoDoLokacije/app/src/main/res/drawable/button_filter.xml b/Client/BrzoDoLokacije/app/src/main/res/drawable/button_filter.xml
new file mode 100644
index 0000000..00b22aa
--- /dev/null
+++ b/Client/BrzoDoLokacije/app/src/main/res/drawable/button_filter.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="#FF093A4C"
+ android:pathData="M11 18c-0.28 0-0.52-0.1-0.71-0.29C10.09 17.52 10 17.28 10 17c0-0.28 0.1-0.52 0.29-0.71C10.48 16.09 10.72 16 11 16h2c0.28 0 0.52 0.1 0.71 0.29C13.91 16.48 14 16.72 14 17c0 0.28-0.1 0.52-0.29 0.71C13.52 17.91 13.28 18 13 18h-2ZM4 8C3.72 8 3.48 7.9 3.29 7.71 3.09 7.52 3 7.28 3 7c0-0.28 0.1-0.52 0.29-0.71C3.48 6.09 3.72 6 4 6h16c0.28 0 0.52 0.1 0.71 0.29C20.91 6.48 21 6.72 21 7c0 0.28-0.1 0.52-0.29 0.71C20.52 7.91 20.28 8 20 8H4Zm3 5c-0.28 0-0.52-0.1-0.71-0.29C6.09 12.52 6 12.28 6 12c0-0.28 0.1-0.52 0.29-0.71C6.48 11.09 6.72 11 7 11h10c0.28 0 0.52 0.1 0.71 0.29C17.91 11.48 18 11.72 18 12c0 0.28-0.1 0.52-0.29 0.71C17.52 12.91 17.28 13 17 13H7Z"/>
+</vector> \ No newline at end of file
diff --git a/Client/BrzoDoLokacije/app/src/main/res/drawable/button_find_on_map.xml b/Client/BrzoDoLokacije/app/src/main/res/drawable/button_find_on_map.xml
new file mode 100644
index 0000000..4c0c8a5
--- /dev/null
+++ b/Client/BrzoDoLokacije/app/src/main/res/drawable/button_find_on_map.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:strokeColor="#FF093A4C"
+ android:strokeWidth="2"
+ android:strokeLineCap="round"
+ android:strokeLineJoin="round"
+ android:pathData="M11 18l-2-1-6 3V7l6-3 6 3 6-3v10M9 4v13m6-10v5"/>
+ <path
+ android:strokeColor="#FF093A4C"
+ android:strokeWidth="2"
+ android:strokeLineCap="round"
+ android:strokeLineJoin="round"
+ android:pathData="M16.5 20c1.38 0 2.5-1.12 2.5-2.5S17.88 15 16.5 15 14 16.12 14 17.5s1.12 2.5 2.5 2.5Z"/>
+ <path
+ android:strokeColor="#FF093A4C"
+ android:strokeWidth="2"
+ android:strokeLineCap="round"
+ android:strokeLineJoin="round"
+ android:pathData="M18.5 19.5L21 22"/>
+</vector> \ No newline at end of file
diff --git a/Client/BrzoDoLokacije/app/src/main/res/drawable/button_follow.xml b/Client/BrzoDoLokacije/app/src/main/res/drawable/button_follow.xml
new file mode 100644
index 0000000..80553a5
--- /dev/null
+++ b/Client/BrzoDoLokacije/app/src/main/res/drawable/button_follow.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="119dp"
+ android:height="45dp"
+ android:viewportWidth="119"
+ android:viewportHeight="45">
+ <group>
+ <path
+ android:fillColor="#FF093A4D"
+ android:pathData="M4 18.5c0-10.22 8.28-18.5 18.5-18.5h74c10.22 0 18.5 8.28 18.5 18.5v0c0 10.22-8.28 18.5-18.5 18.5h-74c-10.22 0-18.5-8.28-18.5-18.5z"/>
+ </group>
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M64.32 23V12.1h3.69c0.85 0 1.55 0.15 2.1 0.45 0.54 0.31 0.95 0.72 1.21 1.25 0.26 0.52 0.4 1.1 0.4 1.74 0 0.65-0.14 1.23-0.4 1.76-0.26 0.52-0.66 0.94-1.2 1.25-0.55 0.31-1.24 0.47-2.1 0.47H65.4v-1.18h2.6c0.58 0 1.05-0.1 1.4-0.3 0.36-0.2 0.62-0.48 0.78-0.82 0.16-0.35 0.24-0.74 0.24-1.18 0-0.43-0.08-0.82-0.24-1.17-0.16-0.34-0.42-0.61-0.78-0.8-0.36-0.2-0.83-0.3-1.43-0.3h-2.32V23h-1.32Zm9.35 0v-8.18h1.22v1.23h0.08c0.15-0.4 0.42-0.73 0.81-0.98 0.4-0.25 0.83-0.38 1.32-0.38h0.35l0.31 0.02V16l-0.29-0.05c-0.15-0.02-0.3-0.04-0.47-0.04-0.4 0-0.76 0.09-1.07 0.26-0.3 0.16-0.55 0.39-0.73 0.68-0.18 0.28-0.27 0.61-0.27 0.98V23h-1.26Zm8 0.2c-0.53 0-1-0.1-1.42-0.3-0.42-0.2-0.76-0.49-1-0.86-0.26-0.38-0.38-0.83-0.38-1.36 0-0.47 0.1-0.85 0.28-1.14 0.18-0.3 0.43-0.53 0.74-0.7 0.3-0.16 0.65-0.29 1.02-0.37 0.38-0.08 0.75-0.15 1.13-0.2l1.21-0.14c0.32-0.04 0.54-0.1 0.69-0.18 0.14-0.08 0.21-0.22 0.21-0.43v-0.04c0-0.52-0.14-0.93-0.43-1.22-0.28-0.3-0.71-0.44-1.3-0.44-0.6 0-1.06 0.13-1.4 0.4-0.34 0.26-0.58 0.54-0.72 0.84l-1.2-0.43c0.22-0.5 0.5-0.88 0.86-1.16 0.35-0.28 0.75-0.48 1.17-0.59 0.42-0.11 0.84-0.17 1.26-0.17 0.26 0 0.56 0.03 0.9 0.1 0.35 0.06 0.68 0.18 1 0.38 0.32 0.19 0.59 0.48 0.8 0.86 0.21 0.4 0.32 0.9 0.32 1.56V23h-1.26v-1.1H84.1c-0.09 0.17-0.23 0.36-0.43 0.56-0.2 0.2-0.46 0.38-0.79 0.52s-0.73 0.21-1.2 0.21Zm0.18-1.14c0.5 0 0.92-0.1 1.26-0.29 0.34-0.2 0.6-0.45 0.78-0.76 0.17-0.3 0.26-0.63 0.26-0.97v-1.15c-0.05 0.06-0.17 0.12-0.35 0.17-0.18 0.05-0.38 0.1-0.62 0.14l-0.67 0.1-0.53 0.06c-0.33 0.04-0.63 0.1-0.92 0.2-0.28 0.1-0.5 0.24-0.68 0.43-0.17 0.18-0.25 0.43-0.25 0.75 0 0.44 0.16 0.77 0.48 1 0.33 0.21 0.74 0.32 1.24 0.32Zm9.41-7.24v1.06h-4.24v-1.06h4.24Zm-3-1.96h1.26v7.8c0 0.35 0.05 0.62 0.15 0.8 0.1 0.17 0.24 0.29 0.4 0.35 0.17 0.05 0.35 0.08 0.53 0.08 0.14 0 0.26 0 0.34-0.02l0.22-0.04 0.25 1.13-0.35 0.1c-0.16 0.03-0.35 0.05-0.58 0.05-0.36 0-0.7-0.08-1.05-0.23-0.34-0.16-0.62-0.39-0.84-0.7-0.22-0.31-0.33-0.7-0.33-1.18v-8.14ZM93.16 23v-8.18h1.25V23h-1.26Zm0.63-9.55c-0.24 0-0.45-0.08-0.63-0.25-0.17-0.16-0.26-0.36-0.26-0.6 0-0.23 0.09-0.43 0.26-0.6 0.18-0.17 0.39-0.25 0.63-0.25 0.25 0 0.46 0.08 0.63 0.25 0.18 0.17 0.27 0.37 0.27 0.6 0 0.24-0.09 0.44-0.27 0.6-0.17 0.17-0.38 0.25-0.63 0.25Z"/>
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M34 21.25v2.1c-0.9-0.33-1.87-0.43-2.82-0.3-0.96 0.14-1.86 0.5-2.64 1.05-0.79 0.55-1.43 1.29-1.87 2.14C26.23 27.1 26 28.04 26 29h-2c0-1.22 0.28-2.43 0.82-3.52 0.53-1.1 1.31-2.06 2.28-2.8 0.97-0.75 2.09-1.27 3.29-1.52 1.2-0.24 2.43-0.21 3.61 0.1ZM32 20c-3.32 0-6-2.68-6-6 0-3.31 2.68-6 6-6 3.31 0 6 2.69 6 6 0 3.32-2.69 6-6 6Zm0-2c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4Zm6 6v-3h2v3h3v2h-3v3h-2v-3h-3v-2h3Z"/>
+</vector> \ No newline at end of file
diff --git a/Client/BrzoDoLokacije/app/src/main/res/drawable/button_sort.xml b/Client/BrzoDoLokacije/app/src/main/res/drawable/button_sort.xml
new file mode 100644
index 0000000..fe93f22
--- /dev/null
+++ b/Client/BrzoDoLokacije/app/src/main/res/drawable/button_sort.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:strokeColor="#FF093A4C"
+ android:strokeWidth="1.5"
+ android:strokeLineCap="round"
+ android:strokeLineJoin="round"
+ android:pathData="M10 14H2m6-4H2m4-4H2m10 12H2m17 2V4m0 16l3-3m-3 3l-3-3m3-13l3 3m-3-3l-3 3"/>
+</vector> \ No newline at end of file
diff --git a/Client/BrzoDoLokacije/app/src/main/res/drawable/button_unfollow.xml b/Client/BrzoDoLokacije/app/src/main/res/drawable/button_unfollow.xml
new file mode 100644
index 0000000..d3e3bbb
--- /dev/null
+++ b/Client/BrzoDoLokacije/app/src/main/res/drawable/button_unfollow.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="178dp"
+ android:height="45dp"
+ android:viewportWidth="178"
+ android:viewportHeight="45">
+ <group>
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M4 18.5c0-10.22 8.28-18.5 18.5-18.5h133c10.22 0 18.5 8.28 18.5 18.5v0c0 10.22-8.28 18.5-18.5 18.5h-133c-10.22 0-18.5-8.28-18.5-18.5z"/>
+ <path
+ android:strokeColor="#FF093A4C"
+ android:strokeWidth="1"
+ android:pathData="M4.5 18.5c0-9.94 8.06-18 18-18h133c9.94 0 18 8.06 18 18v0c0 9.94-8.06 18-18 18h-133c-9.94 0-18-8.06-18-18z"/>
+ </group>
+ <path
+ android:fillColor="#FF093A4C"
+ android:pathData="M47.82 23V12.1h3.69c0.85 0 1.55 0.15 2.1 0.45 0.54 0.31 0.95 0.72 1.21 1.25 0.26 0.52 0.4 1.1 0.4 1.74 0 0.65-0.14 1.23-0.4 1.76-0.26 0.52-0.66 0.94-1.2 1.25-0.55 0.31-1.24 0.47-2.1 0.47H48.9v-1.18h2.6c0.58 0 1.05-0.1 1.4-0.3 0.36-0.2 0.62-0.48 0.78-0.82 0.16-0.35 0.24-0.74 0.24-1.18 0-0.43-0.08-0.82-0.24-1.17-0.16-0.34-0.42-0.61-0.78-0.8-0.36-0.2-0.83-0.3-1.43-0.3h-2.32V23h-1.32Zm9.35 0v-8.18h1.22v1.23h0.08c0.15-0.4 0.42-0.73 0.81-0.98 0.4-0.25 0.83-0.38 1.32-0.38h0.35l0.31 0.02V16l-0.29-0.05c-0.15-0.02-0.3-0.04-0.47-0.04-0.4 0-0.76 0.09-1.07 0.26-0.3 0.16-0.55 0.39-0.73 0.68-0.18 0.28-0.27 0.61-0.27 0.98V23h-1.26Zm8.76 0.17c-0.78 0-1.46-0.17-2.04-0.52-0.56-0.35-1-0.84-1.31-1.47-0.3-0.63-0.46-1.37-0.46-2.2 0-0.85 0.15-1.58 0.46-2.22 0.3-0.65 0.74-1.15 1.29-1.5 0.55-0.37 1.2-0.55 1.94-0.55 0.42 0 0.84 0.07 1.26 0.21 0.41 0.15 0.8 0.38 1.13 0.7 0.34 0.31 0.62 0.73 0.82 1.25 0.2 0.53 0.3 1.17 0.3 1.93v0.54h-6.3v-1.1h5.02c0-0.45-0.09-0.86-0.27-1.23-0.18-0.36-0.44-0.65-0.78-0.85-0.33-0.21-0.73-0.32-1.18-0.32-0.5 0-0.94 0.13-1.3 0.37-0.37 0.25-0.64 0.57-0.84 0.96-0.2 0.4-0.3 0.82-0.3 1.27v0.72c0 0.62 0.11 1.15 0.33 1.58 0.21 0.42 0.51 0.75 0.9 0.97 0.38 0.22 0.83 0.33 1.33 0.33 0.33 0 0.63-0.04 0.9-0.14s0.5-0.24 0.7-0.42c0.2-0.2 0.34-0.43 0.45-0.72l1.21 0.34c-0.12 0.42-0.34 0.78-0.64 1.09-0.3 0.3-0.67 0.55-1.12 0.72-0.44 0.18-0.94 0.26-1.5 0.26Zm6.48-3.15l-0.02-1.56h0.25l3.58-3.64h1.56l-3.82 3.85h-0.1l-1.45 1.35ZM71.23 23V12.1h1.26V23h-1.26Zm5.2 0l-3.2-4.05 0.9-0.87 3.9 4.92h-1.6Zm2.96 0v-8.18h1.26V23H79.4Zm0.64-9.55c-0.24 0-0.45-0.08-0.63-0.25-0.17-0.16-0.26-0.36-0.26-0.6 0-0.23 0.09-0.43 0.26-0.6 0.18-0.17 0.39-0.25 0.63-0.25 0.25 0 0.46 0.08 0.63 0.25 0.18 0.17 0.27 0.37 0.27 0.6 0 0.24-0.1 0.44-0.27 0.6-0.17 0.17-0.38 0.25-0.63 0.25Zm4.18 4.63V23h-1.26v-8.18h1.22v1.28h0.1c0.2-0.42 0.49-0.75 0.88-1 0.39-0.26 0.9-0.39 1.51-0.39 0.55 0 1.04 0.12 1.45 0.34 0.42 0.23 0.74 0.57 0.97 1.03 0.24 0.45 0.35 1.03 0.35 1.72V23h-1.26v-5.11c0-0.65-0.16-1.15-0.5-1.5-0.33-0.37-0.79-0.55-1.37-0.55-0.4 0-0.76 0.09-1.08 0.26-0.31 0.18-0.56 0.43-0.74 0.76-0.18 0.34-0.27 0.74-0.27 1.22ZM91.73 23v-8.18h1.25V23h-1.25Zm0.64-9.55c-0.25 0-0.46-0.08-0.64-0.25-0.17-0.16-0.26-0.36-0.26-0.6 0-0.23 0.09-0.43 0.26-0.6 0.18-0.17 0.4-0.25 0.64-0.25S92.82 11.83 93 12c0.17 0.17 0.26 0.37 0.26 0.6 0 0.24-0.09 0.44-0.26 0.6-0.18 0.17-0.39 0.25-0.63 0.25Zm7.14 12.62V14.82h1.21v1.3h0.15l0.38-0.55c0.17-0.22 0.4-0.42 0.72-0.6 0.3-0.17 0.73-0.26 1.27-0.26 0.68 0 1.3 0.17 1.82 0.52 0.52 0.34 0.93 0.83 1.23 1.46 0.3 0.64 0.44 1.38 0.44 2.24 0 0.87-0.15 1.62-0.44 2.25-0.3 0.64-0.7 1.13-1.23 1.47-0.52 0.35-1.12 0.52-1.8 0.52-0.53 0-0.95-0.09-1.27-0.26-0.31-0.18-0.56-0.38-0.73-0.6-0.17-0.23-0.3-0.42-0.39-0.57h-0.1v4.33H99.5Zm1.23-7.16c0 0.62 0.1 1.16 0.27 1.63 0.18 0.47 0.45 0.84 0.8 1.1 0.34 0.27 0.77 0.4 1.28 0.4 0.52 0 0.96-0.14 1.31-0.41 0.36-0.28 0.62-0.66 0.8-1.13 0.18-0.48 0.27-1 0.27-1.6 0-0.57-0.09-1.08-0.26-1.55-0.18-0.46-0.44-0.83-0.8-1.1-0.35-0.27-0.8-0.4-1.32-0.4s-0.95 0.12-1.3 0.38c-0.34 0.26-0.6 0.61-0.78 1.08-0.18 0.45-0.27 0.99-0.27 1.6Zm7.9 4.09v-8.18h1.22v1.23h0.09c0.15-0.4 0.41-0.73 0.8-0.98 0.4-0.25 0.84-0.38 1.33-0.38h0.34l0.32 0.02V16l-0.3-0.05c-0.14-0.02-0.3-0.04-0.47-0.04-0.4 0-0.75 0.09-1.06 0.26-0.31 0.16-0.56 0.39-0.74 0.68-0.18 0.28-0.27 0.61-0.27 0.98V23h-1.25Zm8 0.2c-0.52 0-1-0.1-1.42-0.3-0.42-0.2-0.75-0.49-1-0.86-0.25-0.38-0.38-0.83-0.38-1.36 0-0.47 0.1-0.85 0.28-1.14 0.19-0.3 0.43-0.53 0.74-0.7 0.31-0.16 0.65-0.29 1.02-0.37 0.38-0.08 0.76-0.15 1.14-0.2l1.2-0.14c0.32-0.04 0.55-0.1 0.69-0.18 0.15-0.08 0.22-0.22 0.22-0.43v-0.04c0-0.52-0.15-0.93-0.43-1.22-0.29-0.3-0.72-0.44-1.3-0.44-0.6 0-1.07 0.13-1.4 0.4-0.35 0.26-0.59 0.54-0.73 0.84l-1.2-0.43c0.22-0.5 0.5-0.88 0.86-1.16 0.36-0.28 0.75-0.48 1.17-0.59 0.43-0.11 0.85-0.17 1.26-0.17 0.26 0 0.56 0.03 0.9 0.1 0.35 0.06 0.68 0.18 1 0.38 0.32 0.19 0.6 0.48 0.8 0.86 0.22 0.4 0.33 0.9 0.33 1.56V23h-1.26v-1.1h-0.07c-0.08 0.17-0.22 0.36-0.42 0.56-0.2 0.2-0.47 0.38-0.8 0.52-0.33 0.14-0.73 0.21-1.2 0.21Zm0.19-1.14c0.5 0 0.91-0.1 1.25-0.29 0.35-0.2 0.6-0.45 0.78-0.76 0.18-0.3 0.27-0.63 0.27-0.97v-1.15c-0.05 0.06-0.17 0.12-0.35 0.17-0.18 0.05-0.39 0.1-0.62 0.14l-0.68 0.1-0.53 0.06c-0.32 0.04-0.63 0.1-0.91 0.2s-0.5 0.24-0.68 0.43c-0.17 0.18-0.26 0.43-0.26 0.75 0 0.44 0.16 0.77 0.49 1 0.32 0.21 0.74 0.32 1.24 0.32Zm9.17 1.11c-0.76 0-1.42-0.18-1.98-0.54-0.55-0.37-0.98-0.86-1.28-1.5-0.3-0.64-0.44-1.36-0.44-2.18 0-0.83 0.15-1.56 0.45-2.2 0.31-0.64 0.74-1.14 1.3-1.5 0.55-0.36 1.2-0.54 1.93-0.54 0.58 0 1.1 0.1 1.56 0.32 0.46 0.21 0.84 0.51 1.13 0.9 0.3 0.38 0.48 0.83 0.55 1.34h-1.26c-0.1-0.37-0.3-0.7-0.63-1-0.33-0.28-0.77-0.43-1.33-0.43-0.49 0-0.92 0.13-1.28 0.38-0.37 0.26-0.66 0.61-0.86 1.08-0.2 0.45-0.3 1-0.3 1.6 0 0.64 0.1 1.2 0.3 1.66 0.2 0.47 0.48 0.83 0.84 1.1 0.37 0.25 0.8 0.38 1.3 0.38 0.33 0 0.63-0.06 0.9-0.17 0.26-0.11 0.48-0.28 0.67-0.49 0.18-0.21 0.32-0.47 0.4-0.77h1.25c-0.07 0.49-0.25 0.92-0.53 1.3-0.27 0.4-0.64 0.7-1.1 0.92-0.45 0.23-0.98 0.34-1.59 0.34Zm-0.61-9.46l1.3-2.47h1.47l-1.67 2.47h-1.1Zm9.1 9.46c-0.79 0-1.47-0.17-2.04-0.52-0.57-0.35-1-0.84-1.32-1.47-0.3-0.63-0.45-1.37-0.45-2.2 0-0.85 0.15-1.58 0.45-2.22 0.31-0.65 0.74-1.15 1.3-1.5 0.55-0.37 1.2-0.55 1.93-0.55 0.43 0 0.85 0.07 1.26 0.21 0.42 0.15 0.8 0.38 1.14 0.7 0.34 0.31 0.61 0.73 0.81 1.25 0.2 0.53 0.3 1.17 0.3 1.93v0.54h-6.3v-1.1h5.03c0-0.45-0.1-0.86-0.28-1.23-0.18-0.36-0.44-0.65-0.78-0.85-0.33-0.21-0.72-0.32-1.18-0.32-0.5 0-0.93 0.13-1.3 0.37-0.36 0.25-0.64 0.57-0.84 0.96-0.19 0.4-0.29 0.82-0.29 1.27v0.72c0 0.62 0.1 1.15 0.32 1.58 0.22 0.42 0.52 0.75 0.9 0.97 0.39 0.22 0.83 0.33 1.34 0.33 0.33 0 0.63-0.04 0.9-0.14 0.26-0.1 0.5-0.24 0.7-0.42 0.19-0.2 0.34-0.43 0.44-0.72l1.22 0.34c-0.13 0.42-0.34 0.78-0.65 1.09-0.3 0.3-0.67 0.55-1.11 0.72-0.45 0.18-0.95 0.26-1.5 0.26Zm6.56-5.1V23h-1.26v-8.18H141v1.28h0.11c0.2-0.42 0.48-0.75 0.87-1 0.4-0.26 0.9-0.39 1.52-0.39 0.55 0 1.03 0.12 1.45 0.34 0.42 0.23 0.74 0.57 0.97 1.03 0.23 0.45 0.35 1.03 0.35 1.72V23H145v-5.11c0-0.65-0.17-1.15-0.5-1.5-0.33-0.37-0.8-0.55-1.38-0.55-0.4 0-0.76 0.09-1.07 0.26-0.31 0.18-0.56 0.43-0.74 0.76-0.18 0.34-0.27 0.74-0.27 1.22Zm7.51-3.25h1.26v8.78c0 0.5-0.09 0.94-0.26 1.3-0.17 0.38-0.43 0.66-0.78 0.86-0.34 0.2-0.78 0.3-1.3 0.3h-0.13-0.13V24.9h0.12 0.12c0.38 0 0.66-0.12 0.84-0.34 0.17-0.23 0.26-0.55 0.26-0.96v-8.78Zm0.62-1.37c-0.24 0-0.46-0.08-0.63-0.25-0.18-0.16-0.26-0.36-0.26-0.6 0-0.23 0.08-0.43 0.26-0.6 0.17-0.17 0.39-0.25 0.63-0.25 0.25 0 0.46 0.08 0.63 0.25 0.18 0.17 0.27 0.37 0.27 0.6 0 0.24-0.1 0.44-0.27 0.6-0.17 0.17-0.38 0.25-0.63 0.25Zm6.37 9.72c-0.79 0-1.47-0.17-2.04-0.52-0.56-0.35-1-0.84-1.31-1.47-0.3-0.63-0.46-1.37-0.46-2.2 0-0.85 0.15-1.58 0.46-2.22 0.3-0.65 0.74-1.15 1.29-1.5 0.55-0.37 1.2-0.55 1.94-0.55 0.42 0 0.84 0.07 1.26 0.21 0.41 0.15 0.8 0.38 1.13 0.7 0.34 0.31 0.62 0.73 0.82 1.25 0.2 0.53 0.3 1.17 0.3 1.93v0.54h-6.3v-1.1h5.02c0-0.45-0.09-0.86-0.27-1.23-0.18-0.36-0.44-0.65-0.78-0.85-0.34-0.21-0.73-0.32-1.18-0.32-0.5 0-0.94 0.13-1.3 0.37-0.37 0.25-0.64 0.57-0.84 0.96-0.2 0.4-0.3 0.82-0.3 1.27v0.72c0 0.62 0.11 1.15 0.33 1.58 0.21 0.42 0.51 0.75 0.9 0.97 0.38 0.22 0.83 0.33 1.33 0.33 0.33 0 0.63-0.04 0.9-0.14s0.5-0.24 0.7-0.42c0.2-0.2 0.34-0.43 0.45-0.72l1.21 0.34c-0.12 0.42-0.34 0.78-0.64 1.09-0.3 0.3-0.68 0.55-1.12 0.72-0.44 0.18-0.94 0.26-1.5 0.26Z"/>
+ <path
+ android:fillColor="#FF093A4C"
+ android:pathData="M32 20.25v2.1c-0.9-0.33-1.87-0.43-2.82-0.3-0.96 0.14-1.86 0.5-2.64 1.05-0.79 0.55-1.43 1.29-1.87 2.14C24.23 26.1 24 27.04 24 28h-2c0-1.22 0.28-2.43 0.82-3.52 0.53-1.1 1.31-2.06 2.28-2.8 0.97-0.75 2.09-1.27 3.29-1.52 1.2-0.24 2.43-0.21 3.61 0.1ZM30 19c-3.32 0-6-2.68-6-6 0-3.31 2.68-6 6-6 3.31 0 6 2.69 6 6 0 3.32-2.69 6-6 6Zm0-2c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4Zm7 6.59l2.12-2.13 1.42 1.42L38.4 25l2.13 2.12-1.42 1.42L37 26.4l-2.12 2.13-1.42-1.42L35.6 25l-2.13-2.12 1.42-1.42L37 23.6Z"/>
+</vector> \ No newline at end of file
diff --git a/Client/BrzoDoLokacije/app/src/main/res/drawable/ic_baseline_add_location_24.xml b/Client/BrzoDoLokacije/app/src/main/res/drawable/ic_baseline_add_location_24.xml
new file mode 100644
index 0000000..8f88131
--- /dev/null
+++ b/Client/BrzoDoLokacije/app/src/main/res/drawable/ic_baseline_add_location_24.xml
@@ -0,0 +1,5 @@
+<vector android:height="24dp" android:tint="#FF3535"
+ 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,2C8.14,2 5,5.14 5,9c0,5.25 7,13 7,13s7,-7.75 7,-13c0,-3.86 -3.14,-7 -7,-7zM16,10h-3v3h-2v-3L8,10L8,8h3L11,5h2v3h3v2z"/>
+</vector>
diff --git a/Client/BrzoDoLokacije/app/src/main/res/drawable/ic_baseline_check_24.xml b/Client/BrzoDoLokacije/app/src/main/res/drawable/ic_baseline_check_24.xml
new file mode 100644
index 0000000..257e641
--- /dev/null
+++ b/Client/BrzoDoLokacije/app/src/main/res/drawable/ic_baseline_check_24.xml
@@ -0,0 +1,5 @@
+<vector android:height="24dp" android:tint="#666666"
+ 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="M9,16.17L4.83,12l-1.42,1.41L9,19 21,7l-1.41,-1.41z"/>
+</vector>
diff --git a/Client/BrzoDoLokacije/app/src/main/res/drawable/ic_baseline_close_24.xml b/Client/BrzoDoLokacije/app/src/main/res/drawable/ic_baseline_close_24.xml
new file mode 100644
index 0000000..42a6279
--- /dev/null
+++ b/Client/BrzoDoLokacije/app/src/main/res/drawable/ic_baseline_close_24.xml
@@ -0,0 +1,5 @@
+<vector android:height="24dp" android:tint="#666666"
+ 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="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"/>
+</vector>
diff --git a/Client/BrzoDoLokacije/app/src/main/res/drawable/profile_view_background.xml b/Client/BrzoDoLokacije/app/src/main/res/drawable/profile_view_background.xml
new file mode 100644
index 0000000..2af9f24
--- /dev/null
+++ b/Client/BrzoDoLokacije/app/src/main/res/drawable/profile_view_background.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+ <solid android:color="#E6FFFFFF"/>
+ <padding android:left="2dp"
+ android:top="2dp"
+ android:right="2dp"
+ android:bottom="2dp"/>
+
+ <corners
+ android:topLeftRadius="30dp"
+ android:topRightRadius="30dp"
+ android:bottomLeftRadius="0dp"
+ android:bottomRightRadius="0dp"
+ />
+</shape> \ No newline at end of file
diff --git a/Client/BrzoDoLokacije/app/src/main/res/layout/activity_add_post.xml b/Client/BrzoDoLokacije/app/src/main/res/layout/activity_add_post.xml
index a7a6e06..fbe2230 100644
--- a/Client/BrzoDoLokacije/app/src/main/res/layout/activity_add_post.xml
+++ b/Client/BrzoDoLokacije/app/src/main/res/layout/activity_add_post.xml
@@ -19,7 +19,7 @@
<Button
android:id="@+id/nextImage"
android:layout_width="78dp"
- android:layout_height="499dp"
+ android:layout_height="0dp"
android:background="@drawable/rounded_transparent_button"
android:gravity="right"
android:padding="30dp"
@@ -33,7 +33,7 @@
<Button
android:id="@+id/previousImage"
android:layout_width="70dp"
- android:layout_height="497dp"
+ android:layout_height="0dp"
android:background="@drawable/rounded_transparent_button"
android:gravity="left"
@@ -73,7 +73,7 @@
<EditText
android:id="@+id/etActivityAddPostLocation"
- android:layout_width="match_parent"
+ android:layout_width="200dp"
android:layout_height="50dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
@@ -81,9 +81,22 @@
android:hint="Reykjavik, Iceland"
android:inputType="textEmailAddress"
app:layout_constraintBottom_toTopOf="@+id/tvActivityAddPostDescriptiontext"
- app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
+ <Button
+ android:id="@+id/btnActivityAddPostAddLocation"
+ android:layout_width="wrap_content"
+ android:layout_height="50dp"
+ android:layout_marginStart="16dp"
+ android:layout_marginEnd="16dp"
+ android:background="@drawable/rounded_cyan_button"
+ android:backgroundTint="#1C789A"
+ android:text="Dodaj lokaciju"
+ app:layout_constraintBottom_toTopOf="@+id/tvActivityAddPostDescriptiontext"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toEndOf="@+id/etActivityAddPostLocation" />
+
+
<TextView
android:id="@+id/tvActivityAddPostDescriptiontext"
android:layout_width="match_parent"
@@ -104,7 +117,7 @@
android:ems="10"
android:hint="Reykjavik, Iceland"
android:inputType="textEmailAddress"
- app:layout_constraintBottom_toTopOf="@+id/btnActivityAddPostPost"
+ app:layout_constraintBottom_toTopOf="@+id/llTags"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
@@ -136,5 +149,44 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/isActivityAddPostSwitcher" />
+ <LinearLayout
+ android:id="@+id/llTags"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="20dp"
+ android:layout_marginRight="20dp"
+ android:orientation="horizontal"
+ app:layout_constraintBottom_toTopOf="@+id/acTags"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"></LinearLayout>
+
+ <EditText
+ android:id="@+id/acTags"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="20dp"
+ android:layout_marginRight="20dp"
+ android:hint="Planina,Reka,Park..."
+ android:minHeight="48dp"
+ android:maxLength= "12"
+ app:layout_constraintBottom_toTopOf="@+id/btnActivityAddPostPost"
+ app:layout_constraintEnd_toStartOf="@+id/btnActivityAddPostAddTag"
+ app:layout_constraintStart_toStartOf="parent" />
+
+ <Button
+ android:id="@+id/btnActivityAddPostAddTag"
+ android:layout_width="wrap_content"
+ android:layout_height="40dp"
+ android:layout_marginTop="5dp"
+ android:layout_marginEnd="20dp"
+ android:layout_marginStart="20dp"
+ android:layout_marginBottom="5dp"
+ android:background="@drawable/rounded_cyan_button"
+ android:backgroundTint="#1C789A"
+ android:text="Dodaj tag"
+ app:layout_constraintBottom_toTopOf="@+id/btnActivityAddPostPost"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintTop_toBottomOf="@+id/llTags" />
+
</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file
diff --git a/Client/BrzoDoLokacije/app/src/main/res/layout/activity_capture_post.xml b/Client/BrzoDoLokacije/app/src/main/res/layout/activity_capture_post.xml
index 23d34ee..2b64a27 100644
--- a/Client/BrzoDoLokacije/app/src/main/res/layout/activity_capture_post.xml
+++ b/Client/BrzoDoLokacije/app/src/main/res/layout/activity_capture_post.xml
@@ -39,59 +39,68 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
- android:layout_marginTop="516dp"
android:layout_marginEnd="16dp"
android:text="Lokacija"
+ app:layout_constraintBottom_toTopOf="@+id/etActivityCapturePostLocation"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toTopOf="parent" />
+ app:layout_constraintStart_toStartOf="parent" />
<EditText
android:id="@+id/etActivityCapturePostLocation"
- android:layout_width="match_parent"
+ android:layout_width="200dp"
android:layout_height="50dp"
android:layout_marginStart="16dp"
- android:layout_marginTop="4dp"
android:layout_marginEnd="16dp"
android:ems="10"
android:hint="Reykjavik, Iceland"
+ android:importantForAutofill="no"
android:inputType="textEmailAddress"
+ app:layout_constraintBottom_toTopOf="@+id/tvActivityCapturePostDescriptiontext"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toBottomOf="@+id/tvActivityCapturePostLocationtext"
- tools:ignore="DuplicateSpeakableTextCheck,TextContrastCheck"
- android:importantForAutofill="no" />
+ tools:ignore="DuplicateSpeakableTextCheck,TextContrastCheck" />
+ <Button
+ android:id="@+id/btnActivityCapturePostAddLocation"
+ android:layout_width="wrap_content"
+ android:layout_height="50dp"
+ android:layout_marginStart="16dp"
+ android:layout_marginEnd="16dp"
+ android:background="@drawable/rounded_cyan_button"
+ android:backgroundTint="#1C789A"
+ android:text="Dodaj lokaciju"
+ app:layout_constraintBottom_toTopOf="@+id/tvActivityCapturePostDescriptiontext"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toEndOf="@+id/etActivityCapturePostLocation" />
+
<TextView
android:id="@+id/tvActivityCapturePostDescriptiontext"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
- android:layout_marginTop="8dp"
android:layout_marginEnd="16dp"
android:text="Opis"
+ app:layout_constraintBottom_toTopOf="@+id/etActivityCapturePostDescription"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toBottomOf="@+id/etActivityCapturePostLocation" />
+ app:layout_constraintStart_toStartOf="parent" />
<EditText
android:id="@+id/etActivityCapturePostDescription"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginStart="16dp"
- android:layout_marginTop="4dp"
android:layout_marginEnd="16dp"
android:ems="10"
android:hint="Reykjavik, Iceland"
+ android:importantForAutofill="no"
android:inputType="textEmailAddress"
+ app:layout_constraintBottom_toTopOf="@+id/llTagsCap"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toBottomOf="@+id/tvActivityCapturePostDescriptiontext"
- tools:ignore="TextContrastCheck"
- android:importantForAutofill="no" />
+ tools:ignore="TextContrastCheck" />
<Button
@@ -126,4 +135,43 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
+ <LinearLayout
+ android:id="@+id/llTagsCap"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="20dp"
+ android:layout_marginRight="20dp"
+ android:orientation="horizontal"
+ app:layout_constraintBottom_toTopOf="@+id/acTagsCap"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"></LinearLayout>
+
+ <EditText
+ android:id="@+id/acTagsCap"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="20dp"
+ android:layout_marginRight="20dp"
+ android:hint="Planina,Reka,Park..."
+ android:minHeight="48dp"
+ android:maxLength= "12"
+ app:layout_constraintBottom_toTopOf="@+id/btnActivityCapturePostPost"
+ app:layout_constraintEnd_toStartOf="@+id/btnActivityAddPostAddTagCap"
+ app:layout_constraintStart_toStartOf="parent" />
+
+ <Button
+ android:id="@+id/btnActivityAddPostAddTagCap"
+ android:layout_width="wrap_content"
+ android:layout_height="40dp"
+ android:layout_marginTop="5dp"
+ android:layout_marginEnd="20dp"
+ android:layout_marginStart="20dp"
+ android:layout_marginBottom="5dp"
+ android:background="@drawable/rounded_cyan_button"
+ android:backgroundTint="#1C789A"
+ android:text="Dodaj tag"
+ app:layout_constraintBottom_toTopOf="@+id/btnActivityCapturePostPost"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintTop_toBottomOf="@+id/llTagsCap" />
+
</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file
diff --git a/Client/BrzoDoLokacije/app/src/main/res/layout/activity_chat.xml b/Client/BrzoDoLokacije/app/src/main/res/layout/activity_chat.xml
new file mode 100644
index 0000000..9e28d6d
--- /dev/null
+++ b/Client/BrzoDoLokacije/app/src/main/res/layout/activity_chat.xml
@@ -0,0 +1,51 @@
+<?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=".Activities.ChatActivity">
+ <androidx.constraintlayout.widget.ConstraintLayout
+ android:id="@+id/topBanner"
+ android:layout_width="match_parent"
+ android:clickable="true"
+ android:layout_height="50dp"
+ android:background="@color/dark_blue_transparent"
+ app:layout_constraintStart_toStartOf="parent">
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:textSize="40dp"
+ android:id="@+id/tvFragmentTitle"
+ android:text="Chat"
+ android:textColor="@color/white"/>
+
+ </androidx.constraintlayout.widget.ConstraintLayout>
+ <ImageButton
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:id="@+id/addNewMessage"
+ android:clickable="true"
+ android:focusable="true"
+ app:layout_constraintTop_toBottomOf="@id/topBanner"
+ android:src="@drawable/button_chat">
+
+
+ </ImageButton>
+ <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:id="@+id/swipeContainer"
+ app:layout_constraintTop_toBottomOf="@id/addNewMessage">
+
+ <androidx.recyclerview.widget.RecyclerView
+ android:id="@+id/rvMain"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent" >
+
+ </androidx.recyclerview.widget.RecyclerView>
+ </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
+
+</androidx.constraintlayout.widget.ConstraintLayout> \ 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
new file mode 100644
index 0000000..72060f7
--- /dev/null
+++ b/Client/BrzoDoLokacije/app/src/main/res/layout/activity_chat_conversation.xml
@@ -0,0 +1,104 @@
+<?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=".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"
+ 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: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.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">
+
+ <androidx.recyclerview.widget.RecyclerView
+ android:id="@+id/rvMain"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ app:layout_constraintBottom_toBottomOf="parent"
+ >
+
+ </androidx.recyclerview.widget.RecyclerView>
+ </androidx.constraintlayout.widget.ConstraintLayout>
+
+ <androidx.cardview.widget.CardView
+ android:id="@+id/cvParentMessageEdit"
+ 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_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent">
+
+
+ <com.google.android.material.textfield.TextInputEditText
+ android:id="@+id/etNewMessage"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@drawable/rounded_white_button_login"
+ android:hint=" poruka"
+ android:inputType="textPersonName"
+ android:paddingLeft="15dp" />
+
+ <ImageButton
+ android:id="@+id/btnSendMessage"
+ android:layout_width="49dp"
+ android:layout_height="50dp"
+ android:layout_gravity="right"
+ android:scaleType="centerCrop"
+ android:src="@drawable/post_comment"
+ app:cornerRadius="16dp" />
+
+ </androidx.cardview.widget.CardView>
+</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file
diff --git a/Client/BrzoDoLokacije/app/src/main/res/layout/activity_maps.xml b/Client/BrzoDoLokacije/app/src/main/res/layout/activity_maps.xml
index 01c8abd..8d37c29 100644
--- a/Client/BrzoDoLokacije/app/src/main/res/layout/activity_maps.xml
+++ b/Client/BrzoDoLokacije/app/src/main/res/layout/activity_maps.xml
@@ -1,9 +1,89 @@
<?xml version="1.0" encoding="utf-8"?>
-<fragment xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:map="http://schemas.android.com/apk/res-auto"
+<androidx.constraintlayout.widget.ConstraintLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
- android:id="@+id/map"
- android:name="com.google.android.gms.maps.SupportMapFragment"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
- tools:context=".Activities.MapsActivity" /> \ No newline at end of file
+ tools:context=".Activities.MapsActivity">
+ <org.osmdroid.views.MapView
+ android:id="@+id/ActivityMapsMapView"
+ 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"
+ />
+
+
+
+ <com.google.android.material.floatingactionbutton.FloatingActionButton
+ android:id="@+id/ActivityMapsMyLocation"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentStart="true"
+ android:backgroundTint="#FFFFFF"
+ android:layout_marginRight="10dp"
+ android:layout_marginBottom="80dp"
+ android:clickable="true"
+ android:focusable="true"
+ android:tint="#FFFFFF"
+ app:layout_constraintBottom_toBottomOf="@+id/ActivityMapsMapView"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:rippleColor="#FFFFFF"
+ app:srcCompat="@android:drawable/ic_menu_mylocation" />
+
+ <com.google.android.material.floatingactionbutton.FloatingActionButton
+ android:id="@+id/ActivityMapsConfirmLocation"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentStart="true"
+ android:layout_marginBottom="80dp"
+ android:layout_marginLeft="10dp"
+ android:backgroundTint="#FFFFFF"
+ android:clickable="true"
+ android:focusable="true"
+ android:tint="#FFFFFF"
+ app:layout_constraintBottom_toBottomOf="@+id/ActivityMapsMapView"
+ app:layout_constraintStart_toStartOf="parent"
+ app:rippleColor="#FFFFFF"
+ app:srcCompat="@drawable/ic_baseline_check_24"
+ android:visibility="invisible"/>
+
+ <androidx.cardview.widget.CardView
+ android:id="@+id/ActivityMapsCardViewSearch"
+ android:layout_width="0dp"
+ android:layout_marginTop="60dp"
+ android:layout_height="40dp"
+ android:layout_marginStart="16dp"
+ 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/ActivityMapsSearchBar"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@drawable/rounded_white_button_login"
+ android:hint=" Pretraga"
+ android:inputType="textPersonName"
+ android:paddingLeft="15dp" />
+
+ <com.google.android.material.button.MaterialButton
+ android:id="@+id/ActivityMapsSearchButton"
+ android:layout_width="49dp"
+ android:layout_height="match_parent"
+ android:layout_gravity="right"
+ android:background="#00FFFFFF"
+ app:backgroundTint="#00FFFFFF"
+ app:cornerRadius="16dp"
+ app:icon="@drawable/ic_baseline_search_24"
+ app:iconTint="#333D70" />
+
+ </androidx.cardview.widget.CardView>
+
+ </androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file
diff --git a/Client/BrzoDoLokacije/app/src/main/res/layout/activity_single_post.xml b/Client/BrzoDoLokacije/app/src/main/res/layout/activity_single_post.xml
index 7c1f8bc..e3cabb5 100644
--- a/Client/BrzoDoLokacije/app/src/main/res/layout/activity_single_post.xml
+++ b/Client/BrzoDoLokacije/app/src/main/res/layout/activity_single_post.xml
@@ -41,8 +41,8 @@
android:gravity="top|start"
android:padding="@dimen/text_padding"
android:text="Drzava, grad"
- app:layout_constraintTop_toBottomOf="@+id/tvLocationType"
- tools:layout_editor_absoluteX="0dp" />
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@+id/tvLocationType" />
<TextView
android:id="@+id/tvTitle"
@@ -52,7 +52,8 @@
android:padding="@dimen/text_padding"
android:text="Naslov"
android:textSize="@dimen/header1_size"
- android:textStyle="bold" />
+ android:textStyle="bold"
+ app:layout_constraintStart_toStartOf="parent" />
<TextView
android:id="@+id/tvLocationType"
@@ -61,15 +62,27 @@
android:gravity="top|start"
android:padding="@dimen/text_padding"
android:text="Tip lokacije"
- app:layout_constraintTop_toBottomOf="@+id/tvTitle"
- tools:layout_editor_absoluteX="0dp" />
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@+id/tvTitle" />
+
+ <TextView
+ android:id="@+id/tvUser"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:clickable="true"
+ android:gravity="top|start"
+ android:padding="@dimen/text_padding"
+ android:text="User"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@+id/tvLocationParent" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/constraintLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginTop="20dp"
+ android:layout_marginTop="36dp"
app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tvLocationParent">
@@ -161,6 +174,7 @@
android:layout_height="wrap_content"
android:text="TextViewTextViewTextViewTextViewTextViewTextViewTextViewTextViewTextViewTextViewTextViewTextViewTextViewTextViewTextViewTextViewTextViewTextViewTextViewTextViewTextViewTextViewTextViewTextViewTextViewTextViewTextViewTextViewTextViewTextViewTextViewTextView"
app:layout_constraintTop_toBottomOf="@+id/tvDescriptionLabel" />
+
</androidx.constraintlayout.widget.ConstraintLayout>
<LinearLayout
@@ -177,9 +191,9 @@
android:layout_width="30dp"
android:layout_height="40dp"
android:layout_gravity="center_vertical"
- android:scaleType="centerCrop"
android:layout_weight="1"
android:backgroundTint="@color/white"
+ android:scaleType="centerCrop"
android:src="@drawable/empty_star" />
<ImageButton
@@ -187,9 +201,9 @@
android:layout_width="30dp"
android:layout_height="40dp"
android:layout_gravity="center_vertical"
- android:scaleType="centerCrop"
android:layout_weight="1"
android:backgroundTint="@color/white"
+ android:scaleType="centerCrop"
android:src="@drawable/empty_star" />
<ImageButton
@@ -197,9 +211,9 @@
android:layout_width="30dp"
android:layout_height="40dp"
android:layout_gravity="center_vertical"
- android:scaleType="centerCrop"
android:layout_weight="1"
android:backgroundTint="@color/white"
+ android:scaleType="centerCrop"
android:src="@drawable/empty_star" />
<ImageButton
@@ -207,9 +221,9 @@
android:layout_width="30dp"
android:layout_height="40dp"
android:layout_gravity="center_vertical"
- android:scaleType="centerCrop"
android:layout_weight="1"
android:backgroundTint="@color/white"
+ android:scaleType="centerCrop"
android:src="@drawable/empty_star" />
<ImageButton
@@ -217,48 +231,48 @@
android:layout_width="30dp"
android:layout_height="40dp"
android:layout_gravity="center_vertical"
- android:scaleType="centerCrop"
android:layout_weight="1"
android:backgroundTint="@color/white"
+ android:scaleType="centerCrop"
android:src="@drawable/empty_star" />
<Button
android:id="@+id/submitRating"
android:layout_width="30dp"
android:layout_height="40dp"
+ android:layout_gravity="center_vertical"
android:layout_weight="1"
android:backgroundTint="@color/white"
android:text="ok"
- android:layout_gravity="center_vertical"
- android:textColor="@color/black"
- />
+ android:textColor="@color/black" />
</LinearLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/linearLayout2">
+
<LinearLayout
+ android:id="@+id/postCommentLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:id="@+id/postCommentLayout"
android:orientation="horizontal"
- app:layout_constraintStart_toStartOf="parent" >
+ app:layout_constraintStart_toStartOf="parent">
+
<EditText
+ android:id="@+id/NewComment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
- android:hint="Unesite komentar ovde"
- android:id="@+id/NewComment"
- />
+ android:hint="Unesite komentar ovde" />
<ImageButton
android:id="@+id/btnPostComment"
android:layout_width="50dp"
- android:scaleType="fitCenter"
android:layout_height="50dp"
- android:src="@drawable/post_comment"
- android:backgroundTint="@color/white"/>
+ android:backgroundTint="@color/white"
+ android:scaleType="fitCenter"
+ android:src="@drawable/post_comment" />
</LinearLayout>
@@ -266,26 +280,26 @@
android:id="@+id/tvCommentLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- app:layout_constraintTop_toBottomOf="@id/postCommentLayout"
android:padding="@dimen/text_padding"
android:text="Komentari"
- android:textStyle="bold" />
+ android:textStyle="bold"
+ app:layout_constraintTop_toBottomOf="@id/postCommentLayout" />
<TextView
android:id="@+id/tvCommentCount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="@dimen/text_padding"
- app:layout_constraintTop_toBottomOf="@id/postCommentLayout"
- android:text="3"
- app:layout_constraintStart_toEndOf="@id/tvCommentLabel" />
+ android:text="0"
+ app:layout_constraintStart_toEndOf="@id/tvCommentLabel"
+ app:layout_constraintTop_toBottomOf="@id/postCommentLayout" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvComments"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- app:layout_constraintTop_toBottomOf="@id/tvCommentLabel"
- android:nestedScrollingEnabled="false">
+ android:nestedScrollingEnabled="false"
+ app:layout_constraintTop_toBottomOf="@id/tvCommentLabel">
</androidx.recyclerview.widget.RecyclerView>
</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/Client/BrzoDoLokacije/app/src/main/res/layout/activity_user_profile.xml b/Client/BrzoDoLokacije/app/src/main/res/layout/activity_user_profile.xml
new file mode 100644
index 0000000..8762183
--- /dev/null
+++ b/Client/BrzoDoLokacije/app/src/main/res/layout/activity_user_profile.xml
@@ -0,0 +1,252 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout 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=".Activities.ActivityUserProfile">
+
+
+ <androidx.constraintlayout.widget.ConstraintLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <ImageView
+
+ android:id="@+id/imageView3"
+ android:layout_width="match_parent"
+ android:layout_height="300dp"
+ android:foreground="@drawable/b3"
+ android:foregroundGravity="center_vertical|center|center_horizontal|fill"
+ android:src="@drawable/b3"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent" />
+
+
+ <com.google.android.material.imageview.ShapeableImageView
+
+ android:id="@+id/tvFragmentProfileInfoContainer"
+ android:layout_width="0dp"
+ android:layout_height="199dp"
+ android:layout_marginStart="20dp"
+ android:layout_marginTop="150dp"
+ android:layout_marginEnd="20dp"
+ android:adjustViewBounds="true"
+ android:background="@drawable/profile_view_background"
+
+ android:elevation="1dp"
+ android:scaleType="fitEnd"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintHorizontal_bias="0.0"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="@+id/imageView3"
+ app:shapeAppearanceOverlay="@style/imageViewRoundedEdge" />
+
+
+ <androidx.cardview.widget.CardView
+ android:id="@+id/cvFragmentHomePageProfile"
+ android:layout_width="140dp"
+ android:layout_height="140dp"
+ android:layout_gravity="center"
+ android:layout_marginTop="80dp"
+ android:elevation="10dp"
+ app:cardCornerRadius="250dp"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent">
+
+ <ImageView
+
+ android:id="@+id/tvActivityProfileProfilePicture"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:elevation="10dp"
+ android:scaleType="centerCrop"
+ android:src="@drawable/ic_baseline_person_24"
+ tools:ignore="ContentDescription" />
+ </androidx.cardview.widget.CardView>
+
+ <View
+ android:id="@+id/divider"
+ android:layout_width="409dp"
+ android:layout_height="1dp"
+ android:background="?android:attr/listDivider"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@+id/btnFragmentUserProfileShowPosts" />
+
+ <Button
+ android:id="@+id/btnFragmentUserProfileShowPosts"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="20dp"
+ android:layout_marginTop="4dp"
+ android:backgroundTint="#FFFFFF"
+ android:stateListAnimator="@null"
+ android:text="Objave"
+
+ android:textColor="@color/cardview_dark_background"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@+id/tvFragmentProfileInfoContainer" />
+
+ <Button
+ android:id="@+id/btnFragmentUserProfileShowData"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="4dp"
+ android:layout_marginEnd="20dp"
+ android:backgroundTint="#FFFFFF"
+ android:stateListAnimator="@null"
+ android:text="Podaci"
+
+ android:textColor="@color/cardview_dark_background"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintHorizontal_bias="1.0"
+ app:layout_constraintStart_toEndOf="@+id/btnFragmentUserProfileShowRecensions"
+ app:layout_constraintTop_toBottomOf="@+id/tvFragmentProfileInfoContainer" />
+
+ <Button
+ android:id="@+id/btnFragmentUserProfileShowRecensions"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="36dp"
+ android:layout_marginTop="4dp"
+ android:backgroundTint="#FFFFFF"
+ android:stateListAnimator="@null"
+ android:text="Recenzije"
+ android:textColor="@color/cardview_dark_background"
+ app:layout_constraintStart_toEndOf="@+id/btnFragmentUserProfileShowPosts"
+ app:layout_constraintTop_toBottomOf="@+id/tvFragmentProfileInfoContainer" />
+
+ <FrameLayout
+ android:id="@+id/flFragmentProfileFragmentContainer"
+ android:layout_width="409dp"
+ android:layout_height="319dp"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="@+id/divider">
+ </FrameLayout>
+
+ <TableLayout
+
+ android:layout_width="363dp"
+
+ android:layout_height="122dp"
+ android:layout_marginStart="30dp"
+ android:layout_marginTop="8dp"
+ android:layout_marginEnd="30dp"
+ android:layout_marginBottom="8dp"
+ android:elevation="1dp"
+ android:numColumns="3"
+
+ android:stretchColumns="1"
+ app:layout_constraintBottom_toBottomOf="@+id/tvFragmentProfileInfoContainer"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@+id/cvFragmentHomePageProfile">
+
+ <TableRow
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_column="1">
+
+ <TextView
+ android:id="@+id/tvActivityUserProfileName"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:layout_column="1"
+ android:layout_gravity="center"
+ android:layout_marginBottom="5dp"
+ android:text="Petar Petrović"
+ android:textSize="20sp" />
+ </TableRow>
+
+ <TableRow>
+
+ <androidx.constraintlayout.widget.ConstraintLayout android:layout_span="3">
+
+ <ImageButton
+
+ android:id="@+id/materialButton"
+ android:layout_width="115dp"
+ android:layout_height="40dp"
+ android:layout_marginStart="16dp"
+ android:background="@drawable/rounded_transparent_button"
+ android:foreground="@drawable/button_follow"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintVertical_bias="0.0"
+ tools:ignore="TouchTargetSizeCheck" />
+
+ <ImageButton
+ android:layout_width="115dp"
+ android:layout_height="40dp"
+ android:layout_gravity="center"
+ android:layout_marginEnd="16dp"
+ android:height="40dp"
+ android:background="@drawable/rounded_transparent_button"
+ android:foreground="@drawable/button_chat"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintVertical_bias="0.0"
+ tools:ignore="SpeakableTextPresentCheck" />
+ </androidx.constraintlayout.widget.ConstraintLayout>
+ </TableRow>
+
+
+ <TableRow android:layout_marginTop="5dp">
+
+ <TextView
+ android:id="@+id/tvFragmentUserProfilePosts"
+ android:layout_width="110dp"
+ android:gravity="center"
+ android:text="OBJAVE" />
+
+ <TextView
+ android:id="@+id/tvFragmentUserProfileFollowers"
+ android:layout_width="10dp"
+ android:gravity="center"
+ android:text="PRATIOCI" />
+
+ <TextView
+ android:id="@+id/tvFragmentUserProfileFollow"
+
+ android:layout_width="110dp"
+ android:gravity="center"
+ android:text="PRAĆENJA" />
+ </TableRow>
+
+ <TableRow>
+
+ <TextView
+ android:id="@+id/tvActivityUserProfilePostsNo"
+ android:layout_width="110dp"
+ android:layout_height="match_parent"
+ android:gravity="center"
+ android:text="156"
+ android:textFontWeight="700" />
+
+ <TextView
+ android:id="@+id/tvActivityUserProfileFollowersNo"
+ android:layout_width="110dp"
+ android:gravity="center"
+ android:text="50" />
+
+ <TextView
+ android:id="@+id/tvActivityUserProfileFollowNo"
+ android:layout_width="110dp"
+ android:gravity="center"
+ android:text="40" />
+
+ </TableRow>
+
+ </TableLayout>
+
+ </androidx.constraintlayout.widget.ConstraintLayout>
+
+
+</FrameLayout> \ No newline at end of file
diff --git a/Client/BrzoDoLokacije/app/src/main/res/layout/bottom_sheet_filter.xml b/Client/BrzoDoLokacije/app/src/main/res/layout/bottom_sheet_filter.xml
new file mode 100644
index 0000000..249c654
--- /dev/null
+++ b/Client/BrzoDoLokacije/app/src/main/res/layout/bottom_sheet_filter.xml
@@ -0,0 +1,147 @@
+<?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="wrap_content">
+
+ <TextView
+ android:id="@+id/textView7"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="16dp"
+ android:layout_marginTop="16dp"
+ android:text="Filteri"
+ android:textSize="25sp"
+ android:textStyle="bold"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent" />
+
+ <TextView
+ android:id="@+id/textView8"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="16dp"
+ android:layout_marginTop="16dp"
+ android:text="@string/datum"
+ android:textSize="17sp"
+ android:textStyle="bold"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintHorizontal_bias="0.0"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@+id/textView7" />
+
+ <EditText
+ android:id="@+id/dateFromBSF"
+ android:layout_width="140dp"
+ android:layout_height="48dp"
+ android:layout_marginStart="8dp"
+ android:layout_marginTop="8dp"
+ android:ems="10"
+ android:inputType="date"
+ app:layout_constraintStart_toEndOf="@+id/textView9"
+ app:layout_constraintTop_toBottomOf="@+id/textView8"
+ tools:ignore="SpeakableTextPresentCheck" />
+
+ <TextView
+ android:id="@+id/textView9"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="16dp"
+ android:layout_marginTop="20dp"
+ android:text="@string/od"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@+id/textView8" />
+
+ <TextView
+ android:id="@+id/textView10"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="20dp"
+ android:layout_marginEnd="8dp"
+ android:text="Do"
+ app:layout_constraintEnd_toStartOf="@+id/dateToBSF"
+ app:layout_constraintTop_toBottomOf="@+id/textView8" />
+
+ <EditText
+ android:id="@+id/dateToBSF"
+ android:layout_width="140dp"
+ android:layout_height="48dp"
+ android:layout_marginTop="8dp"
+ android:layout_marginEnd="16dp"
+ android:ems="10"
+ android:inputType="date"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintTop_toBottomOf="@+id/textView8"
+ tools:ignore="SpeakableTextPresentCheck" />
+
+ <TextView
+ android:id="@+id/textView11"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="16dp"
+ android:layout_marginTop="16dp"
+ android:text="Lokacija"
+ android:textSize="17sp"
+ android:textStyle="bold"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@+id/divider2" />
+
+ <View
+ android:id="@+id/divider2"
+ android:layout_width="409dp"
+ android:layout_height="1dp"
+ android:background="?android:attr/listDivider"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@+id/dateFromBSF" />
+
+ <EditText
+ android:id="@+id/locationBSF"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="16dp"
+ android:layout_marginTop="8dp"
+ android:layout_marginEnd="24dp"
+ android:ems="10"
+ android:inputType="textPersonName"
+ app:layout_constraintEnd_toStartOf="@+id/imageView8"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@+id/textView11"
+ tools:ignore="TouchTargetSizeCheck,SpeakableTextPresentCheck" />
+
+ <ImageView
+ android:id="@+id/imageView8"
+ android:layout_width="50dp"
+ android:layout_height="40dp"
+ android:layout_marginTop="8dp"
+ android:layout_marginEnd="16dp"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintTop_toBottomOf="@+id/textView11"
+ app:srcCompat="@drawable/button_find_on_map" />
+
+ <View
+ android:id="@+id/divider4"
+ android:layout_width="409dp"
+ android:layout_height="1dp"
+ android:background="?android:attr/listDivider"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@+id/locationBSF" />
+
+ <Button
+ android:id="@+id/btnBSFFilter"
+ android:layout_width="169dp"
+ android:layout_height="39dp"
+ android:layout_marginTop="16dp"
+ android:layout_marginBottom="24dp"
+ android:background="@drawable/rounded_cyan_button"
+ android:text="Primeni"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@+id/divider4"
+ app:layout_constraintVertical_bias="1.0"
+ tools:ignore="TouchTargetSizeCheck" />
+
+</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file
diff --git a/Client/BrzoDoLokacije/app/src/main/res/layout/bottom_sheet_sort.xml b/Client/BrzoDoLokacije/app/src/main/res/layout/bottom_sheet_sort.xml
new file mode 100644
index 0000000..fb06308
--- /dev/null
+++ b/Client/BrzoDoLokacije/app/src/main/res/layout/bottom_sheet_sort.xml
@@ -0,0 +1,67 @@
+<?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="wrap_content">
+
+ <RadioGroup
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@+id/textView12">
+
+ <RadioButton
+ android:id="@+id/radioButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="16dp"
+ android:layout_marginTop="12dp"
+ android:text="Najnovije"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintHorizontal_bias="0.0"
+ app:layout_constraintStart_toStartOf="parent"
+ />
+
+ <RadioButton
+ android:id="@+id/radioButton2"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="16dp"
+ android:text="Najbolje ocenjeno"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintTop_toBottomOf="@+id/radioButton4" />
+
+ <RadioButton
+ android:id="@+id/radioButton3"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="16dp"
+ android:text="Najstarije"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@+id/radioButton" />
+
+ <RadioButton
+ android:id="@+id/radioButton4"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="16dp"
+
+ android:text="Najviše pregleda"
+ app:layout_constraintTop_toBottomOf="@+id/radioButton3"
+ tools:layout_editor_absoluteX="16dp" />
+ </RadioGroup>
+
+ <TextView
+ android:id="@+id/textView12"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="16dp"
+ android:layout_marginTop="16dp"
+ android:text="Sortiraj po"
+ android:textSize="25sp"
+ android:textStyle="bold"
+ 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/chat_message.xml b/Client/BrzoDoLokacije/app/src/main/res/layout/chat_message.xml
new file mode 100644
index 0000000..2342779
--- /dev/null
+++ b/Client/BrzoDoLokacije/app/src/main/res/layout/chat_message.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:background="@drawable/rounded_cyan_button"
+ android:clipToOutline="true"
+ android:id="@+id/clMessage"
+ android:layout_margin="@dimen/text_padding"
+ android:layout_gravity="end">
+ <androidx.cardview.widget.CardView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:cardBackgroundColor="@color/cardview_dark_background">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textColor="@color/white"
+ android:id="@+id/tvMessage"
+ android:text="blabla"
+ android:padding="@dimen/component_padding"/>
+ </androidx.cardview.widget.CardView>
+
+</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file
diff --git a/Client/BrzoDoLokacije/app/src/main/res/layout/chat_message_other.xml b/Client/BrzoDoLokacije/app/src/main/res/layout/chat_message_other.xml
new file mode 100644
index 0000000..647127c
--- /dev/null
+++ b/Client/BrzoDoLokacije/app/src/main/res/layout/chat_message_other.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:background="@drawable/rounded_cyan_button"
+ android:id="@+id/clMessage"
+ android:layout_margin="@dimen/text_padding"
+ android:clipToOutline="true">
+
+ <androidx.cardview.widget.CardView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ app:cardBackgroundColor="@color/dark_blue_transparent">
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textColor="@color/white"
+ android:id="@+id/tvMessage"
+ android:text="blabla"
+ android:padding="@dimen/component_padding"/>
+ </androidx.cardview.widget.CardView>
+</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
new file mode 100644
index 0000000..35431ff
--- /dev/null
+++ b/Client/BrzoDoLokacije/app/src/main/res/layout/chat_preview.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ xmlns:app="http://schemas.android.com/apk/res-auto">
+ <androidx.appcompat.widget.AppCompatImageView
+ android:layout_width="50dp"
+ android:layout_height="50dp"
+ android:id="@+id/ivUserImage"
+ android:src="@drawable/ic_nav_profile"/>
+ <TextView
+ 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
diff --git a/Client/BrzoDoLokacije/app/src/main/res/layout/follower_item.xml b/Client/BrzoDoLokacije/app/src/main/res/layout/follower_item.xml
new file mode 100644
index 0000000..bc43f1b
--- /dev/null
+++ b/Client/BrzoDoLokacije/app/src/main/res/layout/follower_item.xml
@@ -0,0 +1,87 @@
+<?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/tvFolloewItemUsername"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_marginBottom="10dp">
+
+ <androidx.constraintlayout.widget.ConstraintLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintHorizontal_bias="1.0"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent">
+
+
+ <androidx.cardview.widget.CardView
+ android:id="@+id/cvFragmentHomePageProfile"
+ android:layout_width="100dp"
+ android:layout_height="100dp"
+ android:layout_gravity="center"
+
+ android:elevation="10dp"
+ app:cardCornerRadius="250dp"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent">
+
+ <ImageView
+
+ android:id="@+id/tvFragmentProfileProfilePicture"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:elevation="10dp"
+ android:scaleType="centerCrop"
+ android:src="@drawable/ic_baseline_person_24"
+ tools:ignore="ContentDescription" />
+ </androidx.cardview.widget.CardView>
+
+
+ <TextView
+ android:id="@+id/tvFollowerItemName"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginHorizontal="15dp"
+ android:layout_marginStart="24dp"
+ android:layout_marginTop="28dp"
+ android:text="Petar Petrovic"
+ android:textSize="17sp"
+ android:textStyle="bold"
+ app:layout_constraintEnd_toStartOf="@+id/materialButton"
+ app:layout_constraintHorizontal_bias="0.0"
+ app:layout_constraintStart_toEndOf="@+id/cvFragmentHomePageProfile"
+ app:layout_constraintTop_toTopOf="parent">
+
+ </TextView>
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Petar Petrovic"
+ android:textSize="15sp"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toStartOf="@+id/materialButton"
+ app:layout_constraintHorizontal_bias="0.656"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@+id/tvFollowerItemName"
+ app:layout_constraintVertical_bias="0.0" />
+
+ <ImageButton
+
+ android:id="@+id/materialButton"
+ android:layout_width="101dp"
+ android:layout_height="39dp"
+ android:layout_marginEnd="16dp"
+ android:background="@drawable/rounded_transparent_button"
+ android:foreground="@drawable/button_follow"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintVertical_bias="0.508"
+ tools:ignore="TouchTargetSizeCheck" />
+
+ </androidx.constraintlayout.widget.ConstraintLayout>
+</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file
diff --git a/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_followers.xml b/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_followers.xml
new file mode 100644
index 0000000..6092e01
--- /dev/null
+++ b/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_followers.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ tools:context=".Fragments.FragmentFollowers">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+ <LinearLayout
+ android:layout_width="110dp"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+ <ImageView
+ android:id="@+id/btnFragmentFollowersBack"
+ android:clickable="true"
+ android:layout_width="30dp"
+ android:layout_height="30dp"
+ android:src="@drawable/ic_baseline_arrow_back_24"/>
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="right"
+ android:text="Pratioci"
+ android:textSize="20sp"
+ android:textStyle="bold"
+ />
+ </LinearLayout>
+ <androidx.recyclerview.widget.RecyclerView
+ android:id="@+id/rvFragmentShowFollowers"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+
+ </LinearLayout>
+</FrameLayout> \ No newline at end of file
diff --git a/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_following.xml b/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_following.xml
new file mode 100644
index 0000000..424094f
--- /dev/null
+++ b/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_following.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ tools:context=".Fragments.FragmentFollowing">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+<LinearLayout
+ android:layout_width="80dp"
+ android:layout_height="wrap_content">
+ <ImageView
+ android:id="@+id/btnFragmentFollowingBack"
+ android:layout_width="30dp"
+ android:layout_height="30dp"
+ android:clickable="true"
+ android:src="@drawable/ic_baseline_arrow_back_24"
+
+ />
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="right"
+ android:text="Prati"
+ android:textSize="20sp"
+ android:textStyle="bold" />
+ </LinearLayout>
+ <androidx.recyclerview.widget.RecyclerView
+ android:id="@+id/rvFragmentShowFollowing"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+ </LinearLayout>
+
+</FrameLayout> \ No newline at end of file
diff --git a/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_my_recensions.xml b/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_my_recensions.xml
index d5452b9..72706e0 100644
--- a/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_my_recensions.xml
+++ b/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_my_recensions.xml
@@ -1,14 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<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=".Fragments.FragmentMyRecensions">
- <!-- TODO: Update blank fragment layout -->
- <TextView
+
+ <com.google.android.material.divider.MaterialDivider
+ android:id="@+id/materialDivider"
+ android:layout_width="match_parent"
+ android:layout_height="50dp"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent"
+ android:visibility="invisible"/>
+
+ <androidx.recyclerview.widget.RecyclerView
+ android:id="@+id/rvFragmentMyRecensionPostHistory"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:text="Moje recenzije" />
+ android:layout_height="wrap_content"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@+id/materialDivider"
+ android:layout_marginHorizontal="16dp"/>
-</FrameLayout> \ No newline at end of file
+</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file
diff --git a/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_profile.xml b/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_profile.xml
index c75e1e4..ec78de6 100644
--- a/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_profile.xml
+++ b/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_profile.xml
@@ -151,6 +151,7 @@
<TextView
android:id="@+id/tvFragmentProfileFollowers"
android:gravity="center"
+ android:clickable="true"
android:text="PRATIOCI" />
<TextView
@@ -231,7 +232,7 @@
android:layout_marginTop="4dp"
android:backgroundTint="#FFFFFF"
android:stateListAnimator="@null"
- android:text="Recenzije"
+ android:text="Istorija"
android:textColor="@color/cardview_dark_background"
app:layout_constraintStart_toEndOf="@+id/btnFragmentProfileShowMyPosts"
app:layout_constraintTop_toBottomOf="@+id/tvFragmentProfileInfoContainer" />
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 5dfbc98..e1effc4 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
@@ -52,10 +52,11 @@
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentRight="true"
+ android:layout_marginStart="16dp"
android:background="@color/white"
android:padding="@dimen/component_padding"
android:scaleType="centerCrop"
- android:src="@drawable/filter"
+ android:src="@drawable/button_filter"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
@@ -63,16 +64,28 @@
android:id="@+id/btnSortDirection"
android:layout_width="50dp"
android:layout_height="50dp"
- android:layout_marginStart="8dp"
android:layout_weight="1"
android:background="@color/white"
android:padding="@dimen/component_padding"
android:scaleType="centerCrop"
- android:src="@drawable/sort"
+ android:src="@drawable/button_sort"
app:layout_constraintStart_toEndOf="@+id/btnSortType"
app:layout_constraintTop_toTopOf="parent" />
<ImageButton
+ android:id="@+id/btnChat"
+ android:layout_width="84dp"
+ android:layout_height="50dp"
+ android:layout_marginStart="8dp"
+ android:layout_weight="1"
+ android:background="@color/white"
+ android:padding="@dimen/component_padding"
+ android:scaleType="centerCrop"
+ android:src="@android:drawable/sym_action_chat"
+ app:layout_constraintStart_toEndOf="@+id/btnSortDirection"
+ app:layout_constraintTop_toTopOf="parent" />
+
+ <ImageButton
android:id="@+id/btnLinearLayout"
android:layout_width="50dp"
android:layout_height="50dp"
@@ -91,7 +104,7 @@
android:id="@+id/btnGridLayout"
android:layout_width="50dp"
android:layout_height="50dp"
- android:layout_marginStart="248dp"
+ android:layout_marginStart="220dp"
android:layout_weight="1"
android:background="@color/white"
android:clickable="true"
diff --git a/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_user_profile.xml b/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_user_profile.xml
new file mode 100644
index 0000000..15031e3
--- /dev/null
+++ b/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_user_profile.xml
@@ -0,0 +1,248 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout 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=".Fragments.FragmentUserProfile">
+
+
+ <androidx.constraintlayout.widget.ConstraintLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <ImageView
+
+ android:id="@+id/imageView3"
+ android:layout_width="match_parent"
+ android:layout_height="300dp"
+ android:foreground="@drawable/b3"
+ android:foregroundGravity="center_vertical|center|center_horizontal|fill"
+ android:src="@drawable/b3"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent" />
+
+
+ <com.google.android.material.imageview.ShapeableImageView
+
+ android:id="@+id/tvFragmentProfileInfoContainer"
+ android:layout_width="0dp"
+ android:layout_height="199dp"
+ android:layout_marginStart="20dp"
+ android:layout_marginTop="150dp"
+ android:layout_marginEnd="20dp"
+ android:adjustViewBounds="true"
+ android:background="@drawable/profile_view_background"
+
+ android:elevation="1dp"
+ android:scaleType="fitEnd"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintHorizontal_bias="0.0"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="@+id/imageView3"
+ app:shapeAppearanceOverlay="@style/imageViewRoundedEdge" />
+
+
+ <androidx.cardview.widget.CardView
+ android:id="@+id/cvFragmentHomePageProfile"
+ android:layout_width="140dp"
+ android:layout_height="140dp"
+ android:layout_gravity="center"
+ android:layout_marginTop="80dp"
+ android:elevation="10dp"
+ app:cardCornerRadius="250dp"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent">
+
+ <ImageView
+
+ android:id="@+id/tvFragmentProfileProfilePicture"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:elevation="10dp"
+ android:scaleType="centerCrop"
+ android:src="@drawable/ic_baseline_person_24"
+ tools:ignore="ContentDescription" />
+ </androidx.cardview.widget.CardView>
+
+ <View
+ android:id="@+id/divider"
+ android:layout_width="409dp"
+ android:layout_height="1dp"
+ android:background="?android:attr/listDivider"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@+id/btnFragmentUserProfileShowPosts" />
+
+ <Button
+ android:id="@+id/btnFragmentUserProfileShowPosts"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="20dp"
+ android:layout_marginTop="4dp"
+ android:backgroundTint="#FFFFFF"
+ android:stateListAnimator="@null"
+ android:text="Objave"
+
+ android:textColor="@color/cardview_dark_background"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@+id/tvFragmentProfileInfoContainer" />
+
+ <Button
+ android:id="@+id/btnFragmentUserProfileShowData"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="4dp"
+ android:layout_marginEnd="20dp"
+ android:backgroundTint="#FFFFFF"
+ android:stateListAnimator="@null"
+ android:text="Podaci"
+
+ android:textColor="@color/cardview_dark_background"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintHorizontal_bias="1.0"
+ app:layout_constraintStart_toEndOf="@+id/btnFragmentUserProfileShowRecensions"
+ app:layout_constraintTop_toBottomOf="@+id/tvFragmentProfileInfoContainer" />
+
+ <Button
+ android:id="@+id/btnFragmentUserProfileShowRecensions"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="36dp"
+ android:layout_marginTop="4dp"
+ android:backgroundTint="#FFFFFF"
+ android:stateListAnimator="@null"
+ android:text="Recenzije"
+ android:textColor="@color/cardview_dark_background"
+ app:layout_constraintStart_toEndOf="@+id/btnFragmentUserProfileShowPosts"
+ app:layout_constraintTop_toBottomOf="@+id/tvFragmentProfileInfoContainer" />
+
+ <FrameLayout
+ android:id="@+id/flFragmentProfileFragmentContainer"
+ android:layout_width="409dp"
+ android:layout_height="319dp"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="@+id/divider">
+ </FrameLayout>
+
+ <TableLayout
+ android:elevation="1dp"
+
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:layout_marginStart="30dp"
+ android:layout_marginTop="8dp"
+ android:layout_marginEnd="30dp"
+ android:layout_marginBottom="8dp"
+ android:numColumns="3"
+
+ android:stretchColumns="1"
+ app:layout_constraintBottom_toBottomOf="@+id/tvFragmentProfileInfoContainer"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@+id/cvFragmentHomePageProfile">
+
+ <TableRow android:layout_column="1">
+
+ <TextView
+ android:id="@+id/tvFragmentUserProfileName"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:layout_column="1"
+ android:layout_gravity="center"
+ android:text="Petar Petrović"
+ android:textSize="20sp"
+ android:layout_marginBottom="5dp"/>
+ </TableRow>
+
+ <TableRow>
+ <androidx.constraintlayout.widget.ConstraintLayout
+ android:layout_span="3">
+
+ <ImageButton
+
+ android:id="@+id/materialButton"
+ android:layout_width="115dp"
+ android:layout_height="40dp"
+ android:layout_marginStart="16dp"
+ android:background="@drawable/rounded_transparent_button"
+ android:foreground="@drawable/button_follow"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintVertical_bias="0.0"
+ tools:ignore="TouchTargetSizeCheck" />
+
+ <ImageButton
+ android:layout_width="115dp"
+ android:layout_height="40dp"
+ android:layout_gravity="center"
+ android:layout_marginEnd="16dp"
+ android:height="40dp"
+ android:background="@drawable/rounded_transparent_button"
+ android:foreground="@drawable/button_chat"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintVertical_bias="0.0"
+ tools:ignore="SpeakableTextPresentCheck" />
+ </androidx.constraintlayout.widget.ConstraintLayout>
+ </TableRow>
+
+
+ <TableRow
+ android:layout_marginTop="5dp">
+
+ <TextView
+ android:id="@+id/tvFragmentUserProfilePosts"
+ android:layout_width="110dp"
+ android:gravity="center"
+ android:text="OBJAVE" />
+
+ <TextView
+ android:id="@+id/tvFragmentUserProfileFollowers"
+ android:layout_width="10dp"
+ android:gravity="center"
+ android:text="PRATIOCI" />
+
+ <TextView
+ android:id="@+id/tvFragmentUserProfileFollow"
+
+ android:layout_width="110dp"
+ android:gravity="center"
+ android:text="PRAĆENJA" />
+ </TableRow>
+
+ <TableRow>
+
+ <TextView
+ android:id="@+id/tvFragmentUserProfilePostsNo"
+ android:layout_width="110dp"
+ android:gravity="center"
+ android:textFontWeight="700"
+ android:text="156" />
+
+ <TextView
+ android:id="@+id/tvFragmentUserProfileFollowersNo"
+ android:layout_width="110dp"
+ android:gravity="center"
+ android:text="50" />
+
+ <TextView
+ android:id="@+id/tvFragmentUserProfileFollowNo"
+ android:layout_width="110dp"
+ android:gravity="center"
+ android:text="40" />
+
+ </TableRow>
+
+ </TableLayout>
+
+ </androidx.constraintlayout.widget.ConstraintLayout>
+
+
+</FrameLayout> \ No newline at end of file
diff --git a/Client/BrzoDoLokacije/app/src/main/res/layout/single_post_history.xml b/Client/BrzoDoLokacije/app/src/main/res/layout/single_post_history.xml
new file mode 100644
index 0000000..12c29ee
--- /dev/null
+++ b/Client/BrzoDoLokacije/app/src/main/res/layout/single_post_history.xml
@@ -0,0 +1,75 @@
+<?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="wrap_content"
+ android:layout_margin="0dp"
+ android:background="@drawable/rounded_picture_background"
+ android:clipToOutline="true"
+ >
+
+
+
+
+ <View
+ android:id="@+id/vBannerSinglePostHistory"
+ android:layout_width="match_parent"
+ android:layout_height="80dp"
+ android:background="@color/dark_blue_transparent"
+ android:outlineProvider="background"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintHorizontal_bias="0.0"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintVertical_bias="0.0"
+ tools:layout_editor_absoluteX="10dp"
+ android:layout_marginTop="5dp"
+ >
+
+
+ </View>
+
+ <TextView
+ android:id="@+id/tvTitleSinglePostHistory"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="top|left"
+ android:text="Naslov"
+ android:textColor="@color/white"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintHorizontal_bias="0.076"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="@+id/vBannerSinglePostHistory"
+ app:layout_constraintVertical_bias="0.18" />
+
+ <TextView
+ android:id="@+id/tvLocationTypeSinglePostHistory"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Tip lokacije"
+ android:textColor="@color/white"
+ app:layout_constraintBottom_toBottomOf="@+id/vBannerSinglePostHistory"
+ app:layout_constraintEnd_toStartOf="@+id/tvLocationParentSinglePostHistory"
+ app:layout_constraintHorizontal_bias="0.112"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="@+id/vBannerSinglePostHistory"
+ app:layout_constraintVertical_bias="0.721" />
+
+ <TextView
+ android:id="@+id/tvLocationParentSinglePostHistory"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:text="22.11.2022"
+ android:textAlignment="viewEnd"
+ android:textColor="@color/white"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintHorizontal_bias="0.952"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="@+id/vBannerSinglePostHistory"
+ app:layout_constraintVertical_bias="0.737" />
+
+</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file
diff --git a/Client/BrzoDoLokacije/app/src/main/res/values/strings.xml b/Client/BrzoDoLokacije/app/src/main/res/values/strings.xml
index a969148..b180869 100644
--- a/Client/BrzoDoLokacije/app/src/main/res/values/strings.xml
+++ b/Client/BrzoDoLokacije/app/src/main/res/values/strings.xml
@@ -6,4 +6,48 @@
<string name="title_activity_maps">MapsActivity</string>
<string name="dodaj_objavu">Dodaj objavu</string>
<string name="todo">TODO</string>
+ <string name="datum">Datum</string>
+
+ <string name="od">Od</string>
+
+
+ <!-- example lista tagova, make actual list for app -->
+ <string-array name="Tags">
+ <item>GRAD</item>
+ <item>ULICA</item>
+ <item>JEZERO</item>
+ <item>REKA</item>
+ <item>PLAZA</item>
+ <item>OKEAN</item>
+ <item>MORE</item>
+ <item>MOREUZ</item>
+ <item>MOST</item>
+ <item>BANJA</item>
+ <item>PLANINA</item>
+ <item>VISORAVAN</item>
+ <item>PIRAMIDA</item>
+ <item>LIVADA</item>
+ <item>SELO</item>
+ <item>OSTRVO</item>
+ <item>POLUOSTRVO</item>
+ <item>KLISURA</item>
+ <item>ARHIPELAG</item>
+ <item>ADA</item>
+ <item>DELTA</item>
+ <item>FJORD</item>
+ <item>GEJZIR</item>
+ <item>IZVOR</item>
+ <item>KOTLINA</item>
+ <item>MINERALNI_IZVOR</item>
+ <item>PECINA</item>
+ <item>SUMA</item>
+ <item>VODOPAD</item>
+ <item>VULKAN</item>
+ <item>MUZEJ</item>
+ <item>ZAMAK</item>
+ <item>TRG</item>
+ <item>SPOMENIK</item>
+ <item>PARK</item>
+ <item>ZGRADA</item>
+ </string-array>
</resources> \ No newline at end of file