diff options
Diffstat (limited to 'Client')
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 Binary files differnew file mode 100644 index 0000000..967d741 --- /dev/null +++ b/Client/BrzoDoLokacije/app/libs/signalr-client-sdk-android.jar diff --git a/Client/BrzoDoLokacije/app/libs/signalr-client-sdk.jar b/Client/BrzoDoLokacije/app/libs/signalr-client-sdk.jar Binary files differnew file mode 100644 index 0000000..f736f64 --- /dev/null +++ b/Client/BrzoDoLokacije/app/libs/signalr-client-sdk.jar 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 |