From 7c4295f6edd0074733c628300bdb4e6c8b4fd8ef Mon Sep 17 00:00:00 2001 From: Ognjen Cirkovic Date: Sun, 13 Nov 2022 21:36:02 +0100 Subject: Dodata myLocatio na mapi. Dodato dogme da korisnik moze da ode do svoje lokacije. --- Client/BrzoDoLokacije/app/build.gradle | 1 + .../brzodolokacije/Fragments/FragmentBrowse.kt | 128 ++++++++++++++++++++- .../app/src/main/res/layout/fragment_browse.xml | 15 +++ 3 files changed, 139 insertions(+), 5 deletions(-) diff --git a/Client/BrzoDoLokacije/app/build.gradle b/Client/BrzoDoLokacije/app/build.gradle index d0eabb6..8739bf1 100644 --- a/Client/BrzoDoLokacije/app/build.gradle +++ b/Client/BrzoDoLokacije/app/build.gradle @@ -49,6 +49,7 @@ dependencies { implementation 'androidx.constraintlayout:constraintlayout:2.1.4' implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' implementation 'com.google.android.gms:play-services-maps:18.1.0' + implementation 'com.google.android.gms:play-services-location:21.0.1' 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/src/main/java/com/example/brzodolokacije/Fragments/FragmentBrowse.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentBrowse.kt index 08d0fdd..8012583 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 @@ -3,17 +3,18 @@ package com.example.brzodolokacije.Fragments 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 android.os.Looper import android.os.StrictMode import android.os.StrictMode.ThreadPolicy import android.preference.PreferenceManager import android.util.DisplayMetrics -import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import android.widget.Button import android.widget.EditText import android.widget.Toast import androidx.core.app.ActivityCompat @@ -21,6 +22,7 @@ import androidx.core.content.ContextCompat import androidx.fragment.app.Fragment import com.example.brzodolokacije.R import com.example.brzodolokacije.Services.GeocoderHelper +import com.google.android.gms.location.* import com.google.android.material.floatingactionbutton.FloatingActionButton import org.osmdroid.config.Configuration import org.osmdroid.tileprovider.tilesource.TileSourceFactory @@ -41,8 +43,11 @@ class FragmentBrowse : Fragment(R.layout.fragment_browse) { var mRotationGestureOverlay:RotationGestureOverlay?=null var mScaleBarOverlay: ScaleBarOverlay?=null var mCompassOverlay:CompassOverlay?=null + private lateinit var locationManager: LocationManager private lateinit var searchButton:FloatingActionButton + private lateinit var gpsButton:FloatingActionButton private lateinit var searchBar: EditText + var client: FusedLocationProviderClient? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -60,13 +65,16 @@ class FragmentBrowse : Fragment(R.layout.fragment_browse) { map!!.setTileSource(TileSourceFactory.MAPNIK); setUpMap() searchButton=v.findViewById(R.id.FragmentBrowseSearchButton) as FloatingActionButton + gpsButton=v.findViewById(R.id.FragmentBrowseMyLocation) as FloatingActionButton searchBar=v.findViewById(R.id.FragmentBrowseSearchBar) as EditText - + client=LocationServices.getFusedLocationProviderClient(requireActivity()) searchButton.setOnClickListener{ searchMap() - } - + } + gpsButton.setOnClickListener{ + getLocation() + } return v } @@ -156,6 +164,116 @@ class FragmentBrowse : Fragment(R.layout.fragment_browse) { } } } + private fun getLocation() { + if (ContextCompat.checkSelfPermission( + requireActivity(), + Manifest.permission + .ACCESS_FINE_LOCATION) + == PackageManager + .PERMISSION_GRANTED + && ContextCompat.checkSelfPermission( + requireActivity(), + Manifest.permission + .ACCESS_COARSE_LOCATION) + == PackageManager + .PERMISSION_GRANTED) { + // When permission is granted + // Call method + getCurrentLocation() + } + else { + requestPermissions( + arrayOf( + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.ACCESS_COARSE_LOCATION + ), + 111 + ) + + } + } + override fun onRequestPermissionsResult( + requestCode: Int, permissions: Array, + 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( + activity, + "Permission denied", + Toast.LENGTH_SHORT + ) + .show() + } + } + @Suppress("MissingPermission") + private fun getCurrentLocation(){ + val locationManager = requireActivity() + .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)) + Toast.makeText(requireContext()," "+location1!!.latitude,Toast.LENGTH_LONG) + + } + } + client!!.requestLocationUpdates( + locationRequest, + locationCallback, + Looper.myLooper()); + } else { + map!!.controller.animateTo(GeoPoint(location!!.latitude,location!!.longitude)) + Toast.makeText(requireContext()," "+location.latitude,Toast.LENGTH_LONG) + } + + + + } + } + + +} } \ No newline at end of file diff --git a/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_browse.xml b/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_browse.xml index cdccaa6..5f20c5f 100644 --- a/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_browse.xml +++ b/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_browse.xml @@ -45,5 +45,20 @@ app:rippleColor="#FFFFFF" app:srcCompat="@android:drawable/ic_search_category_default" /> + + \ No newline at end of file -- cgit v1.2.3 From 9b059bc69abaa01b76827d3d57cf94f8885a99c1 Mon Sep 17 00:00:00 2001 From: Ognjen Cirkovic Date: Sun, 13 Nov 2022 21:51:58 +0100 Subject: Promenjen izgled search bar-a. Omoguceno ukoliko korisnik pritisne enter da se odmah izvrsi pretraga. --- .../Activities/NavigationActivity.kt | 1 + .../brzodolokacije/Fragments/FragmentBrowse.kt | 24 ++++++-- .../app/src/main/res/layout/fragment_browse.xml | 64 +++++++++++++--------- 3 files changed, 57 insertions(+), 32 deletions(-) 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 ce8cdb2..604b373 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 @@ -7,6 +7,7 @@ import android.view.View import android.widget.Button import android.widget.ImageButton import android.widget.Toast +import androidx.appcompat.app.AppCompatDelegate import androidx.fragment.app.Fragment import com.example.brzodolokacije.Fragments.* import com.example.brzodolokacije.R 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 8012583..9d8a68a 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 @@ -12,10 +12,11 @@ import android.os.StrictMode import android.os.StrictMode.ThreadPolicy import android.preference.PreferenceManager import android.util.DisplayMetrics +import android.view.KeyEvent import android.view.LayoutInflater import android.view.View +import android.view.View.OnKeyListener import android.view.ViewGroup -import android.widget.EditText import android.widget.Toast import androidx.core.app.ActivityCompat import androidx.core.content.ContextCompat @@ -23,7 +24,9 @@ import androidx.fragment.app.Fragment import com.example.brzodolokacije.R 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 @@ -44,9 +47,9 @@ class FragmentBrowse : Fragment(R.layout.fragment_browse) { var mScaleBarOverlay: ScaleBarOverlay?=null var mCompassOverlay:CompassOverlay?=null private lateinit var locationManager: LocationManager - private lateinit var searchButton:FloatingActionButton + private lateinit var searchButton: MaterialButton private lateinit var gpsButton:FloatingActionButton - private lateinit var searchBar: EditText + private lateinit var searchBar: TextInputEditText var client: FusedLocationProviderClient? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -64,9 +67,9 @@ class FragmentBrowse : Fragment(R.layout.fragment_browse) { map=v.findViewById(R.id.FragmentBrowseMapView) as MapView map!!.setTileSource(TileSourceFactory.MAPNIK); setUpMap() - searchButton=v.findViewById(R.id.FragmentBrowseSearchButton) as FloatingActionButton + searchButton=v.findViewById(R.id.FragmentBrowseSearchButton) as MaterialButton gpsButton=v.findViewById(R.id.FragmentBrowseMyLocation) as FloatingActionButton - searchBar=v.findViewById(R.id.FragmentBrowseSearchBar) as EditText + searchBar=v.findViewById(R.id.FragmentBrowseSearchBar) as TextInputEditText client=LocationServices.getFusedLocationProviderClient(requireActivity()) searchButton.setOnClickListener{ searchMap() @@ -75,6 +78,17 @@ class FragmentBrowse : Fragment(R.layout.fragment_browse) { gpsButton.setOnClickListener{ getLocation() } + searchBar.setOnKeyListener(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 + }) + return v } diff --git a/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_browse.xml b/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_browse.xml index 5f20c5f..9e6dd9d 100644 --- a/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_browse.xml +++ b/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_browse.xml @@ -15,35 +15,9 @@ app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toTopOf="@+id/FragmentBrowseSearchBar" /> + /> - - + + + + + + + + + \ No newline at end of file -- cgit v1.2.3 From 48eda927be73a222ab50b8e8d8c20c9a51639aab Mon Sep 17 00:00:00 2001 From: Ognjen Cirkovic Date: Sun, 13 Nov 2022 21:57:41 +0100 Subject: Omoguceno postavljanje markera na pretrazenu lokaciju. --- .../java/com/example/brzodolokacije/Fragments/FragmentBrowse.kt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) 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 9d8a68a..5ba3785 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 @@ -31,6 +31,7 @@ import org.osmdroid.config.Configuration import org.osmdroid.tileprovider.tilesource.TileSourceFactory import org.osmdroid.util.GeoPoint import org.osmdroid.views.MapView +import org.osmdroid.views.overlay.Marker import org.osmdroid.views.overlay.ScaleBarOverlay import org.osmdroid.views.overlay.compass.CompassOverlay import org.osmdroid.views.overlay.compass.InternalCompassOrientationProvider @@ -172,7 +173,12 @@ class FragmentBrowse : Fragment(R.layout.fragment_browse) { Toast.makeText(requireContext(),"Nepostojeca lokacija",Toast.LENGTH_SHORT) else{ //move to spot - map!!.controller.animateTo(GeoPoint(result.latitude,result.longitude)) + val searchPoint = GeoPoint(result.latitude,result.longitude) + val startMarker = Marker(map) + startMarker.setPosition(searchPoint) + startMarker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM) + map!!.getOverlays().add(startMarker) + map!!.controller.animateTo(searchPoint) } -- cgit v1.2.3 From 2d0b642a0a7d55e059ebceb59bc35199635a88f0 Mon Sep 17 00:00:00 2001 From: Jelena Petrovic Date: Sun, 13 Nov 2022 23:58:09 +0100 Subject: uklonjeno skrolovanje komentara posebno,izmenjen izgled ocena #31 #30 --- .../Activities/ActivitySinglePost.kt | 10 +++-- .../app/src/main/res/drawable/post_comment.webp | Bin 0 -> 2708 bytes .../src/main/res/layout/activity_single_post.xml | 46 +++++++++++++-------- 3 files changed, 35 insertions(+), 21 deletions(-) create mode 100644 Client/BrzoDoLokacije/app/src/main/res/drawable/post_comment.webp 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 8dd7eea..ea82cda 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 @@ -5,6 +5,7 @@ import android.util.Log import android.widget.Adapter 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 @@ -123,6 +124,11 @@ class ActivitySinglePost : AppCompatActivity() { if(binding.NewComment.text.isNotEmpty()){ val comment=CommentReceive(binding.NewComment.text.toString(),"") requestAddComment(comment) + + + } + else{ + Toast.makeText(this@ActivitySinglePost,"Unesite tekst komentara.",Toast.LENGTH_LONG).show() } } @@ -136,9 +142,7 @@ class ActivitySinglePost : AppCompatActivity() { override fun onResponse(call: Call, response: Response) { if(response.isSuccessful){ requestGetComments() - Toast.makeText( - this@ActivitySinglePost, "prosao zahtev", Toast.LENGTH_LONG - ).show() + binding.NewComment.text.clear() }else{ if(response.errorBody()!=null) Log.d("main1",response.message().toString()) diff --git a/Client/BrzoDoLokacije/app/src/main/res/drawable/post_comment.webp b/Client/BrzoDoLokacije/app/src/main/res/drawable/post_comment.webp new file mode 100644 index 0000000..fc677d1 Binary files /dev/null and b/Client/BrzoDoLokacije/app/src/main/res/drawable/post_comment.webp differ 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 cbfc063..7c1f8bc 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 @@ -174,8 +174,9 @@ + android:text="ok" + android:layout_gravity="center_vertical" + android:textColor="@color/black" + /> + android:layout_width="50dp" + android:scaleType="fitCenter" + android:layout_height="50dp" + android:src="@drawable/post_comment" + android:backgroundTint="@color/white"/> @@ -274,11 +284,11 @@ android:id="@+id/rvComments" android:layout_width="match_parent" android:layout_height="wrap_content" - app:layout_constraintTop_toBottomOf="@id/tvCommentLabel"> + app:layout_constraintTop_toBottomOf="@id/tvCommentLabel" + android:nestedScrollingEnabled="false"> - -- cgit v1.2.3 From d32034c831451d303b16b31a92b79a6c783699f0 Mon Sep 17 00:00:00 2001 From: Jelena Petrovic Date: Mon, 14 Nov 2022 01:45:02 +0100 Subject: izmenjen izgled polja za pretragu i ikonica u listi objava #29 --- .../app/src/main/res/drawable/filter.png | Bin 1509 -> 3581 bytes .../app/src/main/res/drawable/grid.png | Bin 661 -> 0 bytes .../app/src/main/res/drawable/grid_full.png | Bin 0 -> 4215 bytes .../app/src/main/res/drawable/list_empty.png | Bin 0 -> 5692 bytes .../app/src/main/res/drawable/sort.png | Bin 3953 -> 6603 bytes .../src/main/res/layout/fragment_show_posts.xml | 50 ++++++++++++++++----- 6 files changed, 40 insertions(+), 10 deletions(-) delete mode 100644 Client/BrzoDoLokacije/app/src/main/res/drawable/grid.png create mode 100644 Client/BrzoDoLokacije/app/src/main/res/drawable/grid_full.png create mode 100644 Client/BrzoDoLokacije/app/src/main/res/drawable/list_empty.png diff --git a/Client/BrzoDoLokacije/app/src/main/res/drawable/filter.png b/Client/BrzoDoLokacije/app/src/main/res/drawable/filter.png index 4342c2c..745a5e8 100644 Binary files a/Client/BrzoDoLokacije/app/src/main/res/drawable/filter.png and b/Client/BrzoDoLokacije/app/src/main/res/drawable/filter.png differ diff --git a/Client/BrzoDoLokacije/app/src/main/res/drawable/grid.png b/Client/BrzoDoLokacije/app/src/main/res/drawable/grid.png deleted file mode 100644 index 03d9ef9..0000000 Binary files a/Client/BrzoDoLokacije/app/src/main/res/drawable/grid.png and /dev/null differ diff --git a/Client/BrzoDoLokacije/app/src/main/res/drawable/grid_full.png b/Client/BrzoDoLokacije/app/src/main/res/drawable/grid_full.png new file mode 100644 index 0000000..9bed50a Binary files /dev/null and b/Client/BrzoDoLokacije/app/src/main/res/drawable/grid_full.png differ diff --git a/Client/BrzoDoLokacije/app/src/main/res/drawable/list_empty.png b/Client/BrzoDoLokacije/app/src/main/res/drawable/list_empty.png new file mode 100644 index 0000000..3568c49 Binary files /dev/null and b/Client/BrzoDoLokacije/app/src/main/res/drawable/list_empty.png differ diff --git a/Client/BrzoDoLokacije/app/src/main/res/drawable/sort.png b/Client/BrzoDoLokacije/app/src/main/res/drawable/sort.png index 828cd01..b4fd960 100644 Binary files a/Client/BrzoDoLokacije/app/src/main/res/drawable/sort.png and b/Client/BrzoDoLokacije/app/src/main/res/drawable/sort.png differ 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 a12801e..64ad74c 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 @@ -7,14 +7,40 @@ xmlns:app="http://schemas.android.com/apk/res-auto" tools:context=".Fragments.FragmentShowPosts"> - + + + + + + + + @@ -38,6 +65,7 @@ android:layout_weight="1" android:scaleType="centerCrop" android:src="@drawable/sort" + android:padding="@dimen/component_padding" app:layout_constraintStart_toEndOf="@+id/btnSortType" tools:layout_editor_absoluteY="0dp" android:background="@color/white"/> @@ -49,8 +77,9 @@ android:layout_marginEnd="16dp" android:layout_weight="1" android:background="@color/white" + android:padding="@dimen/component_padding" android:scaleType="centerCrop" - android:src="@drawable/list" + android:src="@drawable/list_empty" app:layout_constraintEnd_toStartOf="@+id/btnGridLayout" app:layout_constraintHorizontal_bias="1.0" app:layout_constraintStart_toEndOf="@+id/btnSortDirection" @@ -64,7 +93,8 @@ android:layout_weight="1" android:background="@color/white" android:scaleType="centerCrop" - android:src="@drawable/grid" + android:src="@drawable/grid_full" + android:padding="@dimen/component_padding" android:clickable="true" app:layout_constraintStart_toEndOf="@+id/btnSortDirection" tools:layout_editor_absoluteY="0dp" /> -- cgit v1.2.3 From a30222749d891314d4aad1ac8798ae115392407c Mon Sep 17 00:00:00 2001 From: "branislav.radivojevic" Date: Mon, 14 Nov 2022 10:55:04 +0100 Subject: return commend on add,user data controller,add pfp --- Backend/Api/Api/Controllers/PostController.cs | 7 ++-- Backend/Api/Api/Controllers/UserController.cs | 51 +++++++++++++++++++++++ Backend/Api/Api/Interfaces/IPostService.cs | 2 +- Backend/Api/Api/Interfaces/IUserService.cs | 4 +- Backend/Api/Api/Models/User.cs | 10 +++++ Backend/Api/Api/Services/PostService.cs | 6 +-- Backend/Api/Api/Services/UserService.cs | 58 ++++++++++++++++++++++++++- 7 files changed, 129 insertions(+), 9 deletions(-) create mode 100644 Backend/Api/Api/Controllers/UserController.cs diff --git a/Backend/Api/Api/Controllers/PostController.cs b/Backend/Api/Api/Controllers/PostController.cs index 3faaa62..dc48c73 100644 --- a/Backend/Api/Api/Controllers/PostController.cs +++ b/Backend/Api/Api/Controllers/PostController.cs @@ -89,11 +89,12 @@ 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(); - if (await _postService.AddComment(cmnt,userid,id)) - return Ok(); + var c = await _postService.AddComment(cmnt, userid, id); + if (c != null) + return Ok(c); return BadRequest(); } diff --git a/Backend/Api/Api/Controllers/UserController.cs b/Backend/Api/Api/Controllers/UserController.cs new file mode 100644 index 0000000..4e0f0a3 --- /dev/null +++ b/Backend/Api/Api/Controllers/UserController.cs @@ -0,0 +1,51 @@ +using Api.Interfaces; +using Api.Models; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; + +namespace Api.Controllers +{ + [Route("api/user/")] + public class UserController : Controller + { + private readonly IUserService _userService; + private readonly IJwtService _jwtService; + public UserController(IUserService userService, IJwtService jwtService) + { + _userService = userService; + _jwtService = jwtService; + } + [HttpPost("profile/pfp")] + [Authorize(Roles = "User")] + public async Task> setPfp([FromBody] IFormFile image) + { + if (image == null) + return BadRequest(); + var id = await _userService.UserIdFromJwt(); + if (id == null) + return Unauthorized(); + if(await _userService.AddOrChangePfp(id,image)) + return Ok(); + return BadRequest(); + } + [HttpGet("profile")] + [Authorize(Roles = "User")] + public async Task> SelfProfile() + { + var id = await _userService.UserIdFromJwt(); + var rez = await _userService.GetSelfUserData(id); + if (rez != null) + return Ok(rez); + return BadRequest(); + } + [HttpGet("{username}/profile")] + [Authorize(Roles = "User")] + public async Task> GetProfile(string username) + { + var rez = await _userService.GetUserData(username); + if (rez != null) + return Ok(rez); + return BadRequest(); + } + } +} diff --git a/Backend/Api/Api/Interfaces/IPostService.cs b/Backend/Api/Api/Interfaces/IPostService.cs index 0274b26..24a1e74 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/Interfaces/IUserService.cs b/Backend/Api/Api/Interfaces/IUserService.cs index db2eac1..313e909 100644 --- a/Backend/Api/Api/Interfaces/IUserService.cs +++ b/Backend/Api/Api/Interfaces/IUserService.cs @@ -23,6 +23,8 @@ namespace Api.Interfaces Task ResetPassword(ResetPass rp); Task CheckVerification(Login login); Task VerifyFromToken(string token); - + Task AddOrChangePfp(string userid, IFormFile image); + Task GetUserData(string username); + Task GetSelfUserData(string id); } } diff --git a/Backend/Api/Api/Models/User.cs b/Backend/Api/Api/Models/User.cs index a1fe149..b212ebb 100644 --- a/Backend/Api/Api/Models/User.cs +++ b/Backend/Api/Api/Models/User.cs @@ -15,6 +15,7 @@ namespace Api.Models public Boolean verified { get; set; } public String password { get; set; } public DateTime creationDate { get; set; } + public File? pfp { get; set; } } public class Login @@ -48,4 +49,13 @@ namespace Api.Models public String password { get; set; } public String kod { get; set; } } + public class UserSend + { + public String _id { get; set; } + public String name { get; set; } + public String username { get; set; } + public String email { get; set; } + public DateTime creationDate { get; set; } + public File? pfp { get; set; } + } } diff --git a/Backend/Api/Api/Services/PostService.cs b/Backend/Api/Api/Services/PostService.cs index a0b2941..321aebe 100644 --- a/Backend/Api/Api/Services/PostService.cs +++ b/Backend/Api/Api/Services/PostService.cs @@ -164,7 +164,7 @@ 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) @@ -177,9 +177,9 @@ namespace Api.Services c._id = ObjectId.GenerateNewId().ToString(); p.comments.Add(c); await _posts.ReplaceOneAsync(x => x._id == postid, p); - return true; + return c; } - return false; + return null; } public async Task> ListComments(string postid) diff --git a/Backend/Api/Api/Services/UserService.cs b/Backend/Api/Api/Services/UserService.cs index 5fd61f6..d8361cd 100644 --- a/Backend/Api/Api/Services/UserService.cs +++ b/Backend/Api/Api/Services/UserService.cs @@ -14,13 +14,15 @@ namespace Api.Services private readonly IMongoCollection _users; private readonly IJwtService _jwtService; private IConfiguration _configuration; - public UserService(IDatabaseConnection settings, IMongoClient mongoClient, IJwtService jwtService, IHttpContextAccessor httpContextAccessor, IConfiguration configuration) + private readonly IFileService _fileService; + public UserService(IDatabaseConnection settings, IMongoClient mongoClient, IJwtService jwtService, IHttpContextAccessor httpContextAccessor, IConfiguration configuration, IFileService fileService) { var database = mongoClient.GetDatabase(settings.DatabaseName); _users = database.GetCollection(settings.UserCollectionName); _jwtService = jwtService; this._httpContext = httpContextAccessor; this._configuration = configuration; + _fileService = fileService; } public async Task createUser(User user) @@ -311,5 +313,59 @@ namespace Api.Services } return false; } + + public async Task AddOrChangePfp(string userid,IFormFile image) + { + var user = await _users.Find(x => x._id == userid).FirstOrDefaultAsync(); + if (user == null) + return false; + var folderPath = Path.Combine(Directory.GetCurrentDirectory(), "Files", userid); + if (!Directory.Exists(folderPath)) + Directory.CreateDirectory(folderPath); + var filename = image.FileName; + var ext = Path.GetExtension(filename).ToLowerInvariant(); + var name ="PFP - " + user._id; + var fullPath = Path.Combine(folderPath, name+ext); + if (System.IO.File.Exists(fullPath)) + System.IO.File.Delete(fullPath); + using (var stream = new FileStream(fullPath, FileMode.Create)) + { + await image.CopyToAsync(stream); + } + var f = new Models.File(); + f.path = fullPath; + f._id = ""; + f = await _fileService.add(f); + user.pfp = f; + await _users.ReplaceOneAsync(x => x._id == user._id, user); + return true; + } + + public async Task GetUserData(string username) + { + var user = await _users.Find(x => x.username == username).FirstOrDefaultAsync(); + if(user == null) + return null; + var tosend = new UserSend(); + tosend.pfp = user.pfp; + tosend.username = user.username; + tosend._id= user._id; + tosend.creationDate = user.creationDate; + tosend.email=""; + return tosend; + } + public async Task GetSelfUserData(string id) + { + var user = await _users.Find(x => x._id == id).FirstOrDefaultAsync(); + if (user == null) + return null; + var tosend = new UserSend(); + tosend.pfp = user.pfp; + tosend.username = user.username; + tosend._id = user._id; + tosend.creationDate = user.creationDate; + tosend.email = user.email; + return tosend; + } } } -- cgit v1.2.3 From c0c7b37d7abaa7d9519c58d5c0caefd0ba42b4de Mon Sep 17 00:00:00 2001 From: "branislav.radivojevic" Date: Mon, 14 Nov 2022 11:29:17 +0100 Subject: user name, pfp bug --- Backend/Api/Api/Controllers/UserController.cs | 6 +----- Backend/Api/Api/Services/UserService.cs | 4 +++- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/Backend/Api/Api/Controllers/UserController.cs b/Backend/Api/Api/Controllers/UserController.cs index 4e0f0a3..965ad6b 100644 --- a/Backend/Api/Api/Controllers/UserController.cs +++ b/Backend/Api/Api/Controllers/UserController.cs @@ -17,13 +17,9 @@ namespace Api.Controllers } [HttpPost("profile/pfp")] [Authorize(Roles = "User")] - public async Task> setPfp([FromBody] IFormFile image) + public async Task> setPfp(IFormFile image) { - if (image == null) - return BadRequest(); var id = await _userService.UserIdFromJwt(); - if (id == null) - return Unauthorized(); if(await _userService.AddOrChangePfp(id,image)) return Ok(); return BadRequest(); diff --git a/Backend/Api/Api/Services/UserService.cs b/Backend/Api/Api/Services/UserService.cs index d8361cd..8e7cd42 100644 --- a/Backend/Api/Api/Services/UserService.cs +++ b/Backend/Api/Api/Services/UserService.cs @@ -324,7 +324,7 @@ namespace Api.Services Directory.CreateDirectory(folderPath); var filename = image.FileName; var ext = Path.GetExtension(filename).ToLowerInvariant(); - var name ="PFP - " + user._id; + var name =user._id; var fullPath = Path.Combine(folderPath, name+ext); if (System.IO.File.Exists(fullPath)) System.IO.File.Delete(fullPath); @@ -347,6 +347,7 @@ namespace Api.Services if(user == null) return null; var tosend = new UserSend(); + tosend.name = user.name; tosend.pfp = user.pfp; tosend.username = user.username; tosend._id= user._id; @@ -360,6 +361,7 @@ namespace Api.Services if (user == null) return null; var tosend = new UserSend(); + tosend.name = user.name; tosend.pfp = user.pfp; tosend.username = user.username; tosend._id = user._id; -- cgit v1.2.3 From 155be78c0e5ac272e3cee558bc8d76f4dc14b947 Mon Sep 17 00:00:00 2001 From: Ognjen Cirkovic Date: Mon, 14 Nov 2022 18:11:57 +0100 Subject: Preuzimanja podatka o korisniku sa backend-a i prikaz tih podataka na profile fragmentu. --- Backend/Api/Api/Controllers/UserController.cs | 2 +- .../brzodolokacije/Fragments/FragmentProfile.kt | 46 +++++++++++++++++++++- .../brzodolokacije/Interfaces/IBackendApi.kt | 10 +++++ .../java/com/example/brzodolokacije/Models/User.kt | 8 ++++ 4 files changed, 64 insertions(+), 2 deletions(-) diff --git a/Backend/Api/Api/Controllers/UserController.cs b/Backend/Api/Api/Controllers/UserController.cs index 965ad6b..d4a9cb7 100644 --- a/Backend/Api/Api/Controllers/UserController.cs +++ b/Backend/Api/Api/Controllers/UserController.cs @@ -17,7 +17,7 @@ namespace Api.Controllers } [HttpPost("profile/pfp")] [Authorize(Roles = "User")] - public async Task> setPfp(IFormFile image) + public async Task> setPfp([FromForm]IFormFile image) { var id = await _userService.UserIdFromJwt(); if(await _userService.AddOrChangePfp(id,image)) 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 243cab0..87519f4 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,14 +1,23 @@ package com.example.brzodolokacije.Fragments +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.TextView +import android.widget.Toast import androidx.fragment.app.FragmentTransaction +import com.example.brzodolokacije.Activities.NavigationActivity +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.Response // TODO: Rename parameter arguments, choose names that match // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER @@ -71,15 +80,50 @@ class FragmentProfile : Fragment(R.layout.fragment_profile) { } showMyRecensions.setOnClickListener{ - + getProfileInfo() var fm: FragmentTransaction =childFragmentManager.beginTransaction() fm.replace(R.id.flFragmentProfileFragmentContainer, FragmentMyRecensions()) fm.commit() } + getProfileInfo() return view } + private fun getProfileInfo(){ + val authApi=RetrofitHelper.getInstance() + val token= SharedPreferencesHelper.getValue("jwt", requireActivity()) + val request=authApi.selfProfile("Bearer "+token) + + request.enqueue(object : retrofit2.Callback { + override fun onResponse(call: Call, response: Response) { + if(response.isSuccessful()){ + setUserInfo(response.body()!!) + }else{ + if(response.errorBody()!=null) + Toast.makeText(activity, response.errorBody()!!.string(), Toast.LENGTH_LONG).show(); + } + + + } + + override fun onFailure(call: Call, t: Throwable) { + Log.d("Main","Graska3") + Toast.makeText( + activity, t.toString(), Toast.LENGTH_LONG + ).show(); + } + }) + } + private fun setUserInfo(user:UserReceive){ + name.setText(user.name) + username.setText(user.username) + + postsCount.setText("to do backend") + followersCount.setText("to do backend") + followingCount.setText("to do backend") + } + } \ 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 cd23a65..236db1d 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 @@ -43,6 +43,16 @@ interface IBackendApi { fun getComments(@Header("Authorization") authHeader:String,@Path("id") id:String):Call> + @Multipart + @POST("/api/user/profile/pfp") + fun setPfp(@Header("Authorization") authHeader:String, @Part image: MultipartBody.Part):Call + @GET("/api/user/profile") + fun selfProfile(@Header("Authorization") authHeader:String):Call + @GET("/api/user/{username}/profile") + fun getProfile(@Header("Authorization") authHeader:String,@Path("username") username:String):Call + + + //@POST("putanja") //fun add(@Body obj:Post,@Header("Authorization") authHeader: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 52090f9..505ac51 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 @@ -20,4 +20,12 @@ data class User ( var postIds:List, var postNumber:Int +) +data class UserReceive( + var _id:String, + var name:String, + var username:String, + var email:String, + var creationDate: Date, + var pfp:PostImage? ) \ No newline at end of file -- cgit v1.2.3 From 2ab8d852dd12434711e19ee4e23fbc8a1f2a950d Mon Sep 17 00:00:00 2001 From: Ognjen Cirkovic Date: Mon, 14 Nov 2022 18:33:51 +0100 Subject: Omoguceno da korisnik klikom na profilnu sliku moze da zameni ili da doda novu profilnu sliku. --- .../brzodolokacije/Fragments/FragmentProfile.kt | 82 ++++++++++++++++++---- 1 file changed, 70 insertions(+), 12 deletions(-) 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 87519f4..2ed28ce 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,23 +1,30 @@ package com.example.brzodolokacije.Fragments import android.content.Intent +import android.net.Uri 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.TextView import android.widget.Toast +import androidx.appcompat.app.AppCompatActivity +import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentTransaction -import com.example.brzodolokacije.Activities.NavigationActivity +import com.bumptech.glide.Glide 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.google.android.material.imageview.ShapeableImageView +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.MultipartBody +import okhttp3.RequestBody +import okhttp3.ResponseBody 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 @@ -44,6 +51,7 @@ class FragmentProfile : Fragment(R.layout.fragment_profile) { private lateinit var showMyPosts: Button private lateinit var showMyData: Button private lateinit var showMyRecensions: Button + private lateinit var profilePicture: ShapeableImageView override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? @@ -58,6 +66,7 @@ class FragmentProfile : Fragment(R.layout.fragment_profile) { showMyPosts=view.findViewById(R.id.btnFragmentProfileShowMyPosts) as Button showMyData=view.findViewById(R.id.btnFragmentProfileShowMyData) as Button showMyRecensions=view.findViewById(R.id.btnFragmentProfileShowMyRecensions) as Button + profilePicture=view.findViewById(R.id.tvFragmentProfileProfilePicture) as ShapeableImageView //podaci iz baze @@ -86,11 +95,56 @@ class FragmentProfile : Fragment(R.layout.fragment_profile) { fm.replace(R.id.flFragmentProfileFragmentContainer, FragmentMyRecensions()) fm.commit() } + profilePicture.setOnClickListener{ + addProfilePicture() + } getProfileInfo() return view } + private fun addProfilePicture(){ + val intent= Intent(Intent.ACTION_PICK) + intent.action = Intent.ACTION_GET_CONTENT + intent.type="image/*" + startActivityForResult(Intent.createChooser(intent,"Izaberi profilnu sliku"),201) + } + private fun uploadProfilePicture(imageUri:Uri){ + val api =RetrofitHelper.getInstance() + var inputStream=requireActivity().getContentResolver().openInputStream(imageUri) + val file: File = File.createTempFile("temp","pfp") + file!!.writeBytes(inputStream!!.readBytes()) + var imageReq=RequestBody.create("image/*".toMediaTypeOrNull(),file) + val imageBody: MultipartBody.Part = MultipartBody.Part.createFormData("image", file.name, imageReq) + val token= SharedPreferencesHelper.getValue("jwt", requireActivity()) + val req=api.setPfp("Bearer "+token,imageBody) + + req.enqueue(object : retrofit2.Callback { + override fun onResponse(call: Call, response: Response) { + if(response.isSuccessful()){ + getProfileInfo() + }else{ + if(response.errorBody()!=null) + Toast.makeText(activity, response.errorBody()!!.string(), Toast.LENGTH_LONG).show(); + } + } + override fun onFailure(call: Call, t: Throwable) { + Toast.makeText( + activity, t.toString(), Toast.LENGTH_LONG + ).show(); + } + }) + } + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + super.onActivityResult(requestCode, resultCode, data) + //nakon otvaranja + if(requestCode==201 && resultCode== AppCompatActivity.RESULT_OK){ + var imageUri=data!!.data + uploadProfilePicture(imageUri!!) + + } + } + private fun getProfileInfo(){ val authApi=RetrofitHelper.getInstance() val token= SharedPreferencesHelper.getValue("jwt", requireActivity()) @@ -104,12 +158,8 @@ class FragmentProfile : Fragment(R.layout.fragment_profile) { if(response.errorBody()!=null) Toast.makeText(activity, response.errorBody()!!.string(), Toast.LENGTH_LONG).show(); } - - } - override fun onFailure(call: Call, t: Throwable) { - Log.d("Main","Graska3") Toast.makeText( activity, t.toString(), Toast.LENGTH_LONG ).show(); @@ -118,11 +168,19 @@ class FragmentProfile : Fragment(R.layout.fragment_profile) { } private fun setUserInfo(user:UserReceive){ name.setText(user.name) - username.setText(user.username) - - postsCount.setText("to do backend") - followersCount.setText("to do backend") - followingCount.setText("to do backend") + username.setText("@"+user.username) + + postsCount.setText("to do back") + followersCount.setText("to do back") + followingCount.setText("to do back") + + //Add Profile image + if(user.pfp!=null) { + Glide.with(requireActivity()) + .load(RetrofitHelper.baseUrl + "/api/post/image/" + user.pfp!!._id) + .circleCrop()//Round image + .into(profilePicture) + } } -- cgit v1.2.3 From 9862f1af5c2f0cdff24d7292a10b2388175fbaa5 Mon Sep 17 00:00:00 2001 From: Ognjen Cirkovic Date: Mon, 14 Nov 2022 19:07:34 +0100 Subject: Dodata oznaka da korisnik moze da doda profilnu sliku. --- .../res/drawable-anydpi/add_profile_picture_plus.xml | 11 +++++++++++ .../add_profile_picture_plus_color.xml | 11 +++++++++++ .../add_profile_picture_plus_color_1.xml | 16 ++++++++++++++++ .../res/drawable-hdpi/add_profile_picture_plus.png | Bin 0 -> 439 bytes .../drawable-hdpi/add_profile_picture_plus_color.png | Bin 0 -> 461 bytes .../add_profile_picture_plus_color_1.png | Bin 0 -> 461 bytes .../res/drawable-mdpi/add_profile_picture_plus.png | Bin 0 -> 267 bytes .../drawable-mdpi/add_profile_picture_plus_color.png | Bin 0 -> 291 bytes .../add_profile_picture_plus_color_1.png | Bin 0 -> 338 bytes .../res/drawable-xhdpi/add_profile_picture_plus.png | Bin 0 -> 546 bytes .../add_profile_picture_plus_color.png | Bin 0 -> 580 bytes .../add_profile_picture_plus_color_1.png | Bin 0 -> 630 bytes .../res/drawable-xxhdpi/add_profile_picture_plus.png | Bin 0 -> 768 bytes .../add_profile_picture_plus_color.png | Bin 0 -> 813 bytes .../add_profile_picture_plus_color_1.png | Bin 0 -> 920 bytes .../brzodolokacije/Fragments/FragmentProfile.kt | 5 +++++ .../app/src/main/res/layout/fragment_profile.xml | 19 +++++++++++++++++++ 17 files changed, 62 insertions(+) create mode 100644 Client/BrzoDoLokacije/app/src/debug/res/drawable-anydpi/add_profile_picture_plus.xml create mode 100644 Client/BrzoDoLokacije/app/src/debug/res/drawable-anydpi/add_profile_picture_plus_color.xml create mode 100644 Client/BrzoDoLokacije/app/src/debug/res/drawable-anydpi/add_profile_picture_plus_color_1.xml create mode 100644 Client/BrzoDoLokacije/app/src/debug/res/drawable-hdpi/add_profile_picture_plus.png create mode 100644 Client/BrzoDoLokacije/app/src/debug/res/drawable-hdpi/add_profile_picture_plus_color.png create mode 100644 Client/BrzoDoLokacije/app/src/debug/res/drawable-hdpi/add_profile_picture_plus_color_1.png create mode 100644 Client/BrzoDoLokacije/app/src/debug/res/drawable-mdpi/add_profile_picture_plus.png create mode 100644 Client/BrzoDoLokacije/app/src/debug/res/drawable-mdpi/add_profile_picture_plus_color.png create mode 100644 Client/BrzoDoLokacije/app/src/debug/res/drawable-mdpi/add_profile_picture_plus_color_1.png create mode 100644 Client/BrzoDoLokacije/app/src/debug/res/drawable-xhdpi/add_profile_picture_plus.png create mode 100644 Client/BrzoDoLokacije/app/src/debug/res/drawable-xhdpi/add_profile_picture_plus_color.png create mode 100644 Client/BrzoDoLokacije/app/src/debug/res/drawable-xhdpi/add_profile_picture_plus_color_1.png create mode 100644 Client/BrzoDoLokacije/app/src/debug/res/drawable-xxhdpi/add_profile_picture_plus.png create mode 100644 Client/BrzoDoLokacije/app/src/debug/res/drawable-xxhdpi/add_profile_picture_plus_color.png create mode 100644 Client/BrzoDoLokacije/app/src/debug/res/drawable-xxhdpi/add_profile_picture_plus_color_1.png diff --git a/Client/BrzoDoLokacije/app/src/debug/res/drawable-anydpi/add_profile_picture_plus.xml b/Client/BrzoDoLokacije/app/src/debug/res/drawable-anydpi/add_profile_picture_plus.xml new file mode 100644 index 0000000..34823a6 --- /dev/null +++ b/Client/BrzoDoLokacije/app/src/debug/res/drawable-anydpi/add_profile_picture_plus.xml @@ -0,0 +1,11 @@ + + + diff --git a/Client/BrzoDoLokacije/app/src/debug/res/drawable-anydpi/add_profile_picture_plus_color.xml b/Client/BrzoDoLokacije/app/src/debug/res/drawable-anydpi/add_profile_picture_plus_color.xml new file mode 100644 index 0000000..af3270c --- /dev/null +++ b/Client/BrzoDoLokacije/app/src/debug/res/drawable-anydpi/add_profile_picture_plus_color.xml @@ -0,0 +1,11 @@ + + + diff --git a/Client/BrzoDoLokacije/app/src/debug/res/drawable-anydpi/add_profile_picture_plus_color_1.xml b/Client/BrzoDoLokacije/app/src/debug/res/drawable-anydpi/add_profile_picture_plus_color_1.xml new file mode 100644 index 0000000..b643016 --- /dev/null +++ b/Client/BrzoDoLokacije/app/src/debug/res/drawable-anydpi/add_profile_picture_plus_color_1.xml @@ -0,0 +1,16 @@ + + + + + diff --git a/Client/BrzoDoLokacije/app/src/debug/res/drawable-hdpi/add_profile_picture_plus.png b/Client/BrzoDoLokacije/app/src/debug/res/drawable-hdpi/add_profile_picture_plus.png new file mode 100644 index 0000000..ac7f48c Binary files /dev/null and b/Client/BrzoDoLokacije/app/src/debug/res/drawable-hdpi/add_profile_picture_plus.png differ diff --git a/Client/BrzoDoLokacije/app/src/debug/res/drawable-hdpi/add_profile_picture_plus_color.png b/Client/BrzoDoLokacije/app/src/debug/res/drawable-hdpi/add_profile_picture_plus_color.png new file mode 100644 index 0000000..c58371e Binary files /dev/null and b/Client/BrzoDoLokacije/app/src/debug/res/drawable-hdpi/add_profile_picture_plus_color.png differ diff --git a/Client/BrzoDoLokacije/app/src/debug/res/drawable-hdpi/add_profile_picture_plus_color_1.png b/Client/BrzoDoLokacije/app/src/debug/res/drawable-hdpi/add_profile_picture_plus_color_1.png new file mode 100644 index 0000000..74786ad Binary files /dev/null and b/Client/BrzoDoLokacije/app/src/debug/res/drawable-hdpi/add_profile_picture_plus_color_1.png differ diff --git a/Client/BrzoDoLokacije/app/src/debug/res/drawable-mdpi/add_profile_picture_plus.png b/Client/BrzoDoLokacije/app/src/debug/res/drawable-mdpi/add_profile_picture_plus.png new file mode 100644 index 0000000..e853535 Binary files /dev/null and b/Client/BrzoDoLokacije/app/src/debug/res/drawable-mdpi/add_profile_picture_plus.png differ diff --git a/Client/BrzoDoLokacije/app/src/debug/res/drawable-mdpi/add_profile_picture_plus_color.png b/Client/BrzoDoLokacije/app/src/debug/res/drawable-mdpi/add_profile_picture_plus_color.png new file mode 100644 index 0000000..62eeb35 Binary files /dev/null and b/Client/BrzoDoLokacije/app/src/debug/res/drawable-mdpi/add_profile_picture_plus_color.png differ diff --git a/Client/BrzoDoLokacije/app/src/debug/res/drawable-mdpi/add_profile_picture_plus_color_1.png b/Client/BrzoDoLokacije/app/src/debug/res/drawable-mdpi/add_profile_picture_plus_color_1.png new file mode 100644 index 0000000..eb81643 Binary files /dev/null and b/Client/BrzoDoLokacije/app/src/debug/res/drawable-mdpi/add_profile_picture_plus_color_1.png differ diff --git a/Client/BrzoDoLokacije/app/src/debug/res/drawable-xhdpi/add_profile_picture_plus.png b/Client/BrzoDoLokacije/app/src/debug/res/drawable-xhdpi/add_profile_picture_plus.png new file mode 100644 index 0000000..66fa4aa Binary files /dev/null and b/Client/BrzoDoLokacije/app/src/debug/res/drawable-xhdpi/add_profile_picture_plus.png differ diff --git a/Client/BrzoDoLokacije/app/src/debug/res/drawable-xhdpi/add_profile_picture_plus_color.png b/Client/BrzoDoLokacije/app/src/debug/res/drawable-xhdpi/add_profile_picture_plus_color.png new file mode 100644 index 0000000..6cad473 Binary files /dev/null and b/Client/BrzoDoLokacije/app/src/debug/res/drawable-xhdpi/add_profile_picture_plus_color.png differ diff --git a/Client/BrzoDoLokacije/app/src/debug/res/drawable-xhdpi/add_profile_picture_plus_color_1.png b/Client/BrzoDoLokacije/app/src/debug/res/drawable-xhdpi/add_profile_picture_plus_color_1.png new file mode 100644 index 0000000..35f6294 Binary files /dev/null and b/Client/BrzoDoLokacije/app/src/debug/res/drawable-xhdpi/add_profile_picture_plus_color_1.png differ diff --git a/Client/BrzoDoLokacije/app/src/debug/res/drawable-xxhdpi/add_profile_picture_plus.png b/Client/BrzoDoLokacije/app/src/debug/res/drawable-xxhdpi/add_profile_picture_plus.png new file mode 100644 index 0000000..89b14f1 Binary files /dev/null and b/Client/BrzoDoLokacije/app/src/debug/res/drawable-xxhdpi/add_profile_picture_plus.png differ diff --git a/Client/BrzoDoLokacije/app/src/debug/res/drawable-xxhdpi/add_profile_picture_plus_color.png b/Client/BrzoDoLokacije/app/src/debug/res/drawable-xxhdpi/add_profile_picture_plus_color.png new file mode 100644 index 0000000..a15759e Binary files /dev/null and b/Client/BrzoDoLokacije/app/src/debug/res/drawable-xxhdpi/add_profile_picture_plus_color.png differ diff --git a/Client/BrzoDoLokacije/app/src/debug/res/drawable-xxhdpi/add_profile_picture_plus_color_1.png b/Client/BrzoDoLokacije/app/src/debug/res/drawable-xxhdpi/add_profile_picture_plus_color_1.png new file mode 100644 index 0000000..a0cab62 Binary files /dev/null and b/Client/BrzoDoLokacije/app/src/debug/res/drawable-xxhdpi/add_profile_picture_plus_color_1.png differ 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 2ed28ce..9628a6b 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 @@ -52,6 +52,7 @@ class FragmentProfile : Fragment(R.layout.fragment_profile) { private lateinit var showMyData: Button private lateinit var showMyRecensions: Button private lateinit var profilePicture: ShapeableImageView + private lateinit var profilePicturePlus: ShapeableImageView override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? @@ -67,6 +68,7 @@ class FragmentProfile : Fragment(R.layout.fragment_profile) { showMyData=view.findViewById(R.id.btnFragmentProfileShowMyData) as Button showMyRecensions=view.findViewById(R.id.btnFragmentProfileShowMyRecensions) as Button profilePicture=view.findViewById(R.id.tvFragmentProfileProfilePicture) as ShapeableImageView + profilePicturePlus=view.findViewById(R.id.tvFragmentProfileProfilePicturePlus) as ShapeableImageView //podaci iz baze @@ -95,6 +97,9 @@ class FragmentProfile : Fragment(R.layout.fragment_profile) { fm.replace(R.id.flFragmentProfileFragmentContainer, FragmentMyRecensions()) fm.commit() } + profilePicturePlus.setOnClickListener{ + addProfilePicture() + } profilePicture.setOnClickListener{ addProfilePicture() } 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 e7cccff..96f60f6 100644 --- a/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_profile.xml +++ b/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_profile.xml @@ -75,6 +75,24 @@ app:layout_constraintVertical_bias="1.0" app:shapeAppearanceOverlay="@style/imageViewCircle" /> + + + + Date: Mon, 14 Nov 2022 20:22:05 +0100 Subject: user post list and count --- Backend/Api/Api/Controllers/UserController.cs | 14 +++++++++++++- Backend/Api/Api/Interfaces/IPostService.cs | 1 + Backend/Api/Api/Models/User.cs | 1 + Backend/Api/Api/Services/PostService.cs | 13 +++++++++++++ Backend/Api/Api/Services/UserService.cs | 6 ++++++ 5 files changed, 34 insertions(+), 1 deletion(-) diff --git a/Backend/Api/Api/Controllers/UserController.cs b/Backend/Api/Api/Controllers/UserController.cs index d4a9cb7..539620b 100644 --- a/Backend/Api/Api/Controllers/UserController.cs +++ b/Backend/Api/Api/Controllers/UserController.cs @@ -10,10 +10,12 @@ namespace Api.Controllers { private readonly IUserService _userService; private readonly IJwtService _jwtService; - public UserController(IUserService userService, IJwtService jwtService) + private readonly IPostService _postService; + public UserController(IUserService userService, IJwtService jwtService, IPostService postService) { _userService = userService; _jwtService = jwtService; + _postService = postService; } [HttpPost("profile/pfp")] [Authorize(Roles = "User")] @@ -43,5 +45,15 @@ namespace Api.Controllers return Ok(rez); return BadRequest(); } + [HttpGet("posts")] + [Authorize(Roles = "User")] + public async Task> SelfPosts() + { + var id = await _userService.UserIdFromJwt(); + var rez = await _postService.GetUsersPosts(id); + if (rez != null) + return Ok(rez); + return BadRequest(); + } } } diff --git a/Backend/Api/Api/Interfaces/IPostService.cs b/Backend/Api/Api/Interfaces/IPostService.cs index 24a1e74..fc2ae03 100644 --- a/Backend/Api/Api/Interfaces/IPostService.cs +++ b/Backend/Api/Api/Interfaces/IPostService.cs @@ -17,5 +17,6 @@ namespace Api.Interfaces Task CascadeDeleteComments(string cmntid, Post p); Task SearchPosts(string locid, int page = 0, int sorttype = 1, int filterdate = 1); int DateEnumToDays(int filterdate); + Task> GetUsersPosts(string id); } } \ No newline at end of file diff --git a/Backend/Api/Api/Models/User.cs b/Backend/Api/Api/Models/User.cs index b212ebb..2e323a8 100644 --- a/Backend/Api/Api/Models/User.cs +++ b/Backend/Api/Api/Models/User.cs @@ -57,5 +57,6 @@ namespace Api.Models public String email { get; set; } public DateTime creationDate { get; set; } public File? pfp { get; set; } + public int postcount { get; set; } } } diff --git a/Backend/Api/Api/Services/PostService.cs b/Backend/Api/Api/Services/PostService.cs index 321aebe..2d62f49 100644 --- a/Backend/Api/Api/Services/PostService.cs +++ b/Backend/Api/Api/Services/PostService.cs @@ -336,5 +336,18 @@ namespace Api.Services default: return 365 * 10; } } + public async Task> GetUsersPosts(string id) + { + var userposts = await _posts.Find(x => x.ownerId == id).ToListAsync(); + if (userposts == null) + return null; + var tosend = new List(); + foreach (var post in userposts) + { + var x = await postToPostSend(post); + tosend.Add(x); + } + return tosend; + } } } diff --git a/Backend/Api/Api/Services/UserService.cs b/Backend/Api/Api/Services/UserService.cs index 8e7cd42..33e6d11 100644 --- a/Backend/Api/Api/Services/UserService.cs +++ b/Backend/Api/Api/Services/UserService.cs @@ -12,6 +12,7 @@ namespace Api.Services { private readonly IHttpContextAccessor _httpContext; private readonly IMongoCollection _users; + private readonly IMongoCollection _posts; private readonly IJwtService _jwtService; private IConfiguration _configuration; private readonly IFileService _fileService; @@ -19,6 +20,7 @@ namespace Api.Services { var database = mongoClient.GetDatabase(settings.DatabaseName); _users = database.GetCollection(settings.UserCollectionName); + _posts = database.GetCollection(settings.PostCollectionName); _jwtService = jwtService; this._httpContext = httpContextAccessor; this._configuration = configuration; @@ -353,6 +355,8 @@ namespace Api.Services tosend._id= user._id; tosend.creationDate = user.creationDate; tosend.email=""; + var userposts = await _posts.Find(x => x.ownerId == user._id).ToListAsync(); + tosend.postcount = userposts.Count(); return tosend; } public async Task GetSelfUserData(string id) @@ -367,6 +371,8 @@ namespace Api.Services tosend._id = user._id; tosend.creationDate = user.creationDate; tosend.email = user.email; + var userposts = await _posts.Find(x => x.ownerId == user._id).ToListAsync(); + tosend.postcount = userposts.Count(); return tosend; } } -- cgit v1.2.3 From 81fae5e55c7a2b5a1ddc8055d32bc310e22e014d Mon Sep 17 00:00:00 2001 From: Ognjen Cirkovic Date: Mon, 14 Nov 2022 22:12:00 +0100 Subject: Prosiren model za user-a. Omogucen prikaz objava korisnika na njegovom profilu. --- Backend/Api/Api/Controllers/UserController.cs | 2 +- .../brzodolokacije/Fragments/FragmentProfile.kt | 19 +++-- .../brzodolokacije/Fragments/FragmentUserPosts.kt | 85 +++++++++++++--------- .../brzodolokacije/Interfaces/IBackendApi.kt | 3 +- .../java/com/example/brzodolokacije/Models/User.kt | 3 +- .../src/main/res/layout/fragment_user_posts.xml | 24 ++++-- 6 files changed, 85 insertions(+), 51 deletions(-) diff --git a/Backend/Api/Api/Controllers/UserController.cs b/Backend/Api/Api/Controllers/UserController.cs index 539620b..1ef8234 100644 --- a/Backend/Api/Api/Controllers/UserController.cs +++ b/Backend/Api/Api/Controllers/UserController.cs @@ -47,7 +47,7 @@ namespace Api.Controllers } [HttpGet("posts")] [Authorize(Roles = "User")] - public async Task> SelfPosts() + public async Task>> SelfPosts() { var id = await _userService.UserIdFromJwt(); var rez = await _postService.GetUsersPosts(id); 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 9628a6b..198e125 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 @@ -75,10 +75,7 @@ class FragmentProfile : Fragment(R.layout.fragment_profile) { showMyPosts.setOnClickListener{ - var fm: FragmentTransaction =childFragmentManager.beginTransaction() - - fm.replace(R.id.flFragmentProfileFragmentContainer, FragmentUserPosts()) - fm.commit() + openMyPosts() } @@ -104,9 +101,15 @@ class FragmentProfile : Fragment(R.layout.fragment_profile) { addProfilePicture() } getProfileInfo() - + openMyPosts() return view } + fun openMyPosts(){ + var fm: FragmentTransaction =childFragmentManager.beginTransaction() + + fm.replace(R.id.flFragmentProfileFragmentContainer, FragmentUserPosts()) + fm.commit() + } private fun addProfilePicture(){ val intent= Intent(Intent.ACTION_PICK) @@ -174,10 +177,10 @@ class FragmentProfile : Fragment(R.layout.fragment_profile) { private fun setUserInfo(user:UserReceive){ name.setText(user.name) username.setText("@"+user.username) + postsCount.setText(user.postcount.toString()) - postsCount.setText("to do back") - followersCount.setText("to do back") - followingCount.setText("to do back") + followersCount.setText("to do") + followingCount.setText("to do") //Add Profile image if(user.pfp!=null) { 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 561de10..66e7846 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 @@ -5,56 +5,73 @@ import androidx.fragment.app.Fragment import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.widget.Toast +import androidx.core.content.ContextCompat +import androidx.recyclerview.widget.DividerItemDecoration +import androidx.recyclerview.widget.GridLayoutManager +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import com.example.brzodolokacije.Adapters.ShowPostsAdapter +import com.example.brzodolokacije.Adapters.ShowPostsHomePageAdapter +import com.example.brzodolokacije.Interfaces.IBackendApi +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 +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory -// 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 [FragmentUserPosts.newInstance] factory method to - * create an instance of this fragment. - */ class FragmentUserPosts : Fragment() { - // TODO: Rename and change types of parameters - private var param1: String? = null - private var param2: String? = null - + private lateinit var posts : MutableList + 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? { + var view=inflater.inflate(R.layout.fragment_user_posts, container, false) // Inflate the layout for this fragment - return inflater.inflate(R.layout.fragment_user_posts, container, false) + rvPosts=view.findViewById(R.id.rvFragmentUserPostsPosts) as RecyclerView + getPosts() + return view } - 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 FragmentUserPosts. - */ - // TODO: Rename and change types and number of parameters - @JvmStatic - fun newInstance(param1: String, param2: String) = - FragmentUserPosts().apply { - arguments = Bundle().apply { - putString(ARG_PARAM1, param1) - putString(ARG_PARAM2, param2) + fun getPosts(){ + val api = RetrofitHelper.getInstance() + val token= SharedPreferencesHelper.getValue("jwt", requireActivity()) + val data=api.getMyPosts("Bearer "+token) + + data.enqueue(object : Callback> { + override fun onResponse( + call: Call>, + response: Response> + ) { + if (response.body() == null) { + return } + posts = response.body()!!.toMutableList() + loadPosts() + } + override fun onFailure(call: Call>, t: Throwable) { + } + }) } + private fun loadPosts(){//most viewed + rvPosts.apply { + layoutManager= GridLayoutManager(requireContext(),2,GridLayoutManager.VERTICAL,false) + adapter= ShowPostsAdapter(requireActivity(),posts) + + } + } + + } \ 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 236db1d..2f5cff1 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 @@ -51,7 +51,8 @@ interface IBackendApi { @GET("/api/user/{username}/profile") fun getProfile(@Header("Authorization") authHeader:String,@Path("username") username:String):Call - + @GET("/api/user/posts") + fun getMyPosts(@Header("Authorization") authHeader:String):Call> //@POST("putanja") //fun add(@Body obj:Post,@Header("Authorization") authHeader:String):Call 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 505ac51..c726978 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 @@ -27,5 +27,6 @@ data class UserReceive( var username:String, var email:String, var creationDate: Date, - var pfp:PostImage? + var pfp:PostImage?, + var postcount:Int ) \ No newline at end of file diff --git a/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_user_posts.xml b/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_user_posts.xml index 185719b..f48d0a2 100644 --- a/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_user_posts.xml +++ b/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_user_posts.xml @@ -1,14 +1,26 @@ - - - + + + android:layout_height="wrap_content" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/space" /> - \ No newline at end of file + \ No newline at end of file -- cgit v1.2.3