diff options
45 files changed, 1373 insertions, 380 deletions
diff --git a/Backend/Api/Api/Controllers/AuthController.cs b/Backend/Api/Api/Controllers/AuthController.cs index abb7adc..b63665b 100644 --- a/Backend/Api/Api/Controllers/AuthController.cs +++ b/Backend/Api/Api/Controllers/AuthController.cs @@ -120,5 +120,15 @@ namespace Api.Controllers return base.Content(html, "text/html"); } } + [HttpGet("jwttoid")] + [Authorize(Roles = "User")] + public async Task<ActionResult<string>> JwtToUserId() + { + var userid = await _userService.UserIdFromJwt(); + if (userid != null) + return Ok(userid); + return BadRequest(); + } + } } diff --git a/Backend/Api/Api/Controllers/PostController.cs b/Backend/Api/Api/Controllers/PostController.cs index 61a4f48..33c240c 100644 --- a/Backend/Api/Api/Controllers/PostController.cs +++ b/Backend/Api/Api/Controllers/PostController.cs @@ -56,7 +56,7 @@ namespace Api.Controllers } return BadRequest(); } - [HttpGet("posts/delete/{id}")] + [HttpDelete("posts/delete/{id}")] [Authorize(Roles = "User")] public async Task<ActionResult<string>> deletePost(string id) { diff --git a/Backend/Api/Api/Controllers/UserController.cs b/Backend/Api/Api/Controllers/UserController.cs index 30beac4..abdf685 100644 --- a/Backend/Api/Api/Controllers/UserController.cs +++ b/Backend/Api/Api/Controllers/UserController.cs @@ -164,9 +164,9 @@ namespace Api.Controllers [HttpPost("changePass")] [Authorize(Roles = "User")] - public async Task<ActionResult<int>> ChangePass(string currentPass, string newPass) + public async Task<ActionResult<int>> ChangePass([FromBody] ChangePass cp) { - return Ok(await _userService.ChangePass(currentPass,newPass)); + return Ok(await _userService.ChangePass(cp.currentPass,cp.newPass)); } diff --git a/Backend/Api/Api/Models/User.cs b/Backend/Api/Api/Models/User.cs index 52d0f24..f789ffe 100644 --- a/Backend/Api/Api/Models/User.cs +++ b/Backend/Api/Api/Models/User.cs @@ -65,7 +65,7 @@ namespace Api.Models public File? pfp { get; set; } public int postcount { get; set; } - public List<String> followers{ get; set; } + public List<String> followers { get; set; } public List<String> following { get; set; } public int followersCount { get; set; } @@ -80,8 +80,9 @@ namespace Api.Models public int totalViews { get; set; } public int numberOfPosts { get; set; } public int numberOfRatingsOnPosts { get; set; } - public double averagePostRatingOnPosts {get; set; } + public double averagePostRatingOnPosts { get; set; } public List<MonthlyViews> monthlyViews { get; set; } + public int numberOfFavouritePosts { get; set; } } public class MonthlyViews @@ -89,4 +90,9 @@ namespace Api.Models public int month { get; set; } public int views { get; set; } } + public class ChangePass + { + public string currentPass { get; set; } + public string newPass { get; set; } + } } diff --git a/Backend/Api/Api/Services/PostService.cs b/Backend/Api/Api/Services/PostService.cs index 0799f10..07e225e 100644 --- a/Backend/Api/Api/Services/PostService.cs +++ b/Backend/Api/Api/Services/PostService.cs @@ -115,7 +115,7 @@ namespace Api.Services foreach (var image in p.images) System.IO.File.Delete(image.path); - await _posts.DeleteOneAsync(postid); + await _posts.FindOneAndDeleteAsync(x => x._id==postid); return true; } @@ -672,6 +672,7 @@ namespace Api.Services stats.numberOfPosts = 0; stats.totalViews = 0; stats.monthlyViews = new List<MonthlyViews>(); + stats.numberOfFavouritePosts = 0; if(posts != null) @@ -691,6 +692,8 @@ namespace Api.Services stats.totalViews += post.views; stats.numberOfRatingsOnPosts += post.ratingscount; stats.numberOfPosts++; + if(post.favourites!=null) + stats.numberOfFavouritePosts+=post.favourites.Count; ratingsum += post.ratings * post.ratingscount; } if(stats.numberOfRatingsOnPosts > 0) //don't forget to check div by 0 jesus diff --git a/Backend/Api/Api/Services/UserService.cs b/Backend/Api/Api/Services/UserService.cs index 74c0894..d8ec4a2 100644 --- a/Backend/Api/Api/Services/UserService.cs +++ b/Backend/Api/Api/Services/UserService.cs @@ -416,7 +416,9 @@ namespace Api.Services } User f = await _users.Find(user => user._id == followerId).FirstOrDefaultAsync(); User u = await _users.Find(user => user._id == id).FirstOrDefaultAsync(); - + if(await CheckIfAlreadyFollow(followerId)) + return false; + if (id != null && followerId!=null) { if (f.followers == null) @@ -617,27 +619,33 @@ namespace Api.Services User u = await _users.Find(user => user._id == myId).FirstOrDefaultAsync(); User f = await _users.Find(user => user._id == id).FirstOrDefaultAsync(); - + if(await CheckIfAlreadyFollow(id)) if (u != null) { - if (u.following != null && f.followers!=null) - { u.following.Remove(f._id); + if (u.following == null) + u.following = new List<string>(); u.followingCount=u.following.Count(); + if (u.followers == null) + u.followers = new List<string>(); u.followersCount = u.followers.Count(); f.followers.Remove(u._id); + if (f.followers == null) + f.followers = new List<string>(); f.followersCount =f.followers.Count(); + if (f.following == null) + f.following = new List<string>(); f.followingCount =f.following.Count(); - _users.ReplaceOne(user => user._id == myId, u); - _users.ReplaceOne(user => user._id == id, f); + await _users.ReplaceOneAsync(user => user._id == myId, u); + await _users.ReplaceOneAsync(user => user._id == id, f); //updateUserFollowerFollowingCount(u.followers, u.following, u._id); //updateUserFollowerFollowingCount(f.followers, f.following, f._id); return true; - } + } return false; diff --git a/Client/BrzoDoLokacije/app/build.gradle b/Client/BrzoDoLokacije/app/build.gradle index cae3d80..0bc0fe8 100644 --- a/Client/BrzoDoLokacije/app/build.gradle +++ b/Client/BrzoDoLokacije/app/build.gradle @@ -73,4 +73,10 @@ dependencies { //OSMDROID implementation 'org.osmdroid:osmdroid-android:6.1.14' implementation 'com.github.MKergall:osmbonuspack:6.9.0' + + //KeyboardVisibilityEvents + implementation 'net.yslibrary.keyboardvisibilityevent:keyboardvisibilityevent:3.0.0-RC3' + + //zoom + implementation 'com.github.piasy:GlideImageLoader:1.8.1' }
\ No newline at end of file diff --git a/Client/BrzoDoLokacije/app/src/main/AndroidManifest.xml b/Client/BrzoDoLokacije/app/src/main/AndroidManifest.xml index 347fdc6..1ec64ec 100644 --- a/Client/BrzoDoLokacije/app/src/main/AndroidManifest.xml +++ b/Client/BrzoDoLokacije/app/src/main/AndroidManifest.xml @@ -38,6 +38,14 @@ android:usesCleartextTraffic="true" tools:targetApi="31"> <activity + android:name=".Activities.ActivityOpenedImages" + android:screenOrientation="portrait" + android:exported="false"> + <meta-data + android:name="android.app.lib_name" + android:value="" /> + </activity> + <activity android:name=".Activities.ActivityChangePassword" android:exported="false"> <meta-data @@ -92,7 +100,8 @@ <activity android:name=".Activities.MapsActivity" - android:screenOrientation="portrait" /> + android:screenOrientation="portrait" + android:windowSoftInputMode="stateAlwaysHidden|adjustResize" /> <activity android:name=".Activities.ActivityCapturePost" android:screenOrientation="portrait" /> @@ -128,7 +137,8 @@ android:screenOrientation="portrait" /> <activity android:name=".Activities.NavigationActivity" - android:screenOrientation="portrait" /> + android:screenOrientation="portrait" + android:windowSoftInputMode="stateAlwaysHidden|adjustResize" /> <activity android:name=".MainActivity" android:screenOrientation="portrait" /> diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ActivityChangePassword.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ActivityChangePassword.kt index 2501f8a..d403609 100644 --- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ActivityChangePassword.kt +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ActivityChangePassword.kt @@ -3,34 +3,41 @@ package com.example.brzodolokacije.Activities import android.graphics.Color import androidx.appcompat.app.AppCompatActivity import android.os.Bundle + +import com.example.brzodolokacije.R import android.widget.Button +import android.widget.EditText +import android.widget.ImageView import android.widget.TextView import android.widget.Toast import androidx.core.view.isVisible import com.exam.DBHelper.Companion.activity +import com.example.brzodolokacije.Models.Auth.ChangePass import com.example.brzodolokacije.Models.UserReceive -import com.example.brzodolokacije.R import com.example.brzodolokacije.Services.RetrofitHelper import com.example.brzodolokacije.Services.SharedPreferencesHelper +import kotlinx.android.synthetic.main.fragment_my_profile_info.* import retrofit2.Call import retrofit2.Response + class ActivityChangePassword : AppCompatActivity() { - private lateinit var oldPass:TextView + private lateinit var oldPass:EditText private lateinit var oldPassError:TextView - private lateinit var newPass:TextView + private lateinit var newPass:EditText private lateinit var newPassError:TextView - private lateinit var confirmPass:TextView + private lateinit var confirmPass:EditText private lateinit var confirmPassError:TextView private lateinit var forgotten:TextView private lateinit var submit:Button + private lateinit var backButton:ImageView override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_change_password) - oldPass=findViewById(R.id.changeDataOldPassword) + oldPass=findViewById(R.id.tvActivityChangePasswordCurrentPass) oldPassError=findViewById(R.id.ActivityChangePasswordOldError) newPass=findViewById(R.id.tvActivityChangePasswordNewPass) newPassError=findViewById(R.id.btnActivityChangePasswordNewError) @@ -38,10 +45,14 @@ class ActivityChangePassword : AppCompatActivity() { confirmPassError=findViewById(R.id.btnActivityChangePasswordConfirmError) forgotten=findViewById(R.id.btnActivityChangePasswordForgottenPass) submit=findViewById(R.id.ActivityChangePasswordChangePassword) + backButton=findViewById(R.id.btnBackToUser) oldPassError.isVisible=false newPassError.isVisible=false confirmPassError.isVisible=false + backButton.setOnClickListener{ + finish() + } submit.setOnClickListener{ oldPassError.isVisible=false @@ -54,10 +65,10 @@ class ActivityChangePassword : AppCompatActivity() { if(newPass.text.toString().trim() == confirmPass.text.toString().trim()){ //PROVERI DA LI JE TRENUTA LOZINKA ISTA KAO TRENUTNI UNOS - + var cp= ChangePass(oldPass.text.toString(),newPass.text.toString()) val authApi= RetrofitHelper.getInstance() val token= SharedPreferencesHelper.getValue("jwt",this@ActivityChangePassword) - val request=authApi.changePass("Bearer "+token) + val request=authApi.changePass("Bearer "+token,cp) request.enqueue(object : retrofit2.Callback<Int> { override fun onResponse(call: Call<Int>, response: Response<Int>) { diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ActivityOpenedImages.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ActivityOpenedImages.kt new file mode 100644 index 0000000..d1f1e4c --- /dev/null +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ActivityOpenedImages.kt @@ -0,0 +1,83 @@ +package com.example.brzodolokacije.Activities + +import android.graphics.Bitmap +import android.graphics.drawable.Drawable +import android.os.Build +import android.os.Bundle +import android.provider.MediaStore +import android.widget.Toast +import androidx.appcompat.app.AppCompatActivity +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.PagerSnapHelper +import androidx.recyclerview.widget.RecyclerView +import androidx.recyclerview.widget.SnapHelper +import com.bumptech.glide.Glide +import com.bumptech.glide.request.target.CustomTarget +import com.bumptech.glide.request.transition.Transition +import com.example.brzodolokacije.Adapters.OpenedPostImageAdapter +import com.example.brzodolokacije.Models.PostImage +import com.example.brzodolokacije.Models.PostPreview +import com.example.brzodolokacije.Services.RetrofitHelper +import com.example.brzodolokacije.databinding.ActivityOpenedImagesBinding +import java.util.* + +class ActivityOpenedImages : AppCompatActivity() { + lateinit var binding:ActivityOpenedImagesBinding + var rvImages: RecyclerView?=null + var linearLayout:LinearLayoutManager?=null + var adapter:OpenedPostImageAdapter?=null + var images:List<PostImage>?=null + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding= ActivityOpenedImagesBinding.inflate(layoutInflater) + setContentView(binding.root) + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + images=(intent.extras?.getParcelable("post",PostPreview::class.java) as PostPreview).images + } + else{ + images=(intent.extras?.getParcelable("post") as PostPreview?)?.images + } + + setRecyclerView() + setListeners() + } + + fun setListeners(){ + binding.btnBackToPost.setOnClickListener { + finish() + } + binding.btnDownload.setOnClickListener { + //uzmi id trenutne slike + var selected:PostImage?=null + linearLayout?.findFirstVisibleItemPosition()?.let { it1 -> selected=images?.get(it1) } + if(selected!=null){ + //sacuvaj na telefonu + var image=Glide.with(this) + .asBitmap() + .load(RetrofitHelper.baseUrl + "/api/post/image/" + selected!!._id) + .into(object : CustomTarget<Bitmap>(){ + override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) { + Toast.makeText(this@ActivityOpenedImages,"Slika se preuzima...",Toast.LENGTH_LONG).show() + MediaStore.Images.Media.insertImage(contentResolver, resource, "odyssey_"+ Calendar.getInstance().timeInMillis , ""); + Toast.makeText(this@ActivityOpenedImages,"Slika je sačuvana.",Toast.LENGTH_LONG).show() + } + override fun onLoadCleared(placeholder: Drawable?) { + } + }) + } + } + } + + fun setRecyclerView(){ + rvImages=binding.rvImages + linearLayout= LinearLayoutManager(this,LinearLayoutManager.HORIZONTAL,false) + adapter= OpenedPostImageAdapter(images,this) + rvImages!!.setHasFixedSize(true) + var snap:SnapHelper=PagerSnapHelper() + snap.attachToRecyclerView(rvImages) + rvImages!!.layoutManager=linearLayout + rvImages!!.adapter=adapter + } + +}
\ No newline at end of file diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ActivitySinglePost.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ActivitySinglePost.kt index b7848df..623b670 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,7 +5,6 @@ import android.graphics.Color import android.os.Bundle import android.preference.PreferenceManager import android.util.TypedValue -import android.view.View import android.view.ViewGroup import android.widget.* import androidx.appcompat.app.AppCompatActivity @@ -16,7 +15,9 @@ import androidx.core.view.isVisible import androidx.core.view.setMargins import androidx.fragment.app.FragmentTransaction import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.PagerSnapHelper import androidx.recyclerview.widget.RecyclerView +import androidx.recyclerview.widget.SnapHelper import com.auth0.android.jwt.JWT import com.example.brzodolokacije.Adapters.CommentsAdapter import com.example.brzodolokacije.Adapters.PostImageAdapter @@ -31,7 +32,6 @@ import com.example.brzodolokacije.Services.RetrofitHelper import com.example.brzodolokacije.Services.SharedPreferencesHelper import com.example.brzodolokacije.databinding.ActivitySinglePostBinding import com.google.gson.Gson -import kotlinx.android.synthetic.main.fragment_single_post_description.* import org.osmdroid.config.Configuration import org.osmdroid.tileprovider.tilesource.TileSourceFactory import org.osmdroid.util.GeoPoint @@ -51,8 +51,11 @@ class ActivitySinglePost : AppCompatActivity() { private var recyclerViewComments: RecyclerView?=null private var favouriteImage: ImageView?=null private lateinit var tagLayout: LinearLayout + private lateinit var createdAt:TextView public lateinit var post: PostPreview + public lateinit var ratings:TextView + public lateinit var ratingscount:TextView private var comments:MutableList<CommentSend>?=mutableListOf() private var starNumber:Number=0 @@ -94,6 +97,8 @@ class ActivitySinglePost : AppCompatActivity() { //DODATI SLIKE recyclerViewImages?.setHasFixedSize(true) + var snap: SnapHelper = PagerSnapHelper() + snap.attachToRecyclerView(recyclerViewImages) recyclerViewImages?.layoutManager = layoutManagerImages recyclerViewImages?.adapter = adapterImages @@ -140,7 +145,6 @@ class ActivitySinglePost : AppCompatActivity() { recyclerViewImages?.setHasFixedSize(true) recyclerViewImages?.layoutManager = layoutManagerImages recyclerViewImages?.adapter = adapterImages - } btnChangeHeightDown.setOnClickListener { btnChangeHeightDown.isVisible=false @@ -184,6 +188,8 @@ class ActivitySinglePost : AppCompatActivity() { } fun loadTags(){ + + if(post.tags!=null) for( item in post.tags!!){ var newbtn = Button(this) @@ -193,17 +199,23 @@ class ActivitySinglePost : AppCompatActivity() { 50 ) layoutParams.setMargins(3) - newbtn.layoutParams=layoutParams + + newbtn.layoutParams = layoutParams newbtn.setBackgroundColor(Color.parseColor("#1C789A")) newbtn.setTextColor(Color.WHITE) newbtn.setTextSize(TypedValue.COMPLEX_UNIT_SP, 10F) - newbtn.setPadding(3,1,3,1) - newbtn.isClickable=false + newbtn.setPadding(3, 1, 3, 1) + newbtn.isClickable = false tagLayout.addView(newbtn) } + } + public fun updateratings(rc:Int,r:Double){ + binding.tvRating.text=r.toString() + binding.tvNumberOfRatings.text=rc.toString() } + fun loadFavourite(){ if(post.favourites!=null){ var jwtString=SharedPreferencesHelper.getValue("jwt",this) @@ -277,7 +289,8 @@ class ActivitySinglePost : AppCompatActivity() { tvNumberOfRatings.invalidate() //tvRating.text=String.format("%.2f",data.ratings) //tvNumberOfRatings.text=String.format("%d",data.ratingscount) - + tvDatePosted.text=post.createdAt.toLocaleString() + tvDatePosted.invalidate() } diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ActivityUserProfile.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ActivityUserProfile.kt index 4962006..b568d73 100644 --- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ActivityUserProfile.kt +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ActivityUserProfile.kt @@ -92,14 +92,16 @@ class ActivityUserProfile : AppCompatActivity() { call: Call<Boolean>, response: Response<Boolean> ) { - unfollowUser.isVisible=true - unfollowUser.isClickable=true - unfollowUser.isEnabled=true - followUser.isVisible=false - followUser.isClickable=false - followUser.isEnabled=false + if(response.body()==true) { + unfollowUser.isVisible = true + unfollowUser.isClickable = true + unfollowUser.isEnabled = true + followUser.isVisible = false + followUser.isClickable = false + followUser.isEnabled = false - updateUserData() + updateUserData() + } Toast.makeText( this@ActivityUserProfile, "PRATITE KORISNIKA", Toast.LENGTH_LONG @@ -123,13 +125,15 @@ class ActivityUserProfile : AppCompatActivity() { call: Call<Boolean>, response: Response<Boolean> ) { - unfollowUser.isVisible = false - unfollowUser.isClickable = false - unfollowUser.isEnabled = false - followUser.isVisible = true - followUser.isClickable = true - followUser.isEnabled = true - updateUserData() + if(response.body()==true) { + unfollowUser.isVisible = false + unfollowUser.isClickable = false + unfollowUser.isEnabled = false + followUser.isVisible = true + followUser.isClickable = true + followUser.isEnabled = true + updateUserData() + } Toast.makeText( this@ActivityUserProfile, "VIŠE NE PRATITE KORISNIKA", Toast.LENGTH_LONG ).show(); diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ChatActivity.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ChatActivity.kt index 9c489b3..6d8afd6 100644 --- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ChatActivity.kt +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ChatActivity.kt @@ -24,6 +24,7 @@ import com.example.brzodolokacije.Models.MessageReceive import com.example.brzodolokacije.R import com.example.brzodolokacije.Services.RetrofitHelper import com.example.brzodolokacije.Services.SharedPreferencesHelper +import com.example.brzodolokacije.chat.Notifications import com.example.brzodolokacije.chat.SignalRListener import com.example.brzodolokacije.databinding.ActivityChatBinding import kotlinx.coroutines.MainScope @@ -50,41 +51,9 @@ class ChatActivity : AppCompatActivity(), SwipeRefreshLayout.OnRefreshListener { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding= ActivityChatBinding.inflate(layoutInflater) - permissionLauncher=registerForActivityResult( - ActivityResultContracts.RequestPermission() - ) { isGranted: Boolean -> - if (!isGranted) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - if (Build.VERSION.SDK_INT >= 33) { - //ako je upravo odbijena dozvola na uredjaju na kome je ona neophodna - binding.btnNotifications.setImageResource(R.drawable.bell_off) - } - else{ - //ako je upravo odbijena dozvola na uredjaju na kome nije ona neophodna - binding.btnNotifications.setImageResource(R.drawable.bell_on) - } - } - else{ - //ako je upravo odbijena dozvola na uredjaju na kome nije ona neophodna - binding.btnNotifications.setImageResource(R.drawable.bell_on) - } - } - else{ - //ako je upravo prihvacena dozvola na uredjaju na kome nije ona neophodna - binding.btnNotifications.setImageResource(R.drawable.bell_on) - } - } - //provera da li je dozvoljeno - when { - ContextCompat.checkSelfPermission(this,Manifest.permission.POST_NOTIFICATIONS) == PackageManager.PERMISSION_GRANTED -> { - binding.btnNotifications.setImageResource(R.drawable.bell_on) - } - else -> { - binding.btnNotifications.setImageResource(R.drawable.bell_off) - } - } - - + Notifications.makeChannel(this) + setPermissionLauncher() + checkPermissions() setContentView(binding.root) dbConnection= DBHelper(this@ChatActivity,null) ws=SignalRListener.getInstance(this@ChatActivity) @@ -106,6 +75,46 @@ class ChatActivity : AppCompatActivity(), SwipeRefreshLayout.OnRefreshListener { requestNewMessages() } + fun setPermissionLauncher(){ + permissionLauncher=registerForActivityResult( + ActivityResultContracts.RequestPermission() + ) { isGranted: Boolean -> + if (!isGranted) { + binding.btnNotifications.setImageResource(R.drawable.bell_off) + } + else{ + binding.btnNotifications.setImageResource(R.drawable.bell_on) + } + } + } + + fun checkPermissions(){ + when { + //treba proveriti permisije + Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU-> { + if(ContextCompat.checkSelfPermission(this,Manifest.permission.POST_NOTIFICATIONS) == PackageManager.PERMISSION_GRANTED) { + binding.btnNotifications.setImageResource(R.drawable.bell_on) + } + else{ + binding.btnNotifications.setImageResource(R.drawable.bell_off) + } + } + //treba proveriti preference + else-> { + if(SharedPreferencesHelper.getValue("notifications",this)==null){ + SharedPreferencesHelper.addValue("notifications","false",this@ChatActivity) + } + else if (SharedPreferencesHelper.getValue("notifications",this)=="true") { + binding.btnNotifications.setImageResource(R.drawable.bell_on) + } + else{ + binding.btnNotifications.setImageResource(R.drawable.bell_off) + } + } + + } + } + fun launchNotificationPermissionPrompt(){ permissionLauncher.launch(android.Manifest.permission.POST_NOTIFICATIONS) } @@ -131,15 +140,28 @@ class ChatActivity : AppCompatActivity(), SwipeRefreshLayout.OnRefreshListener { } findViewById<ImageButton>(R.id.btnNotifications).setOnClickListener { when { - ContextCompat.checkSelfPermission(this,Manifest.permission.POST_NOTIFICATIONS) == PackageManager.PERMISSION_GRANTED -> { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + //treba proveriti permisije + Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU-> { + if(ContextCompat.checkSelfPermission(this,Manifest.permission.POST_NOTIFICATIONS) == PackageManager.PERMISSION_GRANTED) { revokeSelfPermissionOnKill(Manifest.permission.POST_NOTIFICATIONS) + launchInfoDialog() + } + else{ + launchNotificationPermissionPrompt() } - launchInfoDialog() } - else -> { - launchNotificationPermissionPrompt() + //treba proveriti preference + else-> { + if (SharedPreferencesHelper.getValue("notifications",this)=="true") { + SharedPreferencesHelper.addValue("notifications","false",this@ChatActivity) + binding.btnNotifications.setImageResource(R.drawable.bell_off) + } + else{ + SharedPreferencesHelper.addValue("notifications","true",this@ChatActivity) + binding.btnNotifications.setImageResource(R.drawable.bell_on) + } } + } } } diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ChatActivityConversation.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ChatActivityConversation.kt index 04dd9de..b81867e 100644 --- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ChatActivityConversation.kt +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/ChatActivityConversation.kt @@ -11,6 +11,7 @@ import androidx.appcompat.app.AppCompatActivity import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.auth0.android.jwt.JWT +import com.bumptech.glide.Glide import com.exam.DBHelper import com.example.brzodolokacije.Adapters.ChatMessagesAdapter import com.example.brzodolokacije.Models.Message @@ -39,6 +40,7 @@ class ChatActivityConversation : AppCompatActivity() { var webSocketConnection:SignalRListener?=null var items:MutableList<Message>?=mutableListOf() var userImage:Bitmap?=null + var userImageId:String?=null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -46,7 +48,12 @@ class ChatActivityConversation : AppCompatActivity() { setContentView(binding.root) userId=intent.extras?.get("userId").toString() receiverUsername=intent.extras?.get("username").toString() - userImage=intent.extras?.get("pfp") as Bitmap? + if(intent.extras?.get("pfp") is Bitmap){ + userImage=intent.extras?.get("pfp") as Bitmap? + } + else{ + userImageId=intent.extras?.get("pfp") as String? + } dbConnection=DBHelper.getInstance(this@ChatActivityConversation) setHeader() setRecyclerView() @@ -172,8 +179,15 @@ class ChatActivityConversation : AppCompatActivity() { binding.btnBack.setOnClickListener { finish() } - if(userImage!=null) + if(userImage!=null){ binding.ivUserImage.setImageBitmap(userImage) + } + else if(userImageId!=null){ + Glide.with(this) + .load(RetrofitHelper.baseUrl + "/api/post/image/compress/" + userImageId!!) + .circleCrop() + .into(binding.ivUserImage) + } } fun setRecyclerView(setParams:Boolean=true){ MainScope().launch { 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 23cbca6..4e355b6 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 @@ -1,18 +1,19 @@ package com.example.brzodolokacije.Activities import android.content.Intent -import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.view.View -import android.widget.Button import android.widget.ImageButton import android.widget.Toast -import androidx.appcompat.app.AppCompatDelegate +import androidx.appcompat.app.AppCompatActivity import androidx.fragment.app.Fragment import com.example.brzodolokacije.Fragments.* import com.example.brzodolokacije.R import com.google.android.material.bottomnavigation.BottomNavigationView import com.google.android.material.bottomsheet.BottomSheetDialog +import kotlinx.coroutines.MainScope +import kotlinx.coroutines.launch +import net.yslibrary.android.keyboardvisibilityevent.KeyboardVisibilityEvent class NavigationActivity : AppCompatActivity() { @@ -33,6 +34,7 @@ class NavigationActivity : AppCompatActivity() { val profileFragment=FragmentProfile() bottomNav=findViewById<View>(R.id.bottomNavigationView) as BottomNavigationView setCurrentFragment(fragmentHomePage) + KeyboardEvents() bottomNav.setOnNavigationItemSelectedListener { when(it.itemId){ R.id.navHomePage->setCurrentFragment(fragmentHomePage) @@ -115,5 +117,21 @@ class NavigationActivity : AppCompatActivity() { } } + fun KeyboardEvents(){ + KeyboardVisibilityEvent.setEventListener( + this + ) { isOpen -> + if (isOpen) { + bottomNav.visibility = View.GONE + bottomNav.forceLayout() + + } else { + MainScope().launch { + bottomNav.visibility = View.VISIBLE + bottomNav.forceLayout() + } + } + } + } }
\ No newline at end of file diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/MonthViewsAdapter.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/MonthViewsAdapter.kt new file mode 100644 index 0000000..240deb0 --- /dev/null +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/MonthViewsAdapter.kt @@ -0,0 +1,63 @@ +package com.example.brzodolokacije.Adapters + +import android.app.Activity +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView +import com.example.brzodolokacije.Models.MonthlyViews +import com.example.brzodolokacije.databinding.SingleDateViewBinding + +class MonthViewsAdapter (val activity: Activity, val items : MutableList<MonthlyViews>) + : RecyclerView.Adapter<MonthViewsAdapter.ViewHolder>() { + + + private lateinit var binding: SingleDateViewBinding + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + val inflater = LayoutInflater.from(parent.context) + binding = SingleDateViewBinding.inflate(inflater, parent, false) + return ViewHolder(binding) + } + + + + + override fun getItemCount() = items.size + inner class ViewHolder(itemView: SingleDateViewBinding) : RecyclerView.ViewHolder(itemView.root) { + fun bind(item: MonthlyViews) { + binding.apply { + tvMonth.text=numberToMonthName(item.month) + tvMonthViews.text=item.views.toString() + + } + } + } + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + return holder.bind(items[position]) + + } + fun numberToMonthName(number:Int):String{ + var text="" + when (number) { + 1 -> text="Januar" + 2 -> text="Februar" + 3 -> text="Mart" + 4 -> text="April" + 5 -> text="Maj" + 6 -> text="Jun" + 7 -> text="Jul" + 8 -> text="Avgust" + 9 -> text="Septembar" + 10 -> text="Oktobar" + 11 -> text="Novembar" + 12 -> text="Decembar" + else -> { + text = "nedefinisan" + } + } + + return text + + } + +} diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/MyPostsAdapter.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/MyPostsAdapter.kt index e557e02..de7d619 100644 --- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/MyPostsAdapter.kt +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/MyPostsAdapter.kt @@ -2,12 +2,9 @@ package com.example.brzodolokacije.Adapters import android.app.Activity import android.content.Intent -import android.graphics.BitmapFactory -import android.os.AsyncTask import android.os.Bundle import android.view.LayoutInflater import android.view.ViewGroup -import android.widget.Toast import androidx.recyclerview.widget.RecyclerView import com.bumptech.glide.Glide import com.example.brzodolokacije.Activities.ActivitySinglePost @@ -17,11 +14,6 @@ import com.example.brzodolokacije.Models.PostPreview import com.example.brzodolokacije.Services.RetrofitHelper import com.example.brzodolokacije.Services.SharedPreferencesHelper import com.example.brzodolokacije.databinding.PostPreviewBinding -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.launch -import okhttp3.ResponseBody -import retrofit2.Call -import retrofit2.Response class MyPostsAdapter (val activity:Activity,val items : MutableList<PostPreview>) @@ -29,8 +21,6 @@ class MyPostsAdapter (val activity:Activity,val items : MutableList<PostPreview> private lateinit var token: String private lateinit var imageApi: IBackendApi - //constructer has one argument - list of objects that need to be displayed - //it is bound to xml of single item private lateinit var binding: PostPreviewBinding override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val inflater = LayoutInflater.from(parent.context) diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/OpenedPostImageAdapter.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/OpenedPostImageAdapter.kt new file mode 100644 index 0000000..525549d --- /dev/null +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/OpenedPostImageAdapter.kt @@ -0,0 +1,47 @@ +package com.example.brzodolokacije.Adapters + +import android.app.Activity +import android.net.Uri +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView +import com.example.brzodolokacije.Models.PostImage +import com.example.brzodolokacije.Services.RetrofitHelper +import com.example.brzodolokacije.databinding.OpenedPostImageBinding +import com.github.piasy.biv.BigImageViewer +import com.github.piasy.biv.loader.glide.GlideImageLoader +import com.github.piasy.biv.view.BigImageView + +class OpenedPostImageAdapter(val items:List<PostImage>?,val activity:Activity): RecyclerView.Adapter<OpenedPostImageAdapter.ViewHolder>() { + lateinit var binding:OpenedPostImageBinding + + inner class ViewHolder(itemView: OpenedPostImageBinding) : RecyclerView.ViewHolder(itemView.root) { + fun bind(item:PostImage){ + binding.apply { + ivOpenedImage.setInitScaleType(BigImageView.INIT_SCALE_TYPE_FIT_START) + ivOpenedImage.showImage(Uri.parse(RetrofitHelper.baseUrl + "/api/post/image/compress/" + item._id)) + } + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + BigImageViewer.initialize(GlideImageLoader.with(activity)) + val inflater = LayoutInflater.from(parent.context) + binding= OpenedPostImageBinding.inflate(inflater,parent,false) + return ViewHolder(binding) + } + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + holder.bind(items!![position]) + } + + override fun getItemCount(): Int { + if(items==null){ + return 0 + } + else{ + return items.size + } + } + +}
\ No newline at end of file diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/PostImageAdapter.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/PostImageAdapter.kt index 74bfd92..f3a8345 100644 --- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/PostImageAdapter.kt +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/PostImageAdapter.kt @@ -1,17 +1,16 @@ package com.example.brzodolokacije.Adapters import android.app.Activity -import android.graphics.BitmapFactory -import android.media.Image +import android.content.Intent import android.view.LayoutInflater import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView import com.bumptech.glide.Glide -import com.example.brzodolokacije.Models.Post +import com.example.brzodolokacije.Activities.ActivityOpenedImages +import com.example.brzodolokacije.Activities.ActivitySinglePost import com.example.brzodolokacije.Models.PostImage import com.example.brzodolokacije.Services.RetrofitHelper import com.example.brzodolokacije.databinding.PostImageBinding -import com.example.brzodolokacije.databinding.PostPreviewBinding class PostImageAdapter(val activity: Activity, val items : MutableList<PostImage>) : RecyclerView.Adapter<PostImageAdapter.ViewHolder>(){ @@ -37,6 +36,11 @@ class PostImageAdapter(val activity: Activity, val items : MutableList<PostImage .into(locationImage) } } + itemView.setOnClickListener { + val intent: Intent = Intent(activity, ActivityOpenedImages::class.java) + intent.putExtra("post",(activity as ActivitySinglePost).post) + activity.startActivity(intent) + } } } }
\ No newline at end of file diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/FragmentProfileStatistics.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/FragmentProfileStatistics.kt new file mode 100644 index 0000000..fb4c563 --- /dev/null +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/FragmentProfileStatistics.kt @@ -0,0 +1,98 @@ +package com.example.brzodolokacije + +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.TextView +import android.widget.Toast +import androidx.recyclerview.widget.GridLayoutManager +import androidx.recyclerview.widget.RecyclerView +import com.example.brzodolokacije.Adapters.MonthViewsAdapter +import com.example.brzodolokacije.Adapters.MyPostsAdapter +import com.example.brzodolokacije.Models.MonthlyViews +import com.example.brzodolokacije.Models.Statistics +import com.example.brzodolokacije.Models.UserReceive +import com.example.brzodolokacije.Services.RetrofitHelper +import com.example.brzodolokacije.Services.SharedPreferencesHelper +import retrofit2.Call +import retrofit2.Response + + +class FragmentProfileStatistics : Fragment() { + + private var stats:Statistics?=null + private var username:String?=null + private lateinit var totalViews:TextView + private lateinit var numberOfRatings:TextView + private lateinit var averageRatings:TextView + private lateinit var numberOfFavourite:TextView + private lateinit var rcMonths:RecyclerView + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + } + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + var view=inflater.inflate(R.layout.fragment_profile_statistics, container, false) + username=this.requireArguments().getString("username") + totalViews=view.findViewById(R.id.tvProfileStatisticsViews) + numberOfRatings=view.findViewById(R.id.tvProfileStatisticsRatingNumber) + averageRatings=view.findViewById(R.id.tvProfileStatisticsAverageRating) + numberOfFavourite=view.findViewById(R.id.tvProfileStatisticsFavouriteNumber) + rcMonths=view.findViewById(R.id.rvFragmentProfileStatisticsMonths) + + + + loadStats() + + return view + } + + + fun loadStats(){ + val authApi= RetrofitHelper.getInstance() + val token= SharedPreferencesHelper.getValue("jwt", requireActivity()) + val request=authApi.getUserStatsFromUsername("Bearer "+token,username!!) + + request.enqueue(object : retrofit2.Callback<Statistics?> { + override fun onResponse(call: Call<Statistics?>, response: Response<Statistics?>) { + if(response.isSuccessful()){ + stats=response.body() + loadText() + loadMonths() + + + } + } + override fun onFailure(call: Call<Statistics?>, t: Throwable) { + Toast.makeText( + activity, t.toString(), Toast.LENGTH_LONG + ).show(); + } + }) + + } + fun loadText(){ + totalViews.text=stats!!.totalViews.toString() + numberOfRatings.text=stats!!.numberOfRatingsOnPosts.toString() + averageRatings.text=stats!!.averagePostRatingOnPosts.toString() + numberOfFavourite.text=stats!!.numberOfFavouritePosts.toString() + } + private fun loadMonths(){ + rcMonths.apply { + layoutManager= GridLayoutManager(requireContext(),1, GridLayoutManager.HORIZONTAL,false) + adapter= MonthViewsAdapter(requireActivity(), + stats!!.monthlyViews as MutableList<MonthlyViews> + ) + + } + } + + +}
\ No newline at end of file diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentHomePageMainScroll.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentHomePageMainScroll.kt index 82c78a1..df41b3a 100644 --- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentHomePageMainScroll.kt +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentHomePageMainScroll.kt @@ -8,11 +8,11 @@ import android.widget.Button import android.widget.ImageButton import android.widget.LinearLayout import android.widget.Toast -import androidx.core.view.isVisible import androidx.fragment.app.Fragment -import androidx.fragment.app.FragmentTransaction import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener import com.example.brzodolokacije.Adapters.ShowPostsHomePageAdapter import com.example.brzodolokacije.Interfaces.IBackendApi import com.example.brzodolokacije.Models.LocationType @@ -20,15 +20,15 @@ import com.example.brzodolokacije.Models.PostPreview import com.example.brzodolokacije.R import com.example.brzodolokacije.Services.RetrofitHelper import com.example.brzodolokacije.Services.SharedPreferencesHelper -import kotlinx.android.synthetic.main.fragment_home_page_main_scroll.* import retrofit2.Call import retrofit2.Callback import retrofit2.Response import retrofit2.Retrofit import retrofit2.converter.gson.GsonConverterFactory -class FragmentHomePageMainScroll : Fragment() { +class FragmentHomePageMainScroll : Fragment(),OnRefreshListener { + private lateinit var swipeRefreshLayout: SwipeRefreshLayout private lateinit var posts : MutableList<PostPreview> private lateinit var mostViewedPosts : MutableList<PostPreview> private lateinit var newestPosts : MutableList<PostPreview> @@ -79,7 +79,7 @@ private lateinit var change:Button location_waterfall=view.findViewById(R.id.btnFragmentHomePagelocation_waterfall) //pokupi sve objave iz baze' - getAllPosts() + //getAllPosts() var bundle=Bundle() var fragment=FragmentShowPostsByLocation() @@ -190,9 +190,29 @@ private lateinit var change:Button } */ + swipeRefreshLayout = view.findViewById<View>(R.id.swipeContainer) as SwipeRefreshLayout + swipeRefreshLayout.setOnRefreshListener(this) + swipeRefreshLayout.setColorSchemeResources( + R.color.purple_200, + R.color.teal_200, + R.color.dark_blue_transparent, + R.color.purple_700 + ) + swipeRefreshLayout.post(kotlinx.coroutines.Runnable { + swipeRefreshLayout.isRefreshing=true + }) return view } + override fun onRefresh() { + getAllPosts() + } + + override fun onResume() { + super.onResume() + getAllPosts() + } + private fun getAllPosts(){ Toast.makeText( activity," get all", Toast.LENGTH_LONG @@ -289,6 +309,7 @@ private lateinit var change:Button layoutManager= LinearLayoutManager(activity, LinearLayoutManager.HORIZONTAL,false) adapter= ShowPostsHomePageAdapter(newestposts,requireActivity()) } + swipeRefreshLayout.isRefreshing=false } override fun onFailure(call: Call<MutableList<PostPreview>>, t: Throwable) { diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentMyProfileInfo.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentMyProfileInfo.kt index 23de46e..5d1530d 100644 --- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentMyProfileInfo.kt +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentMyProfileInfo.kt @@ -1,18 +1,19 @@ package com.example.brzodolokacije.Fragments + import android.content.Intent import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.Button -import androidx.core.content.ContextCompat.startActivity import androidx.fragment.app.Fragment +import androidx.fragment.app.FragmentTransaction import com.exam.DBHelper import com.example.brzodolokacije.Activities.ActivityChangePassword import com.example.brzodolokacije.Activities.ActivityChangeUserData -import com.example.brzodolokacije.Activities.ActivityForgottenPassword import com.example.brzodolokacije.Activities.ActivityLoginRegister +import com.example.brzodolokacije.FragmentProfileStatistics import com.example.brzodolokacije.R import com.example.brzodolokacije.Services.SharedPreferencesHelper @@ -20,6 +21,7 @@ import com.example.brzodolokacije.Services.SharedPreferencesHelper class FragmentMyProfileInfo : Fragment() { private lateinit var logout:Button private lateinit var changeAccount:Button + private lateinit var statistics:Button private lateinit var changePassword:Button override fun onCreateView( @@ -31,6 +33,7 @@ class FragmentMyProfileInfo : Fragment() { logout=view.findViewById<View>(R.id.buttonLogOut) as Button changeAccount=view.findViewById(R.id.changeAccountData) + statistics=view.findViewById<View>(R.id.getAccoutStatistics) as Button changePassword=view.findViewById(R.id.ChangePassword) logout.setOnClickListener{ @@ -41,6 +44,31 @@ class FragmentMyProfileInfo : Fragment() { val intent = Intent (getActivity(), ActivityChangeUserData::class.java) getActivity()?.startActivity(intent) } + + statistics.setOnClickListener { + + val manager: androidx.fragment.app.FragmentManager? = fragmentManager + val transaction: FragmentTransaction = manager!!.beginTransaction() + + var fragment:FragmentProfileStatistics=FragmentProfileStatistics() + val bundle = Bundle() + var parentFragment:FragmentProfile=parentFragment as FragmentProfile + var username=parentFragment.usernameStringSend + bundle.putString("username", username) + fragment.arguments=bundle + + + + transaction.replace(R.id.flFragmentProfileFragmentContainer,fragment ) + transaction.commit() + + + + + + } + + changePassword.setOnClickListener { val intent = Intent (getActivity(), ActivityChangePassword::class.java) getActivity()?.startActivity(intent) 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 6fe4678..a9858e2 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 @@ -60,6 +60,7 @@ class FragmentProfile : Fragment(com.example.brzodolokacije.R.layout.fragment_pr private lateinit var profilePicturePlus: MaterialButton private lateinit var showFollowers: TextView private lateinit var showFollowing: TextView + public var usernameStringSend:String?=null override fun onCreateView( @@ -208,6 +209,7 @@ class FragmentProfile : Fragment(com.example.brzodolokacije.R.layout.fragment_pr private fun setUserInfo(user:UserReceive){ name.setText(user.name) username.setText("@"+user.username) + usernameStringSend=user.username postsCount.setText(user.postcount.toString()) Log.d("follno",user.followersCount.toString()) Log.d("follno","helllllllllllllllllllllppppppppppppppppppppppppppppppp") diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentSinglePostDescription.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentSinglePostDescription.kt index 1f17a11..6e37052 100644 --- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentSinglePostDescription.kt +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentSinglePostDescription.kt @@ -1,21 +1,24 @@ package com.example.brzodolokacije.Fragments +import android.content.Intent import android.os.Bundle import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import android.widget.ImageButton +import android.widget.Button import android.widget.ImageView import android.widget.TextView -import android.widget.Toast +import androidx.core.view.isGone +import androidx.core.view.isVisible import androidx.fragment.app.Fragment +import com.example.brzodolokacije.Activities.ActivitySinglePost +import com.example.brzodolokacije.Activities.NavigationActivity import com.example.brzodolokacije.Models.* import com.example.brzodolokacije.R import com.example.brzodolokacije.Services.RetrofitHelper import com.example.brzodolokacije.Services.SharedPreferencesHelper import com.google.gson.Gson -import org.w3c.dom.Text import retrofit2.Call import retrofit2.Response @@ -30,6 +33,13 @@ class FragmentSinglePostDescription : Fragment() { private lateinit var star5:ImageView private var starNumber:Number=0 private lateinit var post:PostPreview + private lateinit var parentact:ActivitySinglePost + private lateinit var ocenitext:TextView + private lateinit var userid:String + private lateinit var del:TextView + private lateinit var delbtn:Button + private lateinit var delbtnY:Button + private lateinit var delbtnN:Button override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, @@ -37,7 +47,7 @@ class FragmentSinglePostDescription : Fragment() { ): View? { var view=inflater.inflate(R.layout.fragment_single_post_description, container, false) - + parentact = activity as ActivitySinglePost //uzmi post prosledjen iz single post @@ -45,10 +55,18 @@ class FragmentSinglePostDescription : Fragment() { var jsonPostObject = args!!.getString("post") post= Gson().fromJson(jsonPostObject, PostPreview::class.java) + //setuj opis descriptionContainer=view.findViewById(R.id.tvDescription) descriptionContainer.text=post.description.toString() + + del=view.findViewById(R.id.tvObrisi) + delbtn=view.findViewById(R.id.btnObrisi) + delbtnY=view.findViewById(R.id.btnObrisiY) + delbtnN=view.findViewById(R.id.btnObrisiN) + userid="" + ocenitext=view.findViewById(R.id.title) //setuj zvezdice star1=view.findViewById(R.id.rateStar1) star2=view.findViewById(R.id.rateStar2) @@ -57,15 +75,17 @@ class FragmentSinglePostDescription : Fragment() { star5=view.findViewById(R.id.rateStar5) setRatingListeners() + val alreadyrated= RatingReceive(starNumber.toInt(),post._id) requestAddRating(alreadyrated) - + toggleStarRatings() return view } fun setRatingListeners() { val emptyStar = R.drawable.ic_round_star_outline_24 val fullStar = R.drawable.ic_baseline_star_rate_24 + val offStar = R.drawable.ic_baseline_star_24 star1.setOnClickListener { //Toast.makeText(this,"kliknuta prva zvezdica",Toast.LENGTH_SHORT).show() @@ -140,9 +160,11 @@ class FragmentSinglePostDescription : Fragment() { "--------------", data.ratings.toString() + " " + data.ratingscount.toString() ) + parentact.updateratings(data.ratingscount,data.ratings) if(rating.rating==0) { val emptyStar = R.drawable.empty_star val fullStar = R.drawable.ic_baseline_star_rate_24 + when (data.myrating) { 1 -> { star1.setImageResource(fullStar) @@ -204,4 +226,97 @@ class FragmentSinglePostDescription : Fragment() { } }) } + fun toggleStarRatings(){ + var token= SharedPreferencesHelper.getValue("jwt", requireActivity()).toString() + val api= RetrofitHelper.getInstance() + val request= api.getUserId("Bearer " + token) + request.enqueue(object : retrofit2.Callback<String> { + override fun onResponse(call: Call<String>, + response: Response<String> + ) { + if (response.body() == null) { + return + } + userid=response.body().toString() + Log.d("UID TEST",userid) + if(post.ownerId==userid){ + //val offStar = R.drawable.ic_baseline_star_24 + ocenitext.text="Vlasnik posta ne moze ocenjivati sebe" + /*star1.setImageResource(offStar) + star2.setImageResource(offStar) + star3.setImageResource(offStar) + star4.setImageResource(offStar) + star5.setImageResource(offStar)*/ + star1.isEnabled=false + star2.isEnabled=false + star3.isEnabled=false + star4.isEnabled=false + star5.isEnabled=false + + ocenitext.isVisible=false + ocenitext.isGone=true + star1.isVisible=false + star1.isGone=true + star2.isVisible=false + star2.isGone=true + star3.isVisible=false + star3.isGone=true + star4.isVisible=false + star4.isGone=true + star5.isVisible=false + star5.isGone=true + + delbtn.isGone=false + delbtn.setOnClickListener{ + del.isGone=false + delbtnY.isGone=false + delbtnN.isGone=false + delbtn.isGone=true + delbtnY.setOnClickListener { + deletePostreq() + } + delbtnN.setOnClickListener { + del.isGone=true + delbtnY.isGone=true + delbtnN.isGone=true + delbtn.isGone=false + } + } + + + } + } + + override fun onFailure(call: Call<String>, t: Throwable) { + + } + }) + + + } + + fun deletePostreq(){ + var token= SharedPreferencesHelper.getValue("jwt", requireActivity()).toString() + val api= RetrofitHelper.getInstance() + val request= api.DeletePost("Bearer " + token,post._id) + request.enqueue(object : retrofit2.Callback<String> { + override fun onResponse( + call: Call<String>, + response: Response<String> + ) { + if(response.isSuccessful){ + SharedPreferencesHelper.addValue("jwt",token,activity!!) + val intent= Intent(activity!!, NavigationActivity::class.java) + startActivity(intent) + activity!!.finish() + } + + } + + override fun onFailure(call: Call<String>, t: Throwable) { + + } + }) + } + }
\ 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 960c56d..cc04669 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 @@ -1,10 +1,7 @@ package com.example.brzodolokacije.Interfaces import com.example.brzodolokacije.Models.* -import com.example.brzodolokacije.Models.Auth.JustMail -import com.example.brzodolokacije.Models.Auth.Login -import com.example.brzodolokacije.Models.Auth.Register -import com.example.brzodolokacije.Models.Auth.ResetPass +import com.example.brzodolokacije.Models.Auth.* import okhttp3.MultipartBody import okhttp3.RequestBody import okhttp3.ResponseBody @@ -123,6 +120,11 @@ interface IBackendApi { @POST("/api/user/changePass") - fun changePass(@Header("Authorization") authHeader:String):Call<Int> - + fun changePass(@Header("Authorization") authHeader:String,@Body changePass:ChangePass):Call<Int> + @GET("/api/user/{username}/profile/stats") + fun getUserStatsFromUsername(@Header("Authorization") authHeader:String,@Path("username") username:String):Call<Statistics> + @GET("/api/auth/jwttoid") + fun getUserId(@Header("Authorization") authHeader:String):Call<String> + @DELETE("api/Post/posts/delete/{id}") + fun DeletePost(@Header("Authorization") authHeader:String,@Path("id") id:String):Call<String> }
\ No newline at end of file diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/MainActivity.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/MainActivity.kt index acce7b3..885f7f2 100644 --- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/MainActivity.kt +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/MainActivity.kt @@ -9,7 +9,6 @@ import com.example.brzodolokacije.Activities.ActivityLoginRegister import com.example.brzodolokacije.Activities.NavigationActivity import com.example.brzodolokacije.Services.RetrofitHelper import com.example.brzodolokacije.Services.SharedPreferencesHelper -import com.example.brzodolokacije.chat.Notifications import retrofit2.Call import retrofit2.Response @@ -23,7 +22,6 @@ class MainActivity : AppCompatActivity() { val intent:Intent if(checkLoggedIn()) { - Notifications.makeChannel(this) intent = Intent(this, NavigationActivity::class.java) } else @@ -64,6 +62,9 @@ class MainActivity : AppCompatActivity() { }else{ if(response.errorBody()!=null) Toast.makeText(applicationContext, response.errorBody()!!.string(), Toast.LENGTH_LONG).show(); + intent= Intent(this@MainActivity, ActivityLoginRegister::class.java) + SharedPreferencesHelper.removeValue("jwt",this@MainActivity) + startActivity(intent) } diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Models/Auth/ChangePass.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Models/Auth/ChangePass.kt new file mode 100644 index 0000000..46957df --- /dev/null +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Models/Auth/ChangePass.kt @@ -0,0 +1,6 @@ +package com.example.brzodolokacije.Models.Auth + +data class ChangePass( + var currentPass:String, + var newPass:String +) diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Models/Statistics.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Models/Statistics.kt new file mode 100644 index 0000000..4466e05 --- /dev/null +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Models/Statistics.kt @@ -0,0 +1,18 @@ +package com.example.brzodolokacije.Models + +import android.os.Parcelable +import kotlinx.android.parcel.Parcelize +data class Statistics( + var totalViews:Int, + var numberOfPosts:Int, + var numberOfRatingsOnPosts:Int, + var averagePostRatingOnPosts:Double, + var monthlyViews:List<MonthlyViews>, + var numberOfFavouritePosts:Int +) +@Parcelize +data class MonthlyViews( + var month:Int, + var views:Int +):Parcelable + diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/chat/SignalRListener.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/chat/SignalRListener.kt index 35088a5..49d76c9 100644 --- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/chat/SignalRListener.kt +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/chat/SignalRListener.kt @@ -2,16 +2,20 @@ package com.example.brzodolokacije.chat import android.Manifest import android.app.Activity +import android.app.PendingIntent +import android.content.Intent import android.content.pm.PackageManager import android.graphics.Color import android.util.Log import android.widget.Toast import androidx.core.app.NotificationCompat import androidx.core.app.NotificationManagerCompat +import androidx.core.app.TaskStackBuilder import androidx.core.content.ContextCompat import com.auth0.android.jwt.JWT import com.exam.DBHelper import com.example.brzodolokacije.Activities.ChatActivity +import com.example.brzodolokacije.Activities.ChatActivityConversation import com.example.brzodolokacije.Models.Message import com.example.brzodolokacije.Models.MessageReceive import com.example.brzodolokacije.Models.UserReceive @@ -84,33 +88,40 @@ class SignalRListener private constructor(val activity: Activity){ } activity.onRefresh() } - when { - ContextCompat.checkSelfPermission(activity, - Manifest.permission.POST_NOTIFICATIONS) == PackageManager.PERMISSION_GRANTED -> { - //poslati notifikaciju - var api=RetrofitHelper.getInstance() - var token=SharedPreferencesHelper.getValue("jwt",activity) - val request2=api?.getProfileFromId("Bearer "+token, - message.senderId - ) - request2?.enqueue(object : retrofit2.Callback<UserReceive?> { - override fun onResponse(call: Call<UserReceive?>, response: Response<UserReceive?>) { - if(response.isSuccessful()){ - var user=response.body()!! - createNotification(message,user,activity) - } - } - - override fun onFailure(call: Call<UserReceive?>, t: Throwable) { - //TODO("Not yet implemented") + if(ContextCompat.checkSelfPermission(activity, + Manifest.permission.POST_NOTIFICATIONS) == PackageManager.PERMISSION_GRANTED || SharedPreferencesHelper.getValue("notifications",activity)=="true"){ + //poslati notifikaciju + var api=RetrofitHelper.getInstance() + var token=SharedPreferencesHelper.getValue("jwt",activity) + val request2=api?.getProfileFromId("Bearer "+token, + message.senderId + ) + request2?.enqueue(object : retrofit2.Callback<UserReceive?> { + override fun onResponse(call: Call<UserReceive?>, response: Response<UserReceive?>) { + if(response.isSuccessful()){ + var user=response.body()!! + createNotification(message,user,activity) } - }) } - } + override fun onFailure(call: Call<UserReceive?>, t: Throwable) { + //TODO("Not yet implemented") + } + }) + } } fun createNotification(message: MessageReceive,user: UserReceive,activity: Activity){ + val resultIntent = Intent(activity, ChatActivityConversation::class.java) + resultIntent.putExtra("userId",user._id) + resultIntent.putExtra("username",user.username) + resultIntent.putExtra("pfp",user.pfp?._id) + val resultPendingIntent: PendingIntent? = TaskStackBuilder.create(activity).run { + addNextIntentWithParentStack(resultIntent) + getPendingIntent(0, + PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE) + } + val notificationBuilder = NotificationCompat.Builder(activity, Notifications.CHANNEL_ID) .setSmallIcon(R.drawable.ic_round_chat_24) .setAutoCancel(true) @@ -120,6 +131,7 @@ class SignalRListener private constructor(val activity: Activity){ .setContentTitle(user.username) .setContentText(message.messagge) .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) + .setContentIntent(resultPendingIntent) val notificationManager = NotificationManagerCompat.from(activity) val notification = notificationBuilder.build() notificationManager.notify(NotificationID.iD, notification) diff --git a/Client/BrzoDoLokacije/app/src/main/res/drawable/ic_baseline_calendar_month_24.xml b/Client/BrzoDoLokacije/app/src/main/res/drawable/ic_baseline_calendar_month_24.xml new file mode 100644 index 0000000..a278444 --- /dev/null +++ b/Client/BrzoDoLokacije/app/src/main/res/drawable/ic_baseline_calendar_month_24.xml @@ -0,0 +1,5 @@ +<vector android:height="24dp" android:tint="#747474" + android:viewportHeight="24" android:viewportWidth="24" + android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M19,4h-1V2h-2v2H8V2H6v2H5C3.89,4 3.01,4.9 3.01,6L3,20c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2V6C21,4.9 20.1,4 19,4zM19,20H5V10h14V20zM9,14H7v-2h2V14zM13,14h-2v-2h2V14zM17,14h-2v-2h2V14zM9,18H7v-2h2V18zM13,18h-2v-2h2V18zM17,18h-2v-2h2V18z"/> +</vector> diff --git a/Client/BrzoDoLokacije/app/src/main/res/drawable/ic_baseline_favorite_24.xml b/Client/BrzoDoLokacije/app/src/main/res/drawable/ic_baseline_favorite_24.xml index 84df34b..2dbc440 100644 --- a/Client/BrzoDoLokacije/app/src/main/res/drawable/ic_baseline_favorite_24.xml +++ b/Client/BrzoDoLokacije/app/src/main/res/drawable/ic_baseline_favorite_24.xml @@ -1,4 +1,4 @@ -<vector android:height="24dp" android:tint="#E52121" +<vector android:height="24dp" android:tint="#747474" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> <path android:fillColor="@android:color/white" android:pathData="M12,21.35l-1.45,-1.32C5.4,15.36 2,12.28 2,8.5 2,5.42 4.42,3 7.5,3c1.74,0 3.41,0.81 4.5,2.09C13.09,3.81 14.76,3 16.5,3 19.58,3 22,5.42 22,8.5c0,3.78 -3.4,6.86 -8.55,11.54L12,21.35z"/> diff --git a/Client/BrzoDoLokacije/app/src/main/res/drawable/ic_baseline_star_24.xml b/Client/BrzoDoLokacije/app/src/main/res/drawable/ic_baseline_star_24.xml new file mode 100644 index 0000000..88f8d7a --- /dev/null +++ b/Client/BrzoDoLokacije/app/src/main/res/drawable/ic_baseline_star_24.xml @@ -0,0 +1,5 @@ +<vector android:height="24dp" android:tint="#747474" + android:viewportHeight="24" android:viewportWidth="24" + android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,17.27L18.18,21l-1.64,-7.03L22,9.24l-7.19,-0.61L12,2 9.19,8.63 2,9.24l5.46,4.73L5.82,21z"/> +</vector> diff --git a/Client/BrzoDoLokacije/app/src/main/res/drawable/ic_baseline_star_half_24.xml b/Client/BrzoDoLokacije/app/src/main/res/drawable/ic_baseline_star_half_24.xml new file mode 100644 index 0000000..d532b23 --- /dev/null +++ b/Client/BrzoDoLokacije/app/src/main/res/drawable/ic_baseline_star_half_24.xml @@ -0,0 +1,5 @@ +<vector android:autoMirrored="true" android:height="24dp" + android:tint="#747474" android:viewportHeight="24" + android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M22,9.24l-7.19,-0.62L12,2L9.19,8.63L2,9.24l5.46,4.73L5.82,21L12,17.27L18.18,21l-1.63,-7.03L22,9.24zM12,15.4V6.1l1.71,4.04l4.38,0.38l-3.32,2.88l1,4.28L12,15.4z"/> +</vector> diff --git a/Client/BrzoDoLokacije/app/src/main/res/drawable/ic_total_views.xml b/Client/BrzoDoLokacije/app/src/main/res/drawable/ic_total_views.xml new file mode 100644 index 0000000..3b4e7d5 --- /dev/null +++ b/Client/BrzoDoLokacije/app/src/main/res/drawable/ic_total_views.xml @@ -0,0 +1,5 @@ +<vector android:height="24dp" android:tint="#747474" + android:viewportHeight="24" android:viewportWidth="24" + android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,6.5c3.79,0 7.17,2.13 8.82,5.5 -1.65,3.37 -5.02,5.5 -8.82,5.5S4.83,15.37 3.18,12C4.83,8.63 8.21,6.5 12,6.5m0,-2C7,4.5 2.73,7.61 1,12c1.73,4.39 6,7.5 11,7.5s9.27,-3.11 11,-7.5c-1.73,-4.39 -6,-7.5 -11,-7.5zM12,9.5c1.38,0 2.5,1.12 2.5,2.5s-1.12,2.5 -2.5,2.5 -2.5,-1.12 -2.5,-2.5 1.12,-2.5 2.5,-2.5m0,-2c-2.48,0 -4.5,2.02 -4.5,4.5s2.02,4.5 4.5,4.5 4.5,-2.02 4.5,-4.5 -2.02,-4.5 -4.5,-4.5z"/> +</vector> diff --git a/Client/BrzoDoLokacije/app/src/main/res/layout/activity_opened_images.xml b/Client/BrzoDoLokacije/app/src/main/res/layout/activity_opened_images.xml new file mode 100644 index 0000000..3a1fbbc --- /dev/null +++ b/Client/BrzoDoLokacije/app/src/main/res/layout/activity_opened_images.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + tools:context=".Activities.ActivityOpenedImages" + android:background="@color/design_default_color_background"> + <androidx.constraintlayout.widget.ConstraintLayout + android:layout_width="match_parent" + android:layout_height="50dp" + android:elevation="5dp" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintStart_toStartOf="parent" + android:background="@color/unfollow_transparent" + android:id="@+id/clImageHeader"> + <ImageButton + android:layout_width="50dp" + android:layout_height="50dp" + app:layout_constraintStart_toStartOf="parent" + android:background="@null" + android:src="@drawable/ic_baseline_arrow_back" + android:id="@+id/btnBackToPost"/> + + <ImageButton + android:layout_width="50dp" + android:layout_height="50dp" + app:layout_constraintEnd_toEndOf="parent" + android:background="@null" + android:src="@drawable/ic_baseline_arrow_back" + android:id="@+id/btnDownload"/> + </androidx.constraintlayout.widget.ConstraintLayout> + <androidx.appcompat.widget.LinearLayoutCompat + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical" + android:id="@+id/rvParent"> + + <androidx.recyclerview.widget.RecyclerView + android:layout_width="match_parent" + android:layout_height="match_parent" + android:id="@+id/rvImages"/> + </androidx.appcompat.widget.LinearLayoutCompat> + +</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file 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 68615f2..4924a1f 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 @@ -89,11 +89,23 @@ android:gravity="top|start" android:padding="@dimen/text_padding" android:text="User" - android:textSize="17dp" + android:textSize="20dp" android:textStyle="bold" + android:textColor="#FF03DAC5" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/tvLocationType" /> + <TextView + android:id="@+id/tvDatePosted" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginEnd="16dp" + android:gravity="top|start" + android:padding="@dimen/text_padding" + android:text="Timestamp" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toBottomOf="@+id/tvLocationType" /> + <LinearLayout android:id="@+id/llTags" android:layout_width="match_parent" diff --git a/Client/BrzoDoLokacije/app/src/main/res/layout/chat_preview.xml b/Client/BrzoDoLokacije/app/src/main/res/layout/chat_preview.xml index 91a8605..694cabe 100644 --- a/Client/BrzoDoLokacije/app/src/main/res/layout/chat_preview.xml +++ b/Client/BrzoDoLokacije/app/src/main/res/layout/chat_preview.xml @@ -8,6 +8,8 @@ android:layout_width="5dp" android:id="@+id/readIndicator" android:layout_height="5dp" + android:background="@drawable/rounded_picture_background" + android:backgroundTint="@null" android:layout_gravity="center_vertical"/> <ImageView android:id="@+id/ivUserImage" diff --git a/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_home_page_main_scroll.xml b/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_home_page_main_scroll.xml index 07d34a3..b64eb0f 100644 --- a/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_home_page_main_scroll.xml +++ b/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_home_page_main_scroll.xml @@ -1,240 +1,248 @@ <?xml version="1.0" encoding="utf-8"?> -<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" +<androidx.swiperefreshlayout.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" + tools:context=".Fragments.FragmentHomePageMainScroll" android:layout_width="match_parent" android:layout_height="match_parent" - xmlns:app="http://schemas.android.com/apk/res-auto" - tools:context=".Fragments.FragmentHomePageMainScroll"> - -<LinearLayout - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="vertical"> + android:id="@+id/swipeContainer"> + <ScrollView - <androidx.cardview.widget.CardView - android:backgroundTint="#f6f6f6" - android:layout_marginStart="10dp" - android:layout_marginEnd="16dp" -app:cardElevation="0dp" - android:id="@+id/cvFragmentHomePageText2" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:stateListAnimator="@null" - android:elevation="0dp" - android:layout_marginTop="16dp"> - - <TextView - android:id="@+id/tvFragmentHomePageNewest" - android:layout_width="wrap_content" - android:layout_height="match_parent" - android:layout_gravity="left" - android:text="Najnovije" - android:clickable="true" - android:textStyle="bold" /> - - - <TextView - android:id="@+id/tvFragmentHomePageNewestShowAll" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="right" - android:clickable="true" - android:text="Prikaži sve" /> - </androidx.cardview.widget.CardView> - - <androidx.recyclerview.widget.RecyclerView - android:layout_marginStart="16dp" - android:layout_marginEnd="16dp" - android:id="@+id/rvFragmentHomePageNewest" - android:layout_marginBottom="20dp" android:layout_width="match_parent" - android:layout_height="wrap_content" /> - - <HorizontalScrollView - android:layout_marginStart="16dp" - android:layout_marginEnd="16dp" - android:id="@+id/hsvFragmentHomePageLocationButtonScroll" - android:layout_width="match_parent" - android:layout_height="wrap_content" - + android:layout_height="match_parent" + xmlns:app="http://schemas.android.com/apk/res-auto" > <LinearLayout - android:id="@+id/llFragmentHomePageLocationButtonLayout" - android:layout_width="wrap_content" - android:layout_height="match_parent"> - - <ImageButton - android:id="@+id/btnFragmentHomePagelocation_city" - android:layout_width="60dp" - android:layout_height="60dp" - android:layout_marginRight="10dp" - android:background="@drawable/location_city" - tools:ignore="SpeakableTextPresentCheck" /> - - <ImageButton - android:id="@+id/btnFragmentHomePagelocation_beach" - android:layout_width="60dp" - android:layout_height="60dp" - android:layout_marginRight="10dp" - android:background="@drawable/location_beach" - tools:ignore="SpeakableTextPresentCheck" /> - - <ImageButton - android:id="@+id/btnFragmentHomePagelocation_mountain" - android:layout_width="60dp" - android:layout_height="60dp" - android:layout_marginRight="10dp" - android:background="@drawable/location_mountain" - tools:ignore="SpeakableTextPresentCheck" /> - - <ImageButton - android:id="@+id/btnFragmentHomePagelocation_lake" - android:layout_width="60dp" - android:layout_height="match_parent" - android:layout_marginRight="10dp" - android:background="@drawable/location_lake" - tools:ignore="SpeakableTextPresentCheck" /> - - <ImageButton - android:id="@+id/btnFragmentHomePagelocation_spa" - android:layout_width="60dp" - android:layout_height="60dp" - android:layout_marginRight="10dp" - android:background="@drawable/location_spa" - tools:ignore="SpeakableTextPresentCheck" /> - - <ImageButton - android:id="@+id/btnFragmentHomePagelocation_waterfall" - android:layout_width="60dp" - android:layout_height="60dp" - android:layout_marginRight="10dp" - android:background="@drawable/location_waterfall" - tools:ignore="SpeakableTextPresentCheck" /> - - <ImageButton - android:id="@+id/btnFragmentHomePagelocation_amusement_park" - android:layout_width="60dp" - android:layout_height="60dp" - android:layout_marginRight="10dp" - android:background="@drawable/location_amusement_park" - tools:ignore="SpeakableTextPresentCheck" /> - - <ImageButton - android:id="@+id/btnFragmentHomePagelocation_attraction" - android:layout_width="60dp" - android:layout_height="60dp" - android:layout_marginRight="10dp" - android:background="@drawable/location_attraction" - tools:ignore="SpeakableTextPresentCheck" /> - - <ImageButton - android:id="@+id/btnFragmentHomePagelocation_landmark" - android:layout_width="60dp" - android:layout_height="60dp" - android:layout_marginRight="10dp" - android:background="@drawable/location_landmark" - tools:ignore="SpeakableTextPresentCheck" /> - - </LinearLayout> - </HorizontalScrollView> - <LinearLayout - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="horizontal"> - - <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> -<LinearLayout - android:orientation="vertical" - android:id="@+id/ll1" - android:layout_width="match_parent" - android:layout_height="wrap_content"> - <androidx.cardview.widget.CardView - android:backgroundTint="#f6f6f6" - android:layout_marginTop="16dp" - android:id="@+id/cvFragmentHomePageText1" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginStart="16dp" - android:layout_marginEnd="16dp" - android:elevation="0dp" - app:cardElevation="0dp" - > - - <TextView - android:id="@+id/tvFragmentHomePagePopular" - android:layout_width="wrap_content" - android:layout_height="match_parent" - android:layout_gravity="left" - android:text="Popularno" - android:textStyle="bold" /> - - <TextView - android:id="@+id/tvFragmentHomePagePopularShowAll" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="right" - android:clickable="true" - android:text="Prikaži sve" - - tools:ignore="TouchTargetSizeCheck" /> - </androidx.cardview.widget.CardView> - - <androidx.recyclerview.widget.RecyclerView - android:id="@+id/rvFragmentHomePagePopular" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginStart="16dp" - android:layout_marginEnd="16dp" - android:layout_marginBottom="16dp" /> - - </LinearLayout> - <LinearLayout - android:id="@+id/ll2" - - android:orientation="vertical" - android:layout_width="match_parent" - android:layout_height="wrap_content"> - <androidx.cardview.widget.CardView - android:backgroundTint="#f6f6f6" -app:cardElevation="0dp" - android:layout_marginStart="16dp" - android:layout_marginEnd="16dp" - android:id="@+id/cvFragmentHomePageText3" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginTop="16dp"> - <TextView - android:id="@+id/tvFragmentHomePageBestRated" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="left" - android:text="Najbolje ocenjeno" - android:textStyle="bold" /> - - <TextView - android:id="@+id/tvFragmentHomePageBestRatedShowAll" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="right" - android:clickable="true" - android:text="Prikaži sve" /> - </androidx.cardview.widget.CardView> - - <androidx.recyclerview.widget.RecyclerView - android:layout_marginStart="16dp" - android:layout_marginEnd="16dp" - android:id="@+id/rvFragmentHomePageBestRated" - android:layout_width="match_parent" - android:layout_height="wrap_content" /> - -</LinearLayout></LinearLayout> -</LinearLayout> -</LinearLayout> -</ScrollView>
\ No newline at end of file + <androidx.cardview.widget.CardView + android:backgroundTint="#f6f6f6" + android:layout_marginStart="10dp" + android:layout_marginEnd="16dp" + app:cardElevation="0dp" + android:id="@+id/cvFragmentHomePageText2" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:stateListAnimator="@null" + android:elevation="0dp" + android:layout_marginTop="16dp"> + + <TextView + android:id="@+id/tvFragmentHomePageNewest" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:layout_gravity="left" + android:text="Najnovije" + android:clickable="true" + android:textStyle="bold" /> + + + <TextView + android:id="@+id/tvFragmentHomePageNewestShowAll" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="right" + android:clickable="true" + android:text="Prikaži sve" /> + </androidx.cardview.widget.CardView> + + <androidx.recyclerview.widget.RecyclerView + android:layout_marginStart="16dp" + android:layout_marginEnd="16dp" + android:id="@+id/rvFragmentHomePageNewest" + android:layout_marginBottom="20dp" + android:layout_width="match_parent" + android:layout_height="wrap_content" /> + + <HorizontalScrollView + android:layout_marginStart="16dp" + android:layout_marginEnd="16dp" + android:id="@+id/hsvFragmentHomePageLocationButtonScroll" + android:layout_width="match_parent" + android:layout_height="wrap_content" + + > + + <LinearLayout + android:id="@+id/llFragmentHomePageLocationButtonLayout" + android:layout_width="wrap_content" + android:layout_height="match_parent"> + + <ImageButton + android:id="@+id/btnFragmentHomePagelocation_city" + android:layout_width="60dp" + android:layout_height="60dp" + android:layout_marginRight="10dp" + android:background="@drawable/location_city" + tools:ignore="SpeakableTextPresentCheck" /> + + <ImageButton + android:id="@+id/btnFragmentHomePagelocation_beach" + android:layout_width="60dp" + android:layout_height="60dp" + android:layout_marginRight="10dp" + android:background="@drawable/location_beach" + tools:ignore="SpeakableTextPresentCheck" /> + + <ImageButton + android:id="@+id/btnFragmentHomePagelocation_mountain" + android:layout_width="60dp" + android:layout_height="60dp" + android:layout_marginRight="10dp" + android:background="@drawable/location_mountain" + tools:ignore="SpeakableTextPresentCheck" /> + + <ImageButton + android:id="@+id/btnFragmentHomePagelocation_lake" + android:layout_width="60dp" + android:layout_height="match_parent" + android:layout_marginRight="10dp" + android:background="@drawable/location_lake" + tools:ignore="SpeakableTextPresentCheck" /> + + <ImageButton + android:id="@+id/btnFragmentHomePagelocation_spa" + android:layout_width="60dp" + android:layout_height="60dp" + android:layout_marginRight="10dp" + android:background="@drawable/location_spa" + tools:ignore="SpeakableTextPresentCheck" /> + + <ImageButton + android:id="@+id/btnFragmentHomePagelocation_waterfall" + android:layout_width="60dp" + android:layout_height="60dp" + android:layout_marginRight="10dp" + android:background="@drawable/location_waterfall" + tools:ignore="SpeakableTextPresentCheck" /> + + <ImageButton + android:id="@+id/btnFragmentHomePagelocation_amusement_park" + android:layout_width="60dp" + android:layout_height="60dp" + android:layout_marginRight="10dp" + android:background="@drawable/location_amusement_park" + tools:ignore="SpeakableTextPresentCheck" /> + + <ImageButton + android:id="@+id/btnFragmentHomePagelocation_attraction" + android:layout_width="60dp" + android:layout_height="60dp" + android:layout_marginRight="10dp" + android:background="@drawable/location_attraction" + tools:ignore="SpeakableTextPresentCheck" /> + + <ImageButton + android:id="@+id/btnFragmentHomePagelocation_landmark" + android:layout_width="60dp" + android:layout_height="60dp" + android:layout_marginRight="10dp" + android:background="@drawable/location_landmark" + tools:ignore="SpeakableTextPresentCheck" /> + + </LinearLayout> + </HorizontalScrollView> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical"> + <LinearLayout + android:orientation="vertical" + android:id="@+id/ll1" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + <androidx.cardview.widget.CardView + android:backgroundTint="#f6f6f6" + android:layout_marginTop="16dp" + android:id="@+id/cvFragmentHomePageText1" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginStart="16dp" + android:layout_marginEnd="16dp" + android:elevation="0dp" + app:cardElevation="0dp" + > + + <TextView + android:id="@+id/tvFragmentHomePagePopular" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:layout_gravity="left" + android:text="Popularno" + android:textStyle="bold" /> + + <TextView + android:id="@+id/tvFragmentHomePagePopularShowAll" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="right" + android:clickable="true" + android:text="Prikaži sve" + + tools:ignore="TouchTargetSizeCheck" /> + + </androidx.cardview.widget.CardView> + + <androidx.recyclerview.widget.RecyclerView + android:id="@+id/rvFragmentHomePagePopular" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginStart="16dp" + android:layout_marginEnd="16dp" + android:layout_marginBottom="16dp" /> + + </LinearLayout> + <LinearLayout + android:id="@+id/ll2" + + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + <androidx.cardview.widget.CardView + android:backgroundTint="#f6f6f6" + app:cardElevation="0dp" + android:layout_marginStart="16dp" + android:layout_marginEnd="16dp" + android:id="@+id/cvFragmentHomePageText3" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="16dp"> + + <TextView + android:id="@+id/tvFragmentHomePageBestRated" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="left" + android:text="Najbolje ocenjeno" + android:textStyle="bold" /> + + <TextView + android:id="@+id/tvFragmentHomePageBestRatedShowAll" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="right" + android:clickable="true" + android:text="Prikaži sve" /> + </androidx.cardview.widget.CardView> + + <androidx.recyclerview.widget.RecyclerView + android:layout_marginStart="16dp" + android:layout_marginEnd="16dp" + android:id="@+id/rvFragmentHomePageBestRated" + android:layout_width="match_parent" + android:layout_height="wrap_content" /> + + </LinearLayout></LinearLayout> + </LinearLayout> + </LinearLayout> + </ScrollView> +</androidx.swiperefreshlayout.widget.SwipeRefreshLayout> diff --git a/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_profile_statistics.xml b/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_profile_statistics.xml new file mode 100644 index 0000000..ca60334 --- /dev/null +++ b/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_profile_statistics.xml @@ -0,0 +1,180 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + tools:context=".FragmentProfileStatistics" + android:padding="16dp" + > + + <LinearLayout + android:id="@+id/linearLayout8" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + + android:orientation="vertical" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent"> + + <LinearLayout + android:id="@+id/linearLayout3" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="horizontal" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent"> + + <ImageView + android:layout_width="50dp" + android:layout_height="50dp" + android:src="@drawable/ic_total_views" /> + + <TextView + android:layout_width="100dp" + android:layout_height="match_parent" + android:layout_marginRight="5dp" + android:gravity="center" + android:text="Broj pregleda" /> + + <TextView + android:id="@+id/tvProfileStatisticsViews" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:gravity="center" + android:text="0" + android:textSize="20dp" /> + + </LinearLayout> + + <LinearLayout + android:id="@+id/linearLayout4" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="horizontal" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/linearLayout3"> + + <ImageView + android:layout_width="50dp" + android:layout_height="50dp" + android:src="@drawable/ic_baseline_star_24" /> + + <TextView + android:layout_width="100dp" + android:layout_height="match_parent" + android:layout_marginRight="5dp" + android:gravity="center" + android:text="Broj ocena" /> + + <TextView + android:id="@+id/tvProfileStatisticsRatingNumber" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:gravity="center" + android:text="0" + android:textSize="20dp" /> + + </LinearLayout> + + <LinearLayout + android:id="@+id/linearLayout5" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="horizontal" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/linearLayout4"> + + <ImageView + android:layout_width="50dp" + android:layout_height="50dp" + android:src="@drawable/ic_baseline_star_half_24" /> + + <TextView + android:layout_width="100dp" + android:layout_height="match_parent" + android:layout_marginRight="5dp" + android:gravity="center" + android:text="Prosečna ocena po objavi" /> + + <TextView + android:id="@+id/tvProfileStatisticsAverageRating" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:gravity="center" + android:text="0" + android:textSize="20dp" /> + + + </LinearLayout> + + <LinearLayout + android:id="@+id/linearLayout7" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="horizontal" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/linearLayout5"> + + <ImageView + android:layout_width="50dp" + android:layout_height="50dp" + android:src="@drawable/ic_baseline_favorite_24" /> + + <TextView + android:layout_width="100dp" + android:layout_height="match_parent" + android:layout_marginRight="5dp" + android:gravity="center" + android:text="Broj omiljenih objava" /> + + <TextView + android:id="@+id/tvProfileStatisticsFavouriteNumber" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:gravity="center" + android:text="0" + android:textSize="20dp" /> + + + </LinearLayout> + + <LinearLayout + android:id="@+id/linearLayout6" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="horizontal" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/linearLayout7"> + + <ImageView + android:layout_width="50dp" + android:layout_height="50dp" + android:src="@drawable/ic_baseline_calendar_month_24" /> + + <TextView + android:layout_width="100dp" + android:layout_height="match_parent" + android:layout_marginRight="5dp" + android:gravity="center" + android:text="Pregledi po mesecima" /> + + </LinearLayout> + + + </LinearLayout> + + <androidx.recyclerview.widget.RecyclerView + android:id="@+id/rvFragmentProfileStatisticsMonths" + android:layout_width="match_parent" + android:layout_height="wrap_content" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/linearLayout8" /> +</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file diff --git a/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_single_post_comments.xml b/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_single_post_comments.xml index 005c802..91f1fd7 100644 --- a/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_single_post_comments.xml +++ b/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_single_post_comments.xml @@ -6,7 +6,16 @@ android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".FragmentSinglePostComments"> - +<androidx.core.widget.NestedScrollView + android:layout_width="match_parent" + android:layout_height="wrap_content" + app:layout_constraintTop_toTopOf="parent" + > + <androidx.constraintlayout.widget.ConstraintLayout + android:id="@+id/constraintLayout2" + android:layout_width="match_parent" + android:layout_height="wrap_content" + app:layout_constraintTop_toTopOf="parent"> <androidx.constraintlayout.widget.ConstraintLayout android:id="@+id/constraintLayout" android:layout_width="match_parent" @@ -105,5 +114,7 @@ tools:ignore="SpeakableTextPresentCheck" /> </androidx.cardview.widget.CardView> </androidx.appcompat.widget.LinearLayoutCompat> + </androidx.constraintlayout.widget.ConstraintLayout> +</androidx.core.widget.NestedScrollView> </androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file diff --git a/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_single_post_description.xml b/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_single_post_description.xml index 5bbdb14..f4dcb9d 100644 --- a/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_single_post_description.xml +++ b/Client/BrzoDoLokacije/app/src/main/res/layout/fragment_single_post_description.xml @@ -39,6 +39,8 @@ app:layout_constraintTop_toBottomOf="@+id/tvDescription" /> <LinearLayout + + android:id="@+id/linearLayout9" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="8dp" @@ -47,47 +49,89 @@ app:layout_constraintTop_toBottomOf="@+id/title"> <ImageView - android:clickable="true" android:id="@+id/rateStar1" android:layout_width="50dp" android:layout_height="50dp" + android:clickable="true" android:scaleType="centerCrop" android:src="@drawable/ic_round_star_outline_24" /> <ImageView - android:clickable="true" android:id="@+id/rateStar2" android:layout_width="50dp" android:layout_height="50dp" + android:clickable="true" android:scaleType="centerCrop" android:src="@drawable/ic_round_star_outline_24" /> <ImageView - android:clickable="true" android:id="@+id/rateStar3" android:layout_width="50dp" android:layout_height="50dp" + android:clickable="true" android:scaleType="centerCrop" android:src="@drawable/ic_round_star_outline_24" /> <ImageView - android:clickable="true" android:id="@+id/rateStar4" android:layout_width="50dp" android:layout_height="50dp" + android:clickable="true" android:scaleType="centerCrop" android:src="@drawable/ic_round_star_outline_24" /> <ImageView - android:clickable="true" android:id="@+id/rateStar5" android:layout_width="50dp" android:layout_height="50dp" + android:clickable="true" android:scaleType="centerCrop" android:src="@drawable/ic_round_star_outline_24" /> </LinearLayout> + + <TextView + android:id="@+id/tvObrisi" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="Sigurno? Brisanje je trajno." + android:visibility="gone" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/btnObrisi" /> + + <Button + android:id="@+id/btnObrisi" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="19dp" + android:text="Obrisi objavu" + android:visibility="gone" + android:backgroundTint="#8B0000" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/linearLayout9" /> + + <Button + android:id="@+id/btnObrisiN" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:backgroundTint="#FFFFFF" + android:textColor="@color/cardview_dark_background" + android:layout_marginStart="20dp" + android:text="Odustani" + android:visibility="gone" + app:layout_constraintStart_toEndOf="@+id/btnObrisiY" + app:layout_constraintTop_toBottomOf="@+id/tvObrisi" /> + + <Button + android:id="@+id/btnObrisiY" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="Potvrdi" + android:visibility="gone" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/tvObrisi" /> + <!--<LinearLayout android:id="@+id/linearLayout2" android:layout_width="match_parent" diff --git a/Client/BrzoDoLokacije/app/src/main/res/layout/opened_post_image.xml b/Client/BrzoDoLokacije/app/src/main/res/layout/opened_post_image.xml new file mode 100644 index 0000000..e63a903 --- /dev/null +++ b/Client/BrzoDoLokacije/app/src/main/res/layout/opened_post_image.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + xmlns:app="http://schemas.android.com/apk/res-auto"> + + <com.github.piasy.biv.view.BigImageView + android:layout_width="match_parent" + android:layout_height="match_parent" + app:initScaleType="centerInside" + app:optimizeDisplay="true" + android:id="@+id/ivOpenedImage"/> + +</androidx.appcompat.widget.LinearLayoutCompat>
\ No newline at end of file diff --git a/Client/BrzoDoLokacije/app/src/main/res/layout/single_comment.xml b/Client/BrzoDoLokacije/app/src/main/res/layout/single_comment.xml index 45ecde0..7b8aee7 100644 --- a/Client/BrzoDoLokacije/app/src/main/res/layout/single_comment.xml +++ b/Client/BrzoDoLokacije/app/src/main/res/layout/single_comment.xml @@ -3,8 +3,8 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" + android:id="@+id/llroot" android:orientation="vertical" - android:padding="@dimen/component_padding" xmlns:app="http://schemas.android.com/apk/res-auto"> <androidx.appcompat.widget.LinearLayoutCompat android:layout_width="match_parent" @@ -111,9 +111,23 @@ tools:ignore="SpeakableTextPresentCheck" /> </androidx.cardview.widget.CardView> </androidx.appcompat.widget.LinearLayoutCompat> - <androidx.recyclerview.widget.RecyclerView + <androidx.appcompat.widget.LinearLayoutCompat android:layout_width="match_parent" - android:layout_height="wrap_content" - android:id="@+id/rvReplies"/> + android:layout_height="wrap_content"> + + <androidx.constraintlayout.widget.ConstraintLayout + android:layout_width="2dp" + android:layout_height="match_parent" + android:backgroundTint="@color/unfollow" + android:layout_marginHorizontal="23dp" + android:background="@drawable/rounded_picture_background" + /> + + <androidx.recyclerview.widget.RecyclerView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_weight="1" + android:id="@+id/rvReplies"/> + </androidx.appcompat.widget.LinearLayoutCompat> </androidx.appcompat.widget.LinearLayoutCompat>
\ No newline at end of file diff --git a/Client/BrzoDoLokacije/app/src/main/res/layout/single_date_view.xml b/Client/BrzoDoLokacije/app/src/main/res/layout/single_date_view.xml new file mode 100644 index 0000000..fd4c568 --- /dev/null +++ b/Client/BrzoDoLokacije/app/src/main/res/layout/single_date_view.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:layout_width="150dp" + android:layout_height="50dp"> + + <TextView + android:id="@+id/tvMonth" + android:layout_width="100dp" + android:layout_height="match_parent" + android:gravity="center" + android:text="Mesec" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + + <TextView + android:id="@+id/tvMonthViews" + android:layout_width="50dp" + android:layout_height="match_parent" + android:gravity="center" + android:text="5" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toEndOf="@+id/tvMonth" + app:layout_constraintTop_toTopOf="parent" /> +</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file diff --git a/Client/BrzoDoLokacije/app/src/main/res/values/colors.xml b/Client/BrzoDoLokacije/app/src/main/res/values/colors.xml index 9cd2082..e5ec888 100644 --- a/Client/BrzoDoLokacije/app/src/main/res/values/colors.xml +++ b/Client/BrzoDoLokacije/app/src/main/res/values/colors.xml @@ -8,6 +8,7 @@ <color name="black">#FF000000</color> <color name="white">#FFFFFFFF</color> <color name="unfollow">#c4c4c4</color> + <color name="unfollow_transparent">#66c4c4c4</color> <color name="dark_blue_transparent">#DE093A4C</color> <color name="button_main">#183e4b</color> <color name="grey">#747474</color> |