WIP rediseño pantalla de publicar

This commit is contained in:
erik-everardo 2023-12-27 00:31:54 -06:00
parent 4aa61cfb38
commit 5a26cdbfb9
11 changed files with 341 additions and 86 deletions

View File

@ -301,25 +301,11 @@
<entry key="vectorAssetStep">
<value>
<PersistentState>
<option name="children">
<map>
<entry key="clipartAsset">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="url" value="jar:file:/home/erik/Descargas/android-studio/plugins/android/lib/android.jar!/images/material/icons/materialicons/play_circle/baseline_play_circle_24.xml" />
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
<option name="values">
<map>
<entry key="outputName" value="baseline_play_circle_24" />
<entry key="sourceFile" value="$USER_HOME$/C:\Users\erike\Downloads\isolaatti.svg" />
<entry key="assetSourceType" value="FILE" />
<entry key="outputName" value="face_kiss_wink_heart_solid" />
<entry key="sourceFile" value="C:\Users\erike\Downloads\face-kiss-wink-heart-solid.svg" />
</map>
</option>
</PersistentState>

34
.idea/navEditor.xml generated
View File

@ -181,6 +181,40 @@
</LayoutPositions>
</value>
</entry>
<entry key="post_creator_navigation.xml">
<value>
<LayoutPositions>
<option name="myPositions">
<map>
<entry key="markdownEditingFragment">
<value>
<LayoutPositions>
<option name="myPosition">
<Point>
<option name="x" value="-218" />
<option name="y" value="-11" />
</Point>
</option>
</LayoutPositions>
</value>
</entry>
<entry key="markdownPreviewFragment">
<value>
<LayoutPositions>
<option name="myPosition">
<Point>
<option name="x" value="72" />
<option name="y" value="-9" />
</Point>
</option>
</LayoutPositions>
</value>
</entry>
</map>
</option>
</LayoutPositions>
</value>
</entry>
<entry key="profile_navigation.xml">
<value>
<LayoutPositions>

View File

