* seleccionador de imagenes.

* se puede insertar imagenes en posts
This commit is contained in:
erik-everardo 2024-01-04 00:35:39 -06:00
parent 53e41d2034
commit 8373adcb63
26 changed files with 593 additions and 76 deletions

View File

@ -301,10 +301,24 @@
<entry key="vectorAssetStep">
<value>
<PersistentState>
<option name="children">
<map>
<entry key="clipartAsset">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="url" value="file:/$USER_HOME$/AppData/Local/Android/Sdk/icons/material/materialicons/file_upload/baseline_file_upload_24.xml" />
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
<option name="values">
<map>
<entry key="assetSourceType" value="FILE" />
<entry key="outputName" value="face_kiss_wink_heart_solid" />
<entry key="outputName" value="baseline_file_upload_24" />
<entry key="sourceFile" value="C:\Users\erike\Downloads\face-kiss-wink-heart-solid.svg" />
</map>
</option>

43
.idea/navEditor.xml generated
View File

@ -159,6 +159,49 @@
</LayoutPositions>
</value>
</entry>
<entry key="image_chooser_navigation.xml">
<value>
<LayoutPositions>
<option name="myPositions">
<map>
<entry key="imageChooserMainFragment">
<value>
<LayoutPositions>
<option name="myPosition">
<Point>
<option name="x" value="-268" />
<option name="y" value="-16" />
</Point>
</option>
<option name="myPositions">
<map>
<entry key="action_imageChooserMainFragment_to_imageChooserPreview">
<value>
<LayoutPositions />
</value>
</entry>
</map>
</option>
</LayoutPositions>
</value>
</entry>
<entry key="imageChooserPreview">
<value>
<LayoutPositions>
<option name="myPosition">
<Point>
<option name="x" value="9" />
<option name="y" value="-18" />
</Point>
</option>
</LayoutPositions>
</value>
</entry>
</map>
</option>
</LayoutPositions>
</value>
</entry>
<entry key="picture_viewer_navigation.xml">
<value>
<LayoutPositions>

View File

