From bf6c3e1de8cff9af42d7a5f3edf1ee2f159c434b Mon Sep 17 00:00:00 2001 From: Ognjen Cirkovic Date: Thu, 24 Nov 2022 20:52:57 +0100 Subject: Napravljen kontroler i servis za preuzimanje kompresovanih slika. --- Backend/Api/Api/Api.csproj | 1 + Backend/Api/Api/Controllers/PostController.cs | 9 +++++++++ Backend/Api/Api/Interfaces/IFileService.cs | 1 + Backend/Api/Api/Services/FileService.cs | 18 ++++++++++++++++++ 4 files changed, 29 insertions(+) (limited to 'Backend') diff --git a/Backend/Api/Api/Api.csproj b/Backend/Api/Api/Api.csproj index 24c41b7..0e541f9 100644 --- a/Backend/Api/Api/Api.csproj +++ b/Backend/Api/Api/Api.csproj @@ -10,6 +10,7 @@ + diff --git a/Backend/Api/Api/Controllers/PostController.cs b/Backend/Api/Api/Controllers/PostController.cs index dc48c73..3fe1b3f 100644 --- a/Backend/Api/Api/Controllers/PostController.cs +++ b/Backend/Api/Api/Controllers/PostController.cs @@ -66,6 +66,15 @@ namespace Api.Controllers return BadRequest("Slika ne postoji"); return File(System.IO.File.ReadAllBytes(f.path), "image/*", Path.GetFileName(f.path)); } + [HttpGet("image/compress/{id}")] + //[Authorize(Roles = "User")] + public async Task getCompressedImage(string id) + { + Byte[] f = await _fileService.getCompressedImage(id); + if (f == null) + return BadRequest("Slika ne postoji"); + return File(f, "image/*", "tempcompress"); + } [HttpPost("posts/{id}/addrating")] [Authorize(Roles = "User")] diff --git a/Backend/Api/Api/Interfaces/IFileService.cs b/Backend/Api/Api/Interfaces/IFileService.cs index e736305..33ff5d9 100644 --- a/Backend/Api/Api/Interfaces/IFileService.cs +++ b/Backend/Api/Api/Interfaces/IFileService.cs @@ -4,5 +4,6 @@ { Task add(Models.File file); Task getById(string id); + Task getCompressedImage(string id); } } \ No newline at end of file diff --git a/Backend/Api/Api/Services/FileService.cs b/Backend/Api/Api/Services/FileService.cs index 1937c10..b951efc 100644 --- a/Backend/Api/Api/Services/FileService.cs +++ b/Backend/Api/Api/Services/FileService.cs @@ -1,5 +1,6 @@ using Api.Interfaces; using Api.Models; +using ImageMagick; using MongoDB.Driver; using File = Api.Models.File; @@ -24,5 +25,22 @@ namespace Api.Services { return await _files.Find(file => file._id == id).FirstOrDefaultAsync(); } + public async Task getCompressedImage(string id) + { + Byte[] res = null; + Models.File f = await getById(id); + if (f == null || !System.IO.File.Exists(f.path)) + return res; + using (MagickImage image = new MagickImage(f.path)) + { + image.Format = image.Format; + image.Quality = 30; + res= image.ToByteArray(); + } + + + return res; + + } } } -- cgit v1.2.3 From e06bc945b7f0cffa0cf2ee9e26440ba5f6e7b461 Mon Sep 17 00:00:00 2001 From: Ognjen Cirkovic Date: Sun, 27 Nov 2022 15:43:25 +0100 Subject: Ukoliko postoji kompresovana slika on je samo vraca , ukoliko ne upisuje je na fajl sistem i vraca bytearray. Dodati pozivi za preuzimanje kompresovanih slika na clientu. --- Backend/Api/Api/Services/FileService.cs | 3 +++ .../main/java/com/example/brzodolokacije/Adapters/MyPostsAdapter.kt | 2 +- .../main/java/com/example/brzodolokacije/Adapters/PostImageAdapter.kt | 2 +- .../main/java/com/example/brzodolokacije/Adapters/ShowPostsAdapter.kt | 2 +- .../com/example/brzodolokacije/Adapters/ShowPostsHomePageAdapter.kt | 2 +- 5 files changed, 7 insertions(+), 4 deletions(-) (limited to 'Backend') diff --git a/Backend/Api/Api/Services/FileService.cs b/Backend/Api/Api/Services/FileService.cs index b951efc..440b24f 100644 --- a/Backend/Api/Api/Services/FileService.cs +++ b/Backend/Api/Api/Services/FileService.cs @@ -31,11 +31,14 @@ namespace Api.Services Models.File f = await getById(id); if (f == null || !System.IO.File.Exists(f.path)) return res; + if (System.IO.File.Exists(f.path + "-compress")) + return System.IO.File.ReadAllBytes(f.path + "-compress"); using (MagickImage image = new MagickImage(f.path)) { image.Format = image.Format; image.Quality = 30; res= image.ToByteArray(); + image.Write(f.path + "-compress"); } 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 index 1b57e5b..d8a70c6 100644 --- 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 @@ -52,7 +52,7 @@ class MyPostsAdapter (val activity:Activity,val items : MutableList tvLocationType.text = "TODO" if(item.images.isNotEmpty()) { Glide.with(activity) - .load(RetrofitHelper.baseUrl + "/api/post/image/" + item.images[0]._id) + .load(RetrofitHelper.baseUrl + "/api/post/image/compress/" + item.images[0]._id) .into(locationImage) } diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/PostImageAdapter.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/PostImageAdapter.kt index 655b717..74bfd92 100644 --- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/PostImageAdapter.kt +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/PostImageAdapter.kt @@ -33,7 +33,7 @@ class PostImageAdapter(val activity: Activity, val items : MutableList Date: Mon, 28 Nov 2022 01:46:34 +0100 Subject: Dodato sortiranje objava na back-u i prikaz sortiranih objava na front-u. Izmenjen prikaz objave. --- Backend/Api/Api/Controllers/PostController.cs | 22 ++++ Backend/Api/Api/Interfaces/IPostService.cs | 6 ++ Backend/Api/Api/Services/PostService.cs | 36 +++++++ .../Fragments/FragmentHomePageMainScroll.kt | 111 ++++++++++++++++----- .../brzodolokacije/Interfaces/IBackendApi.kt | 9 ++ .../brzodolokacije/Services/RetrofitHelper.kt | 4 +- .../main/res/drawable/ic_baseline_circle_24.xml | 5 + .../src/main/res/drawable/ic_baseline_circle_7.xml | 5 + .../res/layout/fragment_home_page_main_scroll.xml | 27 +++-- .../src/main/res/layout/post_item_home_page.xml | 28 +++--- .../app/src/main/res/values/styles.xml | 5 + 11 files changed, 208 insertions(+), 50 deletions(-) create mode 100644 Client/BrzoDoLokacije/app/src/main/res/drawable/ic_baseline_circle_24.xml create mode 100644 Client/BrzoDoLokacije/app/src/main/res/drawable/ic_baseline_circle_7.xml (limited to 'Backend') diff --git a/Backend/Api/Api/Controllers/PostController.cs b/Backend/Api/Api/Controllers/PostController.cs index 3fe1b3f..4c6fbac 100644 --- a/Backend/Api/Api/Controllers/PostController.cs +++ b/Backend/Api/Api/Controllers/PostController.cs @@ -137,5 +137,27 @@ namespace Api.Controllers } return BadRequest(); } + + [HttpGet("posts/get10MostViewed")] + [Authorize(Roles = "User")] + public async Task>> Get10MostViewed() + { + return Ok(await _postService.Get10MostViewed()); + } + + [HttpGet("posts/get10Newest")] + [Authorize(Roles = "User")] + public async Task>> Get10Newest() + { + return Ok(await _postService.Get10Newest()); + } + + [HttpGet("posts/get10Best")] + [Authorize(Roles = "User")] + public async Task>> Get10Best() + { + return Ok(await _postService.Get10Best()); + } + } } diff --git a/Backend/Api/Api/Interfaces/IPostService.cs b/Backend/Api/Api/Interfaces/IPostService.cs index 12a5fe8..5b04dc3 100644 --- a/Backend/Api/Api/Interfaces/IPostService.cs +++ b/Backend/Api/Api/Interfaces/IPostService.cs @@ -19,5 +19,11 @@ namespace Api.Interfaces int DateEnumToDays(int filterdate); Task> GetUsersPosts(string id); Task> UserHistory(string userid); + + Task> Get10Best(); + + Task> Get10MostViewed(); + + Task> Get10Newest(); } } \ No newline at end of file diff --git a/Backend/Api/Api/Services/PostService.cs b/Backend/Api/Api/Services/PostService.cs index bdf150b..b75656e 100644 --- a/Backend/Api/Api/Services/PostService.cs +++ b/Backend/Api/Api/Services/PostService.cs @@ -368,5 +368,41 @@ namespace Api.Services } return tosend; } + + public async Task> Get10Best() + { + List posts = await _posts.Find(_ => true).ToListAsync(); + List temp = new List(); + foreach (var post in posts) + { + temp.Add(await postToPostSend(post)); + } + List best = temp.OrderByDescending(o => o.ratings).Take(10).ToList(); + return best; + } + + public async Task> Get10MostViewed() + { + List posts = await _posts.Find(_ => true).ToListAsync(); + List temp = new List(); + foreach (var post in posts) + { + temp.Add(await postToPostSend(post)); + } + List mostViewed = temp.OrderByDescending(o => o.views).Take(10).ToList(); + return mostViewed; + } + + public async Task> Get10Newest() + { + List posts = await _posts.Find(_ => true).ToListAsync(); + List temp = new List(); + foreach (var post in posts) + { + temp.Add(await postToPostSend(post)); + } + List newest = temp.OrderByDescending(o => o.createdAt).Take(10).ToList(); + return newest; + } } } 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 3846d6c..46904d4 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 @@ -194,6 +194,9 @@ private lateinit var change:Button } private fun getAllPosts(){ + Toast.makeText( + activity," get all", Toast.LENGTH_LONG + ).show(); val api = Retrofit.Builder() .addConverterFactory(GsonConverterFactory.create()) .baseUrl(RetrofitHelper.baseUrl) @@ -219,9 +222,9 @@ private lateinit var change:Button // activity, "get all ", Toast.LENGTH_LONG // ).show(); posts = response.body()!!.toMutableList() - getPopularPosts(posts) - getNewestPosts(posts) - getBestRatedPosts(posts) + getPopularPosts() + getNewestPosts() + getBestRatedPosts() } override fun onFailure(call: Call>, t: Throwable) { @@ -232,41 +235,101 @@ private lateinit var change:Button }) } - private fun getPopularPosts(allPosts:MutableList){//most viewed + private fun getPopularPosts(){//most viewed // Toast.makeText( // activity, "get all mv ", Toast.LENGTH_LONG // ).show(); - mostViewedPosts=allPosts - mostViewedPosts.sortByDescending { it.views } - rvPopular.apply { - layoutManager= LinearLayoutManager(activity, LinearLayoutManager.HORIZONTAL,false) - adapter= ShowPostsHomePageAdapter(mostViewedPosts,requireActivity()) + Toast.makeText( + activity," get popular all", Toast.LENGTH_LONG + ).show(); + val api = RetrofitHelper.getInstance() + val token= SharedPreferencesHelper.getValue("jwt", requireActivity()) + val data=api.get10MostViewed("Bearer "+token) + + data.enqueue(object : Callback> { + override fun onResponse( + call: Call>, + response: Response> + ) { + if (response.body() == null) { + return + } + var mostpopular = response.body()!!.toMutableList() + rvPopular.apply { + layoutManager= LinearLayoutManager(activity, LinearLayoutManager.HORIZONTAL,false) + adapter= ShowPostsHomePageAdapter(mostpopular,requireActivity()) + + } + } + override fun onFailure(call: Call>, t: Throwable) { + + } + }) - } } - private fun getNewestPosts(allPosts:MutableList){ + private fun getNewestPosts(){ // Toast.makeText( // activity, "get all r ", Toast.LENGTH_LONG // ).show(); - newestPosts=allPosts/// izmeniti nakon dodavanja datuma u model!!!!!! - newestPosts.sortBy { it.ratings} - rvNewest.apply { - layoutManager= LinearLayoutManager(activity, LinearLayoutManager.HORIZONTAL,false) - adapter= ShowPostsHomePageAdapter(newestPosts,requireActivity()) - } + Toast.makeText( + activity," get all newest", Toast.LENGTH_LONG + ).show(); + val api = RetrofitHelper.getInstance() + val token= SharedPreferencesHelper.getValue("jwt", requireActivity()) + val data=api.get10Newest("Bearer "+token) + + data.enqueue(object : Callback> { + override fun onResponse( + call: Call>, + response: Response> + ) { + if (response.body() == null) { + return + } + var newestposts = response.body()!!.toMutableList() + rvNewest.apply { + layoutManager= LinearLayoutManager(activity, LinearLayoutManager.HORIZONTAL,false) + adapter= ShowPostsHomePageAdapter(newestposts,requireActivity()) + } + } + override fun onFailure(call: Call>, t: Throwable) { + + } + }) + } - private fun getBestRatedPosts(allPosts:MutableList){ + private fun getBestRatedPosts(){ // Toast.makeText( // activity, "get all br ", Toast.LENGTH_LONG // ).show(); - bestRatedPosts=allPosts - bestRatedPosts.sortByDescending { it.ratings } - rvBestRated.apply { - layoutManager= LinearLayoutManager(activity, LinearLayoutManager.HORIZONTAL,false) - adapter= ShowPostsHomePageAdapter(bestRatedPosts,requireActivity()) - } + Toast.makeText( + activity," get all best", Toast.LENGTH_LONG + ).show(); + val api = RetrofitHelper.getInstance() + val token= SharedPreferencesHelper.getValue("jwt", requireActivity()) + val data=api.get10Best("Bearer "+token) + + data.enqueue(object : Callback> { + override fun onResponse( + call: Call>, + response: Response> + ) { + if (response.body() == null) { + return + } + var bestposts = response.body()!!.toMutableList() + rvBestRated.apply { + layoutManager= LinearLayoutManager(activity, LinearLayoutManager.HORIZONTAL,false) + adapter= ShowPostsHomePageAdapter(bestposts,requireActivity()) + } + } + override fun onFailure(call: Call>, t: Throwable) { + + } + }) + } 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 cb51627..e4bfbc8 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 @@ -83,4 +83,13 @@ interface IBackendApi { @GET("/api/user/{id}/id/profile") fun getProfileFromId(@Header("Authorization") authHeader:String,@Path("id") username:String):Call + @GET("/api/Post/posts/get10MostViewed") + fun get10MostViewed(@Header("Authorization") authHeader:String):Call> + + @GET("/api/Post/posts/get10Best") + fun get10Best(@Header("Authorization") authHeader:String):Call> + + @GET("/api/Post/posts/get10Newest") + fun get10Newest(@Header("Authorization") authHeader:String):Call> + } \ No newline at end of file diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Services/RetrofitHelper.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Services/RetrofitHelper.kt index 88685e4..43c2109 100644 --- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Services/RetrofitHelper.kt +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Services/RetrofitHelper.kt @@ -7,8 +7,8 @@ import retrofit2.converter.gson.GsonConverterFactory object RetrofitHelper { - //val baseUrl="http://10.0.2.2:5279" - val baseUrl="http://147.91.204.115:10082" + val baseUrl="http://10.0.2.2:5279" + //val baseUrl="http://147.91.204.115:10082" private var retrofit_noauth: IBackendApi? = null private var retrofit_auth: IBackendApi? = null diff --git a/Client/BrzoDoLokacije/app/src/main/res/drawable/ic_baseline_circle_24.xml b/Client/BrzoDoLokacije/app/src/main/res/drawable/ic_baseline_circle_24.xml new file mode 100644 index 0000000..4d57238 --- /dev/null +++ b/Client/BrzoDoLokacije/app/src/main/res/drawable/ic_baseline_circle_24.xml @@ -0,0 +1,5 @@ + + + diff --git a/Client/BrzoDoLokacije/app/src/main/res/drawable/ic_baseline_circle_7.xml b/Client/BrzoDoLokacije/app/src/main/res/drawable/ic_baseline_circle_7.xml new file mode 100644 index 0000000..6d080ea --- /dev/null +++ b/Client/BrzoDoLokacije/app/src/main/res/drawable/ic_baseline_circle_7.xml @@ -0,0 +1,5 @@ + + + diff --git a/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_home_page_main_scroll.xml b/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_home_page_main_scroll.xml index 2883291..efae8d4 100644 --- a/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_home_page_main_scroll.xml +++ b/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_home_page_main_scroll.xml @@ -154,19 +154,34 @@ android:layout_marginTop="16dp" + - + 20dp 20dp + + \ No newline at end of file -- cgit v1.2.3 From d945204fba909a2dfeb25cae2d320ab6e62eaf51 Mon Sep 17 00:00:00 2001 From: Ognjen Cirkovic Date: Mon, 28 Nov 2022 11:23:53 +0100 Subject: Promenjen zahtev za pretragu lokacije na backendu. Omogucena pretraga lokacija na clientu, prikazuje se naziv lokacije. --- Backend/Api/Api/Controllers/LocationController.cs | 9 +++-- .../brzodolokacije/Activities/MapsActivity.kt | 42 ++++++++++++++++++---- .../brzodolokacije/Interfaces/IBackendApi.kt | 3 ++ 3 files changed, 46 insertions(+), 8 deletions(-) (limited to 'Backend') diff --git a/Backend/Api/Api/Controllers/LocationController.cs b/Backend/Api/Api/Controllers/LocationController.cs index c9ef9ba..ba9c9a8 100644 --- a/Backend/Api/Api/Controllers/LocationController.cs +++ b/Backend/Api/Api/Controllers/LocationController.cs @@ -51,10 +51,15 @@ namespace Api.Controllers return BadRequest(); } - [HttpPost("search")] + [HttpGet("search")] [Authorize(Roles = "User")] - public async Task>> searchLocation(int searchtype ,string? query,Coords? coords) + public async Task>> searchLocation(int searchtype ,string? query,double? latitude,double? longitude) { + Coords coords = new Coords(); + if (latitude!=null && longitude!=null) { + coords.latitude = (double)latitude; + coords.longitude = (double)longitude; + } List ret = new List(); switch (searchtype) { 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 d8c874c..46cc5fe 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 @@ -22,8 +22,11 @@ import androidx.appcompat.app.AppCompatActivity import androidx.core.app.ActivityCompat import androidx.core.content.ContextCompat import androidx.core.widget.addTextChangedListener +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 com.google.android.gms.location.* import com.google.android.material.button.MaterialButton import com.google.android.material.floatingactionbutton.FloatingActionButton @@ -41,6 +44,8 @@ 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 +import retrofit2.Call +import retrofit2.Response import java.util.* import kotlin.collections.ArrayList @@ -59,6 +64,8 @@ class MapsActivity : AppCompatActivity() { var client: FusedLocationProviderClient? = null var locLongitude:Double?=null var locLatitude:Double?=null + var selectedLocation:com.example.brzodolokacije.Models.Location?=null + var responseLocations:MutableList?=null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_maps) @@ -114,8 +121,6 @@ class MapsActivity : AppCompatActivity() { fun setUpSpinner() { arraySpinner=mutableListOf() - arraySpinner!!.add("test") - spinnerAdapter= ArrayAdapter( this, android.R.layout.simple_list_item_1, arraySpinner!!) @@ -128,11 +133,36 @@ class MapsActivity : AppCompatActivity() { } - var test=1 fun onTextEnter(){ - test++ - spinnerAdapter!!.add("test"+test) - spinnerAdapter!!.notifyDataSetChanged() + var api=RetrofitHelper.getInstance() + var jwtString= SharedPreferencesHelper.getValue("jwt",this) + var text=searchBar.text + if(text==null ||text.toString().trim()=="") + return + var data=api.searchLocationsQuery("Bearer "+jwtString,text.toString()) + data.enqueue(object : retrofit2.Callback> { + override fun onResponse(call: Call?>, response: Response>) { + if(response.isSuccessful){ + var existingLocation=responseLocations + responseLocations=response.body()!! + var tempList=mutableListOf() + if(existingLocation!=null && existingLocation.size>0) + for(loc in existingLocation!!){ + spinnerAdapter!!.remove(loc.name) + } + for(loc in responseLocations!!){ + spinnerAdapter!!.add(loc.name) + } + spinnerAdapter!!.notifyDataSetChanged() + } + } + + override fun onFailure(call: Call>, t: Throwable) { + + } + }) + + } fun returnValue(){ val intent = intent 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 e4bfbc8..8556047 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 @@ -92,4 +92,7 @@ interface IBackendApi { @GET("/api/Post/posts/get10Newest") fun get10Newest(@Header("Authorization") authHeader:String):Call> + @GET("api/Location/search") + fun searchLocationsQuery(@Header("Authorization") authHeader:String,@Query("query") query: String):Call> + } \ No newline at end of file -- cgit v1.2.3 From 9c3cebe6f89586d2abd5f854cf5baa079d839b39 Mon Sep 17 00:00:00 2001 From: Ognjen Cirkovic Date: Mon, 28 Nov 2022 11:54:31 +0100 Subject: Napravljen dialog za dodavanje imena lokacije. Dodata logika dodavanje lokacije. Uplodovanje lokacije. Dodata provera na backu ukoliko nema tagova. Omoguceno dodavanje objave pomocu novog dodavanja lokacije. --- Backend/Api/Api/Services/PostService.cs | 7 +- .../brzodolokacije/Activities/ActivityAddPost.kt | 74 ++------------- .../brzodolokacije/Activities/MapsActivity.kt | 102 ++++++++++++++++++--- 3 files changed, 101 insertions(+), 82 deletions(-) (limited to 'Backend') diff --git a/Backend/Api/Api/Services/PostService.cs b/Backend/Api/Api/Services/PostService.cs index b75656e..e2e4e40 100644 --- a/Backend/Api/Api/Services/PostService.cs +++ b/Backend/Api/Api/Services/PostService.cs @@ -39,8 +39,11 @@ namespace Api.Services p.comments = new List(); p.images = new List(); p.createdAt = DateTime.Now.ToUniversalTime(); - var tags = post.tags.Split("|").ToList(); - p.tags = tags; + if (post.tags != null) + { + var tags = post.tags.Split("|").ToList(); + p.tags = tags; + } var folderPath = Path.Combine(Directory.GetCurrentDirectory(), "Files", p.ownerId); if (!Directory.Exists(folderPath)) { 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 f29db17..c2abf37 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 @@ -53,33 +53,27 @@ class ActivityAddPost : AppCompatActivity() { private lateinit var tagButtonAdd:Button private lateinit var tagList: MutableList private var tagidcounter:Int = 0 - val incorectCoord:Double=1000.0 val LOCATIONREQCODE=123 - var longitude:Double=incorectCoord - var latitude:Double=incorectCoord + var locationId:String?=null var progressDialog:ProgressDialog?=null private lateinit var addDescription:Button - //private var paths :ArrayList?=null + private var place=0; override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_add_post) -// Toast.makeText( -// applicationContext, "Add new ", Toast.LENGTH_LONG -// ).show(); + uploadedImages= ArrayList() tagList = mutableListOf() tagButtons= mutableListOf() tagidcounter = 0 - //paths= ArrayList() uploadFromGallery=findViewById(R.id.btnActivityAddPostUploadFromGalleryVisible) as Button showNextImage=findViewById(R.id.nextImage) as Button showPreviousImage=findViewById(R.id.previousImage) as Button switcher=findViewById(R.id.isActivityAddPostSwitcher) as ImageSwitcher - //location=findViewById(R.id.etActivityAddPostLocation) as EditText description=findViewById(R.id.etActivityAddPostDescription) as EditText post=findViewById(R.id.btnActivityAddPostPost) as Button addLocation=findViewById(R.id.btnActivityAddPostAddLocation) as Button @@ -205,11 +199,11 @@ class ActivityAddPost : AppCompatActivity() { description.hint="Unesite opis" description.setHintTextColor(Color.RED) } - if(longitude!=incorectCoord && latitude!=incorectCoord){ + if(locationId==null || locationId!!.trim()==""){ Toast.makeText(this,"Unesite lokaciju klikom na dugme",Toast.LENGTH_LONG) } - if(!locationString.isEmpty() && !descriptionString.isEmpty() && longitude!=incorectCoord && latitude!=incorectCoord && uploadedImages!!.size>0){ + if(!descriptionString.isEmpty() && uploadedImages!!.size>0){ sendPost() } } @@ -249,9 +243,7 @@ class ActivityAddPost : AppCompatActivity() { } 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") + locationId=bundle!!.getString("locationId") } } private fun sendPost(){ @@ -259,58 +251,8 @@ class ActivityAddPost : AppCompatActivity() { } fun uploadLocation() { - //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="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 { - override fun onResponse(call: Call, response: Response) { - if(response.isSuccessful()){ - - uploadPost(response.body()!!._id) - Toast.makeText( - applicationContext, "USPEH", Toast.LENGTH_LONG - ).show(); - - }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()) - } - - - } - - override fun onFailure(call: Call, t: Throwable) { - Toast.makeText( - applicationContext, t.toString(), Toast.LENGTH_LONG - ).show(); - Log.d("Main",t.toString()) - progressDialog!!.dismiss() - } - }) + if(locationId!=null && locationId!!.trim()!="") + uploadPost(locationId!!) } fun uploadPost(loc:String){ val api =RetrofitHelper.getInstance() 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 46cc5fe..faaa3b4 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,7 +1,9 @@ package com.example.brzodolokacije.Activities import android.Manifest +import android.app.AlertDialog import android.content.Context +import android.content.DialogInterface import android.content.pm.PackageManager import android.graphics.Color import android.location.Location @@ -22,6 +24,7 @@ import androidx.appcompat.app.AppCompatActivity import androidx.core.app.ActivityCompat import androidx.core.content.ContextCompat import androidx.core.widget.addTextChangedListener +import com.example.brzodolokacije.Models.LocationType import com.example.brzodolokacije.Models.PostPreview import com.example.brzodolokacije.R import com.example.brzodolokacije.Services.GeocoderHelper @@ -88,8 +91,12 @@ class MapsActivity : AppCompatActivity() { getLocation() } confirmButton.setOnClickListener{ - if(locLatitude!=null && locLatitude!=null) + if(selectedLocation!=null) returnValue() + else{ + addLocation() + + } } 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 && @@ -115,6 +122,73 @@ class MapsActivity : AppCompatActivity() { + } + fun addLocation(){ + var editText=EditText(this) + var dialog=AlertDialog.Builder(this).setTitle("Naziv").setMessage("Unesite naziv") + .setView(editText) + dialog.setPositiveButton("Dodaj") { dialog, which -> + uploadLocation(editText.text.toString()) + } + dialog.setNegativeButton("Prekini") { dialog, which -> + + } + dialog.show() + + } + fun uploadLocation(locationName:String){ + val api =RetrofitHelper.getInstance() + var geocoder=GeocoderHelper.getInstance() + var loc1=geocoder!!.getFromLocation(locLatitude!!,locLongitude!!,1) + if(loc1==null ||loc1.size<=0) + { + 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: com.example.brzodolokacije.Models.Location = + com.example.brzodolokacije.Models.Location( + "", + locationName, + city, + countryName, + address, + locLatitude!!, + locLongitude!!, + LocationType.GRAD + ) + var jwtString= SharedPreferencesHelper.getValue("jwt",this) + var data=api.addLocation("Bearer "+jwtString,loc) + + data.enqueue(object : retrofit2.Callback { + override fun onResponse(call: Call, response: Response) { + if(response.isSuccessful()){ + selectedLocation=response.body() + returnValue() + + }else { + + 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()) + } + + + } + + override fun onFailure(call: Call, t: Throwable) { + Toast.makeText( + applicationContext, t.toString(), Toast.LENGTH_LONG + ).show(); + Log.d("Main",t.toString()) + } + }) } var arraySpinner :MutableList?=null var spinnerAdapter: ArrayAdapter?=null @@ -128,10 +202,22 @@ class MapsActivity : AppCompatActivity() { searchBar.setAdapter(spinnerAdapter) searchBar.setOnItemClickListener(OnItemClickListener { parent, view, position, id -> val selected = parent.getItemAtPosition(position) as String - Log.d("Main",selected) + selectedLocation=responseLocations!!.find { location -> location.name==selected } + Log.d("main",selectedLocation.toString()) + confirmButton.visibility=View.VISIBLE }) + } + fun returnValue(){ + val intent = intent + val bundle = Bundle() + if(selectedLocation==null) + return + bundle.putString("locationId",selectedLocation!!._id) + intent.putExtras(bundle) + setResult(RESULT_OK, intent) + finish() } fun onTextEnter(){ var api=RetrofitHelper.getInstance() @@ -164,18 +250,6 @@ class MapsActivity : AppCompatActivity() { } - 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() -- cgit v1.2.3 From 78caf6a59402f930b0d828bc6ce5faac1c5b4ed4 Mon Sep 17 00:00:00 2001 From: "branislav.radivojevic" Date: Mon, 28 Nov 2022 14:06:40 +0100 Subject: Sortiranje istorije + bugfixes --- Backend/Api/Api/Models/Post.cs | 2 ++ Backend/Api/Api/Services/PostService.cs | 24 +++++++++++++++++----- .../brzodolokacije/Activities/ActivityAddPost.kt | 14 +++++++------ .../Activities/ActivityCapturePost.kt | 14 +++++++------ .../Activities/ActivitySinglePost.kt | 4 +++- .../java/com/example/brzodolokacije/Models/Post.kt | 6 ++++++ 6 files changed, 46 insertions(+), 18 deletions(-) (limited to 'Backend') diff --git a/Backend/Api/Api/Models/Post.cs b/Backend/Api/Api/Models/Post.cs index 1a4129f..0dc8158 100644 --- a/Backend/Api/Api/Models/Post.cs +++ b/Backend/Api/Api/Models/Post.cs @@ -38,9 +38,11 @@ namespace Api.Models public DateTime createdAt { get; set; } public int views { get; set; } public double ratings { get; set; } + public int ratingscount { get; set; } public List comments { get; set; } public List images { get; set; } public List? tags { get; set; } + public DateTime? lastViewed { get; set; } } public class Rating { diff --git a/Backend/Api/Api/Services/PostService.cs b/Backend/Api/Api/Services/PostService.cs index b75656e..0676d74 100644 --- a/Backend/Api/Api/Services/PostService.cs +++ b/Backend/Api/Api/Services/PostService.cs @@ -39,7 +39,10 @@ namespace Api.Services p.comments = new List(); p.images = new List(); p.createdAt = DateTime.Now.ToUniversalTime(); - var tags = post.tags.Split("|").ToList(); + List tags; + if (post.tags != "none") + tags = post.tags.Remove(post.tags.Length-1,1).Split("|").ToList(); + else tags = null; p.tags = tags; var folderPath = Path.Combine(Directory.GetCurrentDirectory(), "Files", p.ownerId); if (!Directory.Exists(folderPath)) @@ -85,6 +88,7 @@ namespace Api.Services p.views = post.views.Count(); p.createdAt = post.createdAt; p.tags = post.tags; + p.ratingscount = post.ratings.Count(); if (post.ratings.Count() > 0) { List ratings = new List(); @@ -116,9 +120,16 @@ namespace Api.Services Post p = await _posts.Find(post => post._id == id).FirstOrDefaultAsync(); if (p != null) { - if (!p.views.Any(x => x == userid)) + if (!p.views.Any(x => x.Split("|")[0] == userid)) { - p.views.Add(userid); + p.views.Add(userid + "|" + DateTime.Now.ToUniversalTime().ToString()); + await _posts.ReplaceOneAsync(x => x._id == id, p); + } + else + { + var v = p.views.Find(x => x.Split("|")[0] == userid); + p.views.Remove(v); + p.views.Add(userid + "|" + DateTime.Now.ToUniversalTime().ToString()); await _posts.ReplaceOneAsync(x => x._id == id, p); } } @@ -308,7 +319,7 @@ namespace Api.Services xd = ls.OrderByDescending(x => x.createdAt).ToList(); break; default: - + xd = ls.OrderByDescending(x => x.views).ToList(); break; } if(xd != null) @@ -360,12 +371,15 @@ namespace Api.Services var tosend = new List(); foreach (var post in posts) { - if (post.views.Any(x => x.Equals(userid))) + if (post.views.Any(x => x.Split("|")[0] == userid)) { + var t = post.views.Find(x => x.Split("|")[0] == userid); var x = await postToPostSend(post); + x.lastViewed = DateTime.Parse(t.Split("|")[1]).ToUniversalTime(); tosend.Add(x); } } + tosend = tosend.OrderByDescending(x => x.lastViewed).ToList(); return tosend; } 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 995ef4d..6db305e 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 @@ -120,7 +120,7 @@ class ActivityAddPost : AppCompatActivity() { tagText.isGone=false tagText.isVisible=true - if(tagList.count()<5) { + if(tagList.count()<4 && tagText.text.toString().length>=3) { var tagstr = tagText.text.toString() var newbtn = Button(this) newbtn.setId(tagidcounter) @@ -149,7 +149,7 @@ class ActivityAddPost : AppCompatActivity() { tagText.text.clear() } else{ - Toast.makeText(this,"Maksimalno 5 tagova",Toast.LENGTH_LONG) + Toast.makeText(this,"Maksimalno 4 tagova ( duzine + karaktera)",Toast.LENGTH_LONG) } } @@ -326,10 +326,12 @@ class ActivityAddPost : AppCompatActivity() { 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 tagliststring="none" + if(tagList.count()>0){ + tagliststring="" + for(tag in tagList){ + tagliststring=tagliststring+tag+"|" + }} var tagReq=RequestBody.create("text/plain".toMediaTypeOrNull(),tagliststring) val imagesParts = arrayOfNulls( 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 2321f18..40adea2 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 @@ -102,7 +102,7 @@ class ActivityCapturePost : AppCompatActivity() { tagText.isGone=false tagText.isVisible=true - if(tagList.count()<5) { + if(tagList.count()<4 && tagText.text.toString().length>=3) { var tagstr = tagText.text.toString() var newbtn = Button(this) newbtn.setId(tagidcounter) @@ -131,7 +131,7 @@ class ActivityCapturePost : AppCompatActivity() { tagText.text.clear() } else{ - Toast.makeText(this,"Maksimalno 5 tagova",Toast.LENGTH_LONG) + Toast.makeText(this,"Maksimalno 4 tagova (duzine 3+ karaktera)",Toast.LENGTH_LONG) } } @@ -328,10 +328,12 @@ class ActivityCapturePost : AppCompatActivity() { 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 tagliststring="none" + if(tagList.count()>0){ + tagliststring="" + for(tag in tagList){ + tagliststring=tagliststring+tag+"|" + }} var tagReq=RequestBody.create("text/plain".toMediaTypeOrNull(),tagliststring) val imagesParts = arrayOfNulls( 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 0e9c9da..569ab89 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 @@ -7,8 +7,10 @@ import android.graphics.Color import android.graphics.drawable.ColorDrawable import android.os.Bundle import android.preference.PreferenceManager +import android.provider.ContactsContract.CommonDataKinds.Im import android.util.Log import android.view.Gravity +import android.widget.ImageButton import android.widget.TextView import android.widget.Toast import androidx.appcompat.app.AppCompatActivity @@ -122,7 +124,7 @@ class ActivitySinglePost : AppCompatActivity() { fun setRatingListeners(){ val emptyStar=R.drawable.empty_star val fullStar=R.drawable.full_star - + //var starlist:List = mutableListOf() binding.rateStar1.setOnClickListener { Toast.makeText(this,"kliknuta prva zvezdica",Toast.LENGTH_SHORT).show() 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 e2e9209..47e581d 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 @@ -4,6 +4,7 @@ import android.os.Parcelable import kotlinx.android.parcel.Parcelize import okhttp3.MultipartBody import java.time.LocalDateTime +import java.util.* data class Post ( var _id:String, @@ -35,7 +36,12 @@ data class PostPreview ( var ratings:Float, var comments:List?, var images:List, + var ratingscount:Int, + var createdAt:LocalDateTime, + var lastViewed: LocalDateTime?, //samo za istoriju pregleda var tags:List? + + //nedostaju datum i vreme kreiranja ):Parcelable -- cgit v1.2.3 From 74936fc8083a6d0ff242d5328786822471dfc58f Mon Sep 17 00:00:00 2001 From: TAMARA JERINIC Date: Mon, 28 Nov 2022 16:34:41 +0100 Subject: Omogućeno praćenje korisnika. Dodata provera pratilaca na back-u. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Backend/Api/Api/Controllers/UserController.cs | 18 ++- Backend/Api/Api/Interfaces/IUserService.cs | 5 +- Backend/Api/Api/Services/UserService.cs | 92 ++++++++++++++- .../.idea/deploymentTargetDropDown.xml | 2 +- .../Activities/ActivitySinglePost.kt | 3 + .../Activities/ActivityUserProfile.kt | 127 ++++++++++++++++----- .../brzodolokacije/Fragments/FragmentFollowers.kt | 6 +- .../brzodolokacije/Fragments/FragmentFollowing.kt | 6 +- .../brzodolokacije/Fragments/FragmentProfile.kt | 4 +- .../brzodolokacije/Interfaces/IBackendApi.kt | 18 ++- .../java/com/example/brzodolokacije/Models/User.kt | 8 +- .../app/src/main/res/values/colors.xml | 2 + 12 files changed, 233 insertions(+), 58 deletions(-) (limited to 'Backend') diff --git a/Backend/Api/Api/Controllers/UserController.cs b/Backend/Api/Api/Controllers/UserController.cs index 7764af1..ada0f35 100644 --- a/Backend/Api/Api/Controllers/UserController.cs +++ b/Backend/Api/Api/Controllers/UserController.cs @@ -89,14 +89,26 @@ namespace Api.Controllers return Ok(await _userService.GetFollowing(id)); } - [HttpGet("addFollower")] + [HttpGet("{id}/addFollower")] [Authorize(Roles = "User")] - public async Task>> AddFollower(string userId, string followerId) + public async Task> AddFollower(string id) { - return Ok(await _userService.AddFollower(userId, followerId)); + return Ok(await _userService.AddFollower(id)); } + [HttpGet("{id}/myFollowings")] + [Authorize(Roles = "User")] + public async Task>> GetMyFollowings() + { + return Ok(await _userService.GetMyFollowings()); + } + [HttpGet("{id}/checkIfAlreadyFollow")] + [Authorize(Roles = "User")] + public async Task> CheckIfAlreadyFollow(String id) + { + return Ok(await _userService.CheckIfAlreadyFollow(id)); + } } } diff --git a/Backend/Api/Api/Interfaces/IUserService.cs b/Backend/Api/Api/Interfaces/IUserService.cs index 5770de1..21dcdc0 100644 --- a/Backend/Api/Api/Interfaces/IUserService.cs +++ b/Backend/Api/Api/Interfaces/IUserService.cs @@ -27,8 +27,11 @@ namespace Api.Interfaces Task GetUserData(string username); Task GetSelfUserData(string id); - Task AddFollower(string userId,string followerId); + Task AddFollower(string followerId); Task> GetFollowers(string id); Task> GetFollowing(string id); + Task> GetMyFollowings(); + + Task CheckIfAlreadyFollow(string id); } } diff --git a/Backend/Api/Api/Services/UserService.cs b/Backend/Api/Api/Services/UserService.cs index f616d99..7bfc24a 100644 --- a/Backend/Api/Api/Services/UserService.cs +++ b/Backend/Api/Api/Services/UserService.cs @@ -380,20 +380,25 @@ namespace Api.Services return tosend; } - public async Task AddFollower(string userId,string followerId) + public async Task AddFollower(string followerId) { - User u = await _users.Find(user => user._id==userId).FirstOrDefaultAsync(); + string id = null; + if (_httpContext.HttpContext.User.FindFirstValue("id") != null) + { + id = _httpContext.HttpContext.User.FindFirstValue("id").ToString(); + } User f = await _users.Find(user => user._id == followerId).FirstOrDefaultAsync(); - - if (userId != null && followerId!=null) + User u = await _users.Find(user => user._id == id).FirstOrDefaultAsync(); + + if (id != null && followerId!=null) { if (u.followers == null) u.followers = new List(); u.followers.Add(followerId); if (f.following == null) f.following = new List(); - f.following.Add(userId); - _users.ReplaceOne(user=>user._id==userId, u); + f.following.Add(id); + _users.ReplaceOne(user=>user._id==id, u); _users.ReplaceOne(user => user._id == followerId, f); return true; } @@ -428,6 +433,7 @@ namespace Api.Services followers.Add((UserSend)follower); } } + u.followersCount=followers.Count() ; return followers; } return null; @@ -459,9 +465,83 @@ namespace Api.Services following.Add((UserSend)follower); } } + u.followersCount = following.Count(); return following; } return null; } + + public async Task> GetMyFollowings() + { + string id = null; + + if (_httpContext.HttpContext.User.FindFirstValue("id") != null) + { + id = _httpContext.HttpContext.User.FindFirstValue("id").ToString(); + } + User u = await _users.Find(user => user._id == id).FirstOrDefaultAsync(); + List myFollowings = new List(); + if (u != null) + { + + if (u.following != null && u.following.Count() > 0) + { + foreach (string userid in u.following) + { + User utemp = await _users.Find(user => user._id == userid).FirstOrDefaultAsync(); + if (utemp == null) + { + continue; + } + UserSend following = new UserSend(); + following.pfp = utemp.pfp; + following.username = utemp.username; + following.email = utemp.username; + following.followers = utemp.followers; + following._id = utemp._id; + + myFollowings.Add((UserSend)following); + } + } + return myFollowings; + } + return null; + } + + public async Task CheckIfAlreadyFollow(string id) + { + string myId = null; + + if (_httpContext.HttpContext.User.FindFirstValue("id") != null) + { + myId = _httpContext.HttpContext.User.FindFirstValue("id").ToString(); + } + + User u = await _users.Find(user => user._id == myId).FirstOrDefaultAsync(); + User f = await _users.Find(user => user._id == id).FirstOrDefaultAsync(); + + if (u != null) + { + + if (u.following != null && u.following.Count() > 0) + { + foreach (string userid in u.following) + { + User utemp = await _users.Find(user => user._id == userid).FirstOrDefaultAsync(); + if (utemp == null) + { + continue; + } + if (utemp._id == f._id) + { + return true; + } + } + } + + } + + return false; + } } } diff --git a/Client/BrzoDoLokacije/.idea/deploymentTargetDropDown.xml b/Client/BrzoDoLokacije/.idea/deploymentTargetDropDown.xml index 6d9839f..394c76a 100644 --- a/Client/BrzoDoLokacije/.idea/deploymentTargetDropDown.xml +++ b/Client/BrzoDoLokacije/.idea/deploymentTargetDropDown.xml @@ -12,6 +12,6 @@ - + \ No newline at end of file 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 0e9c9da..e925984 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 @@ -303,6 +303,7 @@ class ActivitySinglePost : AppCompatActivity() { } fun translateOwnerIdToName(id:String) { + //binding.tvUser.text="proba" var token= SharedPreferencesHelper.getValue("jwt", this).toString() val api= RetrofitHelper.getInstance() val request= api.getProfileFromId("Bearer " + token, id) @@ -313,6 +314,7 @@ class ActivitySinglePost : AppCompatActivity() { return } userData = response.body()!! + binding.tvUser.text= userData!!.username.toString() } @@ -322,4 +324,5 @@ class ActivitySinglePost : AppCompatActivity() { }) } + } 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 index 2d290db..c03dbd3 100644 --- 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 @@ -1,26 +1,28 @@ package com.example.brzodolokacije.Activities +import android.annotation.SuppressLint +import android.graphics.Color +import android.graphics.PorterDuff +import android.graphics.drawable.Drawable import android.os.Bundle -import android.widget.Button -import android.widget.FrameLayout -import android.widget.ImageButton -import android.widget.ImageView -import android.widget.TextView -import androidx.annotation.DrawableRes +import android.util.Log +import android.widget.* import androidx.appcompat.app.AppCompatActivity +import androidx.core.content.ContextCompat import androidx.fragment.app.Fragment import com.bumptech.glide.Glide import com.example.brzodolokacije.Fragments.FragmentShowUserPosts -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.R.* import com.example.brzodolokacije.Services.RetrofitHelper import com.example.brzodolokacije.Services.SharedPreferencesHelper import com.google.gson.Gson import retrofit2.Call import retrofit2.Callback import retrofit2.Response +import java.security.AccessController.getContext + class ActivityUserProfile : AppCompatActivity() { private lateinit var name:TextView @@ -28,58 +30,125 @@ class ActivityUserProfile : AppCompatActivity() { private lateinit var followersNumber:TextView private lateinit var followingNumber:TextView private lateinit var profilePicture:ImageView - private lateinit var followUser: ImageButton + private lateinit var followUser: Button private lateinit var showUserPosts: Button private lateinit var fragmentContainer: FrameLayout - private lateinit var myObject:UserReceive + private lateinit var userObject:UserReceive + private lateinit var openChat:ImageButton + + private lateinit var followersList: MutableList + private lateinit var followingList: MutableList + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContentView(R.layout.activity_user_profile) + setContentView(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) - followUser=findViewById(R.id.btnActivityUserProfileFollow) - showUserPosts=findViewById(R.id.btnActivityUserProfileShowPosts) - fragmentContainer=findViewById(R.id.flActivityProfileFragmentContainer) + name=findViewById(id.tvActivityUserProfileName) + postsNumber=findViewById(id.tvActivityUserProfilePostsNo) + followersNumber=findViewById(id.tvActivityUserProfileFollowersNo) + followingNumber=findViewById(id.tvActivityUserProfileFollowNo) + profilePicture=findViewById(id.tvActivityProfileProfilePicture) + followUser=findViewById(id.btnActivityUserProfileFollow) + showUserPosts=findViewById(id.btnActivityUserProfileShowPosts) + fragmentContainer=findViewById(id.flActivityProfileFragmentContainer) + openChat=findViewById(id.activityUserProfileOpenChat) val jsonMyObject: String val extras = intent.extras if (extras != null) { jsonMyObject = extras.getString("user")!! - myObject= Gson().fromJson(jsonMyObject, UserReceive::class.java) + //val myObject: UserReceive = Gson().fromJson(jsonMyObject, UserReceive::class.java) - name.text=myObject.name - postsNumber.text=myObject.postNumber.toString() - followersNumber.text=myObject.followers.toString() - followingNumber.text=myObject.following.toString() + userObject= Gson().fromJson(jsonMyObject, UserReceive::class.java) - if(myObject.pfp!=null) { + name.text=userObject.name + postsNumber.text=userObject.postNumber.toString() + followersNumber.text=userObject?.followersCount.toString() + followingNumber.text=userObject?.followingCount.toString() + + if(userObject.pfp!=null) { Glide.with(this) - .load(RetrofitHelper.baseUrl + "/api/post/image/" + myObject.pfp!!._id) + .load(RetrofitHelper.baseUrl + "/api/post/image/" + userObject.pfp!!._id) .circleCrop()//Round image .into(profilePicture) } } + checkIfAlreadyFollow() + followUser.setOnClickListener{ + + checkIfAlreadyFollow() + + val api = RetrofitHelper.getInstance() val token= SharedPreferencesHelper.getValue("jwt", this@ActivityUserProfile) - api.addFollower("Bearer "+token,myObject._id); + var data=api.addFollower("Bearer "+token,userObject._id); + data.enqueue(object : Callback { + override fun onResponse( + call: Call, + response: Response + ) { + Toast.makeText( + this@ActivityUserProfile, "PRATITE KORISNIKA", Toast.LENGTH_LONG + ).show(); + } + override fun onFailure(call: Call, t: Throwable) { + Toast.makeText( + this@ActivityUserProfile, t.toString(), Toast.LENGTH_LONG + ).show(); + } + }) } showUserPosts.setOnClickListener { val bundle = Bundle() - bundle.putString("user", Gson().toJson(myObject)) + bundle.putString("user", Gson().toJson(userObject)) val fragment = Fragment() fragment.arguments = bundle getSupportFragmentManager().beginTransaction() - .replace(R.id.flActivityProfileFragmentContainer,FragmentShowUserPosts()).commit() + .replace(id.flActivityProfileFragmentContainer,FragmentShowUserPosts()).commit() } } + fun checkIfAlreadyFollow(){ + val api = RetrofitHelper.getInstance() + val token= SharedPreferencesHelper.getValue("jwt", this@ActivityUserProfile) + var data=api.checkIfAlreadyFollow("Bearer "+token,userObject._id); + data.enqueue(object : Callback { + + override fun onFailure(call: Call, t: Throwable) {; + Log.d("fail","faillllllllllllllllllllllllllllllllllllllllllllllllllllllll") + Log.d("fail",t.toString()) + } + + @SuppressLint("ResourceAsColor") + override fun onResponse(call: Call, response: Response) { + Log.d("success","successsssssssssssssssssss") + if (response.body() == null) { + return + } + var follow = response.body()!! + if(follow){ + Log.d("success","follow") + followUser.setCompoundDrawablesWithIntrinsicBounds(drawable.ic_outline_person_remove_24,0,0,0) + followUser.text="Ne prati više" + + } + if(!follow){ + Log.d("success","not follow") + followUser.setCompoundDrawablesWithIntrinsicBounds(drawable.ic_outline_person_add_alt_24,0,0,0) + followUser.text="Prati" + } + + } + }) + + } + + fun checkIfAlreadyFollowChangeButton(){ + + } } \ No newline at end of file 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 index f1d9321..7450134 100644 --- 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 @@ -44,7 +44,7 @@ class FragmentFollowers : Fragment() { ).show(); } - getFollowers() + //getFollowers() btnBack.setOnClickListener { val fragmentProfile = FragmentProfile() @@ -56,7 +56,7 @@ class FragmentFollowers : Fragment() { return view } - fun getFollowers(){ + /* fun getFollowers(){ val api = RetrofitHelper.getInstance() val data=api.getFollowers(userId) data.enqueue(object : Callback> { @@ -80,5 +80,5 @@ class FragmentFollowers : Fragment() { ).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 index b7a40dc..6f2ce65 100644 --- 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 @@ -38,7 +38,7 @@ class FragmentFollowing : Fragment() { ).show(); } - getFollowing() + //getFollowing() back.setOnClickListener { val fragmentProfile = FragmentProfile() @@ -50,7 +50,7 @@ class FragmentFollowing : Fragment() { return view } - fun getFollowing(){ + /*fun getFollowing(){ val api = RetrofitHelper.getInstance() val data=api.getFollowers(userId) data.enqueue(object : Callback> { @@ -74,5 +74,5 @@ class FragmentFollowing : Fragment() { ).show(); } }) - } + }*/ } \ 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 3427658..669b978 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 @@ -214,8 +214,8 @@ class FragmentProfile : Fragment(com.example.brzodolokacije.R.layout.fragment_pr username.setText("@"+user.username) postsCount.setText(user.postcount.toString()) - followersCount.setText(user.followersNumber.toString()) - followingCount.setText(user.followingNumber.toString()) + followersCount.setText(user.followersCount.toString()) + followingCount.setText(user.followingCount.toString()) userId=user._id 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 8556047..fc2d24f 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 @@ -72,14 +72,14 @@ interface IBackendApi { //@POST("putanja") //fun add(@Body obj:Post,@Header("Authorization") authHeader:String):Call - @POST("/api/user/{id}/followers") - fun getFollowers(@Path("id") id:String):Call > + @GET("/api/user/{id}/followers") + fun getFollowers(@Header("Authorization") authHeader:String,@Path("id") id:String):Call > - @POST("/api/user{id}/following") - fun getFollowing(@Path("id") id:String):Call > + @GET("/api/user/{id}/following") + fun getFollowing(@Header("Authorization") authHeader:String,@Path("id") id:String):Call > - @POST("/api/user{id}/addFollower") - fun addFollower(@Header("Authorization") authHeader:String,@Path("id") id:String):Call + @GET("/api/user/{id}/addFollower") + fun addFollower(@Header("Authorization") authHeader:String,@Path("id") id:String):Call @GET("/api/user/{id}/id/profile") fun getProfileFromId(@Header("Authorization") authHeader:String,@Path("id") username:String):Call @@ -95,4 +95,10 @@ interface IBackendApi { @GET("api/Location/search") fun searchLocationsQuery(@Header("Authorization") authHeader:String,@Query("query") query: String):Call> + @GET("/api/user/{id}/myFollowings") + fun getMyFollowings(@Header("Authorization") authHeader:String):Call > + + @GET("/api/user/{id}/checkIfAlreadyFollow") + fun checkIfAlreadyFollow(@Header("Authorization") authHeader:String,@Path("id") id:String):Call + } \ 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 46338b3..6e282a9 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 @@ -29,10 +29,10 @@ data class UserReceive( var creationDate: Date, var pfp:PostImage?, var postcount:Int, - var followers:List, - var followersNumber:Int, - var following:List, - var followingNumber:Int, + var followers:List, + var followersCount:Int, + var following:List, + var followingCount:Int, var postIds:List, var postNumber:Int ) \ No newline at end of file diff --git a/Client/BrzoDoLokacije/app/src/main/res/values/colors.xml b/Client/BrzoDoLokacije/app/src/main/res/values/colors.xml index 0d4da4f..fe34814 100644 --- a/Client/BrzoDoLokacije/app/src/main/res/values/colors.xml +++ b/Client/BrzoDoLokacije/app/src/main/res/values/colors.xml @@ -7,5 +7,7 @@ #FF018786 #FF000000 #FFFFFFFF + #c4c4c4 #DE093A4C + #183e4b \ No newline at end of file -- cgit v1.2.3 From c20758b0194ecd6fbf50afbd808801542a8f292d Mon Sep 17 00:00:00 2001 From: Jelena Petrovic Date: Mon, 28 Nov 2022 17:38:42 +0100 Subject: dodavanje samo novog komentara u vec ucitane komentare #58 --- Backend/Api/Api/Controllers/PostController.cs | 2 +- Backend/Api/Api/Interfaces/IPostService.cs | 2 +- Backend/Api/Api/Services/PostService.cs | 16 ++++- .../Activities/ActivitySinglePost.kt | 71 +++++++++++----------- .../brzodolokacije/Interfaces/IBackendApi.kt | 2 +- 5 files changed, 52 insertions(+), 41 deletions(-) (limited to 'Backend') diff --git a/Backend/Api/Api/Controllers/PostController.cs b/Backend/Api/Api/Controllers/PostController.cs index 4c6fbac..ec5829e 100644 --- a/Backend/Api/Api/Controllers/PostController.cs +++ b/Backend/Api/Api/Controllers/PostController.cs @@ -98,7 +98,7 @@ namespace Api.Controllers [HttpPost("posts/{id}/addcomment")] [Authorize(Roles = "User")] - public async Task> addComment([FromBody] CommentReceive cmnt,string id) + public async Task> addComment([FromBody] CommentReceive cmnt,string id) { var userid = await _userService.UserIdFromJwt(); var c = await _postService.AddComment(cmnt, userid, id); diff --git a/Backend/Api/Api/Interfaces/IPostService.cs b/Backend/Api/Api/Interfaces/IPostService.cs index 5b04dc3..9bf71d5 100644 --- a/Backend/Api/Api/Interfaces/IPostService.cs +++ b/Backend/Api/Api/Interfaces/IPostService.cs @@ -10,7 +10,7 @@ namespace Api.Interfaces Task postToPostSend(Post post); Task AddOrReplaceRating(RatingReceive rating, string userid); Task RemoveRating(string postid, string userid); - Task AddComment(CommentReceive cmnt, string userid, string postid); + Task AddComment(CommentReceive cmnt, string userid, string postid); Task> ListComments(string postid); Task> CascadeComments(string parentid, Post p); Task DeleteComments(string postid, string cmntid,string userid); diff --git a/Backend/Api/Api/Services/PostService.cs b/Backend/Api/Api/Services/PostService.cs index 0676d74..e59c735 100644 --- a/Backend/Api/Api/Services/PostService.cs +++ b/Backend/Api/Api/Services/PostService.cs @@ -178,20 +178,30 @@ namespace Api.Services } return false; } - public async Task AddComment(CommentReceive cmnt,string userid,string postid) + public async Task AddComment(CommentReceive cmnt,string userid,string postid) { Post p = await _posts.Find(post => post._id == postid).FirstOrDefaultAsync(); if (p != null) { - Comment c= new Comment(); + Comment c = new Comment(); + CommentSend c1= new CommentSend(); c.parentId = cmnt.parentId; + c1.parentId = cmnt.parentId; c.userId = userid; + c1.userId = userid; c.comment = cmnt.comment; + c1.comment = cmnt.comment; c.timestamp = DateTime.Now.ToUniversalTime(); + c1.timestamp = c.timestamp; c._id = ObjectId.GenerateNewId().ToString(); + c1._id = c._id; + var user = await _users.Find(x => x._id == c.userId).FirstOrDefaultAsync(); + if (user != null) + c1.username = user.username; + else c1.username = "Deleted user"; p.comments.Add(c); await _posts.ReplaceOneAsync(x => x._id == postid, p); - return c; + return c1; } return null; } 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 b788b93..d1ec76b 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,16 +1,11 @@ package com.example.brzodolokacije.Activities -import android.app.Dialog -import android.content.Context import android.content.Intent import android.graphics.Color import android.graphics.drawable.ColorDrawable import android.os.Bundle import android.preference.PreferenceManager -import android.provider.ContactsContract.CommonDataKinds.Im import android.util.Log -import android.view.Gravity -import android.widget.ImageButton import android.widget.TextView import android.widget.Toast import androidx.appcompat.app.AppCompatActivity @@ -26,7 +21,6 @@ import com.example.brzodolokacije.Services.SharedPreferencesHelper import com.example.brzodolokacije.databinding.ActivitySinglePostBinding import com.google.android.material.bottomsheet.BottomSheetDialog import com.google.gson.Gson -import kotlinx.android.synthetic.main.activity_single_post.* import okhttp3.ResponseBody import org.osmdroid.config.Configuration import org.osmdroid.tileprovider.tilesource.TileSourceFactory @@ -197,10 +191,11 @@ class ActivitySinglePost : AppCompatActivity() { val postApi= RetrofitHelper.getInstance() val token= SharedPreferencesHelper.getValue("jwt", this@ActivitySinglePost) val request=postApi.addComment("Bearer "+token,post._id,comment) - request.enqueue(object : retrofit2.Callback { - override fun onResponse(call: Call, response: Response) { + request.enqueue(object : retrofit2.Callback { + override fun onResponse(call: Call, response: Response) { if(response.isSuccessful){ - requestGetComments() + var newComment=response.body()!! + requestGetComments(newComment) binding.NewComment.text.clear() }else{ if(response.errorBody()!=null) @@ -210,38 +205,46 @@ class ActivitySinglePost : AppCompatActivity() { } - override fun onFailure(call: Call, t: Throwable) { + override fun onFailure(call: Call, t: Throwable) { Log.d("main2",t.message.toString()) } }) } - fun requestGetComments(){ - val postApi= RetrofitHelper.getInstance() - val token= SharedPreferencesHelper.getValue("jwt", this@ActivitySinglePost) - val request=postApi.getComments("Bearer "+token,post._id) - request.enqueue(object : retrofit2.Callback?> { - override fun onResponse(call: Call?>, response: Response?>) { - if(response.isSuccessful){ - comments= response.body()!! - if(comments!=null && comments!!.isNotEmpty()){ - buildRecyclerViewComments() - if(comments!=null) - binding.tvCommentCount.text=comments?.size.toString() - else - binding.tvCommentCount.text="0" + fun requestGetComments(newComment:CommentSend?=null){ + if(newComment==null){ + val postApi= RetrofitHelper.getInstance() + val token= SharedPreferencesHelper.getValue("jwt", this@ActivitySinglePost) + val request=postApi.getComments("Bearer "+token,post._id) + request.enqueue(object : retrofit2.Callback?> { + override fun onResponse(call: Call?>, response: Response?>) { + if(response.isSuccessful){ + comments= response.body()!! + if(comments!=null && comments!!.isNotEmpty()){ + buildRecyclerViewComments() + if(comments!=null) + binding.tvCommentCount.text=comments?.size.toString() + else + binding.tvCommentCount.text="0" + } + }else{ + if(response.errorBody()!=null) + Log.d("main1",response.message().toString()) } - }else{ - if(response.errorBody()!=null) - Log.d("main1",response.message().toString()) - } - } + } - override fun onFailure(call: Call?>, t: Throwable) { - Log.d("main2",t.message.toString()) - } - }) + override fun onFailure(call: Call?>, t: Throwable) { + Log.d("main2",t.message.toString()) + } + }) + } + else{ + (adapterComments as CommentsAdapter).items.add(0,newComment) + recyclerViewComments?.adapter=adapterComments + Log.d("main",newComment.username) + binding.tvCommentCount.text=comments?.size.toString() + } } fun requestAddRating(rating:RatingReceive){ @@ -325,6 +328,4 @@ class ActivitySinglePost : AppCompatActivity() { } }) } - - } 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 fc2d24f..ce8d7e3 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 @@ -40,7 +40,7 @@ interface IBackendApi { @POST("api/Post/posts/{id}/addrating") fun addRating(@Header("Authorization") authHeader:String,@Path("id") id:String,@Body rating: RatingReceive):Call @POST("api/Post/posts/{id}/addcomment") - fun addComment(@Header("Authorization") authHeader:String,@Path("id") id:String,@Body rating: CommentReceive):Call + fun addComment(@Header("Authorization") authHeader:String,@Path("id") id:String,@Body rating: CommentReceive):Call @GET("api/Post/posts/{id}/listcomments") fun getComments(@Header("Authorization") authHeader:String,@Path("id") id:String):Call> -- cgit v1.2.3 From 50a2fec98d34b51d94e9ff23ee27eda6f6e28589 Mon Sep 17 00:00:00 2001 From: "branislav.radivojevic" Date: Mon, 28 Nov 2022 19:48:33 +0100 Subject: brisanje posta back --- Backend/Api/Api/Controllers/PostController.cs | 13 ++++++++++++- Backend/Api/Api/Interfaces/IPostService.cs | 1 + Backend/Api/Api/Services/PostService.cs | 12 ++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) (limited to 'Backend') diff --git a/Backend/Api/Api/Controllers/PostController.cs b/Backend/Api/Api/Controllers/PostController.cs index ec5829e..3d7199c 100644 --- a/Backend/Api/Api/Controllers/PostController.cs +++ b/Backend/Api/Api/Controllers/PostController.cs @@ -56,7 +56,18 @@ namespace Api.Controllers } return BadRequest(); } - + [HttpGet("posts/delete/{id}")] + [Authorize(Roles = "User")] + public async Task> deletePost(string id) + { + var userid = await _userService.UserIdFromJwt(); + var res = await _postService.deletePost(id, userid); + if (res) + { + return Ok(res); + } + return BadRequest("Post ne postoji ili vi niste vlasnik"); + } [HttpGet("image/{id}")] //[Authorize(Roles = "User")] public async Task getImage(string id) diff --git a/Backend/Api/Api/Interfaces/IPostService.cs b/Backend/Api/Api/Interfaces/IPostService.cs index 9bf71d5..60781bb 100644 --- a/Backend/Api/Api/Interfaces/IPostService.cs +++ b/Backend/Api/Api/Interfaces/IPostService.cs @@ -5,6 +5,7 @@ namespace Api.Interfaces public interface IPostService { Task addPost(PostReceive post); + Task deletePost(string postid, string userid); Task> getAllPosts(); Task getPostById(string id,string userid); Task postToPostSend(Post post); diff --git a/Backend/Api/Api/Services/PostService.cs b/Backend/Api/Api/Services/PostService.cs index e59c735..dcfd5e0 100644 --- a/Backend/Api/Api/Services/PostService.cs +++ b/Backend/Api/Api/Services/PostService.cs @@ -104,6 +104,18 @@ namespace Api.Services return p; } + public async Task deletePost(string postid,string userid) + { + var p = await _posts.Find(x => x._id == postid).FirstOrDefaultAsync(); + if (p == null || p.ownerId != userid) + return false; + foreach (var image in p.images) + System.IO.File.Delete(image.path); + + await _posts.DeleteOneAsync(postid); + return true; + } + public async Task> getAllPosts() { List posts = await _posts.Find(_ => true).ToListAsync(); -- cgit v1.2.3 From f2e816ab9e625b0575f6e81fffb0ee7fceddc84e Mon Sep 17 00:00:00 2001 From: TAMARA JERINIC Date: Mon, 28 Nov 2022 22:26:51 +0100 Subject: Omogućeno praćenje i prestanak praćenja korisnika na front-u i back-u. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Backend/Api/Api/Controllers/UserController.cs | 6 + Backend/Api/Api/Interfaces/IUserService.cs | 2 + Backend/Api/Api/Services/UserService.cs | 79 ++++++++++-- .../Activities/ActivityUserProfile.kt | 138 ++++++++++++++++----- .../brzodolokacije/Interfaces/IBackendApi.kt | 3 + .../src/main/res/layout/activity_user_profile.xml | 33 ++++- 6 files changed, 216 insertions(+), 45 deletions(-) (limited to 'Backend') diff --git a/Backend/Api/Api/Controllers/UserController.cs b/Backend/Api/Api/Controllers/UserController.cs index ada0f35..cc45737 100644 --- a/Backend/Api/Api/Controllers/UserController.cs +++ b/Backend/Api/Api/Controllers/UserController.cs @@ -110,5 +110,11 @@ namespace Api.Controllers return Ok(await _userService.CheckIfAlreadyFollow(id)); } + [HttpGet("{id}/unfollow")] + [Authorize(Roles = "User")] + public async Task> Unfollow(string id) + { + return Ok(await _userService.Unfollow(id)); + } } } diff --git a/Backend/Api/Api/Interfaces/IUserService.cs b/Backend/Api/Api/Interfaces/IUserService.cs index 21dcdc0..5f99733 100644 --- a/Backend/Api/Api/Interfaces/IUserService.cs +++ b/Backend/Api/Api/Interfaces/IUserService.cs @@ -33,5 +33,7 @@ namespace Api.Interfaces Task> GetMyFollowings(); Task CheckIfAlreadyFollow(string id); + Task Unfollow(string id); + } } diff --git a/Backend/Api/Api/Services/UserService.cs b/Backend/Api/Api/Services/UserService.cs index 7bfc24a..cc75533 100644 --- a/Backend/Api/Api/Services/UserService.cs +++ b/Backend/Api/Api/Services/UserService.cs @@ -6,6 +6,7 @@ using System.Security.Claims; using MimeKit; using MailKit.Net.Smtp; using DnsClient; +using MongoDB.Bson; namespace Api.Services { @@ -380,6 +381,18 @@ namespace Api.Services return tosend; } + public async Task updateUserFollowerFollowingCount(List followers,List followings,string userId) + { + User u = await _users.Find(user => user._id == userId).FirstOrDefaultAsync(); + if(u!= null) + { + u.followersCount = followers.Count(); + u.followingCount = followings.Count(); + return true; + } + return false; + } + public async Task AddFollower(string followerId) { string id = null; @@ -392,14 +405,29 @@ namespace Api.Services if (id != null && followerId!=null) { - if (u.followers == null) - u.followers = new List(); - u.followers.Add(followerId); - if (f.following == null) - f.following = new List(); - f.following.Add(id); + if (f.followers == null) + { + f.followers = new List(); + f.followersCount = 0; + } + f.followers.Add(id); + f.followersCount =f.followers.Count(); + + + if (u.following == null) + { + u.following = new List(); + u.followingCount = 0; + } + u.following.Add(followerId); + u.followingCount =u.following.Count(); + _users.ReplaceOne(user=>user._id==id, u); _users.ReplaceOne(user => user._id == followerId, f); + + // updateUserFollowerFollowingCount(u.followers, u.following, u._id); + //updateUserFollowerFollowingCount(f.followers, f.following, f._id); + return true; } @@ -543,5 +571,42 @@ namespace Api.Services return false; } - } + + public async Task Unfollow(string id) + { + string myId = null; + + if (_httpContext.HttpContext.User.FindFirstValue("id") != null) + { + myId = _httpContext.HttpContext.User.FindFirstValue("id").ToString(); + } + + User u = await _users.Find(user => user._id == myId).FirstOrDefaultAsync(); + User f = await _users.Find(user => user._id == id).FirstOrDefaultAsync(); + + if (u != null) + { + if (u.following != null && f.followers!=null) + { + u.following.Remove(f._id); + u.followingCount=u.following.Count(); + u.followersCount = u.followers.Count(); + + + f.followers.Remove(u._id); + f.followersCount =f.followers.Count(); + f.followingCount =f.following.Count(); + + _users.ReplaceOne(user => user._id == myId, u); + _users.ReplaceOne(user => user._id == id, f); + + //updateUserFollowerFollowingCount(u.followers, u.following, u._id); + //updateUserFollowerFollowingCount(f.followers, f.following, f._id); + return true; + } + + } + return false; + } + } } 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 index c03dbd3..4f48dc7 100644 --- 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 @@ -1,19 +1,15 @@ package com.example.brzodolokacije.Activities import android.annotation.SuppressLint -import android.graphics.Color -import android.graphics.PorterDuff -import android.graphics.drawable.Drawable import android.os.Bundle import android.util.Log import android.widget.* import androidx.appcompat.app.AppCompatActivity -import androidx.core.content.ContextCompat +import androidx.core.view.isVisible import androidx.fragment.app.Fragment import com.bumptech.glide.Glide import com.example.brzodolokacije.Fragments.FragmentShowUserPosts import com.example.brzodolokacije.Models.UserReceive -import com.example.brzodolokacije.R import com.example.brzodolokacije.R.* import com.example.brzodolokacije.Services.RetrofitHelper import com.example.brzodolokacije.Services.SharedPreferencesHelper @@ -21,7 +17,6 @@ import com.google.gson.Gson import retrofit2.Call import retrofit2.Callback import retrofit2.Response -import java.security.AccessController.getContext class ActivityUserProfile : AppCompatActivity() { @@ -35,9 +30,10 @@ class ActivityUserProfile : AppCompatActivity() { private lateinit var fragmentContainer: FrameLayout private lateinit var userObject:UserReceive private lateinit var openChat:ImageButton - + private lateinit var unfollowUser:Button private lateinit var followersList: MutableList private lateinit var followingList: MutableList + private var follow:Boolean=false override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -49,6 +45,7 @@ class ActivityUserProfile : AppCompatActivity() { followingNumber=findViewById(id.tvActivityUserProfileFollowNo) profilePicture=findViewById(id.tvActivityProfileProfilePicture) followUser=findViewById(id.btnActivityUserProfileFollow) + unfollowUser=findViewById(id.btnActivityUserProfileUnFollow) showUserPosts=findViewById(id.btnActivityUserProfileShowPosts) fragmentContainer=findViewById(id.flActivityProfileFragmentContainer) openChat=findViewById(id.activityUserProfileOpenChat) @@ -74,31 +71,68 @@ class ActivityUserProfile : AppCompatActivity() { } } + checkIfAlreadyFollow() + updateUserData() followUser.setOnClickListener{ + val api = RetrofitHelper.getInstance() + val token = SharedPreferencesHelper.getValue("jwt", this@ActivityUserProfile) + var data = api.addFollower("Bearer " + token, userObject._id); + data.enqueue(object : Callback { + override fun onResponse( + call: Call, + response: Response + ) { + unfollowUser.isVisible=true + unfollowUser.isClickable=true + unfollowUser.isEnabled=true + followUser.isVisible=false + followUser.isClickable=false + followUser.isEnabled=false + updateUserData() + + Toast.makeText( + this@ActivityUserProfile, "PRATITE KORISNIKA", Toast.LENGTH_LONG + ).show(); + } + + override fun onFailure(call: Call, t: Throwable) { + Toast.makeText( + this@ActivityUserProfile, t.toString(), Toast.LENGTH_LONG + ).show(); + } + }) - checkIfAlreadyFollow() - + } + unfollowUser.setOnClickListener { + val api = RetrofitHelper.getInstance() + val token = SharedPreferencesHelper.getValue("jwt", this@ActivityUserProfile) + var data = api.unfollow("Bearer " + token, userObject._id); + data.enqueue(object : Callback { + override fun onResponse( + call: Call, + response: Response + ) { + unfollowUser.isVisible=false + unfollowUser.isClickable=false + unfollowUser.isEnabled=false + followUser.isVisible=true + followUser.isClickable=true + followUser.isEnabled=true + updateUserData() + Toast.makeText( + this@ActivityUserProfile, "VIŠE NE PRATITE KORISNIKA", Toast.LENGTH_LONG + ).show(); + } + + override fun onFailure(call: Call, t: Throwable) { + Toast.makeText( + this@ActivityUserProfile, t.toString(), Toast.LENGTH_LONG + ).show(); + } + }) - val api = RetrofitHelper.getInstance() - val token= SharedPreferencesHelper.getValue("jwt", this@ActivityUserProfile) - var data=api.addFollower("Bearer "+token,userObject._id); - data.enqueue(object : Callback { - override fun onResponse( - call: Call, - response: Response - ) { - Toast.makeText( - this@ActivityUserProfile, "PRATITE KORISNIKA", Toast.LENGTH_LONG - ).show(); - } - override fun onFailure(call: Call, t: Throwable) { - Toast.makeText( - this@ActivityUserProfile, t.toString(), Toast.LENGTH_LONG - ).show(); - } - }) } @@ -132,15 +166,34 @@ class ActivityUserProfile : AppCompatActivity() { } var follow = response.body()!! if(follow){ + Log.d("success","follow") - followUser.setCompoundDrawablesWithIntrinsicBounds(drawable.ic_outline_person_remove_24,0,0,0) + /*followUser.setCompoundDrawablesWithIntrinsicBounds(drawable.ic_outline_person_remove_24,0,0,0) followUser.text="Ne prati više" - + follow=false + */ + unfollowUser.isVisible=true + unfollowUser.isClickable=true + unfollowUser.isEnabled=true + followUser.isVisible=false + followUser.isClickable=false + followUser.isEnabled=false } - if(!follow){ + else{ Log.d("success","not follow") - followUser.setCompoundDrawablesWithIntrinsicBounds(drawable.ic_outline_person_add_alt_24,0,0,0) + /*followUser.setCompoundDrawablesWithIntrinsicBounds(drawable.ic_outline_person_add_alt_24,0,0,0) followUser.text="Prati" + follow=true + */ + + unfollowUser.isVisible=false + unfollowUser.isClickable=false + unfollowUser.isEnabled=false + followUser.isVisible=true + followUser.isClickable=true + followUser.isEnabled=true + + } } @@ -148,7 +201,28 @@ class ActivityUserProfile : AppCompatActivity() { } - fun checkIfAlreadyFollowChangeButton(){ + fun updateUserData(){ + val api = RetrofitHelper.getInstance() + val token = SharedPreferencesHelper.getValue("jwt", this@ActivityUserProfile) + var data = api.getProfileFromId("Bearer " + token, userObject._id); + data.enqueue(object : Callback { + override fun onResponse( + call: Call, + response: Response + ) { + var userData=response.body()!! + name.text=userData.name + postsNumber.text=userData.postNumber.toString() + followersNumber.text=userData.followersCount.toString() + followingNumber.text=userData.followingCount.toString() + } + override fun onFailure(call: Call, t: Throwable) { + Toast.makeText( + this@ActivityUserProfile, t.toString(), Toast.LENGTH_LONG + ).show(); + } + }) } + } \ 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 ce8d7e3..bc8c7ae 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 @@ -101,4 +101,7 @@ interface IBackendApi { @GET("/api/user/{id}/checkIfAlreadyFollow") fun checkIfAlreadyFollow(@Header("Authorization") authHeader:String,@Path("id") id:String):Call + @GET("/api/user/{id}/unfollow") + fun unfollow(@Header("Authorization") authHeader:String,@Path("id") id:String):Call + } \ No newline at end of file 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 index a446f9a..0e90fc7 100644 --- a/Client/BrzoDoLokacije/app/src/main/res/layout/activity_user_profile.xml +++ b/Client/BrzoDoLokacije/app/src/main/res/layout/activity_user_profile.xml @@ -228,22 +228,44 @@