@ -27,8 +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()
var content: String = ""
fun postDiscussion(content: String) {
fun postDiscussion() {
viewModelScope.launch {
makePost(EditPostDto.PRIVACY_ISOLAATTI, content, null, null).onEach {
when(it) {
@ -48,7 +49,7 @@ class CreatePostViewModel @Inject constructor(private val makePost: MakePost, pr
}
}
fun editDiscussion(postId: Long, content: String) {
fun editDiscussion(postId: Long) {
viewModelScope.launch {
editPost(postId, EditPostDto.PRIVACY_ISOLAATTI, content, null, null).onEach {
when(it) {

View File

@ -9,6 +9,8 @@ import androidx.core.widget.doOnTextChanged
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.navigation.findNavController
import com.google.android.material.tabs.TabLayout
import com.isolaatti.R
import com.isolaatti.common.IsolaattiBaseActivity
import com.isolaatti.databinding.ActivityCreatePostBinding
@ -69,9 +71,9 @@ class CreatePostActivity : IsolaattiBaseActivity() {
}
if(mode == EXTRA_MODE_EDIT && postId != 0L) {
viewModel.editDiscussion(postId, binding.filledTextField.editText?.text.toString())
viewModel.editDiscussion(postId)
} else {
viewModel.postDiscussion(binding.filledTextField.editText?.text.toString())
viewModel.postDiscussion()
}
}
}
@ -81,25 +83,45 @@ 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.filledTextField.requestFocus()
}
private fun setListeners() {
binding.toolbar.setNavigationOnClickListener {
exit()
}
binding.filledTextField.editText?.doOnTextChanged { text, _, _, _ ->
// make better validation :)
viewModel.validation.postValue(!text.isNullOrEmpty())
}
binding.postButton.setOnClickListener {
if(mode == EXTRA_MODE_EDIT && postId != 0L) {
viewModel.editDiscussion(postId, binding.filledTextField.editText?.text.toString())
viewModel.editDiscussion(postId)
} else {
viewModel.postDiscussion(binding.filledTextField.editText?.text.toString())
viewModel.postDiscussion()
}
}
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() {
@ -121,10 +143,6 @@ class CreatePostActivity : IsolaattiBaseActivity() {
viewModel.loading.observe(this@CreatePostActivity) {
binding.progressBarLoading.visibility = if(it) View.VISIBLE else View.GONE
}
viewModel.postToEdit.observe(this) {
binding.filledTextField.editText?.setText(it.content)
}
}
private fun exit() {

View File

@ -0,0 +1,83 @@
package com.isolaatti.posting.posts.ui
import android.os.Bundle
import android.view.ActionMode
import android.view.LayoutInflater
import android.view.Menu
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.databinding.FragmentMarkdownEditingBinding
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()
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
binding = FragmentMarkdownEditingBinding.inflate(layoutInflater)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.filledTextField.requestFocus()
binding.filledTextField.editText?.doOnTextChanged { text, _, _, _ ->
// make better validation :)
viewModel.validation.postValue(!text.isNullOrEmpty())
viewModel.content = text.toString()
}
binding.filledTextField.editText?.customSelectionActionModeCallback = object: ActionMode.Callback {
override fun onCreateActionMode(mode: ActionMode?, menu: Menu?): Boolean {
return true
}
override fun onPrepareActionMode(mode: ActionMode?, menu: Menu?): Boolean {
return true
}
override fun onActionItemClicked(mode: ActionMode?, item: MenuItem?): Boolean {
return true
}
override fun onDestroyActionMode(mode: ActionMode?) {
}
}
binding.filledTextField.editText?.customInsertionActionModeCallback = object: ActionMode.Callback {
override fun onCreateActionMode(mode: ActionMode?, menu: Menu?): Boolean {
return true
}
override fun onPrepareActionMode(mode: ActionMode?, menu: Menu?): Boolean {
return true
}
override fun onActionItemClicked(mode: ActionMode?, item: MenuItem?): Boolean {
return true
}
override fun onDestroyActionMode(mode: ActionMode?) {
}
}
viewModel.postToEdit.observe(viewLifecycleOwner) {
binding.filledTextField.editText?.setText(it.content)
}
}
}

View File

@ -0,0 +1,61 @@
package com.isolaatti.posting.posts.ui
import android.os.Bundle
import android.view.LayoutInflater
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.common.CoilImageLoader
import com.isolaatti.databinding.FragmentMarkdownEditingBinding
import com.isolaatti.databinding.FragmentMarkdownPreviewBinding
import com.isolaatti.posting.posts.presentation.CreatePostViewModel
import dagger.hilt.EntryPoint
import io.noties.markwon.AbstractMarkwonPlugin
import io.noties.markwon.Markwon
import io.noties.markwon.MarkwonConfiguration
import io.noties.markwon.image.coil.CoilImagesPlugin
import io.noties.markwon.image.destination.ImageDestinationProcessorRelativeToAbsolute
import io.noties.markwon.linkify.LinkifyPlugin
class MarkdownPreviewFragment : Fragment() {
private lateinit var binding: FragmentMarkdownPreviewBinding
private val viewModel: CreatePostViewModel by activityViewModels()
private var markwon: Markwon? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
markwon = Markwon.builder(requireContext())
.usePlugin(object: AbstractMarkwonPlugin() {
override fun configureConfiguration(builder: MarkwonConfiguration.Builder) {
builder
.imageDestinationProcessor(
ImageDestinationProcessorRelativeToAbsolute
.create("https://isolaatti.com/"))
}
})
.usePlugin(CoilImagesPlugin.create(requireContext(), CoilImageLoader.imageLoader))
.usePlugin(LinkifyPlugin.create())
.build()
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
binding = FragmentMarkdownPreviewBinding.inflate(layoutInflater)
return binding.root
}
override fun onDestroy() {
super.onDestroy()
markwon = null
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
markwon?.setMarkdown(binding.textView, viewModel.content)
}
}

View File

@ -5,66 +5,83 @@
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appBarLayout"
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:navigationIcon="@drawable/baseline_close_24"
app:navigationIconTint="@color/on_surface"
app:title="@string/new_post"
app:titleCentered="true">
</com.google.android.material.appbar.MaterialToolbar>
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="100dp"
android:layout_marginTop="?attr/actionBarSize"
android:clipToPadding="false">
<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"
app:hintEnabled="false">
<com.google.android.material.textfield.TextInputEditText
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
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"/>
app:navigationIcon="@drawable/baseline_close_24"
app:navigationIconTint="@color/on_surface"
app:title="@string/new_post"
app:titleCentered="true">
</com.google.android.material.appbar.MaterialToolbar>
</com.google.android.material.textfield.TextInputLayout>
</androidx.core.widget.NestedScrollView>
<ProgressBar
android:id="@+id/progress_bar_loading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone"
tools:visibility="visible"/>
</com.google.android.material.appbar.AppBarLayout>
<com.google.android.material.bottomappbar.BottomAppBar
android:id="@+id/bottomAppBar"
style="@style/Widget.Material3.BottomAppBar"
app:menu="@menu/discussion_creator_menu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/postButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="@drawable/baseline_send_24"
app:layout_anchor="@id/bottomAppBar" />
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabs"
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/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"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"
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" />
<ProgressBar
android:id="@+id/progress_bar_loading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginEnd="16dp"
android:layout_marginBottom="16dp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@+id/postButton"
app:layout_constraintTop_toTopOf="@+id/postButton"
tools:visibility="visible" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/postButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginBottom="16dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:srcCompat="@drawable/baseline_send_24" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView 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"
android:paddingBottom="100dp"
android:layout_marginTop="?attr/actionBarSize"
android:clipToPadding="false">
<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"
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>
</androidx.core.widget.NestedScrollView>

View File

@ -0,0 +1,16 @@
<?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="match_parent"
android:layout_height="match_parent">
<TextView
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"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,15 @@
<?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/post_creator_navigation"
app:startDestination="@id/markdownEditingFragment">
<fragment
android:id="@+id/markdownPreviewFragment"
android:name="com.isolaatti.posting.posts.ui.MarkdownPreviewFragment"
android:label="MarkdownPreviewFragment" />
<fragment
android:id="@+id/markdownEditingFragment"
android:name="com.isolaatti.posting.posts.ui.MarkdownEditingFragment"
android:label="MarkdownEditingFragment" />
</navigation>

View File

@ -125,4 +125,6 @@
<string name="yes_discard_image">Yes, discard image</string>
<string name="discard_image">Discard image?</string>
<string name="deleting_please_wait">Deleting, please wait…</string>
<string name="markdown">Markdown</string>
<string name="preview">Preview</string>
</resources>