@ -2,6 +2,7 @@ package com.isolaatti.images.common.domain.entity
import com.isolaatti.common.Deletable
import com.isolaatti.images.common.data.remote.ImageDto
import com.isolaatti.markdown.Generators
import com.isolaatti.utils.UrlGen
import java.io.Serializable
@ -15,7 +16,7 @@ data class Image(
val smallImageUrl : String get() = UrlGen.imageUrl(id, UrlGen.IMAGE_MODE_SMALL)
val reducedImageUrl: String get() = UrlGen.imageUrl(id, UrlGen.IMAGE_MODE_REDUCED)
val markdown: String get() = Generators.generateImage(imageUrl)
companion object {
fun fromDto(imageDto: ImageDto) = Image(imageDto.id, imageDto.userId, imageDto.name, imageDto.username)

View File

@ -1,6 +1,34 @@
package com.isolaatti.images.image_chooser.presentation
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.isolaatti.auth.domain.AuthRepository
import com.isolaatti.images.common.domain.entity.Image
import com.isolaatti.images.common.domain.repository.ImagesRepository
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
@HiltViewModel
class ImageChooserViewModel @Inject constructor(private val authRepository: AuthRepository) : ViewModel() {
val userId: MutableLiveData<Int> = MutableLiveData()
var selectedImage: Image? = null
val choose: MutableLiveData<Boolean> = MutableLiveData()
fun getUserId() {
viewModelScope.launch {
authRepository.getUserId().onEach {
userId.postValue(it)
}.flowOn(Dispatchers.IO).launchIn(this)
}
}
class ImageChooserViewModel : ViewModel() {
}

View File

@ -1,18 +1,39 @@
package com.isolaatti.images.image_chooser.ui
import android.content.Intent
import android.os.Bundle
import android.os.PersistableBundle
import androidx.appcompat.app.AppCompatActivity
import androidx.activity.viewModels
import com.isolaatti.common.IsolaattiBaseActivity
import com.isolaatti.databinding.ActivityImageChooserBinding
import com.isolaatti.images.image_chooser.presentation.ImageChooserViewModel
import dagger.hilt.android.AndroidEntryPoint
class ImageChooserActivity : AppCompatActivity() {
@AndroidEntryPoint
class ImageChooserActivity : IsolaattiBaseActivity() {
private lateinit var binding: ActivityImageChooserBinding
override fun onCreate(savedInstanceState: Bundle?, persistentState: PersistableBundle?) {
super.onCreate(savedInstanceState, persistentState)
private val viewModel: ImageChooserViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityImageChooserBinding.inflate(layoutInflater)
setContentView(binding.root)
setupObservers()
}
private fun setupObservers() {
viewModel.choose.observe(this) {
if(it == true && viewModel.selectedImage != null) {
viewModel.choose.value = false
val resultIntent = Intent().apply {
putExtra(OUTPUT_EXTRA_IMAGE, viewModel.selectedImage)
}
setResult(RESULT_OK, resultIntent)
finish()
return@observe
}
}
}
companion object {

View File

@ -0,0 +1,133 @@
package com.isolaatti.images.image_chooser.ui
import android.app.Activity
import android.content.res.Resources
import android.net.Uri
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.activity.result.PickVisualMediaRequest
import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels
import androidx.core.content.FileProvider
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.fragment.app.viewModels
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.GridLayoutManager
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.isolaatti.MyApplication
import com.isolaatti.R
import com.isolaatti.databinding.FragmentImageChooserMainBinding
import com.isolaatti.images.common.domain.entity.Image
import com.isolaatti.images.image_chooser.presentation.ImageChooserViewModel
import com.isolaatti.images.image_list.presentation.ImageListViewModel
import com.isolaatti.images.image_list.presentation.ImagesAdapter
import com.isolaatti.images.image_maker.ui.ImageMakerContract
import dagger.hilt.android.AndroidEntryPoint
import java.io.File
import java.util.Calendar
@AndroidEntryPoint
class ImageChooserMainFragment : Fragment() {
private lateinit var binding: FragmentImageChooserMainBinding
private val viewModel: ImageChooserViewModel by activityViewModels()
private val imagesListViewModel: ImageListViewModel by viewModels()
private lateinit var adapter: ImagesAdapter
private var cameraPhotoUri: Uri? = null
private val imageOnClick: (images: List<Image>, position: Int) -> Unit = { images, position ->
viewModel.selectedImage = images[position]
findNavController().navigate(ImageChooserMainFragmentDirections.actionImageChooserMainFragmentToImageChooserPreview())
}
private fun makePhotoUri(): Uri {
val cacheFile = File(requireContext().filesDir, "temp_picture_${Calendar.getInstance().timeInMillis}")
return FileProvider.getUriForFile(requireContext(), "${MyApplication.myApp.packageName}.provider", cacheFile)
}
private val imageMakerLauncher = registerForActivityResult(ImageMakerContract()) { image ->
image?.also {
viewModel.selectedImage = it
viewModel.choose.value = true
}
}
private val choosePictureLauncher = registerForActivityResult(ActivityResultContracts.PickVisualMedia()) {
if(it != null) {
imageMakerLauncher.launch(it)
}
}
private val takePhotoLauncher = registerForActivityResult(ActivityResultContracts.TakePicture()) {
if(it && cameraPhotoUri != null) {
imageMakerLauncher.launch(cameraPhotoUri)
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel.getUserId()
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
binding = FragmentImageChooserMainBinding.inflate(inflater)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
adapter = ImagesAdapter(
imageOnClick = imageOnClick,
itemWidth = Resources.getSystem().displayMetrics.widthPixels/3
)
binding.recycler.layoutManager =
GridLayoutManager(requireContext(), 3, GridLayoutManager.VERTICAL, false)
binding.recycler.adapter = adapter
setupObservers()
setupListeners()
}
private fun setupListeners() {
binding.toolbar.setNavigationOnClickListener {
requireActivity().run {
setResult(Activity.RESULT_CANCELED)
finish()
}
}
binding.takePhoto.setOnClickListener {
cameraPhotoUri = makePhotoUri()
takePhotoLauncher.launch(cameraPhotoUri)
}
binding.uploadPhoto.setOnClickListener {
choosePictureLauncher.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly))
}
}
private fun setupObservers() {
viewModel.userId.observe(viewLifecycleOwner) {
imagesListViewModel.userId = it
imagesListViewModel.loadNext()
Log.d("*****", "Se obtiene userId $it")
}
imagesListViewModel.liveList.observe(viewLifecycleOwner) { imageList ->
Log.d("*****", "Se obtiene lista $imageList")
adapter.submitList(imageList)
}
}
}

View File

@ -0,0 +1,48 @@
package com.isolaatti.images.image_chooser.ui
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.navigation.fragment.findNavController
import coil.load
import com.isolaatti.databinding.FragmentImageChooserPreviewBinding
import com.isolaatti.images.image_chooser.presentation.ImageChooserViewModel
class ImageChooserPreview : Fragment() {
private lateinit var binding: FragmentImageChooserPreviewBinding
private val viewModel: ImageChooserViewModel by activityViewModels()
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
binding = FragmentImageChooserPreviewBinding.inflate(inflater)
return binding.root
}
private fun showLoading(show: Boolean) {
binding.chooseImageButton.visibility = if(show) View.INVISIBLE else View.VISIBLE
binding.progressBarLoading.visibility = if(show) View.VISIBLE else View.INVISIBLE
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.toolbar.setNavigationOnClickListener {
findNavController().popBackStack()
}
binding.image.load(viewModel.selectedImage?.imageUrl)
binding.imageDescription.text = viewModel.selectedImage?.name
binding.chooseImageButton.setOnClickListener {
showLoading(true)
viewModel.choose.value = true
}
}
}

View File

@ -0,0 +1,29 @@
package com.isolaatti.images.image_list.presentation
import com.isolaatti.images.common.domain.entity.Image
interface ImageAdapterItem {
val image: Image?
val addImage: Boolean
companion object {
val AddImagePlaceholder: ImageAdapterItem = object: ImageAdapterItem {
override val image: Image?
get() = null
override val addImage: Boolean
get() = true
}
fun fromImage(image: Image): ImageAdapterItem {
return object: ImageAdapterItem {
override val addImage: Boolean
get() = false
override val image: Image?
get() = image
}
}
}
}

View File

@ -27,6 +27,7 @@ import com.isolaatti.R
import com.isolaatti.common.ErrorMessageViewModel
import com.isolaatti.databinding.FragmentImagesBinding
import com.isolaatti.images.common.domain.entity.Image
import com.isolaatti.images.image_list.presentation.ImageAdapterItem
import com.isolaatti.images.image_list.presentation.ImageListViewModel
import com.isolaatti.images.image_list.presentation.ImagesAdapter
import com.isolaatti.images.image_maker.ui.ImageMakerContract

View File

@ -27,7 +27,9 @@ class CreatePostViewModel @Inject constructor(private val makePost: MakePost, pr
val error: MutableLiveData<Resource.Error.ErrorType?> = MutableLiveData()
val loading: MutableLiveData<Boolean> = MutableLiveData(false)
val postToEdit: MutableLiveData<EditPostDto> = MutableLiveData()
val liveContent: MutableLiveData<String> = MutableLiveData()
var content: String = ""
set(value) {field = value; liveContent.value = value} // TODO remove this and use only liveContent
fun postDiscussion() {
viewModelScope.launch {

View File

@ -11,6 +11,7 @@ import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.navigation.findNavController
import com.google.android.material.tabs.TabLayout
import com.google.android.material.tabs.TabLayoutMediator
import com.isolaatti.R
import com.isolaatti.common.IsolaattiBaseActivity
import com.isolaatti.databinding.ActivityCreatePostBinding
@ -84,6 +85,16 @@ class CreatePostActivity : IsolaattiBaseActivity() {
private fun setupUI() {
binding.toolbar.setTitle(if(mode == EXTRA_MODE_EDIT && postId != 0L) R.string.edit else R.string.new_post)
binding.pager.adapter = CreatePostFragmentStateAdapter(this)
TabLayoutMediator(binding.tabs, binding.pager) { tab, position ->
when(position) {
0 -> tab.setText(R.string.markdown)
1 -> tab.setText(R.string.preview)
}
}.attach()
}
private fun setListeners() {
@ -100,28 +111,6 @@ class CreatePostActivity : IsolaattiBaseActivity() {
}
}
binding.tabs.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
override fun onTabSelected(tab: TabLayout.Tab?) {
when(tab?.position) {
0 -> /*editing*/ {
findNavController(binding.fragmentContainerView.id).navigate(R.id.markdownEditingFragment)
}
1 -> /*preview*/ {
findNavController(binding.fragmentContainerView.id).navigate(R.id.markdownPreviewFragment)
}
}
}
override fun onTabReselected(tab: TabLayout.Tab?) {
// Handle tab reselect
}
override fun onTabUnselected(tab: TabLayout.Tab?) {
// Handle tab unselect
}
})
}
private fun setObservers() {

View File

@ -0,0 +1,20 @@
package com.isolaatti.posting.posts.ui
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.FragmentManager
import androidx.viewpager2.adapter.FragmentStateAdapter
class CreatePostFragmentStateAdapter(fragmentActivity: FragmentActivity) : FragmentStateAdapter(fragmentActivity) {
override fun getItemCount(): Int {
return 2
}
override fun createFragment(position: Int): Fragment {
return if(position == 0) {
MarkdownEditingFragment()
} else {
MarkdownPreviewFragment()
}
}
}

View File

@ -2,29 +2,29 @@ package com.isolaatti.posting.posts.ui
import android.os.Bundle
import android.util.Log
import android.view.ActionMode
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import androidx.core.widget.doOnTextChanged
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import com.isolaatti.R
import com.isolaatti.databinding.FragmentMarkdownEditingBinding
import com.isolaatti.images.image_chooser.ui.ImageChooserActivity
import com.isolaatti.images.image_chooser.ui.ImageChooserContract
import com.isolaatti.posting.posts.presentation.CreatePostViewModel
import dagger.hilt.EntryPoint
class MarkdownEditingFragment : Fragment(){
private lateinit var binding: FragmentMarkdownEditingBinding
private val viewModel: CreatePostViewModel by activityViewModels()
private val imageChooserLauncher = registerForActivityResult(ImageChooserContract()) { image ->
Log.d("MarkdownEditingFragment", "$image")
Log.d("MarkdownEditingFragment", "${image?.markdown}")
if(image != null) {
viewModel.content += "\n\n ${image.markdown}"
binding.filledTextField.editText?.setText(viewModel.content)
}
}
override fun onCreateView(
@ -41,6 +41,11 @@ class MarkdownEditingFragment : Fragment(){
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupListeners()
setupObservers()
}
private fun setupListeners() {
binding.filledTextField.editText?.setText(viewModel.content)
binding.filledTextField.requestFocus()
binding.filledTextField.editText?.doOnTextChanged { text, _, _, _ ->
@ -48,7 +53,12 @@ class MarkdownEditingFragment : Fragment(){
viewModel.validation.postValue(!text.isNullOrEmpty())
viewModel.content = text.toString()
}
binding.addImageButton.setOnClickListener {
insertImage()
}
}
private fun setupObservers(){
viewModel.postToEdit.observe(viewLifecycleOwner) {
binding.filledTextField.editText?.setText(it.content)
}

View File

@ -56,6 +56,9 @@ class MarkdownPreviewFragment : Fragment() {
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
markwon?.setMarkdown(binding.textView, viewModel.content)
viewModel.liveContent.observe(viewLifecycleOwner) {
markwon?.setMarkdown(binding.textView, it)
}
}
}

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#000000"
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="M8,11h8v2L8,13zM20.1,12L22,12c0,-2.76 -2.24,-5 -5,-5h-4v1.9h4c1.71,0 3.1,1.39 3.1,3.1zM3.9,12c0,-1.71 1.39,-3.1 3.1,-3.1h4L11,7L7,7c-2.76,0 -5,2.24 -5,5s2.24,5 5,5h4v-1.9L7,15.1c-1.71,0 -3.1,-1.39 -3.1,-3.1zM19,12h-2v3h-3v2h3v3h2v-3h3v-2h-3z"/>
</vector>

View File

@ -0,0 +1,6 @@
<vector android:height="24dp" android:tint="#000000"
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,12m-3.2,0a3.2,3.2 0,1 1,6.4 0a3.2,3.2 0,1 1,-6.4 0"/>
<path android:fillColor="@android:color/white" android:pathData="M9,2L7.17,4L4,4c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2L22,6c0,-1.1 -0.9,-2 -2,-2h-3.17L15,2L9,2zM12,17c-2.76,0 -5,-2.24 -5,-5s2.24,-5 5,-5 5,2.24 5,5 -2.24,5 -5,5z"/>
</vector>

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#000000"
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="M9,16h6v-6h4l-7,-7 -7,7h4zM5,18h14v2L5,20z"/>
</vector>

View File

@ -36,19 +36,10 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/appBarLayout">
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/markdown" />
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/preview" />
</com.google.android.material.tabs.TabLayout>
<androidx.fragment.app.FragmentContainerView
android:id="@+id/fragmentContainerView"
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/pager"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
@ -56,8 +47,7 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tabs"
app:navGraph="@navigation/post_creator_navigation" />
app:layout_constraintTop_toBottomOf="@+id/tabs" />
<ProgressBar
android:id="@+id/progress_bar_loading"

View File

@ -1,7 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:navGraph="@navigation/image_chooser_navigation"
android:name="androidx.navigation.fragment.NavHostFragment"
app:defaultNavHost="true"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -1,15 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.fragment.app.FragmentContainerView 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:id="@+id/profile_fragment_view"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/profile_fragment_view"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/profile_navigation" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/profile_navigation" />

View File

@ -0,0 +1,63 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 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.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:title="@string/choose_image"
app:navigationIcon="@drawable/baseline_close_24"/>
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.google.android.material.card.MaterialCardView
android:id="@+id/image_chooser_actions"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="24dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:layout_margin="16dp"
android:gravity="center">
<com.google.android.material.button.MaterialButton
android:id="@+id/take_photo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="4dp"
app:icon="@drawable/baseline_camera_alt_24"
android:text="@string/take_a_photo"/>
<com.google.android.material.button.MaterialButton
android:id="@+id/upload_photo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:text="@string/upload_photo"
app:icon="@drawable/baseline_file_upload_24"/>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_anchor="@id/image_chooser_actions" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -0,0 +1,63 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="@color/black">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:navigationIcon="@drawable/baseline_arrow_back_24"
app:navigationIconTint="#FFF"
android:translationZ="5dp"
android:background="@color/translucent_black"/>
<com.ortiz.touchview.TouchImageView
android:id="@+id/image"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/image_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:background="@color/translucent_black"
android:padding="16dp"
android:textColor="@android:color/white"
android:textSize="16sp"
app:layout_constraintBottom_toTopOf="@+id/choose_image_button"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:text="Image description" />
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
android:id="@+id/choose_image_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginBottom="16dp"
android:text="@string/choose_image"
app:icon="@drawable/baseline_check_24"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<ProgressBar
android:id="@+id/progress_bar_loading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="@+id/choose_image_button"
app:layout_constraintEnd_toEndOf="@+id/choose_image_button"
app:layout_constraintStart_toStartOf="@+id/choose_image_button"
app:layout_constraintTop_toTopOf="@+id/choose_image_button"
android:visibility="invisible"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -6,17 +6,39 @@
android:paddingBottom="100dp"
android:layout_marginTop="?attr/actionBarSize"
android:clipToPadding="false">
<com.google.android.material.textfield.TextInputLayout
style="?attr/textInputFilledStyle"
android:id="@+id/filledTextField"
<LinearLayout
android:layout_width="match_parent"
app:boxBackgroundMode="none"
android:layout_height="wrap_content"
app:hintEnabled="false">
<com.google.android.material.textfield.TextInputEditText
android:orientation="vertical">
<com.google.android.material.textfield.TextInputLayout
style="?attr/textInputFilledStyle"
android:id="@+id/filledTextField"
android:layout_width="match_parent"
app:boxBackgroundMode="none"
android:layout_height="wrap_content"
android:hint="@string/what_do_you_want_to_talk_about_markdown_is_compatible_you_can_record_an_audio_if_you_want"/>
app:hintEnabled="false">
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/what_do_you_want_to_talk_about_markdown_is_compatible_you_can_record_an_audio_if_you_want"/>
</com.google.android.material.textfield.TextInputLayout>
</com.google.android.material.textfield.TextInputLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.button.MaterialButton
android:id="@+id/add_image_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/Widget.Material3.Button.IconButton"
app:icon="@drawable/baseline_image_24" />
<!-- <com.google.android.material.button.MaterialButton-->
<!-- android:id="@+id/add_link_button"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- style="@style/Widget.Material3.Button.IconButton"-->
<!-- app:icon="@drawable/baseline_add_link_24" />-->
</LinearLayout>
</LinearLayout>
</androidx.core.widget.NestedScrollView>

View File

@ -8,7 +8,6 @@
android:id="@+id/textView"
android:layout_width="0dp"
android:layout_height="0dp"
android:text="TextView"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/image_chooser_navigation"
app:startDestination="@id/imageChooserMainFragment">
<fragment
android:id="@+id/imageChooserMainFragment"
android:name="com.isolaatti.images.image_chooser.ui.ImageChooserMainFragment"
android:label="ImageChooserMainFragment" >
<action
android:id="@+id/action_imageChooserMainFragment_to_imageChooserPreview"
app:destination="@id/imageChooserPreview" />
</fragment>
<fragment
android:id="@+id/imageChooserPreview"
android:name="com.isolaatti.images.image_chooser.ui.ImageChooserPreview"
android:label="ImageChooserPreview" />
</navigation>

View File

@ -128,4 +128,5 @@
<string name="markdown">Markdown</string>
<string name="preview">Preview</string>
<string name="add_image_here">Add image here</string>
<string name="choose_image">Choose image</string>
</resources>