From 71bbfd0c467118b6fa2162ea85290f244f88353e Mon Sep 17 00:00:00 2001 From: Ognjen Cirkovic Date: Wed, 9 Nov 2022 23:48:30 +0100 Subject: Napravljena html stranica sa formom za preuzimanje aplikacije. Dodata provera lozinke prilokom preuzimanja aplikacije. --- Backend/Api/Api.sln | 2 +- Backend/Api/Api/Assets/appDownload.html | 18 ++++++++++++++++++ Backend/Api/Api/Controllers/appController.cs | 18 ++++++++++++++++-- Backend/Api/Api/appsettings.json | 3 ++- 4 files changed, 37 insertions(+), 4 deletions(-) create mode 100644 Backend/Api/Api/Assets/appDownload.html (limited to 'Backend/Api') diff --git a/Backend/Api/Api.sln b/Backend/Api/Api.sln index 006fcf6..3ad9dd0 100644 --- a/Backend/Api/Api.sln +++ b/Backend/Api/Api.sln @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.3.32825.248 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Api", "Api\Api.csproj", "{98D1F700-C988-4F19-89D1-9B7D002D702D}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Api", "Api\Api.csproj", "{98D1F700-C988-4F19-89D1-9B7D002D702D}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/Backend/Api/Api/Assets/appDownload.html b/Backend/Api/Api/Assets/appDownload.html new file mode 100644 index 0000000..0d18e98 --- /dev/null +++ b/Backend/Api/Api/Assets/appDownload.html @@ -0,0 +1,18 @@ + + + + + Verification Successful + + +
+ +

Preuzimanje aplikacije

+
+
+
+

