diff options
| author | TAMARA JERINIC <tamara.jerinic@gmail.com> | 2022-11-14 23:29:19 +0100 | 
|---|---|---|
| committer | TAMARA JERINIC <tamara.jerinic@gmail.com> | 2022-11-14 23:29:19 +0100 | 
| commit | f7bd4d189a2fa635bb4b156381a7b105bf75ab6d (patch) | |
| tree | 824e3ac8f4afc91d9a4013f6605ac364dac775a6 | |
| parent | d98ff2f7d8a15793b5cc92bd430160c53eb3f8ca (diff) | |
| parent | 81fae5e55c7a2b5a1ddc8055d32bc310e22e014d (diff) | |
Merge branch 'develop' of http://gitlab.pmf.kg.ac.rs/BrzoDoLokacije2022/odyssey/brzodolokacije into develop
# Conflicts:
#	Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentProfile.kt
#	Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentUserPosts.kt
#	Client/BrzoDoLokacije/app/src/main/res/layout/fragment_user_posts.xml
43 files changed, 706 insertions, 85 deletions
| 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<ActionResult> addComment([FromBody] CommentReceive cmnt,string id) +        public async Task<ActionResult<Comment>> 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..1ef8234 --- /dev/null +++ b/Backend/Api/Api/Controllers/UserController.cs @@ -0,0 +1,59 @@ +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; +        private readonly IPostService _postService; +        public UserController(IUserService userService, IJwtService jwtService, IPostService postService) +        { +            _userService = userService; +            _jwtService = jwtService; +            _postService = postService; +        } +        [HttpPost("profile/pfp")] +        [Authorize(Roles = "User")] +        public async Task<ActionResult<User>> setPfp([FromForm]IFormFile image) +        { +            var id = await _userService.UserIdFromJwt(); +            if(await _userService.AddOrChangePfp(id,image)) +                return Ok(); +            return BadRequest(); +        } +        [HttpGet("profile")] +        [Authorize(Roles = "User")] +        public async Task<ActionResult<UserSend>> 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<ActionResult<UserSend>> GetProfile(string username) +        { +            var rez =  await _userService.GetUserData(username); +            if (rez != null) +                return Ok(rez); +            return BadRequest(); +        } +        [HttpGet("posts")] +        [Authorize(Roles = "User")]  +        public async Task<ActionResult<List<PostSend>>> 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 0274b26..fc2ae03 100644 --- a/Backend/Api/Api/Interfaces/IPostService.cs +++ b/Backend/Api/Api/Interfaces/IPostService.cs @@ -10,12 +10,13 @@ namespace Api.Interfaces          Task<PostSend> postToPostSend(Post post);          Task<Boolean> AddOrReplaceRating(RatingReceive rating, string userid);          Task<Boolean> RemoveRating(string postid, string userid); -        Task<Boolean> AddComment(CommentReceive cmnt, string userid, string postid); +        Task<Comment> AddComment(CommentReceive cmnt, string userid, string postid);          Task<List<CommentSend>> ListComments(string postid);          Task<List<CommentSend>> CascadeComments(string parentid, Post p);          Task<Boolean> DeleteComments(string postid, string cmntid,string userid);          Task CascadeDeleteComments(string cmntid, Post p);          Task<PostSendPage> SearchPosts(string locid, int page = 0, int sorttype = 1, int filterdate = 1);          int DateEnumToDays(int filterdate); +        Task<List<PostSend>> GetUsersPosts(string id);      }  }
\ No newline at end of file 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<Boolean> ResetPassword(ResetPass rp);          Task<Boolean> CheckVerification(Login login);          Task<Boolean> VerifyFromToken(string token); - +        Task<Boolean> AddOrChangePfp(string userid, IFormFile image); +        Task<UserSend> GetUserData(string username); +        Task<UserSend> GetSelfUserData(string id);      }  } diff --git a/Backend/Api/Api/Models/User.cs b/Backend/Api/Api/Models/User.cs index a1fe149..2e323a8 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,14 @@ 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; } +        public int postcount { get; set; } +    }  } diff --git a/Backend/Api/Api/Services/PostService.cs b/Backend/Api/Api/Services/PostService.cs index a0b2941..2d62f49 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<Boolean> AddComment(CommentReceive cmnt,string userid,string postid) +        public async Task<Comment> 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<List<CommentSend>> ListComments(string postid) @@ -336,5 +336,18 @@ namespace Api.Services                  default: return 365 * 10;              }          } +        public async Task<List<PostSend>> GetUsersPosts(string id) +        { +            var userposts = await _posts.Find(x => x.ownerId == id).ToListAsync(); +            if (userposts == null) +                return null; +            var tosend = new List<PostSend>(); +            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 5fd61f6..33e6d11 100644 --- a/Backend/Api/Api/Services/UserService.cs +++ b/Backend/Api/Api/Services/UserService.cs @@ -12,15 +12,19 @@ namespace Api.Services      {          private readonly IHttpContextAccessor _httpContext;          private readonly IMongoCollection<User> _users; +        private readonly IMongoCollection<Post> _posts;          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<User>(settings.UserCollectionName); +            _posts = database.GetCollection<Post>(settings.PostCollectionName);              _jwtService = jwtService;              this._httpContext = httpContextAccessor;              this._configuration = configuration; +            _fileService = fileService;          }          public async Task<int> createUser(User user) @@ -311,5 +315,65 @@ namespace Api.Services              }              return false;          } + +        public async Task<Boolean> 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 =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<UserSend> GetUserData(string username) +        { +            var user = await _users.Find(x => x.username == username).FirstOrDefaultAsync(); +            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; +            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<UserSend> GetSelfUserData(string id) +        { +            var user = await _users.Find(x => x._id == id).FirstOrDefaultAsync(); +            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; +            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; +        }      }  } diff --git a/Client/BrzoDoLokacije/.idea/deploymentTargetDropDown.xml b/Client/BrzoDoLokacije/.idea/deploymentTargetDropDown.xml new file mode 100644 index 0000000..748026e --- /dev/null +++ b/Client/BrzoDoLokacije/.idea/deploymentTargetDropDown.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> +  <component name="deploymentTargetDropDown"> +    <targetSelectedWithDropDown> +      <Target> +        <type value="QUICK_BOOT_TARGET" /> +        <deviceKey> +          <Key> +            <type value="VIRTUAL_DEVICE_PATH" /> +            <value value="C:\Users\TAMARA\.android\avd\Pixel_3a_XL_API_33.avd" /> +          </Key> +        </deviceKey> +      </Target> +    </targetSelectedWithDropDown> +    <timeTargetWasSelectedWithDropDown value="2022-11-14T22:24:25.011085400Z" /> +  </component> +</project>
\ No newline at end of file diff --git a/Client/BrzoDoLokacije/app/build.gradle b/Client/BrzoDoLokacije/app/build.gradle index 63d28a8..db4ed1b 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'      implementation 'androidx.legacy:legacy-support-v4:1.0.0'      implementation 'androidx.recyclerview:recyclerview:1.2.1'      testImplementation 'junit:junit:4.13.2' 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 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" +    android:width="24dp" +    android:height="24dp" +    android:viewportWidth="24" +    android:viewportHeight="24" +    android:tint="#333333" +    android:alpha="0.6"> +  <path +      android:fillColor="@android:color/white" +      android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM17,13h-4v4h-2v-4L7,13v-2h4L11,7h2v4h4v2z"/> +</vector> 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 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" +    android:width="24dp" +    android:height="24dp" +    android:viewportWidth="24" +    android:viewportHeight="24" +    android:tint="#1C789A" +    android:alpha="0.8"> +  <path +      android:fillColor="@android:color/white" +      android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM17,13h-4v4h-2v-4L7,13v-2h4L11,7h2v4h4v2z"/> +</vector> 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 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" +    android:width="24dp" +    android:height="24dp" +    android:viewportWidth="24" +    android:viewportHeight="24" +    android:tint="#1C789A" +    android:alpha="0.8"> +  <group android:scaleX="1.2" +      android:scaleY="1.2" +      android:translateX="-2.4" +      android:translateY="-2.4"> +    <path +        android:fillColor="@android:color/white" +        android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM17,13h-4v4h-2v-4L7,13v-2h4L11,7h2v4h4v2z"/> +  </group> +</vector> 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.pngBinary files differ new file mode 100644 index 0000000..ac7f48c --- /dev/null +++ b/Client/BrzoDoLokacije/app/src/debug/res/drawable-hdpi/add_profile_picture_plus.png 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.pngBinary files differ new file mode 100644 index 0000000..c58371e --- /dev/null +++ b/Client/BrzoDoLokacije/app/src/debug/res/drawable-hdpi/add_profile_picture_plus_color.png 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.pngBinary files differ new file mode 100644 index 0000000..74786ad --- /dev/null +++ b/Client/BrzoDoLokacije/app/src/debug/res/drawable-hdpi/add_profile_picture_plus_color_1.png 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.pngBinary files differ new file mode 100644 index 0000000..e853535 --- /dev/null +++ b/Client/BrzoDoLokacije/app/src/debug/res/drawable-mdpi/add_profile_picture_plus.png 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.pngBinary files differ new file mode 100644 index 0000000..62eeb35 --- /dev/null +++ b/Client/BrzoDoLokacije/app/src/debug/res/drawable-mdpi/add_profile_picture_plus_color.png 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.pngBinary files differ new file mode 100644 index 0000000..eb81643 --- /dev/null +++ b/Client/BrzoDoLokacije/app/src/debug/res/drawable-mdpi/add_profile_picture_plus_color_1.png 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.pngBinary files differ new file mode 100644 index 0000000..66fa4aa --- /dev/null +++ b/Client/BrzoDoLokacije/app/src/debug/res/drawable-xhdpi/add_profile_picture_plus.png 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.pngBinary files differ new file mode 100644 index 0000000..6cad473 --- /dev/null +++ b/Client/BrzoDoLokacije/app/src/debug/res/drawable-xhdpi/add_profile_picture_plus_color.png 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.pngBinary files differ new file mode 100644 index 0000000..35f6294 --- /dev/null +++ b/Client/BrzoDoLokacije/app/src/debug/res/drawable-xhdpi/add_profile_picture_plus_color_1.png 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.pngBinary files differ new file mode 100644 index 0000000..89b14f1 --- /dev/null +++ b/Client/BrzoDoLokacije/app/src/debug/res/drawable-xxhdpi/add_profile_picture_plus.png 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.pngBinary files differ new file mode 100644 index 0000000..a15759e --- /dev/null +++ b/Client/BrzoDoLokacije/app/src/debug/res/drawable-xxhdpi/add_profile_picture_plus_color.png 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.pngBinary files differ new file mode 100644 index 0000000..a0cab62 --- /dev/null +++ b/Client/BrzoDoLokacije/app/src/debug/res/drawable-xxhdpi/add_profile_picture_plus_color_1.png 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<ResponseBody?>, response: Response<ResponseBody?>) {                  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/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 08d0fdd..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 @@ -3,29 +3,35 @@ 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.KeyEvent  import android.view.LayoutInflater  import android.view.View +import android.view.View.OnKeyListener  import android.view.ViewGroup -import android.widget.Button -import android.widget.EditText  import android.widget.Toast  import androidx.core.app.ActivityCompat  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.button.MaterialButton  import com.google.android.material.floatingactionbutton.FloatingActionButton +import com.google.android.material.textfield.TextInputEditText  import org.osmdroid.config.Configuration  import org.osmdroid.tileprovider.tilesource.TileSourceFactory  import org.osmdroid.util.GeoPoint  import org.osmdroid.views.MapView +import org.osmdroid.views.overlay.Marker  import org.osmdroid.views.overlay.ScaleBarOverlay  import org.osmdroid.views.overlay.compass.CompassOverlay  import org.osmdroid.views.overlay.compass.InternalCompassOrientationProvider @@ -41,8 +47,11 @@ class FragmentBrowse : Fragment(R.layout.fragment_browse) {      var mRotationGestureOverlay:RotationGestureOverlay?=null      var mScaleBarOverlay: ScaleBarOverlay?=null      var mCompassOverlay:CompassOverlay?=null -    private lateinit var searchButton:FloatingActionButton -    private lateinit var searchBar: EditText +    private lateinit var locationManager: LocationManager +    private lateinit var searchButton: MaterialButton +    private lateinit var gpsButton:FloatingActionButton +    private lateinit var searchBar: TextInputEditText +    var client: FusedLocationProviderClient? = null      override fun onCreate(savedInstanceState: Bundle?) {          super.onCreate(savedInstanceState) @@ -59,13 +68,27 @@ class FragmentBrowse : Fragment(R.layout.fragment_browse) {          map=v.findViewById(R.id.FragmentBrowseMapView) as MapView          map!!.setTileSource(TileSourceFactory.MAPNIK);          setUpMap() -        searchButton=v.findViewById<View>(R.id.FragmentBrowseSearchButton) as FloatingActionButton -        searchBar=v.findViewById<View>(R.id.FragmentBrowseSearchBar) as EditText - +        searchButton=v.findViewById<View>(R.id.FragmentBrowseSearchButton) as MaterialButton +        gpsButton=v.findViewById<View>(R.id.FragmentBrowseMyLocation) as FloatingActionButton +        searchBar=v.findViewById<View>(R.id.FragmentBrowseSearchBar) as TextInputEditText +        client=LocationServices.getFusedLocationProviderClient(requireActivity())          searchButton.setOnClickListener{              searchMap() -        } +        } +        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      } @@ -150,12 +173,127 @@ 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)              }          }      } +    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<String?>, +        grantResults: IntArray +    ) { +        super.onRequestPermissionsResult( +            requestCode, permissions, grantResults +        ) +        // Check condition +        if (requestCode == 111 && grantResults.size > 0 +            && (grantResults[0] + grantResults[1] +                    == PackageManager.PERMISSION_GRANTED) +        ) { +            // When permission are granted +            // Call  method +            getCurrentLocation() +        } else { +            // When permission are denied +            // Display toast +            Toast +                .makeText( +                    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/java/com/example/brzodolokacije/Fragments/FragmentProfile.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentProfile.kt index bad3598..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 @@ -1,15 +1,30 @@  package com.example.brzodolokacije.Fragments +import android.content.Intent +import android.net.Uri  import android.os.Bundle -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.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 @@ -36,6 +51,8 @@ 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 +    private lateinit var profilePicturePlus: ShapeableImageView      override fun onCreateView(          inflater: LayoutInflater, container: ViewGroup?,          savedInstanceState: Bundle? @@ -50,16 +67,15 @@ class FragmentProfile : Fragment(R.layout.fragment_profile) {          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 ShapeableImageView +        profilePicturePlus=view.findViewById<View>(R.id.tvFragmentProfileProfilePicturePlus) as ShapeableImageView          //podaci iz baze          showMyPosts.setOnClickListener{ -            var fm: FragmentTransaction =childFragmentManager.beginTransaction() - -            fm.replace(R.id.flFragmentProfileFragmentContainer, FragmentUserPosts()) -            fm.commit() +            openMyPosts()          } @@ -72,15 +88,108 @@ class FragmentProfile : Fragment(R.layout.fragment_profile) {          }          showMyRecensions.setOnClickListener{ - +            getProfileInfo()              var fm: FragmentTransaction =childFragmentManager.beginTransaction()              fm.replace(R.id.flFragmentProfileFragmentContainer, FragmentMyRecensions())              fm.commit()          } - +        profilePicturePlus.setOnClickListener{ +            addProfilePicture() +        } +        profilePicture.setOnClickListener{ +            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) +        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<ResponseBody?> { +            override fun onResponse(call: Call<ResponseBody?>, response: Response<ResponseBody?>) { +                if(response.isSuccessful()){ +                   getProfileInfo() +                }else{ +                    if(response.errorBody()!=null) +                        Toast.makeText(activity, response.errorBody()!!.string(), Toast.LENGTH_LONG).show(); +                } +            } +            override fun onFailure(call: Call<ResponseBody?>, 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()) +        val request=authApi.selfProfile("Bearer "+token) + +        request.enqueue(object : retrofit2.Callback<UserReceive?> { +            override fun onResponse(call: Call<UserReceive?>, response: Response<UserReceive?>) { +                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<UserReceive?>, t: Throwable) { +                Toast.makeText( +                    activity, t.toString(), Toast.LENGTH_LONG +                ).show(); +            } +        }) +    } +    private fun setUserInfo(user:UserReceive){ +        name.setText(user.name) +        username.setText("@"+user.username) +        postsCount.setText(user.postcount.toString()) + +        followersCount.setText("to do") +        followingCount.setText("to do") + +        //Add Profile image +        if(user.pfp!=null) { +            Glide.with(requireActivity()) +                .load(RetrofitHelper.baseUrl + "/api/post/image/" + user.pfp!!._id) +                .circleCrop()//Round image +                .into(profilePicture) +        } +    }  }
\ No newline at end of file diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentUserPosts.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentUserPosts.kt index fb90be7..f1f2257 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 @@ -6,27 +6,53 @@ import androidx.fragment.app.Fragment  import android.view.LayoutInflater  import android.view.View  import android.view.ViewGroup +import androidx.recyclerview.widget.GridLayoutManager +import androidx.recyclerview.widget.RecyclerView +import com.example.brzodolokacije.Adapters.ShowPostsAdapter +import com.example.brzodolokacije.Models.PostPreview +import com.example.brzodolokacije.Services.RetrofitHelper +import com.example.brzodolokacije.Services.SharedPreferencesHelper +import com.google.android.material.button.MaterialButton +import retrofit2.Call +import retrofit2.Callback +import retrofit2.Response + + +import android.widget.Toast +import androidx.core.content.ContextCompat +import androidx.recyclerview.widget.DividerItemDecoration +import androidx.recyclerview.widget.LinearLayoutManager +import com.example.brzodolokacije.Adapters.ShowPostsHomePageAdapter +import com.example.brzodolokacije.Interfaces.IBackendApi +import com.example.brzodolokacije.R + +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory  import android.widget.Button  import android.widget.ImageButton  import android.widget.TextView -import android.widget.Toast  import com.example.brzodolokacije.Activities.ActivityAddPost  import com.example.brzodolokacije.Activities.ActivityCapturePost  import com.example.brzodolokacije.Activities.ActivityForgottenPassword -import com.example.brzodolokacije.R +  import com.google.android.material.bottomsheet.BottomSheetDialog +  class FragmentUserPosts : Fragment() { -    private lateinit var addNewPost: TextView +    private lateinit var posts : MutableList<PostPreview> +    private lateinit var rvPosts: RecyclerView +    private lateinit var addNewPost:TextView +    override fun onCreate(savedInstanceState: Bundle?) { +        super.onCreate(savedInstanceState) + +    }      override fun onCreateView(          inflater: LayoutInflater, container: ViewGroup?,          savedInstanceState: Bundle?      ): View? { -        // Inflate the layout for this fragment +          val view =inflater.inflate(R.layout.fragment_user_posts, container, false) -//        Toast.makeText( -//            activity, "****************USER*****************", Toast.LENGTH_LONG -//        ).show(); +          addNewPost=view.findViewById<View>(R.id.tvFragmentUserPostsAddPost) as TextView          addNewPost.setOnClickListener {              var bottomSheetDialog2: BottomSheetDialog @@ -52,7 +78,38 @@ class FragmentUserPosts : Fragment() {              }          } +        rvPosts=view.findViewById(R.id.rvFragmentUserPostsPosts) as RecyclerView +        getPosts()          return view      } +    fun getPosts(){ +        val api = RetrofitHelper.getInstance() +        val token= SharedPreferencesHelper.getValue("jwt", requireActivity()) +        val data=api.getMyPosts("Bearer "+token) + +        data.enqueue(object : Callback<MutableList<PostPreview>> { +            override fun onResponse( +                call: Call<MutableList<PostPreview>>, +                response: Response<MutableList<PostPreview>> +            ) { +                if (response.body() == null) { +                    return +                } +                posts = response.body()!!.toMutableList<PostPreview>() +                loadPosts() +            } +            override fun onFailure(call: Call<MutableList<PostPreview>>, t: Throwable) { + +            } +        }) +    } +    private fun loadPosts(){//most viewed +        rvPosts.apply { +            layoutManager= GridLayoutManager(requireContext(),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 cd23a65..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 @@ -43,6 +43,17 @@ interface IBackendApi {      fun getComments(@Header("Authorization") authHeader:String,@Path("id") id:String):Call<MutableList<CommentSend>> +    @Multipart +    @POST("/api/user/profile/pfp") +    fun setPfp(@Header("Authorization") authHeader:String, @Part image: MultipartBody.Part):Call<ResponseBody> +    @GET("/api/user/profile") +    fun selfProfile(@Header("Authorization") authHeader:String):Call<UserReceive> +    @GET("/api/user/{username}/profile") +    fun getProfile(@Header("Authorization") authHeader:String,@Path("username") username:String):Call<UserReceive> + +    @GET("/api/user/posts") +    fun getMyPosts(@Header("Authorization") authHeader:String):Call<MutableList<PostPreview>> +  //@POST("putanja")      //fun add(@Body obj:Post,@Header("Authorization") authHeader:String):Call<Post>  }
\ 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..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 @@ -20,4 +20,13 @@ data class User (      var postIds:List<Int>,      var postNumber:Int +) +data class UserReceive( +    var _id:String, +    var name:String, +    var username:String, +    var email:String, +    var creationDate: Date, +    var pfp:PostImage?, +    var postcount:Int  )
\ No newline at end of file diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Services/RetrofitHelper.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Services/RetrofitHelper.kt index 43c2109..88685e4 100644 --- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Services/RetrofitHelper.kt +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Services/RetrofitHelper.kt @@ -7,8 +7,8 @@ import retrofit2.converter.gson.GsonConverterFactory  object RetrofitHelper { -    val baseUrl="http://10.0.2.2:5279" -    //val baseUrl="http://147.91.204.115:10082" +    //val baseUrl="http://10.0.2.2:5279" +    val baseUrl="http://147.91.204.115:10082"      private var retrofit_noauth: IBackendApi? = null      private var retrofit_auth: IBackendApi? = null diff --git a/Client/BrzoDoLokacije/app/src/main/res/drawable/filter.png b/Client/BrzoDoLokacije/app/src/main/res/drawable/filter.pngBinary files differ index 4342c2c..745a5e8 100644 --- a/Client/BrzoDoLokacije/app/src/main/res/drawable/filter.png +++ b/Client/BrzoDoLokacije/app/src/main/res/drawable/filter.png diff --git a/Client/BrzoDoLokacije/app/src/main/res/drawable/grid.png b/Client/BrzoDoLokacije/app/src/main/res/drawable/grid.pngBinary files differ deleted file mode 100644 index 03d9ef9..0000000 --- a/Client/BrzoDoLokacije/app/src/main/res/drawable/grid.png +++ /dev/null diff --git a/Client/BrzoDoLokacije/app/src/main/res/drawable/grid_full.png b/Client/BrzoDoLokacije/app/src/main/res/drawable/grid_full.pngBinary files differ new file mode 100644 index 0000000..9bed50a --- /dev/null +++ b/Client/BrzoDoLokacije/app/src/main/res/drawable/grid_full.png diff --git a/Client/BrzoDoLokacije/app/src/main/res/drawable/list_empty.png b/Client/BrzoDoLokacije/app/src/main/res/drawable/list_empty.pngBinary files differ new file mode 100644 index 0000000..3568c49 --- /dev/null +++ b/Client/BrzoDoLokacije/app/src/main/res/drawable/list_empty.png diff --git a/Client/BrzoDoLokacije/app/src/main/res/drawable/post_comment.webp b/Client/BrzoDoLokacije/app/src/main/res/drawable/post_comment.webpBinary files differ new file mode 100644 index 0000000..fc677d1 --- /dev/null +++ b/Client/BrzoDoLokacije/app/src/main/res/drawable/post_comment.webp diff --git a/Client/BrzoDoLokacije/app/src/main/res/drawable/sort.png b/Client/BrzoDoLokacije/app/src/main/res/drawable/sort.pngBinary files differ index 828cd01..b4fd960 100644 --- a/Client/BrzoDoLokacije/app/src/main/res/drawable/sort.png +++ b/Client/BrzoDoLokacije/app/src/main/res/drawable/sort.png 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 @@              <ImageButton                  android:id="@+id/rateStar1" -                android:layout_width="24dp" -                android:layout_height="24dp" +                android:layout_width="30dp" +                android:layout_height="40dp" +                android:layout_gravity="center_vertical"                  android:scaleType="centerCrop"                  android:layout_weight="1"                  android:backgroundTint="@color/white" @@ -183,8 +184,9 @@              <ImageButton                  android:id="@+id/rateStar2" -                android:layout_width="24dp" -                android:layout_height="24dp" +                android:layout_width="30dp" +                android:layout_height="40dp" +                android:layout_gravity="center_vertical"                  android:scaleType="centerCrop"                  android:layout_weight="1"                  android:backgroundTint="@color/white" @@ -192,8 +194,9 @@              <ImageButton                  android:id="@+id/rateStar3" -                android:layout_width="24dp" -                android:layout_height="24dp" +                android:layout_width="30dp" +                android:layout_height="40dp" +                android:layout_gravity="center_vertical"                  android:scaleType="centerCrop"                  android:layout_weight="1"                  android:backgroundTint="@color/white" @@ -201,8 +204,9 @@              <ImageButton                  android:id="@+id/rateStar4" -                android:layout_width="24dp" -                android:layout_height="24dp" +                android:layout_width="30dp" +                android:layout_height="40dp" +                android:layout_gravity="center_vertical"                  android:scaleType="centerCrop"                  android:layout_weight="1"                  android:backgroundTint="@color/white" @@ -210,8 +214,9 @@              <ImageButton                  android:id="@+id/rateStar5" -                android:layout_width="24dp" -                android:layout_height="24dp" +                android:layout_width="30dp" +                android:layout_height="40dp" +                android:layout_gravity="center_vertical"                  android:scaleType="centerCrop"                  android:layout_weight="1"                  android:backgroundTint="@color/white" @@ -219,12 +224,14 @@              <Button                  android:id="@+id/submitRating" -                android:layout_width="wrap_content" -                android:layout_height="wrap_content" +                android:layout_width="30dp" +                android:layout_height="40dp"                  android:layout_weight="1"                  android:backgroundTint="@color/white" -                android:text="oceni" -                android:textColor="@color/black" /> +                android:text="ok" +                android:layout_gravity="center_vertical" +                android:textColor="@color/black" +                />          </LinearLayout>          <androidx.constraintlayout.widget.ConstraintLayout @@ -247,8 +254,11 @@                  <ImageButton                      android:id="@+id/btnPostComment" -                    android:layout_width="wrap_content" -                    android:layout_height="50dp" /> +                    android:layout_width="50dp" +                    android:scaleType="fitCenter" +                    android:layout_height="50dp" +                    android:src="@drawable/post_comment" +                    android:backgroundTint="@color/white"/>              </LinearLayout> @@ -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">              </androidx.recyclerview.widget.RecyclerView>          </androidx.constraintlayout.widget.ConstraintLayout> -      </androidx.constraintlayout.widget.ConstraintLayout>  </androidx.constraintlayout.widget.ConstraintLayout>  </androidx.constraintlayout.widget.ConstraintLayout> 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..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,60 @@          app:layout_constraintBottom_toBottomOf="parent"          app:layout_constraintEnd_toEndOf="parent"          app:layout_constraintStart_toStartOf="parent" -        app:layout_constraintTop_toTopOf="@+id/FragmentBrowseSearchBar" /> - -    <com.google.android.material.textfield.TextInputEditText -        android:id="@+id/FragmentBrowseSearchBar" -        android:layout_width="250dp" -        android:layout_height="55dp" -        android:layout_marginTop="40dp" -        android:background="@drawable/rounded_white_button_login" -        android:ems="10" -        android:hint="  Pretraga" -        android:inputType="textPersonName" -        app:layout_constraintEnd_toEndOf="parent" -        app:layout_constraintStart_toStartOf="parent" -        app:layout_constraintTop_toTopOf="parent" /> +         /> + +      <com.google.android.material.floatingactionbutton.FloatingActionButton -        android:id="@+id/FragmentBrowseSearchButton" +        android:id="@+id/FragmentBrowseMyLocation"          android:layout_width="wrap_content"          android:layout_height="wrap_content"          android:layout_alignParentStart="true"          android:backgroundTint="#FFFFFF" +        android:layout_marginBottom="80dp"          android:clickable="true"          android:focusable="true"          android:tint="#FFFFFF" +        app:layout_constraintBottom_toBottomOf="@+id/FragmentBrowseMapView"          app:layout_constraintEnd_toEndOf="parent" -        app:layout_constraintStart_toEndOf="@+id/FragmentBrowseSearchBar" -        app:layout_constraintTop_toTopOf="@+id/FragmentBrowseSearchBar"          app:rippleColor="#FFFFFF" -        app:srcCompat="@android:drawable/ic_search_category_default" /> +        app:srcCompat="@android:drawable/ic_menu_mylocation" /> + +    <androidx.cardview.widget.CardView +        android:id="@+id/FragmentBrowseCardViewSearch" +        android:layout_width="0dp" +        android:layout_marginTop="60dp" +        android:layout_height="40dp" +        android:layout_marginStart="16dp" +        android:layout_marginEnd="16dp" +        android:elevation="0dp" +        app:cardCornerRadius="20dp" +        app:layout_constraintEnd_toEndOf="parent" +        app:layout_constraintStart_toStartOf="parent" +        app:layout_constraintTop_toTopOf="parent"> + + +        <com.google.android.material.textfield.TextInputEditText +            android:id="@+id/FragmentBrowseSearchBar" +            android:layout_width="match_parent" +            android:layout_height="match_parent" +            android:background="@drawable/rounded_white_button_login" +            android:hint="  Pretraga" +            android:inputType="textPersonName" +            android:paddingLeft="15dp" /> + +        <com.google.android.material.button.MaterialButton +            android:id="@+id/FragmentBrowseSearchButton" +            android:layout_width="49dp" +            android:layout_height="match_parent" +            android:layout_gravity="right" +            android:background="#00FFFFFF" +            app:backgroundTint="#00FFFFFF" +            app:cornerRadius="16dp" +            app:icon="@drawable/ic_baseline_search_24" +            app:iconTint="#333D70" /> + +    </androidx.cardview.widget.CardView>  </androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file diff --git a/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_profile.xml b/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_profile.xml index e7cccff..19e6212 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,7 @@              app:layout_constraintVertical_bias="1.0"              app:shapeAppearanceOverlay="@style/imageViewCircle" /> +          <TableLayout              android:id="@+id/tableLayout"              android:layout_width="323dp" @@ -159,6 +160,7 @@              </TableRow>          </TableLayout> +          <View              android:id="@+id/divider"              android:layout_width="409dp" 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"> -    <EditText -        android:id="@+id/editTextTextPersonName2" -        android:layout_width="wrap_content" -        android:layout_height="50dp" -        android:layout_gravity="center_horizontal" -        android:ems="10" -        android:inputType="textPersonName" -        android:text="Name" /> +    <androidx.cardview.widget.CardView +        android:id="@+id/cvSearch" +        android:layout_width="match_parent" +        android:layout_height="40dp" +        android:layout_marginTop="10dp" +        android:layout_marginStart="16dp" +        android:layout_marginEnd="16dp" +        android:elevation="0dp" +        app:cardCornerRadius="20dp" +        app:layout_constraintEnd_toEndOf="parent" +        app:layout_constraintStart_toStartOf="parent" +        app:layout_constraintTop_toBottomOf="@+id/tvFragmentHomePageSearch"> + + +        <com.google.android.material.textfield.TextInputEditText +            android:id="@+id/etFragmentHomePageSearch" +            android:layout_width="match_parent" +            android:layout_height="match_parent" +            android:background="@drawable/rounded_white_button_login" +            android:hint="  Pretraga" +            android:paddingLeft="15dp" +            android:inputType="textPersonName" /> + +        <com.google.android.material.button.MaterialButton +            android:layout_width="49dp" +            android:layout_height="match_parent" +            android:layout_gravity="right" +            android:background="#00FFFFFF" +            app:backgroundTint="#00FFFFFF" +            app:cornerRadius="16dp" +            app:icon="@drawable/ic_baseline_search_24" +            app:iconTint="#333D70" /> + +    </androidx.cardview.widget.CardView>      <androidx.constraintlayout.widget.ConstraintLayout          android:layout_width="match_parent" @@ -27,6 +53,7 @@              android:layout_height="50dp"              android:layout_alignParentRight="true"              android:src="@drawable/filter" +            android:padding="@dimen/component_padding"              android:scaleType="centerCrop"              android:background="@color/white"/> @@ -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" /> 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 beada31..390d5bf 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,10 +1,13 @@  <?xml version="1.0" encoding="utf-8"?>  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + +android:orientation="vertical"      xmlns:tools="http://schemas.android.com/tools"      android:layout_width="match_parent"      android:layout_height="match_parent"      tools:context=".Fragments.FragmentUserPosts"> +      <!-- TODO: Update blank fragment layout -->      <androidx.cardview.widget.CardView          android:layout_width="match_parent" @@ -31,4 +34,19 @@      </androidx.cardview.widget.CardView> -</LinearLayout>
\ No newline at end of file + + + +    <androidx.legacy.widget.Space +        android:id="@+id/space" +        android:layout_width="match_parent" +        android:layout_height="50dp" +  /> + +    <androidx.recyclerview.widget.RecyclerView +        android:id="@+id/rvFragmentUserPostsPosts" +        android:layout_width="match_parent" +        android:layout_height="wrap_content" + /> + +    </LinearLayout> | 
