1. edge to edge
2. se quitan imagenes y audios del perfil
3. se quita markdown de posts
4. se agrega pantalla de licencias
5. se agrega soporte para dar clic en hashtags
6. pantalla de hashtags ahora es una actividad
7. se comienza a implementar nuevo flujo de imagenes
This commit is contained in:
erik-everardo 2024-11-09 01:22:18 -06:00
parent a2c9091598
commit 7c073b80c6
38 changed files with 206 additions and 157 deletions

View File

@ -9,6 +9,7 @@ plugins {
id 'androidx.navigation.safeargs.kotlin'
id 'com.google.gms.google-services'
id 'com.google.firebase.crashlytics'
id 'com.google.android.gms.oss-licenses-plugin'
}
android {
@ -73,7 +74,7 @@ dependencies {
// Material 3
implementation "com.google.android.material:material:1.11.0"
implementation "com.google.android.material:material:1.12.0"
// Navigation
def nav_version = "2.7.7"
@ -133,4 +134,7 @@ dependencies {
implementation("com.google.firebase:firebase-crashlytics")
implementation("com.google.firebase:firebase-analytics")
implementation("com.google.firebase:firebase-messaging")
// OSS screen
implementation 'com.google.android.gms:play-services-oss-licenses:17.1.0'
}

View File

@ -16,6 +16,15 @@
android:theme="@style/Theme.Isolaatti"
android:usesCleartextTraffic="true"
tools:targetApi="31">
<activity
android:name="com.google.android.gms.oss.licenses.OssLicensesMenuActivity"
android:theme="@style/Theme.Isolaatti.OSS" />
<activity
android:name="com.google.android.gms.oss.licenses.OssLicensesActivity"
android:theme="@style/Theme.Isolaatti.OSS" />
<activity
android:name=".MainActivity"
android:exported="true"
@ -45,6 +54,7 @@
<activity android:name=".audio.recorder.ui.AudioRecorderActivity" android:theme="@style/Theme.Isolaatti" />
<activity android:name=".audio.audio_selector.ui.AudioSelectorActivity" android:theme="@style/Theme.Isolaatti" />
<activity android:name=".posting.posts.ui.PostInfoActivity" android:theme="@style/Theme.Isolaatti"/>
<activity android:name=".hashtags.ui.HashtagsPostsActivity" android:theme="@style/Theme.Isolaatti" />
<provider
android:authorities="com.isolaatti.provider"
android:name="androidx.core.content.FileProvider"

View File

@ -1,9 +1,11 @@
package com.isolaatti.about
import android.content.Intent
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.browser.customtabs.CustomTabsIntent
import androidx.core.net.toUri
import com.google.android.gms.oss.licenses.OssLicensesMenuActivity
import com.isolaatti.BuildConfig
import com.isolaatti.R
import com.isolaatti.databinding.ActivityAboutBinding
@ -36,9 +38,8 @@ class AboutActivity : AppCompatActivity() {
}
binding.openSourceLicences.setOnClickListener {
CustomTabsIntent.Builder()
.build()
.launchUrl(this, BuildConfig.openSourceLicences.toUri())
startActivity(Intent(this, OssLicensesMenuActivity::class.java))
}
binding.privacyPolicyButton.setOnClickListener {

View File

@ -10,4 +10,5 @@ interface OnUserInteractedWithPostCallback : OnUserInteractedCallback {
fun onPlay(audio: Audio)
fun onMoreInfo(postId: Long)
fun onShare(postId: Long)
fun hashtagClicked(hashtag: String)
}

View File

@ -0,0 +1,4 @@
package com.isolaatti.common
val hashtagRegex = "#(\\w|-|_)+".toRegex()
val userTagRegex = "@(\\w|-|_)+".toRegex()

View File

@ -6,16 +6,18 @@ import com.isolaatti.audio.drafts.data.AudioDraftEntity
import com.isolaatti.audio.drafts.data.AudiosDraftsDao
import com.isolaatti.auth.data.local.UserInfoDao
import com.isolaatti.auth.data.local.UserInfoEntity
import com.isolaatti.images.common.data.dao.ImagesDraftsDao
import com.isolaatti.images.common.data.entity.ImageDraftEntity
import com.isolaatti.search.data.SearchDao
import com.isolaatti.search.data.SearchHistoryEntity
import com.isolaatti.settings.data.KeyValueDao
import com.isolaatti.settings.data.KeyValueEntity
@Database(entities = [KeyValueEntity::class, UserInfoEntity::class, AudioDraftEntity::class, SearchHistoryEntity::class], version = 7)
@Database(entities = [KeyValueEntity::class, UserInfoEntity::class, AudioDraftEntity::class, SearchHistoryEntity::class, ImageDraftEntity::class], version = 8)
abstract class AppDatabase : RoomDatabase() {
abstract fun keyValueDao(): KeyValueDao
abstract fun userInfoDao(): UserInfoDao
abstract fun audioDrafts(): AudiosDraftsDao
abstract fun searchHistoryDao(): SearchDao
abstract fun imagesDraftsDao(): ImagesDraftsDao
}

View File

@ -1,46 +0,0 @@
package com.isolaatti.hashtags.ui
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.fragment.findNavController
import com.isolaatti.databinding.FragmentPostsHashtagBinding
import androidx.navigation.fragment.navArgs
import com.isolaatti.R
import com.isolaatti.posting.posts.ui.PostListingFragment
class HashtagPostsFragment : Fragment() {
private lateinit var binding: FragmentPostsHashtagBinding
private val navArgs: HashtagPostsFragmentArgs by navArgs()
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
binding = FragmentPostsHashtagBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.toolbar.title = "#${navArgs.hashtag}"
setupListeners()
// show feed
(childFragmentManager.findFragmentById(R.id.post_list_fragment_container) as NavHostFragment)
.navController.setGraph(R.navigation.post_listing_navigation, Bundle().apply { putString(PostListingFragment.ARG_HASHTAG, navArgs.hashtag) })
}
private fun setupListeners() {
binding.toolbar.setNavigationOnClickListener {
findNavController().popBackStack()
}
}
}

View File

@ -0,0 +1,46 @@
package com.isolaatti.hashtags.ui
import android.content.Context
import android.content.Intent
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.navigation.fragment.NavHostFragment
import com.isolaatti.R
import com.isolaatti.databinding.ActivityPostsHashtagBinding
import com.isolaatti.posting.posts.ui.PostListingFragment
import dagger.hilt.android.AndroidEntryPoint
@AndroidEntryPoint
class HashtagsPostsActivity : AppCompatActivity() {
lateinit var binding: ActivityPostsHashtagBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityPostsHashtagBinding.inflate(layoutInflater)
setContentView(binding.root)
setupListeners()
val hashtag = intent.extras?.getString(EXTRA_HASHTAG)!!
binding.toolbar.title = "#$hashtag"
(supportFragmentManager.findFragmentById(R.id.post_list_fragment_container) as NavHostFragment)
.navController.setGraph(R.navigation.post_listing_navigation, Bundle().apply { putString(
PostListingFragment.ARG_HASHTAG, hashtag) })
}
private fun setupListeners() {
binding.toolbar.setNavigationOnClickListener {
onBackPressedDispatcher.onBackPressed()
}
}
companion object {
const val EXTRA_HASHTAG = "hashtag"
fun startActivity(context: Context, hashtag: String) {
val intent = Intent(context, HashtagsPostsActivity::class.java)
intent.putExtra(EXTRA_HASHTAG, hashtag)
context.startActivity(intent)
}
}
}

View File

@ -10,6 +10,9 @@ import android.widget.ImageView
import android.widget.TextView
import android.widget.Toast
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.updatePadding
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
@ -136,5 +139,11 @@ class FeedFragment : Fragment() {
}
}
}
ViewCompat.setOnApplyWindowInsetsListener(viewBinding.root) {_, insets ->
val systemBarsInsets = insets.getInsets(WindowInsetsCompat.Type.systemBars())
viewBinding.homeDrawer.getHeaderView(0).updatePadding(top = systemBarsInsets.top)
insets
}
}
}

