WIP agregar foto
This commit is contained in:
parent
05962ff483
commit
a07a323f1d
17
.idea/deploymentTargetDropDown.xml
generated
17
.idea/deploymentTargetDropDown.xml
generated
@ -1,17 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="deploymentTargetDropDown">
|
|
||||||
<targetSelectedWithDropDown>
|
|
||||||
<Target>
|
|
||||||
<type value="QUICK_BOOT_TARGET" />
|
|
||||||
<deviceKey>
|
|
||||||
<Key>
|
|
||||||
<type value="VIRTUAL_DEVICE_PATH" />
|
|
||||||
<value value="$USER_HOME$/.android/avd/Pixel_3a_API_34_extension_level_7_x86_64.avd" />
|
|
||||||
</Key>
|
|
||||||
</deviceKey>
|
|
||||||
</Target>
|
|
||||||
</targetSelectedWithDropDown>
|
|
||||||
<timeTargetWasSelectedWithDropDown value="2023-11-19T23:31:08.478703551Z" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
@ -36,6 +36,14 @@
|
|||||||
<activity android:name=".about.AboutActivity" android:theme="@style/Theme.Isolaatti"/>
|
<activity android:name=".about.AboutActivity" android:theme="@style/Theme.Isolaatti"/>
|
||||||
<activity android:name=".images.picture_viewer.ui.PictureViewerActivity" android:theme="@style/Theme.Isolaatti"/>
|
<activity android:name=".images.picture_viewer.ui.PictureViewerActivity" android:theme="@style/Theme.Isolaatti"/>
|
||||||
<activity android:name=".sign_up.ui.SignUpActivity" android:theme="@style/Theme.Isolaatti"/>
|
<activity android:name=".sign_up.ui.SignUpActivity" android:theme="@style/Theme.Isolaatti"/>
|
||||||
|
<provider
|
||||||
|
android:authorities="com.isolaatti.provider"
|
||||||
|
android:name="androidx.core.content.FileProvider"
|
||||||
|
android:grantUriPermissions="true">
|
||||||
|
<meta-data
|
||||||
|
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||||
|
android:resource="@xml/provider_paths"/>
|
||||||
|
</provider>
|
||||||
</application>
|
</application>
|
||||||
<uses-permission android:name="android.permission.INTERNET"/>
|
<uses-permission android:name="android.permission.INTERNET"/>
|
||||||
</manifest>
|
</manifest>
|
||||||
7
app/src/main/java/com/isolaatti/MyFileProvider.kt
Normal file
7
app/src/main/java/com/isolaatti/MyFileProvider.kt
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package com.isolaatti
|
||||||
|
|
||||||
|
import androidx.core.content.FileProvider
|
||||||
|
|
||||||
|
class MyFileProvider : FileProvider() {
|
||||||
|
|
||||||
|
}
|
||||||
@ -197,7 +197,7 @@ class FeedFragment : Fragment(), OnUserInteractedWithPostCallback {
|
|||||||
|
|
||||||
image?.load(UrlGen.userProfileImage(it.userId), imageLoader)
|
image?.load(UrlGen.userProfileImage(it.userId), imageLoader)
|
||||||
image?.setOnClickListener {_ ->
|
image?.setOnClickListener {_ ->
|
||||||
PictureViewerActivity.startActivityWithUrls(requireContext(), arrayOf(UrlGen.userProfileImageFullQuality(it.userId)))
|
//PictureViewerActivity.startActivityWithImages(requireContext(), arrayOf(UrlGen.userProfileImageFullQuality(it.userId)))
|
||||||
}
|
}
|
||||||
|
|
||||||
textViewName?.text = it.name
|
textViewName?.text = it.name
|
||||||
|
|||||||
@ -2,6 +2,8 @@ package com.isolaatti.images
|
|||||||
|
|
||||||
import com.isolaatti.connectivity.RetrofitClient
|
import com.isolaatti.connectivity.RetrofitClient
|
||||||
import com.isolaatti.images.image_list.data.remote.ImagesApi
|
import com.isolaatti.images.image_list.data.remote.ImagesApi
|
||||||
|
import com.isolaatti.images.image_list.data.repository.ImagesRepositoryImpl
|
||||||
|
import com.isolaatti.images.image_list.domain.repository.ImagesRepository
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
import dagger.Provides
|
import dagger.Provides
|
||||||
import dagger.hilt.InstallIn
|
import dagger.hilt.InstallIn
|
||||||
@ -14,4 +16,9 @@ class Module {
|
|||||||
fun provideImagesApi(retrofitClient: RetrofitClient): ImagesApi {
|
fun provideImagesApi(retrofitClient: RetrofitClient): ImagesApi {
|
||||||
return retrofitClient.client.create(ImagesApi::class.java)
|
return retrofitClient.client.create(ImagesApi::class.java)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
fun provideImagesRepository(imagesApi: ImagesApi): ImagesRepository {
|
||||||
|
return ImagesRepositoryImpl(imagesApi)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -5,5 +5,6 @@ data class ImageDto(
|
|||||||
val userId: Int,
|
val userId: Int,
|
||||||
val name: String,
|
val name: String,
|
||||||
val squadId: String?,
|
val squadId: String?,
|
||||||
|
val username: String,
|
||||||
val idOnFirebase: String
|
val idOnFirebase: String
|
||||||
)
|
)
|
||||||
@ -13,9 +13,9 @@ import retrofit2.http.Path
|
|||||||
import retrofit2.http.Query
|
import retrofit2.http.Query
|
||||||
|
|
||||||
interface ImagesApi {
|
interface ImagesApi {
|
||||||
@POST("images/of_user/{userId}")
|
@GET("images/of_user/{userId}")
|
||||||
fun getImagesOfUser(@Path("userId") userId: Int,
|
fun getImagesOfUser(@Path("userId") userId: Int,
|
||||||
@Query("lastId") lastId: String?): Call<List<ImageDto>>
|
@Query("lastId") lastId: String?): Call<ImagesDto>
|
||||||
|
|
||||||
@POST("images/create")
|
@POST("images/create")
|
||||||
@Multipart
|
@Multipart
|
||||||
|
|||||||
@ -0,0 +1,5 @@
|
|||||||
|
package com.isolaatti.images.image_list.data.remote
|
||||||
|
|
||||||
|
data class ImagesDto(
|
||||||
|
val data: List<ImageDto>
|
||||||
|
)
|
||||||
@ -15,7 +15,7 @@ class ImagesRepositoryImpl @Inject constructor(private val imagesApi: ImagesApi)
|
|||||||
val response = imagesApi.getImagesOfUser(userId, lastId).awaitResponse()
|
val response = imagesApi.getImagesOfUser(userId, lastId).awaitResponse()
|
||||||
if(response.isSuccessful) {
|
if(response.isSuccessful) {
|
||||||
val imagesDto = response.body()
|
val imagesDto = response.body()
|
||||||
val images = imagesDto?.map { Image.fromDto(it) }
|
val images = imagesDto?.data?.map { Image.fromDto(it) }
|
||||||
|
|
||||||
emit(Resource.Success(images))
|
emit(Resource.Success(images))
|
||||||
|
|
||||||
|
|||||||
@ -2,17 +2,19 @@ package com.isolaatti.images.image_list.domain.entity
|
|||||||
|
|
||||||
import com.isolaatti.images.image_list.data.remote.ImageDto
|
import com.isolaatti.images.image_list.data.remote.ImageDto
|
||||||
import com.isolaatti.utils.UrlGen
|
import com.isolaatti.utils.UrlGen
|
||||||
|
import java.io.Serializable
|
||||||
|
|
||||||
data class Image(
|
data class Image(
|
||||||
val id: String,
|
val id: String,
|
||||||
val userId: Int,
|
val userId: Int,
|
||||||
val name: String
|
val name: String,
|
||||||
) {
|
val username: String
|
||||||
|
): Serializable {
|
||||||
val imageUrl: String get() = UrlGen.imageUrl(id)
|
val imageUrl: String get() = UrlGen.imageUrl(id)
|
||||||
val smallImageUrl : String get() = UrlGen.imageUrl(id, UrlGen.IMAGE_MODE_SMALL)
|
val smallImageUrl : String get() = UrlGen.imageUrl(id, UrlGen.IMAGE_MODE_SMALL)
|
||||||
val reducedImageUrl: String get() = UrlGen.imageUrl(id, UrlGen.IMAGE_MODE_REDUCED)
|
val reducedImageUrl: String get() = UrlGen.imageUrl(id, UrlGen.IMAGE_MODE_REDUCED)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun fromDto(imageDto: ImageDto) = Image(imageDto.id, imageDto.userId, imageDto.name)
|
fun fromDto(imageDto: ImageDto) = Image(imageDto.id, imageDto.userId, imageDto.name, imageDto.username)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,12 +1,29 @@
|
|||||||
package com.isolaatti.images.image_list.presentation
|
package com.isolaatti.images.image_list.presentation
|
||||||
|
|
||||||
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import com.isolaatti.images.image_list.domain.entity.Image
|
||||||
import com.isolaatti.images.image_list.domain.repository.ImagesRepository
|
import com.isolaatti.images.image_list.domain.repository.ImagesRepository
|
||||||
|
import com.isolaatti.utils.Resource
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.flow.flowOn
|
||||||
|
import kotlinx.coroutines.flow.launchIn
|
||||||
|
import kotlinx.coroutines.flow.onEach
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
class ImageListViewModel @Inject constructor(private val imagesRepository: ImagesRepository) : ViewModel() {
|
class ImageListViewModel @Inject constructor(private val imagesRepository: ImagesRepository) : ViewModel() {
|
||||||
|
|
||||||
|
val list: MutableLiveData<Resource<List<Image>>> = MutableLiveData()
|
||||||
|
fun loadNext(userId: Int) {
|
||||||
|
viewModelScope.launch {
|
||||||
|
|
||||||
|
imagesRepository.getImagesOfUser(userId, null).onEach {
|
||||||
|
list.postValue(it)
|
||||||
|
}.flowOn(Dispatchers.IO).launchIn(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -1,4 +1,44 @@
|
|||||||
package com.isolaatti.images.image_list.presentation
|
package com.isolaatti.images.image_list.presentation
|
||||||
|
|
||||||
class ImagesAdapter {
|
import android.view.LayoutInflater
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.widget.LinearLayout
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import androidx.recyclerview.widget.RecyclerView.Adapter
|
||||||
|
import coil.load
|
||||||
|
import com.isolaatti.common.CoilImageLoader.imageLoader
|
||||||
|
import com.isolaatti.databinding.ImageItemBinding
|
||||||
|
import com.isolaatti.images.image_list.domain.entity.Image
|
||||||
|
|
||||||
|
class ImagesAdapter(private val imageOnClick: ((images: List<Image>, position: Int) -> Unit), private val itemWidth: Int) : Adapter<ImagesAdapter.ImageViewHolder>(){
|
||||||
|
|
||||||
|
private var data: List<Image> = listOf()
|
||||||
|
|
||||||
|
inner class ImageViewHolder(val imageItemBinding: ImageItemBinding) : RecyclerView.ViewHolder(imageItemBinding.root)
|
||||||
|
|
||||||
|
fun setData(data: List<Image>) {
|
||||||
|
this.data = data
|
||||||
|
notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ImageViewHolder {
|
||||||
|
val inflater = LayoutInflater.from(parent.context)
|
||||||
|
val binding = ImageItemBinding.inflate(inflater)
|
||||||
|
|
||||||
|
binding.root.layoutParams = LinearLayout.LayoutParams(itemWidth, itemWidth)
|
||||||
|
return ImageViewHolder(binding)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemCount(): Int {
|
||||||
|
return data.size
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBindViewHolder(holder: ImageViewHolder, position: Int) {
|
||||||
|
val image = data[position]
|
||||||
|
|
||||||
|
holder.imageItemBinding.image.load(image.smallImageUrl, imageLoader)
|
||||||
|
holder.imageItemBinding.root.setOnClickListener {
|
||||||
|
imageOnClick(data, position)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -1,17 +1,57 @@
|
|||||||
package com.isolaatti.images.image_list.ui
|
package com.isolaatti.images.image_list.ui
|
||||||
|
|
||||||
|
import android.content.res.Resources
|
||||||
|
import android.net.Uri
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import androidx.activity.result.PickVisualMediaRequest
|
||||||
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
|
import androidx.appcompat.widget.PopupMenu
|
||||||
|
import androidx.core.content.FileProvider
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.fragment.app.viewModels
|
||||||
|
import androidx.navigation.fragment.findNavController
|
||||||
|
import androidx.navigation.fragment.navArgs
|
||||||
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
|
import com.isolaatti.MyApplication
|
||||||
|
import com.isolaatti.R
|
||||||
import com.isolaatti.databinding.FragmentImagesBinding
|
import com.isolaatti.databinding.FragmentImagesBinding
|
||||||
|
import com.isolaatti.images.image_list.domain.entity.Image
|
||||||
|
import com.isolaatti.images.image_list.presentation.ImageListViewModel
|
||||||
|
import com.isolaatti.images.image_list.presentation.ImagesAdapter
|
||||||
|
import com.isolaatti.images.picture_viewer.ui.PictureViewerActivity
|
||||||
|
import com.isolaatti.utils.Resource
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import java.io.File
|
||||||
|
import java.util.Calendar
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class ImagesFragment : Fragment() {
|
class ImagesFragment : Fragment() {
|
||||||
lateinit var viewBinding: FragmentImagesBinding
|
lateinit var viewBinding: FragmentImagesBinding
|
||||||
|
lateinit var adapter: ImagesAdapter
|
||||||
|
private val viewModel: ImageListViewModel by viewModels()
|
||||||
|
private val arguments: ImagesFragmentArgs by navArgs()
|
||||||
|
|
||||||
|
private var cameraPhotoUri: Uri? = null
|
||||||
|
|
||||||
|
private val imageOnClick: (images: List<Image>, position: Int) -> Unit = { images, position ->
|
||||||
|
PictureViewerActivity.startActivityWithImages(requireContext(), images.toTypedArray(), position)
|
||||||
|
}
|
||||||
|
|
||||||
|
private val choosePictureLauncher = registerForActivityResult(ActivityResultContracts.PickVisualMedia()) {
|
||||||
|
// use uri
|
||||||
|
}
|
||||||
|
|
||||||
|
private val takePhotoLauncher = registerForActivityResult(ActivityResultContracts.TakePicture()) {
|
||||||
|
// use cameraPhotoUri if success
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun makePhotoUri(): Uri {
|
||||||
|
val cacheFile = File(requireContext().filesDir, "temp_picture_${Calendar.getInstance().timeInMillis}")
|
||||||
|
return FileProvider.getUriForFile(requireContext(), "${MyApplication.myApp.packageName}.provider", cacheFile)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater,
|
inflater: LayoutInflater,
|
||||||
@ -25,5 +65,72 @@ class ImagesFragment : Fragment() {
|
|||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
|
when(arguments.source) {
|
||||||
|
SOURCE_SQUAD -> {}
|
||||||
|
SOURCE_PROFILE -> {
|
||||||
|
viewModel.loadNext(arguments.sourceId.toInt())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setupAdapter()
|
||||||
|
setupObservers()
|
||||||
|
setupListeners()
|
||||||
|
|
||||||
|
viewBinding.topAppBar.inflateMenu(R.menu.images_menu)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupListeners() {
|
||||||
|
viewBinding.topAppBar.setNavigationOnClickListener {
|
||||||
|
findNavController().popBackStack()
|
||||||
|
}
|
||||||
|
viewBinding.newPictureButton.setOnClickListener {
|
||||||
|
val popup = PopupMenu(requireContext(), it)
|
||||||
|
popup.menuInflater.inflate(R.menu.add_picture_menu, popup.menu)
|
||||||
|
|
||||||
|
popup.setOnMenuItemClickListener {
|
||||||
|
when(it.itemId) {
|
||||||
|
R.id.take_a_photo_menu_item -> {
|
||||||
|
cameraPhotoUri = makePhotoUri()
|
||||||
|
takePhotoLauncher.launch(cameraPhotoUri)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
R.id.upload_a_picture_item -> {
|
||||||
|
choosePictureLauncher.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly))
|
||||||
|
true
|
||||||
|
}
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
popup.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupAdapter() {
|
||||||
|
adapter = ImagesAdapter(imageOnClick, Resources.getSystem().displayMetrics.widthPixels/3)
|
||||||
|
viewBinding.recyclerView.layoutManager =
|
||||||
|
GridLayoutManager(requireContext(), 3, GridLayoutManager.VERTICAL, false)
|
||||||
|
viewBinding.recyclerView.adapter = adapter
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupObservers() {
|
||||||
|
|
||||||
|
viewModel.list.observe(viewLifecycleOwner) { resource ->
|
||||||
|
when(resource) {
|
||||||
|
is Resource.Error -> {}
|
||||||
|
is Resource.Loading -> {}
|
||||||
|
is Resource.Success -> {
|
||||||
|
resource.data?.let {
|
||||||
|
adapter.setData(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val SOURCE_PROFILE = "source_profile"
|
||||||
|
const val SOURCE_SQUAD = "source_squads"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2,9 +2,10 @@ package com.isolaatti.images.picture_viewer.presentation
|
|||||||
|
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.viewpager2.adapter.FragmentStateAdapter
|
import androidx.viewpager2.adapter.FragmentStateAdapter
|
||||||
|
import com.isolaatti.images.image_list.domain.entity.Image
|
||||||
import com.isolaatti.images.picture_viewer.ui.PictureViewerImageWrapperFragment
|
import com.isolaatti.images.picture_viewer.ui.PictureViewerImageWrapperFragment
|
||||||
|
|
||||||
class PictureViewerViewPagerAdapter(fragment: Fragment, private val images: Array<String>) : FragmentStateAdapter(fragment) {
|
class PictureViewerViewPagerAdapter(fragment: Fragment, private val images: Array<Image>) : FragmentStateAdapter(fragment) {
|
||||||
override fun getItemCount(): Int {
|
override fun getItemCount(): Int {
|
||||||
return images.size
|
return images.size
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import android.content.Intent
|
|||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import com.isolaatti.databinding.ActivityPictureViewerBinding
|
import com.isolaatti.databinding.ActivityPictureViewerBinding
|
||||||
|
import com.isolaatti.images.image_list.domain.entity.Image
|
||||||
import com.isolaatti.images.picture_viewer.presentation.PictureViewerViewPagerAdapter
|
import com.isolaatti.images.picture_viewer.presentation.PictureViewerViewPagerAdapter
|
||||||
|
|
||||||
class PictureViewerActivity : AppCompatActivity() {
|
class PictureViewerActivity : AppCompatActivity() {
|
||||||
@ -21,12 +22,16 @@ class PictureViewerActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val EXTRA_URLS = "urls"
|
const val EXTRA_IMAGES = "images"
|
||||||
const val EXTRA_PROFILE_ID = "profileId"
|
const val EXTRA_IMAGE_POSITiON = "position"
|
||||||
|
|
||||||
fun startActivityWithUrls(context: Context, urls: Array<String>) {
|
fun startActivityWithImages(context: Context, images: Array<Image>, position: Int = 0) {
|
||||||
|
if(images.isEmpty()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
val intent = Intent(context, PictureViewerActivity::class.java)
|
val intent = Intent(context, PictureViewerActivity::class.java)
|
||||||
intent.putExtra(EXTRA_URLS, urls)
|
intent.putExtra(EXTRA_IMAGES, images)
|
||||||
|
intent.putExtra(EXTRA_IMAGE_POSITiON, position)
|
||||||
context.startActivity(intent)
|
context.startActivity(intent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,13 +8,14 @@ import androidx.fragment.app.Fragment
|
|||||||
import coil.load
|
import coil.load
|
||||||
import com.isolaatti.common.CoilImageLoader.imageLoader
|
import com.isolaatti.common.CoilImageLoader.imageLoader
|
||||||
import com.isolaatti.databinding.FragmentTouchImageViewWrapperBinding
|
import com.isolaatti.databinding.FragmentTouchImageViewWrapperBinding
|
||||||
|
import com.isolaatti.images.image_list.domain.entity.Image
|
||||||
import com.ortiz.touchview.OnTouchImageViewListener
|
import com.ortiz.touchview.OnTouchImageViewListener
|
||||||
|
|
||||||
|
|
||||||
class PictureViewerImageWrapperFragment : Fragment() {
|
class PictureViewerImageWrapperFragment : Fragment() {
|
||||||
|
|
||||||
private lateinit var binding: FragmentTouchImageViewWrapperBinding
|
private lateinit var binding: FragmentTouchImageViewWrapperBinding
|
||||||
private var url: String? = null
|
private var image: Image? = null
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater,
|
inflater: LayoutInflater,
|
||||||
@ -23,7 +24,7 @@ class PictureViewerImageWrapperFragment : Fragment() {
|
|||||||
): View {
|
): View {
|
||||||
binding = FragmentTouchImageViewWrapperBinding.inflate(inflater)
|
binding = FragmentTouchImageViewWrapperBinding.inflate(inflater)
|
||||||
|
|
||||||
url = arguments?.getString(ARGUMENT_URL)
|
image = arguments?.getSerializable(ARGUMENT_IMAGE) as Image
|
||||||
|
|
||||||
return binding.root
|
return binding.root
|
||||||
}
|
}
|
||||||
@ -42,17 +43,17 @@ class PictureViewerImageWrapperFragment : Fragment() {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
url?.let {
|
image?.let {
|
||||||
binding.touchImageView.load(it, imageLoader)
|
binding.touchImageView.load(it.imageUrl, imageLoader)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val ARGUMENT_URL = "url"
|
const val ARGUMENT_IMAGE = "image"
|
||||||
fun getInstance(url: String): PictureViewerImageWrapperFragment {
|
fun getInstance(image: Image): PictureViewerImageWrapperFragment {
|
||||||
val fragment = PictureViewerImageWrapperFragment()
|
val fragment = PictureViewerImageWrapperFragment()
|
||||||
fragment.arguments = Bundle().apply {
|
fragment.arguments = Bundle().apply {
|
||||||
putString(ARGUMENT_URL, url)
|
putSerializable(ARGUMENT_IMAGE, image)
|
||||||
}
|
}
|
||||||
|
|
||||||
return fragment
|
return fragment
|
||||||
|
|||||||
@ -5,12 +5,25 @@ import android.view.LayoutInflater
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.viewpager2.widget.ViewPager2
|
||||||
import com.isolaatti.databinding.FragmentMainPictureViewerBinding
|
import com.isolaatti.databinding.FragmentMainPictureViewerBinding
|
||||||
|
import com.isolaatti.images.image_list.domain.entity.Image
|
||||||
import com.isolaatti.images.picture_viewer.presentation.PictureViewerViewPagerAdapter
|
import com.isolaatti.images.picture_viewer.presentation.PictureViewerViewPagerAdapter
|
||||||
|
|
||||||
class PictureViewerMainFragment : Fragment() {
|
class PictureViewerMainFragment : Fragment() {
|
||||||
|
|
||||||
private lateinit var binding: FragmentMainPictureViewerBinding
|
private lateinit var binding: FragmentMainPictureViewerBinding
|
||||||
|
|
||||||
|
lateinit var images: Array<Image>
|
||||||
|
|
||||||
|
private val onPageChangeCallback = object: ViewPager2.OnPageChangeCallback() {
|
||||||
|
override fun onPageSelected(position: Int) {
|
||||||
|
super.onPageSelected(position)
|
||||||
|
binding.imageAuthor.text = images[position].username
|
||||||
|
binding.imageDescription.text = images[position].name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater,
|
inflater: LayoutInflater,
|
||||||
container: ViewGroup?,
|
container: ViewGroup?,
|
||||||
@ -24,12 +37,19 @@ class PictureViewerMainFragment : Fragment() {
|
|||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
val url = requireActivity().intent.extras?.getStringArray(PictureViewerActivity.EXTRA_URLS)
|
images = requireActivity().intent.extras?.getSerializable(PictureViewerActivity.EXTRA_IMAGES) as Array<Image>
|
||||||
|
val position = requireActivity().intent.extras?.getInt(PictureViewerActivity.EXTRA_IMAGE_POSITiON) ?: 0
|
||||||
url?.let {
|
val adapter = PictureViewerViewPagerAdapter(this, images)
|
||||||
val adapter = PictureViewerViewPagerAdapter(this, it)
|
|
||||||
binding.viewpager.adapter = adapter
|
binding.viewpager.adapter = adapter
|
||||||
|
binding.viewpager.setCurrentItem(position, false)
|
||||||
|
binding.viewpager.registerOnPageChangeCallback(onPageChangeCallback)
|
||||||
|
binding.imageDescription.text = images[position].name
|
||||||
|
binding.imageAuthor.text = images[position].username
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onDestroyView() {
|
||||||
|
super.onDestroyView()
|
||||||
|
binding.viewpager.unregisterOnPageChangeCallback(onPageChangeCallback)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun enableViewPagerUserInput(enabled: Boolean) {
|
fun enableViewPagerUserInput(enabled: Boolean) {
|
||||||
|
|||||||
@ -31,6 +31,7 @@ import com.isolaatti.common.options_bottom_sheet.domain.OptionClicked
|
|||||||
import com.isolaatti.common.options_bottom_sheet.domain.Options
|
import com.isolaatti.common.options_bottom_sheet.domain.Options
|
||||||
import com.isolaatti.common.options_bottom_sheet.presentation.BottomSheetPostOptionsViewModel
|
import com.isolaatti.common.options_bottom_sheet.presentation.BottomSheetPostOptionsViewModel
|
||||||
import com.isolaatti.common.options_bottom_sheet.ui.BottomSheetPostOptionsFragment
|
import com.isolaatti.common.options_bottom_sheet.ui.BottomSheetPostOptionsFragment
|
||||||
|
import com.isolaatti.images.image_list.ui.ImagesFragment
|
||||||
import com.isolaatti.images.picture_viewer.ui.PictureViewerActivity
|
import com.isolaatti.images.picture_viewer.ui.PictureViewerActivity
|
||||||
import com.isolaatti.posting.posts.domain.entity.Post
|
import com.isolaatti.posting.posts.domain.entity.Post
|
||||||
import com.isolaatti.posting.posts.presentation.CreatePostContract
|
import com.isolaatti.posting.posts.presentation.CreatePostContract
|
||||||
@ -149,7 +150,7 @@ class ProfileMainFragment : Fragment() {
|
|||||||
Options.Option.OPTION_PROFILE_PHOTO_VIEW_PHOTO -> {
|
Options.Option.OPTION_PROFILE_PHOTO_VIEW_PHOTO -> {
|
||||||
val profilePictureUrl = profile?.profilePictureUrl
|
val profilePictureUrl = profile?.profilePictureUrl
|
||||||
if(profilePictureUrl != null) {
|
if(profilePictureUrl != null) {
|
||||||
PictureViewerActivity.startActivityWithUrls(requireContext(), arrayOf(profilePictureUrl))
|
//PictureViewerActivity.startActivityWithUrls(requireContext(), arrayOf(profilePictureUrl))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -217,8 +218,14 @@ class ProfileMainFragment : Fragment() {
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
R.id.images_menu_item -> {
|
R.id.images_menu_item -> {
|
||||||
findNavController().navigate(ProfileMainFragmentDirections.actionDiscussionsFragmentToImagesFragment())
|
if(userId != null) {
|
||||||
|
findNavController().navigate(
|
||||||
|
ProfileMainFragmentDirections.actionDiscussionsFragmentToImagesFragment(ImagesFragment.SOURCE_PROFILE, userId.toString())
|
||||||
|
)
|
||||||
true
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else -> { false }
|
else -> { false }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
<vector android:height="24dp" android:tint="#000000"
|
<vector android:height="24dp" android:tint="@color/on_surface"
|
||||||
android:viewportHeight="24" android:viewportWidth="24"
|
android:viewportHeight="24" android:viewportWidth="24"
|
||||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<path android:fillColor="@android:color/white" android:pathData="M6,19c0,1.1 0.9,2 2,2h8c1.1,0 2,-0.9 2,-2V7H6v12zM19,4h-3.5l-1,-1h-5l-1,1H5v2h14V4z"/>
|
<path android:fillColor="@android:color/white" android:pathData="M6,19c0,1.1 0.9,2 2,2h8c1.1,0 2,-0.9 2,-2V7H6v12zM19,4h-3.5l-1,-1h-5l-1,1H5v2h14V4z"/>
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
<FrameLayout
|
<FrameLayout
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
<androidx.fragment.app.FragmentContainerView
|
<androidx.fragment.app.FragmentContainerView
|
||||||
|
|||||||
@ -21,4 +21,13 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior" />
|
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior" />
|
||||||
|
|
||||||
|
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||||
|
android:id="@+id/new_picture_button"
|
||||||
|
android:layout_gravity="bottom|end"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="16dp"
|
||||||
|
app:srcCompat="@drawable/baseline_add_24"
|
||||||
|
android:contentDescription="@string/upload_a_picture" />
|
||||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||||
@ -1,5 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
<androidx.viewpager2.widget.ViewPager2
|
<androidx.viewpager2.widget.ViewPager2
|
||||||
@ -7,4 +8,29 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:background="@color/black"/>
|
android:background="@color/black"/>
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="bottom"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:background="@color/translucent_black"
|
||||||
|
android:padding="16dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/image_author"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textColor="@android:color/white"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
tools:text="Erik" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/image_description"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textColor="@android:color/white"
|
||||||
|
android:textSize="16sp"
|
||||||
|
tools:text="Image description" />
|
||||||
|
</LinearLayout>
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
10
app/src/main/res/layout/image_item.xml
Normal file
10
app/src/main/res/layout/image_item.xml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/image"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
14
app/src/main/res/menu/add_picture_menu.xml
Normal file
14
app/src/main/res/menu/add_picture_menu.xml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/take_a_photo_menu_item"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:title="@string/take_a_photo" />
|
||||||
|
<item
|
||||||
|
android:id="@+id/upload_a_picture_item"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:title="@string/upload_a_picture" />
|
||||||
|
</menu>
|
||||||
12
app/src/main/res/menu/images_menu.xml
Normal file
12
app/src/main/res/menu/images_menu.xml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/delete_item"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:icon="@drawable/baseline_delete_24"
|
||||||
|
app:showAsAction="always"
|
||||||
|
android:title="@string/delete" />
|
||||||
|
</menu>
|
||||||
@ -36,7 +36,14 @@
|
|||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/imagesFragment"
|
android:id="@+id/imagesFragment"
|
||||||
android:name="com.isolaatti.images.image_list.ui.ImagesFragment"
|
android:name="com.isolaatti.images.image_list.ui.ImagesFragment"
|
||||||
android:label="ImagesFragment" />
|
android:label="ImagesFragment" >
|
||||||
|
<argument
|
||||||
|
android:name="source"
|
||||||
|
app:argType="string" />
|
||||||
|
<argument
|
||||||
|
android:name="sourceId"
|
||||||
|
app:argType="string" />
|
||||||
|
</fragment>
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/blockProfileFragment"
|
android:id="@+id/blockProfileFragment"
|
||||||
android:name="com.isolaatti.profile.ui.BlockProfileFragment"
|
android:name="com.isolaatti.profile.ui.BlockProfileFragment"
|
||||||
|
|||||||
@ -6,4 +6,5 @@
|
|||||||
<color name="on_surface">#000000</color>
|
<color name="on_surface">#000000</color>
|
||||||
<color name="danger">#BA0606</color>
|
<color name="danger">#BA0606</color>
|
||||||
<color name="black">#000000</color>
|
<color name="black">#000000</color>
|
||||||
|
<color name="translucent_black">#9A000000</color>
|
||||||
</resources>
|
</resources>
|
||||||
@ -115,4 +115,6 @@
|
|||||||
<string name="display_name_invalid_feedback">Please provide a name. This does not have to be unique and can be your real name or not.</string>
|
<string name="display_name_invalid_feedback">Please provide a name. This does not have to be unique and can be your real name or not.</string>
|
||||||
<string name="validation_error">Validation error</string>
|
<string name="validation_error">Validation error</string>
|
||||||
<string name="email_used">Email is in use already</string>
|
<string name="email_used">Email is in use already</string>
|
||||||
|
<string name="upload_a_picture">Upload a picture</string>
|
||||||
|
<string name="take_a_photo">Take a photo</string>
|
||||||
</resources>
|
</resources>
|
||||||
6
app/src/main/res/xml/provider_paths.xml
Normal file
6
app/src/main/res/xml/provider_paths.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<paths xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<files-path
|
||||||
|
name="files"
|
||||||
|
path="."/>
|
||||||
|
</paths>
|
||||||
Loading…
x
Reference in New Issue
Block a user