diff options
author | TAMARA JERINIC <tamara.jerinic@gmail.com> | 2022-11-21 23:53:25 +0100 |
---|---|---|
committer | TAMARA JERINIC <tamara.jerinic@gmail.com> | 2022-11-21 23:54:04 +0100 |
commit | 4c6172aa80d5b8a8d12f45d1d91ce4e778d9412a (patch) | |
tree | 872565272d2be6173c9c2670d64b134adad5d32b | |
parent | 2404102a5d5a5575ba4e8000da0f90e627d9a1d5 (diff) |
Dodato praćenje korisnika na back-u. Dodati fragmenti za praćenje korisnika na front-u.
14 files changed, 285 insertions, 63 deletions
diff --git a/Backend/Api/Api/Controllers/UserController.cs b/Backend/Api/Api/Controllers/UserController.cs index dd081cb..6cc41ea 100644 --- a/Backend/Api/Api/Controllers/UserController.cs +++ b/Backend/Api/Api/Controllers/UserController.cs @@ -74,5 +74,29 @@ namespace Api.Controllers return Ok(rez); return BadRequest(); } + + [HttpGet("{id}/followers")] + [Authorize(Roles = "User")] + public async Task<ActionResult<List<UserSend>>> GetFollowers(string id) + { + return Ok(await _userService.GetFollowers(id)); + } + + [HttpGet("{id}/following")] + [Authorize(Roles = "User")] + public async Task<ActionResult<List<UserSend>>> GetFollowing(string id) + { + return Ok(await _userService.GetFollowing(id)); + } + + [HttpGet("{id}/addFollower")] + [Authorize(Roles = "User")] + public async Task<ActionResult<List<UserSend>>> AddFollower(string userId, string followerId) + { + return Ok(await _userService.AddFollower(userId, followerId)); + } + + + } } diff --git a/Backend/Api/Api/Interfaces/IUserService.cs b/Backend/Api/Api/Interfaces/IUserService.cs index 313e909..5770de1 100644 --- a/Backend/Api/Api/Interfaces/IUserService.cs +++ b/Backend/Api/Api/Interfaces/IUserService.cs @@ -26,5 +26,9 @@ namespace Api.Interfaces Task<Boolean> AddOrChangePfp(string userid, IFormFile image); Task<UserSend> GetUserData(string username); Task<UserSend> GetSelfUserData(string id); + + Task<Boolean> AddFollower(string userId,string followerId); + Task<List<UserSend>> GetFollowers(string id); + Task<List<UserSend>> GetFollowing(string id); } } diff --git a/Backend/Api/Api/Models/User.cs b/Backend/Api/Api/Models/User.cs index 2e323a8..6c777e7 100644 --- a/Backend/Api/Api/Models/User.cs +++ b/Backend/Api/Api/Models/User.cs @@ -16,6 +16,11 @@ namespace Api.Models public String password { get; set; } public DateTime creationDate { get; set; } public File? pfp { get; set; } + + public List<string> followers { get; set; } + public List<string> following { get; set; } + public int followersCount { get; set; } + public int followingCount { get; set; } } public class Login @@ -58,5 +63,13 @@ namespace Api.Models public DateTime creationDate { get; set; } public File? pfp { get; set; } public int postcount { get; set; } + + public List<String> followers{ get; set; } + public List<String> following { get; set; } + + public int followersCount { get; set; } + public int followingCount { get; set; } + + } } diff --git a/Backend/Api/Api/Services/UserService.cs b/Backend/Api/Api/Services/UserService.cs index 33e6d11..64a7f7a 100644 --- a/Backend/Api/Api/Services/UserService.cs +++ b/Backend/Api/Api/Services/UserService.cs @@ -5,6 +5,7 @@ using Microsoft.AspNetCore.Http; using System.Security.Claims; using MimeKit; using MailKit.Net.Smtp; +using DnsClient; namespace Api.Services { @@ -16,6 +17,8 @@ namespace Api.Services private readonly IJwtService _jwtService; private IConfiguration _configuration; private readonly IFileService _fileService; + + private readonly IMongoCollection<UserSend> _usersSend; public UserService(IDatabaseConnection settings, IMongoClient mongoClient, IJwtService jwtService, IHttpContextAccessor httpContextAccessor, IConfiguration configuration, IFileService fileService) { var database = mongoClient.GetDatabase(settings.DatabaseName); @@ -35,6 +38,7 @@ namespace Api.Services return -2; //username already // user.password = hashPassword(user.password); + await _users.InsertOneAsync(user); return 1; } @@ -375,5 +379,83 @@ namespace Api.Services tosend.postcount = userposts.Count(); return tosend; } + + public async Task<Boolean> AddFollower(string userId,string followerId) + { + UserSend u = await _usersSend.Find(user => user._id==userId).FirstOrDefaultAsync(); + UserSend f = await _usersSend.Find(user => user._id == followerId).FirstOrDefaultAsync(); + + if (userId != null && followerId!=null) + { + u.followers.Add(followerId); + f.following.Add(userId); + return true; + } + + + return false; + } + + public async Task<List<UserSend>> GetFollowers(string id) + { + User u = await _users.Find(user => user._id == id).FirstOrDefaultAsync(); + List<UserSend> followers = new List<UserSend>(); + if (u != null) + { + //List<UserSend> followers = u.followers; + if (u.followers.Count() > 0) + { + foreach (string userid in u.followers) + { + User utemp = await _users.Find(user => user._id == userid).FirstOrDefaultAsync(); + if (utemp == null) + { + continue; + } + UserSend follower = new UserSend(); + follower.pfp = utemp.pfp; + follower.username = utemp.username; + follower.email = utemp.username; + follower.followers = utemp.followers; + follower._id = utemp._id; + + followers.Add((UserSend)follower); + } + } + return followers; + } + return null; + } + + public async Task<List<UserSend>> GetFollowing(string id) + { + User u = await _users.Find(user => user._id == id).FirstOrDefaultAsync(); + List<UserSend> following = new List<UserSend>(); + if (u != null) + { + + if (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 follower = new UserSend(); + follower.pfp = utemp.pfp; + follower.username = utemp.username; + follower.email = utemp.username; + follower.followers = utemp.followers; + follower._id = utemp._id; + + following.Add((UserSend)follower); + } + } + return following; + } + return null; + } } } diff --git a/Client/BrzoDoLokacije/.idea/deploymentTargetDropDown.xml b/Client/BrzoDoLokacije/.idea/deploymentTargetDropDown.xml index d34d986..6fac072 100644 --- a/Client/BrzoDoLokacije/.idea/deploymentTargetDropDown.xml +++ b/Client/BrzoDoLokacije/.idea/deploymentTargetDropDown.xml @@ -7,11 +7,11 @@ <deviceKey> <Key> <type value="VIRTUAL_DEVICE_PATH" /> - <value value="C:\Users\PC\.android\avd\Copy_of_Pixel_2_API_32.avd" /> + <value value="C:\Users\TAMARA\.android\avd\Pixel_3a_XL_API_33.avd" /> </Key> </deviceKey> </Target> </targetSelectedWithDropDown> - <timeTargetWasSelectedWithDropDown value="2022-11-20T22:15:01.646388600Z" /> + <timeTargetWasSelectedWithDropDown value="2022-11-21T20:28:37.906817700Z" /> </component> </project>
\ No newline at end of file diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/FollowersAdapter.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/FollowersAdapter.kt new file mode 100644 index 0000000..117a2c2 --- /dev/null +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/FollowersAdapter.kt @@ -0,0 +1,4 @@ +package com.example.brzodolokacije.Adapters + +class FollowersAdapter { +}
\ 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 new file mode 100644 index 0000000..da480f1 --- /dev/null +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentFollowers.kt @@ -0,0 +1,69 @@ +package com.example.brzodolokacije.Fragments + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.Toast +import androidx.fragment.app.Fragment +import com.example.brzodolokacije.Interfaces.IBackendApi +import com.example.brzodolokacije.Models.PostPreview +import com.example.brzodolokacije.Models.UserReceive +import com.example.brzodolokacije.R +import com.example.brzodolokacije.Services.RetrofitHelper +import com.example.brzodolokacije.Services.SharedPreferencesHelper +import retrofit2.Call +import retrofit2.Callback +import retrofit2.Response +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory + +class FragmentFollowers : Fragment() { + private lateinit var userId:String + private lateinit var followers: MutableList<UserReceive> + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + val view= inflater.inflate(R.layout.fragment_followers, container, false) + + val bundle = this.arguments + + if (bundle != null) { + userId= bundle.getString("userId").toString() + Toast.makeText( + activity, bundle.getString("userId"), Toast.LENGTH_LONG + ).show(); + } + + getPosts() + + return view + } + + fun getPosts(){ + val api = RetrofitHelper.getInstance() + val data=api.getFollowers(userId) + + + data.enqueue(object : Callback<MutableList<UserReceive>> { + override fun onResponse( + call: Call<MutableList<UserReceive>>, + response: Response<MutableList<UserReceive>> + ) { + if (response.body() == null) { + return + } + + followers = response.body()!!.toMutableList<UserReceive>() + + } + + override fun onFailure(call: Call<MutableList<UserReceive>>, t: Throwable) { + Toast.makeText( + activity,"nema objava", Toast.LENGTH_LONG + ).show(); + } + }) + } +}
\ No newline at end of file diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentHomePageMainScroll.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentHomePageMainScroll.kt index bde4dd2..cf811df 100644 --- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentHomePageMainScroll.kt +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentHomePageMainScroll.kt @@ -77,9 +77,6 @@ class FragmentHomePageMainScroll : Fragment() { var fragment=FragmentShowPostsByLocation() location_spa.setOnClickListener { - Toast.makeText( - activity, "BANJAAAAAAAAAAAAAAA", Toast.LENGTH_LONG - ).show(); filter=LocationType.BANJA filterString=filter.toString() bundle.putString("data",filterString) diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentProfile.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentProfile.kt index a792598..03cb4fa 100644 --- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentProfile.kt +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentProfile.kt @@ -1,5 +1,6 @@ package com.example.brzodolokacije.Fragments + import android.content.Intent import android.net.Uri import android.os.Bundle @@ -19,7 +20,6 @@ import com.example.brzodolokacije.R import com.example.brzodolokacije.Services.RetrofitHelper import com.example.brzodolokacije.Services.SharedPreferencesHelper import com.google.android.material.button.MaterialButton -import com.google.android.material.imageview.ShapeableImageView import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MultipartBody import okhttp3.RequestBody @@ -28,6 +28,7 @@ import retrofit2.Call import retrofit2.Response import java.io.File + // TODO: Rename parameter arguments, choose names that match // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER private const val ARG_PARAM1 = "param1" @@ -38,7 +39,7 @@ private const val ARG_PARAM2 = "param2" * Use the [FragmentProfile.newInstance] factory method to * create an instance of this fragment. */ -class FragmentProfile : Fragment(R.layout.fragment_profile) { +class FragmentProfile : Fragment(com.example.brzodolokacije.R.layout.fragment_profile) { // TODO: Rename and change types of parameters private lateinit var username: TextView private lateinit var name: TextView @@ -55,22 +56,31 @@ class FragmentProfile : Fragment(R.layout.fragment_profile) { private lateinit var showMyRecensions: Button private lateinit var profilePicture: ImageView private lateinit var profilePicturePlus: MaterialButton + private lateinit var showFollowers: TextView + + var userId:String = "1" + + override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { + Toast.makeText( + activity, "MOJ PROFILLLLLLLLLLLLLLL", Toast.LENGTH_LONG + ).show(); // Inflate the layout for this fragment - val view:View= inflater.inflate(R.layout.fragment_profile, container, false) - name = view.findViewById<View>(R.id.tvFragmentProfileName) as TextView - username = view.findViewById<View>(R.id.tvFragmentProfileUserName) as TextView - postsCount = view.findViewById<View>(R.id.tvFragmentProfilePostsNo) as TextView - followersCount = view.findViewById<View>(R.id.tvFragmentProfileFollowersNo) as TextView - followingCount = view.findViewById<View>(R.id.tvFragmentProfileFollowNo) as TextView - showMyPosts=view.findViewById<View>(R.id.btnFragmentProfileShowMyPosts) as Button - showMyData=view.findViewById<View>(R.id.btnFragmentProfileShowMyData) as Button - showMyRecensions=view.findViewById<View>(R.id.btnFragmentProfileShowMyRecensions) as Button - profilePicture=view.findViewById<View>(R.id.tvFragmentProfileProfilePicture) as ImageView - profilePicturePlus=view.findViewById<View>(R.id.btnFragmentProfileProfilePicturePlus) as MaterialButton + val view:View= inflater.inflate(com.example.brzodolokacije.R.layout.fragment_profile, container, false) + name = view.findViewById<View>(com.example.brzodolokacije.R.id.tvFragmentProfileName) as TextView + username = view.findViewById<View>(com.example.brzodolokacije.R.id.tvFragmentProfileUserName) as TextView + postsCount = view.findViewById<View>(com.example.brzodolokacije.R.id.tvFragmentProfilePostsNo) as TextView + followersCount = view.findViewById<View>(com.example.brzodolokacije.R.id.tvFragmentProfileFollowersNo) as TextView + followingCount = view.findViewById<View>(com.example.brzodolokacije.R.id.tvFragmentProfileFollowNo) as TextView + showMyPosts=view.findViewById<View>(com.example.brzodolokacije.R.id.btnFragmentProfileShowMyPosts) as Button + showMyData=view.findViewById<View>(com.example.brzodolokacije.R.id.btnFragmentProfileShowMyData) as Button + showMyRecensions=view.findViewById<View>(com.example.brzodolokacije.R.id.btnFragmentProfileShowMyRecensions) as Button + profilePicture=view.findViewById<View>(com.example.brzodolokacije.R.id.tvFragmentProfileProfilePicture) as ImageView + profilePicturePlus=view.findViewById<View>(com.example.brzodolokacije.R.id.btnFragmentProfileProfilePicturePlus) as MaterialButton + showFollowers=view.findViewById(com.example.brzodolokacije.R.id.tvFragmentProfileFollowers) //podaci iz baze @@ -85,7 +95,7 @@ class FragmentProfile : Fragment(R.layout.fragment_profile) { var fm: FragmentTransaction =childFragmentManager.beginTransaction() - fm.replace(R.id.flFragmentProfileFragmentContainer, FragmentMyProfileInfo()) + fm.replace(com.example.brzodolokacije.R.id.flFragmentProfileFragmentContainer, FragmentMyProfileInfo()) fm.commit() } @@ -93,12 +103,24 @@ class FragmentProfile : Fragment(R.layout.fragment_profile) { getProfileInfo() var fm: FragmentTransaction =childFragmentManager.beginTransaction() - fm.replace(R.id.flFragmentProfileFragmentContainer, FragmentMyRecensions()) + fm.replace(com.example.brzodolokacije.R.id.flFragmentProfileFragmentContainer, FragmentMyRecensions()) fm.commit() } profilePicturePlus.setOnClickListener{ addProfilePicture() } + + showFollowers.setOnClickListener { + val bundle = Bundle() + bundle.putString("userId",userId ) // Put anything what you want + val fragmentFollowers = FragmentFollowers() + fragmentFollowers.setArguments(bundle) + + fragmentManager + ?.beginTransaction() + ?.replace(com.example.brzodolokacije.R.id.flNavigationFragment,fragmentFollowers) + ?.commit() + } getProfileInfo() openMyPosts() return view @@ -106,7 +128,7 @@ class FragmentProfile : Fragment(R.layout.fragment_profile) { fun openMyPosts(){ var fm: FragmentTransaction =childFragmentManager.beginTransaction() - fm.replace(R.id.flFragmentProfileFragmentContainer, FragmentUserPosts()) + fm.replace(com.example.brzodolokacije.R.id.flFragmentProfileFragmentContainer, FragmentUserPosts()) fm.commit() } @@ -181,6 +203,8 @@ class FragmentProfile : Fragment(R.layout.fragment_profile) { followersCount.setText("to do") followingCount.setText("to do") + userId=user._id + //Add Profile image if(user.pfp!=null) { Glide.with(requireActivity()) diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentUserProfile.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentUserProfile.kt index 8ab5276..6b1bac9 100644 --- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentUserProfile.kt +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentUserProfile.kt @@ -7,28 +7,8 @@ import android.view.View import android.view.ViewGroup import com.example.brzodolokacije.R -// 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 [FragmentUserProfile.newInstance] factory method to - * create an instance of this fragment. - */ class FragmentUserProfile : Fragment() { - // TODO: Rename and change types of parameters - private var param1: String? = null - private var param2: String? = null - 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?, @@ -38,23 +18,5 @@ class FragmentUserProfile : Fragment() { return inflater.inflate(R.layout.fragment_user_profile, container, false) } - 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 FragmentUserProfile. - */ - // TODO: Rename and change types and number of parameters - @JvmStatic - fun newInstance(param1: String, param2: String) = - FragmentUserProfile().apply { - arguments = Bundle().apply { - putString(ARG_PARAM1, param1) - putString(ARG_PARAM2, param2) - } - } - } + }
\ 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 d8daf14..f7bb9b6 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 @@ -69,4 +69,14 @@ interface IBackendApi { fun getMyHistory(@Header("Authorization") authHeader:String):Call<MutableList<PostPreview>> //@POST("putanja") //fun add(@Body obj:Post,@Header("Authorization") authHeader:String):Call<Post> + + @POST("/api/user/{id}/followers") + fun getFollowers(@Path("id") id:String):Call <MutableList<UserReceive>> + + @POST("/api/user{id}/following") + fun getFollowing(@Path("id") id:String):Call <MutableList<UserReceive>> + + @POST("/api/user{id}/addFollower") + fun addFollower(@Header("Authorization") authHeader:String,@Path("id") id:String):Call<UserReceive> + }
\ No newline at end of file diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Models/User.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Models/User.kt index c726978..46338b3 100644 --- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Models/User.kt +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Models/User.kt @@ -14,9 +14,9 @@ data class User ( //profil var followers:List<User>, - var followersNumber:Int, + var followersCount:Int, var following:List<User>, - var followingNumber:Int, + var followingCount:Int, var postIds:List<Int>, var postNumber:Int @@ -28,5 +28,11 @@ data class UserReceive( var email:String, var creationDate: Date, var pfp:PostImage?, - var postcount:Int + var postcount:Int, + var followers:List<User>, + var followersNumber:Int, + var following:List<User>, + var followingNumber:Int, + var postIds:List<Int>, + var postNumber:Int )
\ No newline at end of file diff --git a/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_followers.xml b/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_followers.xml new file mode 100644 index 0000000..deef1f8 --- /dev/null +++ b/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_followers.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + tools:context=".Fragments.FragmentFollowers"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical"> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="left" + android:text="Pratioci" + android:textSize="20sp" + android:textStyle="bold" /> + + <androidx.recyclerview.widget.RecyclerView + android:id="@+id/rvFragmentShowFollowers" + android:layout_width="match_parent" + android:layout_height="match_parent" /> + </LinearLayout> +</FrameLayout>
\ No newline at end of file diff --git a/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_profile.xml b/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_profile.xml index 138d068..ec78de6 100644 --- a/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_profile.xml +++ b/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_profile.xml @@ -151,6 +151,7 @@ <TextView android:id="@+id/tvFragmentProfileFollowers" android:gravity="center" + android:clickable="true" android:text="PRATIOCI" /> <TextView |