View File

@ -6,6 +6,7 @@ import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import android.view.Menu
import androidx.activity.enableEdgeToEdge
import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels
import androidx.core.content.ContextCompat
@ -36,6 +37,7 @@ class HomeActivity : IsolaattiBaseActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
enableEdgeToEdge()
super.onCreate(savedInstanceState)
viewBinding = ActivityHomeBinding.inflate(layoutInflater)
setContentView(viewBinding.root)

View File

@ -0,0 +1,19 @@
package com.isolaatti.images.common.data.dao
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.Query
import com.isolaatti.images.common.data.entity.ImageDraftEntity
@Dao
interface ImagesDraftsDao {
@Query("SELECT * FROM image_drafts WHERE postId IS NULL")
fun getDetachedImages(): List<ImageDraftEntity>
@Insert
fun insertImageDraft(imageDraftEntity: ImageDraftEntity)
@Query("DELETE FROM image_drafts WHERE id = :id")
fun deleteById(id: Long)
}

View File

@ -0,0 +1,12 @@
package com.isolaatti.images.common.data.entity
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "image_drafts")
data class ImageDraftEntity(
@PrimaryKey(autoGenerate = true)
val id: Long,
val uri: String,
val postId: Long? = null
)

View File

@ -51,9 +51,6 @@ class ImageMakerActivity : IsolaattiBaseActivity() {
binding.uploadPhotoFab.setOnClickListener {
viewModel.uploadPicture()
}
binding.textImageName.editText?.doOnTextChanged { text, _, _, _ ->
viewModel.name = text.toString()
}
binding.toolbar.setNavigationOnClickListener {
showExitConfirmationDialog()
}
@ -66,12 +63,10 @@ class ImageMakerActivity : IsolaattiBaseActivity() {
errorViewModel.error.value = it.errorType
binding.progressBarLoading.visibility = View.GONE
binding.uploadPhotoFab.visibility = View.VISIBLE
binding.textImageName.isEnabled = true
}
is Resource.Loading -> {
binding.progressBarLoading.visibility = View.VISIBLE
binding.uploadPhotoFab.visibility = View.INVISIBLE
binding.textImageName.isEnabled = false
}
is Resource.Success -> {
binding.progressBarLoading.visibility = View.GONE

View File

@ -4,8 +4,8 @@ import android.os.Parcel
import android.os.Parcelable
import com.isolaatti.audio.common.domain.Audio
import com.isolaatti.common.Ownable
import com.isolaatti.common.hashtagRegex
import com.isolaatti.posting.posts.data.remote.FeedDto
import java.io.Serializable
data class Post(
val id: Long,
@ -108,4 +108,8 @@ data class Post(
override fun describeContents(): Int {
return 0
}
val hashtagsSpans by lazy {
hashtagRegex.findAll(textContent).map { it.range }.toList()
}
}

View File

@ -1,6 +1,9 @@
package com.isolaatti.posting.posts.presentation
import android.annotation.SuppressLint
import android.text.SpannableString
import android.text.method.LinkMovementMethod
import android.text.style.ClickableSpan
import android.util.Log
import android.view.LayoutInflater
import android.view.View
@ -8,7 +11,7 @@ import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.appcompat.content.res.AppCompatResources
import androidx.core.content.res.ResourcesCompat
import androidx.core.text.set
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import coil.load
@ -21,10 +24,9 @@ import com.isolaatti.common.OnUserInteractedWithPostCallback
import com.isolaatti.databinding.PostLayoutBinding
import com.isolaatti.posting.posts.domain.entity.Post
import com.isolaatti.utils.UrlGen.userProfileImage
import io.noties.markwon.Markwon
class PostsRecyclerViewAdapter (
private val markwon: Markwon,
private val callback: OnUserInteractedWithPostCallback
) : RecyclerView.Adapter<PostsRecyclerViewAdapter.FeedViewHolder>(){
private var postList: List<Post>? = null
@ -102,7 +104,17 @@ class PostsRecyclerViewAdapter (
dateTextView.text = post.date
val content: TextView = itemView.findViewById(R.id.post_content)
markwon.setMarkdown(content, post.textContent)
content.movementMethod = LinkMovementMethod.getInstance()
val spannableString = SpannableString(post.textContent).apply {
post.hashtagsSpans.forEach {
set(it.first, it.last + 1, object: ClickableSpan() {
override fun onClick(widget: View) {
callback.hashtagClicked(post.textContent.substring(it.first + 1, it.last + 1))
}
})
}
}
content.text = spannableString
itemBinding.likeButton.isEnabled = true

View File

@ -88,7 +88,7 @@ class CreatePostActivity : IsolaattiBaseActivity() {
TabLayoutMediator(binding.tabs, binding.pager) { tab, position ->
when(position) {
0 -> tab.setText(R.string.markdown)
0 -> tab.setText(R.string.create_a_new_discussion)
1 -> tab.setText(R.string.preview)
}
}.attach()

View File

@ -2,7 +2,6 @@ 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) {
@ -12,7 +11,7 @@ class CreatePostFragmentStateAdapter(fragmentActivity: FragmentActivity) : Fragm
override fun createFragment(position: Int): Fragment {
return if(position == 0) {
MarkdownEditingFragment()
PostEditingFragment()
} else {
MarkdownPreviewFragment()
}

View File

@ -15,7 +15,6 @@ import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.LifecycleOwner
import com.isolaatti.R
import com.isolaatti.audio.audio_selector.ui.AudioSelectorActivity
import com.isolaatti.audio.audio_selector.ui.AudioSelectorContract
import com.isolaatti.audio.common.domain.Audio
import com.isolaatti.audio.common.domain.Playable
@ -28,9 +27,9 @@ import com.isolaatti.posting.link_creator.presentation.LinkCreatorViewModel
import com.isolaatti.posting.link_creator.ui.LinkCreatorFragment
import com.isolaatti.posting.posts.presentation.CreatePostViewModel
class MarkdownEditingFragment : Fragment(){
class PostEditingFragment : Fragment(){
companion object {
const val LOG_TAG = "MarkdownEditingFragment"
const val LOG_TAG = "PostEditingFragment"
}
@ -48,7 +47,7 @@ class MarkdownEditingFragment : Fragment(){
}
private val imageChooserLauncher = registerForActivityResult(ImageChooserContract()) { image ->
Log.d("MarkdownEditingFragment", "${image?.markdown}")
Log.d(LOG_TAG, "${image?.markdown}")
if(image != null) {
viewModel.content += "\n\n ${image.markdown}"

View File

@ -27,6 +27,7 @@ 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.ui.BottomSheetPostOptionsFragment
import com.isolaatti.databinding.FragmentPostListingBinding
import com.isolaatti.hashtags.ui.HashtagsPostsActivity
import com.isolaatti.home.ui.FeedFragment
import com.isolaatti.posting.comments.ui.BottomSheetPostComments
import com.isolaatti.posting.posts.domain.entity.Post
@ -124,7 +125,7 @@ class PostListingFragment : Fragment(), OnUserInteractedWithPostCallback {
.usePlugin(CoilImagesPlugin.create(requireContext(), CoilImageLoader.imageLoader))
.usePlugin(LinkifyPlugin.create())
.build()
adapter = PostsRecyclerViewAdapter(markwon, this)
adapter = PostsRecyclerViewAdapter(this)
viewBinding.feedRecyclerView.adapter = adapter
viewBinding.feedRecyclerView.setItemViewCacheSize(7)
viewBinding.feedRecyclerView.layoutManager = LinearLayoutManager(requireContext())
@ -192,6 +193,10 @@ class PostListingFragment : Fragment(), OnUserInteractedWithPostCallback {
startActivity(intent)
}
override fun hashtagClicked(hashtag: String) {
HashtagsPostsActivity.startActivity(requireContext(), hashtag)
}
override fun onProfileClick(userId: Int) {
ProfileActivity.startActivity(requireContext(), userId)
}

View File

@ -75,7 +75,7 @@ class PostViewerActivity : IsolaattiBaseActivity() {
}
viewModel.post.observe(this) {
markwon.setMarkdown(binding.markwonContainer, it.textContent)
binding.markwonContainer.text = it.textContent
binding.author.text = it.userName
binding.profileImageView.load(UrlGen.userProfileImage(it.userId), imageLoader)
binding.commentsInfo.text = getString(R.string.comments_info, it.numberOfComments)

View File

@ -4,6 +4,7 @@ import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.os.Bundle
import androidx.activity.enableEdgeToEdge
import androidx.core.app.TaskStackBuilder
import com.isolaatti.common.IsolaattiBaseActivity
import com.isolaatti.databinding.ActivityProfileBinding
@ -15,6 +16,7 @@ class ProfileActivity : IsolaattiBaseActivity() {
lateinit var viewBinding: ActivityProfileBinding
override fun onCreate(savedInstanceState: Bundle?) {
enableEdgeToEdge()
super.onCreate(savedInstanceState)
viewBinding = ActivityProfileBinding.inflate(layoutInflater)
setContentView(viewBinding.root)

View File

@ -37,6 +37,7 @@ import com.isolaatti.common.options_bottom_sheet.presentation.BottomSheetPostOpt
import com.isolaatti.common.options_bottom_sheet.ui.BottomSheetPostOptionsFragment
import com.isolaatti.databinding.FragmentDiscussionsBinding
import com.isolaatti.followers.domain.FollowingState
import com.isolaatti.hashtags.ui.HashtagsPostsActivity
import com.isolaatti.images.common.domain.entity.Image
import com.isolaatti.images.image_chooser.ui.ImageChooserContract
import com.isolaatti.images.image_list.ui.ImagesFragment
@ -378,16 +379,6 @@ class ProfileMainFragment : Fragment() {
}
}
viewBinding.audiosButton.setOnClickListener {
findNavController().navigate(ProfileMainFragmentDirections.actionDiscussionsFragmentToAudiosFragment(AudiosFragment.SOURCE_PROFILE, userId.toString()))
}
viewBinding.imagesButton.setOnClickListener {
findNavController().navigate(
ProfileMainFragmentDirections.actionDiscussionsFragmentToImagesFragment(ImagesFragment.SOURCE_PROFILE, userId.toString())
)
}
viewBinding.createPostButton.setOnClickListener {
createDiscussion.launch(Unit)
}
@ -456,7 +447,7 @@ class ProfileMainFragment : Fragment() {
.usePlugin(LinkifyPlugin.create())
.build()
postsAdapter = PostsRecyclerViewAdapter(markwon,postListingRecyclerViewAdapterWiring )
postsAdapter = PostsRecyclerViewAdapter(postListingRecyclerViewAdapterWiring )
}
@ -528,6 +519,10 @@ class ProfileMainFragment : Fragment() {
}, getString(R.string.share_post))
startActivity(intent)
}
override fun hashtagClicked(hashtag: String) {
HashtagsPostsActivity.startActivity(requireContext(), hashtag)
}
}
}

View File

@ -1,6 +1,6 @@
package com.isolaatti.search.ui
import android.content.Intent
import android.annotation.SuppressLint
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
@ -10,7 +10,6 @@ import androidx.core.widget.doAfterTextChanged
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.Observer
import androidx.navigation.findNavController
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.carousel.CarouselLayoutManager
@ -18,12 +17,11 @@ import com.google.android.material.carousel.UncontainedCarouselStrategy
import com.google.android.material.chip.Chip
import com.isolaatti.R
import com.isolaatti.databinding.FragmentSearchBinding
import com.isolaatti.hashtags.ui.HashtagsPostsActivity
import com.isolaatti.posting.posts.viewer.ui.PostViewerActivity
import com.isolaatti.profile.domain.entity.ProfileListItem
import com.isolaatti.profile.profile_listing.ui.ProfileListingFragment
import com.isolaatti.profile.ui.ProfileActivity
import com.isolaatti.search.data.HashtagsDto
import com.isolaatti.search.data.NewestUsersDto
import com.isolaatti.search.data.SearchDto
import com.isolaatti.search.data.SearchHistoryEntity
import com.isolaatti.search.data.SearchResultType
@ -63,7 +61,7 @@ class SearchFragment : Fragment() {
viewBinding.chipGroup.addView(Chip(requireContext()).apply {
text = "#$hashtag"
setOnClickListener {
findNavController().navigate(SearchFragmentDirections.actionSearchFragmentToHashtagPostsFragment(hashtag))
HashtagsPostsActivity.startActivity(requireContext(), hashtag)
}
})
}
@ -100,6 +98,7 @@ class SearchFragment : Fragment() {
viewBinding.searchBar.menu.findItem(R.id.close_button)?.setVisible(false)
}
}
@SuppressLint("RestrictedApi")
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupListeners()
@ -141,7 +140,7 @@ class SearchFragment : Fragment() {
it.resourceId.toLongOrNull()?.also { PostViewerActivity.startActivity(requireContext(), it) }
}
SearchResultType.Hashtag -> {
findNavController().navigate(SearchFragmentDirections.actionSearchFragmentToHashtagPostsFragment(it.resourceId))
HashtagsPostsActivity.startActivity(requireContext(), it.resourceId)
}
SearchResultType.Unknown -> {}
}

View File

@ -26,28 +26,6 @@
android:background="@color/translucent_purple"
android:translationZ="2dp">
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/textImageName"
style="?attr/textInputFilledDenseStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="32dp"
android:layout_marginTop="16dp"
android:hint="@string/picture_name"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/upload_photo_fab"
app:layout_constraintStart_toStartOf="parent">
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:layout_height="match_parent"
android:maxLines="1" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/upload_photo_fab"
android:layout_width="wrap_content"
@ -56,7 +34,9 @@
android:layout_marginEnd="16dp"
android:layout_marginBottom="32dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="8dp"/>
<ProgressBar
android:id="@+id/progress_bar_loading"

View File

@ -63,7 +63,8 @@
android:layout_height="wrap_content"
android:layout_marginHorizontal="8dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"/>
android:layout_marginBottom="8dp"
android:linksClickable="true"/>
</LinearLayout>

View File

@ -10,7 +10,8 @@
android:id="@+id/topAppBar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:liftOnScrollColor="@color/on_surface">
app:liftOnScrollColor="@color/on_surface"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar_layout"
android:layout_width="match_parent"
@ -156,23 +157,7 @@
android:text="@string/new_post"
app:icon="@drawable/baseline_post_add_24"/>
<com.google.android.material.button.MaterialButton
android:id="@+id/images_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/Widget.Material3.Button.IconButton.Filled.Tonal"
android:layout_marginStart="16dp"
android:text="@string/images"
app:icon="@drawable/baseline_image_24"/>
<com.google.android.material.button.MaterialButton
android:id="@+id/audios_button"
style="@style/Widget.Material3.Button.IconButton.Filled.Tonal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:text="@string/audios"
app:icon="@drawable/baseline_audio_file_24" />
</LinearLayout>
</HorizontalScrollView>
@ -194,7 +179,8 @@
android:id="@+id/swipe_to_refresh"
android:layout_width="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"
android:clipToPadding="false">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/feed_recycler_view"
android:layout_width="match_parent"

View File

@ -19,7 +19,8 @@
android:id="@+id/topAppBar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:liftOnScroll="true">
app:liftOnScroll="true"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/topAppBar"

View File

@ -6,7 +6,8 @@
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"

View File

@ -20,7 +20,7 @@
<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"/>
android:hint="@string/what_do_you_want_to_talk_about_you_can_record_an_audio_if_you_want"/>
</com.google.android.material.textfield.TextInputLayout>
<LinearLayout

View File

@ -5,7 +5,8 @@
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">
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/topAppBar"

View File

@ -113,7 +113,8 @@
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
<com.google.android.material.search.SearchBar
android:id="@+id/search_bar"
android:layout_width="match_parent"

View File

@ -3,6 +3,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical">
@ -11,7 +12,8 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="?attr/materialCardViewFilledStyle"
android:layout_margin="8dp">
android:layout_margin="8dp"
>
<LinearLayout
android:layout_width="match_parent"
@ -39,11 +41,14 @@
android:id="@+id/text_view_username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textStyle="bold"/>
android:textStyle="bold"
tools:text="Erik"
android:textSize="16sp"/>
<TextView
android:id="@+id/text_view_date"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
android:layout_height="wrap_content"
tools:text="Date"/>
</LinearLayout>
<com.google.android.material.button.MaterialButton
@ -67,7 +72,11 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="8dp"
android:layout_marginTop="8dp" />
android:layout_marginTop="8dp"
android:linksClickable="true"
android:textSize="16sp"
tools:text="Hola"
android:fontFamily="sans-serif"/>
<LinearLayout
android:layout_width="match_parent"

View File

@ -34,9 +34,6 @@
<action
android:id="@+id/action_searchFragment_to_hashtagsFragment"
app:destination="@id/hashtagsFragment" />
<action
android:id="@+id/action_searchFragment_to_hashtagPostsFragment"
app:destination="@id/hashtagPostsFragment2" />
<action
android:id="@+id/action_searchFragment_to_browseProfilesFragment"
app:destination="@id/browseProfilesFragment" />
@ -44,19 +41,7 @@
<fragment
android:id="@+id/hashtagsFragment"
android:name="com.isolaatti.hashtags.ui.HashtagsFragment"
android:label="HashtagsFragment" >
<action
android:id="@+id/action_hashtagsFragment2_to_hashtagPostsFragment2"
app:destination="@id/hashtagPostsFragment2" />
</fragment>
<fragment
android:id="@+id/hashtagPostsFragment2"
android:name="com.isolaatti.hashtags.ui.HashtagPostsFragment"
android:label="HashtagPostsFragment">
<argument
android:name="hashtag"
app:argType="string" />
</fragment>
android:label="HashtagsFragment" />
<fragment
android:id="@+id/browseProfilesFragment"
android:name="com.isolaatti.profile.ui.BrowseProfilesFragment"

View File

@ -10,6 +10,6 @@
android:label="MarkdownPreviewFragment" />
<fragment
android:id="@+id/markdownEditingFragment"
android:name="com.isolaatti.posting.posts.ui.MarkdownEditingFragment"
android:name="com.isolaatti.posting.posts.ui.PostEditingFragment"
android:label="MarkdownEditingFragment" />
</navigation>

View File

@ -58,7 +58,7 @@
<string name="there_is_no_more_content_to_show">There is no more content to show</string>
<string name="post">Post</string>
<string name="add_image">Add image</string>
<string name="what_do_you_want_to_talk_about_markdown_is_compatible_you_can_record_an_audio_if_you_want">What do you want to talk about? Markdown is compatible. You can record an audio if you want.</string>
<string name="what_do_you_want_to_talk_about_you_can_record_an_audio_if_you_want">What do you want to talk about? You can record an audio if you want.</string>
<string name="posted_successfully">Posted!</string>
<string name="drafts">Drafts</string>
<string name="report_profile">Report profile</string>

View File

@ -33,4 +33,13 @@
<item name="android:windowFullscreen">false</item>
<item name="android:windowBackground">#D9000000</item>
</style>
<style name="Theme.Isolaatti.OSS" parent="Theme.Material3.DayNight">
<item name="android:colorPrimary">@color/purple</item>
<item name="colorSurface">@color/surface</item>
<item name="colorOnSurface">@color/on_surface</item>
<item name="android:statusBarColor">@color/purple</item>
<item name="windowActionModeOverlay">true</item>
<item name="actionModeCloseDrawable">@drawable/baseline_close_24</item>
</style>
</resources>

View File

@ -10,6 +10,7 @@ buildscript {
def nav_version = "2.6.0"
classpath "com.google.android.libraries.mapsplatform.secrets-gradle-plugin:secrets-gradle-plugin:2.0.1"
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"
classpath 'com.google.android.gms:oss-licenses-plugin:0.10.6'
}
}
plugins {