+
+
+ + \ No newline at end of file diff --git a/Backend/Api/Api/Controllers/appController.cs b/Backend/Api/Api/Controllers/appController.cs index 004c941..f16cf29 100644 --- a/Backend/Api/Api/Controllers/appController.cs +++ b/Backend/Api/Api/Controllers/appController.cs @@ -14,14 +14,28 @@ namespace Api.Controllers _configuration = configuration; } - [HttpGet("download")] - public async Task getApp() + [HttpPost("download")] + public async Task getApp([FromForm] string password) { string appPath = _configuration.GetSection("AppSettings:AppName").Value; + string truePassword = _configuration.GetSection("AppSettings:AppPassword").Value; if (appPath == null || !System.IO.File.Exists(appPath)) return BadRequest("Aplikacija ne postoji"); + if (password == null || password!=truePassword) + return BadRequest("Pogresna sifra"); return File(System.IO.File.ReadAllBytes(appPath), "application/octet-stream", Path.GetFileName(appPath)); } + [HttpGet("download")] + public async Task> getForm() + { + + var html = await System.IO.File.ReadAllTextAsync(@"./Assets/appDownload.html"); + html = html.Replace("{{name}}", "test"); + return base.Content(html, "text/html"); + + } } + } + diff --git a/Backend/Api/Api/appsettings.json b/Backend/Api/Api/appsettings.json index b1bc59c..d212dda 100644 --- a/Backend/Api/Api/appsettings.json +++ b/Backend/Api/Api/appsettings.json @@ -3,7 +3,8 @@ "JwtToken": "PjrVqQJ1P2VOkuWLw7NaZUluT4z7bkau", "EmailToken": "e8X8c0lm9KS7itWi3wgE6BiPXR21WPvO", "MapQuestApiKey": "47oeviBUoCI2JxWzNARmCtrH9fDp5Mtk", //msbs#556ASDFGGSGSD - "AppName": "app-debug.apk" + "AppName": "app-debug.apk", + "AppPassword": "jabukakruska123" }, "Logging": { -- cgit v1.2.3 From 1ac71fb9eaafe898b2f16503a17ae1322ba07edb Mon Sep 17 00:00:00 2001 From: Ognjen Cirkovic Date: Wed, 9 Nov 2022 23:54:39 +0100 Subject: Sifra se cuva kao hash. --- Backend/Api/Api/Controllers/appController.cs | 5 ++++- Backend/Api/Api/appsettings.json | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'Backend/Api') diff --git a/Backend/Api/Api/Controllers/appController.cs b/Backend/Api/Api/Controllers/appController.cs index f16cf29..ed83231 100644 --- a/Backend/Api/Api/Controllers/appController.cs +++ b/Backend/Api/Api/Controllers/appController.cs @@ -2,6 +2,8 @@ using System.Data; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Api.Interfaces; +using Api.Services; namespace Api.Controllers { @@ -21,7 +23,8 @@ namespace Api.Controllers string truePassword = _configuration.GetSection("AppSettings:AppPassword").Value; if (appPath == null || !System.IO.File.Exists(appPath)) return BadRequest("Aplikacija ne postoji"); - if (password == null || password!=truePassword) + + if (password == null || !UserService.checkPassword(password,truePassword)) return BadRequest("Pogresna sifra"); return File(System.IO.File.ReadAllBytes(appPath), "application/octet-stream", Path.GetFileName(appPath)); } diff --git a/Backend/Api/Api/appsettings.json b/Backend/Api/Api/appsettings.json index d212dda..a3ef323 100644 --- a/Backend/Api/Api/appsettings.json +++ b/Backend/Api/Api/appsettings.json @@ -4,7 +4,7 @@ "EmailToken": "e8X8c0lm9KS7itWi3wgE6BiPXR21WPvO", "MapQuestApiKey": "47oeviBUoCI2JxWzNARmCtrH9fDp5Mtk", //msbs#556ASDFGGSGSD "AppName": "app-debug.apk", - "AppPassword": "jabukakruska123" + "AppPassword": "$2a$10$fq/JWx7ZZ8wVAgwwrS6O9OMtkD7QsAil7ugjE6c0mM1RTTU92bZ/C" }, "Logging": { -- cgit v1.2.3 From a2e36b576eac1f3f7ef6ec185abbb6a7203e0d08 Mon Sep 17 00:00:00 2001 From: Ognjen Cirkovic Date: Fri, 11 Nov 2022 18:38:51 +0100 Subject: Ispravljena stranica za preuzimanje apk. --- Backend/Api/Api/Assets/appDownload.html | 2 +- Backend/Api/Api/Controllers/appController.cs | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) (limited to 'Backend/Api') diff --git a/Backend/Api/Api/Assets/appDownload.html b/Backend/Api/Api/Assets/appDownload.html index 0d18e98..110ddf8 100644 --- a/Backend/Api/Api/Assets/appDownload.html +++ b/Backend/Api/Api/Assets/appDownload.html @@ -2,7 +2,7 @@ - Verification Successful + Preuzimanje apk
diff --git a/Backend/Api/Api/Controllers/appController.cs b/Backend/Api/Api/Controllers/appController.cs index ed83231..30c7e33 100644 --- a/Backend/Api/Api/Controllers/appController.cs +++ b/Backend/Api/Api/Controllers/appController.cs @@ -33,8 +33,6 @@ namespace Api.Controllers { var html = await System.IO.File.ReadAllTextAsync(@"./Assets/appDownload.html"); - html = html.Replace("{{name}}", "test"); - return base.Content(html, "text/html"); } -- cgit v1.2.3 From d99efbee1431d49152954ca6398fe0b060aa3580 Mon Sep 17 00:00:00 2001 From: "branislav.radivojevic" Date: Sat, 12 Nov 2022 18:44:46 +0100 Subject: search location by name and coord,filter posts --- Backend/Api/Api/Controllers/LocationController.cs | 19 +++++++ Backend/Api/Api/Controllers/PostController.cs | 11 ++++ Backend/Api/Api/Interfaces/ILocationService.cs | 2 + Backend/Api/Api/Interfaces/IPostService.cs | 2 + Backend/Api/Api/Models/Location.cs | 16 ++++++ Backend/Api/Api/Models/Post.cs | 24 +++++++++ Backend/Api/Api/Services/LocationService.cs | 54 +++++++++++++++++++ Backend/Api/Api/Services/PostService.cs | 65 ++++++++++++++++++++++- 8 files changed, 191 insertions(+), 2 deletions(-) (limited to 'Backend/Api') diff --git a/Backend/Api/Api/Controllers/LocationController.cs b/Backend/Api/Api/Controllers/LocationController.cs index bb0b0ab..c9ef9ba 100644 --- a/Backend/Api/Api/Controllers/LocationController.cs +++ b/Backend/Api/Api/Controllers/LocationController.cs @@ -50,5 +50,24 @@ namespace Api.Controllers } return BadRequest(); } + + [HttpPost("search")] + [Authorize(Roles = "User")] + public async Task>> searchLocation(int searchtype ,string? query,Coords? coords) + { + List ret = new List(); + switch (searchtype) + { + case 1: + ret = await _locationService.SearchLocation(query); + return Ok(ret); + case 2: + ret = await _locationService.SearchLocation(coords); + return Ok(ret); + default: + ret = await _locationService.SearchLocation(query); + return Ok(ret); + } + } } } diff --git a/Backend/Api/Api/Controllers/PostController.cs b/Backend/Api/Api/Controllers/PostController.cs index 3857ce0..3faaa62 100644 --- a/Backend/Api/Api/Controllers/PostController.cs +++ b/Backend/Api/Api/Controllers/PostController.cs @@ -116,5 +116,16 @@ namespace Api.Controllers return Ok(); return BadRequest(); } + [HttpGet("locations/{id}/posts")] + [Authorize(Roles = "User")] + public async Task>> searchPosts(string id,int page=0,int sorttype=1,int filterdate=1) + { + var res = await _postService.SearchPosts(id,page,sorttype,filterdate); + if (res != null) + { + return Ok(res); + } + return BadRequest(); + } } } diff --git a/Backend/Api/Api/Interfaces/ILocationService.cs b/Backend/Api/Api/Interfaces/ILocationService.cs index 16e00a0..b115fdf 100644 --- a/Backend/Api/Api/Interfaces/ILocationService.cs +++ b/Backend/Api/Api/Interfaces/ILocationService.cs @@ -7,5 +7,7 @@ namespace Api.Interfaces Task add(Location loc); Task getById(string id); Task> getAllLocation(); + Task> SearchLocation(Coords coords); + Task> SearchLocation(string query); } } \ No newline at end of file diff --git a/Backend/Api/Api/Interfaces/IPostService.cs b/Backend/Api/Api/Interfaces/IPostService.cs index daeee92..0274b26 100644 --- a/Backend/Api/Api/Interfaces/IPostService.cs +++ b/Backend/Api/Api/Interfaces/IPostService.cs @@ -15,5 +15,7 @@ namespace Api.Interfaces Task> CascadeComments(string parentid, Post p); Task DeleteComments(string postid, string cmntid,string userid); Task CascadeDeleteComments(string cmntid, Post p); + Task SearchPosts(string locid, int page = 0, int sorttype = 1, int filterdate = 1); + int DateEnumToDays(int filterdate); } } \ No newline at end of file diff --git a/Backend/Api/Api/Models/Location.cs b/Backend/Api/Api/Models/Location.cs index 7c1a0bf..3402f6c 100644 --- a/Backend/Api/Api/Models/Location.cs +++ b/Backend/Api/Api/Models/Location.cs @@ -25,4 +25,20 @@ namespace Api.Models PLANINA, VISORAVAN, PIRAMIDA, LIVADA, SELO, OSTRVO, POLUOSTRVO, KLISURA, ARHIPELAG, ADA, DELTA, FJORD, GEJZIR, IZVOR, KOTLINA, MINERALNI_IZVOR, PECINA ,SUMA, VODOPAD,VULKAN } + + public class Coords + { + public double latitude { get; set; } + public double longitude { get; set; } + } + public enum SearchType + { + BY_NAME = 1 , + BY_COORDS =2 + } + public class LocationViews + { + public Location location { get; set; } + public int views { get; set; } + } } diff --git a/Backend/Api/Api/Models/Post.cs b/Backend/Api/Api/Models/Post.cs index c832d23..8099d6c 100644 --- a/Backend/Api/Api/Models/Post.cs +++ b/Backend/Api/Api/Models/Post.cs @@ -12,6 +12,7 @@ namespace Api.Models public string ownerId { get; set; } public string locationId { get; set; } public string description { get; set; } + public DateTime createdAt { get; set; } public List views { get; set; } public List reports { get; set; } public List ratings { get; set; } @@ -33,6 +34,7 @@ namespace Api.Models public string ownerId { get; set; } public Location location { get; set; } public string description { get; set; } + public DateTime createdAt { get; set; } public int views { get; set; } public double ratings { get; set; } public List comments { get; set; } @@ -74,4 +76,26 @@ namespace Api.Models public string comment { get; set; } public string parentId { get; set; } } + public enum SortType + { + VIEWS_DESC=1, + RATING_DESC=2, + DATE =3 + } + public enum FilterDate + { + ALL =1, + ONE_YEAR=2 , + THREE_MONTHS=3 , + ONE_MONTH=4 , + ONE_WEEK=5 + } + public class PostSendPage + { + public int page { get; set; } + public int index { get; set; } + public int totalpages { get; set; } + public int totalposts { get; set; } + public List posts { get; set; } + } } diff --git a/Backend/Api/Api/Services/LocationService.cs b/Backend/Api/Api/Services/LocationService.cs index e244ed6..c91a1b5 100644 --- a/Backend/Api/Api/Services/LocationService.cs +++ b/Backend/Api/Api/Services/LocationService.cs @@ -3,7 +3,9 @@ using Api.Models; using Geocoding; using Geocoding.Google; using Geocoding.MapQuest; +using MongoDB.Bson; using MongoDB.Driver; +using System.Text.RegularExpressions; using ZstdSharp.Unsafe; using Location = Api.Models.Location; @@ -16,10 +18,12 @@ namespace Api.Services private readonly IHttpContextAccessor _httpContext; private IConfiguration _configuration; private MapQuestGeocoder _geocoder; + private readonly IMongoCollection _posts; public LocationService(IDatabaseConnection settings, IMongoClient mongoClient, IConfiguration configuration) { var database = mongoClient.GetDatabase(settings.DatabaseName); _locations = database.GetCollection(settings.LocationCollectionName); + _posts = database.GetCollection(settings.PostCollectionName); _configuration = configuration; var _mapQuestApiKey = _configuration.GetSection("AppSettings:MapQuestApiKey").Value; _geocoder = new MapQuestGeocoder(_mapQuestApiKey); @@ -43,5 +47,55 @@ namespace Api.Services { return await _locations.Find(_=>true).ToListAsync(); } + + public async Task> SearchLocation(Coords coords) // returns all locations within coord radius 1/5th of a degree of lat and long + { + if (coords == null) + return null; + var lista = await _locations.Find(_ => true).ToListAsync(); + var tosend = new List(); + if (lista != null) + { + foreach (var elem in lista) + { + if (Math.Abs(elem.latitude - coords.latitude) < 0.2 && Math.Abs(elem.longitude - coords.longitude) < 0.2) + tosend.Add(elem); + } + } + return tosend; + } + public async Task> SearchLocation(string query) //returns 10 (n) most relevant locations when searching by name + { + if (query == null) query = ""; + else query = query.ToLower(); + var lista = await _locations.Find(x => x.name.ToLower().Contains(query)).ToListAsync(); + var tosend = new List(); + if (lista != null) + { + var locviews = new List(); + foreach (var elem in lista) + { + var totalviews = 0; + var posts = await _posts.Find(x => x.locationId == elem._id).ToListAsync(); + if(posts != null) + { + foreach(var post in posts) + { + totalviews += post.views.Count(); + } + } + var novi = new LocationViews(); + novi.location = elem; + novi.views = totalviews; + locviews.Add(novi); + } + var top10 = locviews.OrderByDescending(x => x.views).Take(10).ToList(); + foreach(var view in top10) + { + tosend.Add(view.location); + } + } + return tosend; + } } } diff --git a/Backend/Api/Api/Services/PostService.cs b/Backend/Api/Api/Services/PostService.cs index 78167bd..a0b2941 100644 --- a/Backend/Api/Api/Services/PostService.cs +++ b/Backend/Api/Api/Services/PostService.cs @@ -38,7 +38,7 @@ namespace Api.Services p.ratings = new List(); p.comments = new List(); p.images = new List(); - + p.createdAt = DateTime.Now.ToUniversalTime(); var folderPath = Path.Combine(Directory.GetCurrentDirectory(), "Files", p.ownerId); if (!Directory.Exists(folderPath)) { @@ -75,13 +75,13 @@ namespace Api.Services public async Task postToPostSend(Post post) { PostSend p = new PostSend(); - //Convert post to post send (TODO) p._id = post._id; p.ownerId = post.ownerId; p.description = post.description; p.location = await _locationService.getById(post.locationId); p.images = post.images; p.views = post.views.Count(); + p.createdAt = post.createdAt; if (post.ratings.Count() > 0) { List ratings = new List(); @@ -275,5 +275,66 @@ namespace Api.Services } } } + public async Task SearchPosts(string locid,int page = 0,int sorttype = 1 ,int filterdate = 1) // for now sorting by number of ratings , not avg rating + { + var days = DateEnumToDays(filterdate); + var tosend = new PostSendPage(); + var pslista = new List(); + var lista = new List(); + var ls = new List(); + var xd = new List(); + lista = await _posts.Find(x => x.locationId == locid).ToListAsync(); + if (lista != null) + { + foreach (var elem in lista) + { + if ((DateTime.Now - elem.createdAt).TotalDays < days) + ls.Add(await postToPostSend(elem)); + } + + } + switch (sorttype) + { + case 1: + xd = ls.OrderByDescending(x => x.views).ToList(); + break; + case 2: + xd = ls.OrderByDescending(x => x.ratings).ToList(); + break; + case 3: + xd = ls.OrderByDescending(x => x.createdAt).ToList(); + break; + default: + + break; + } + if(xd != null) + { + tosend.page = page; + tosend.index = page * 20; + tosend.totalposts = xd.Count(); + double pgs = xd.Count / 20; + tosend.totalpages = (int)Math.Ceiling(pgs); + var selected = ls.Skip(20 * page).Take(20); + foreach(var post in selected) + { + pslista.Add(post); + } + tosend.posts = pslista; + } + return tosend; + } + public int DateEnumToDays(int filterdate) + { + switch(filterdate) + { + case 1: return 365 * 10; + case 2: return 365; + case 3: return 90; + case 4: return 30; + case 5: return 7; + default: return 365 * 10; + } + } } } -- 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 (limited to 'Backend/Api') 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(-) (limited to 'Backend/Api') 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(-) (limited to 'Backend/Api') 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 b5b888192b8d5b6a477afd153d067bbc36f25def Mon Sep 17 00:00:00 2001 From: "branislav.radivojevic" 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(-) (limited to 'Backend/Api') 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(-) (limited to 'Backend/Api') 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