diff --git a/app/src/main/java/org/futo/circles/feature/timeline/list/TimelineViewHolder.kt b/app/src/main/java/org/futo/circles/feature/timeline/list/TimelineViewHolder.kt
index 02c0c5c037b1093eac3b8803b081fd51cada4f0c..fe56949e62f3406a2aa05bbe75ff16085aa48f26 100644
--- a/app/src/main/java/org/futo/circles/feature/timeline/list/TimelineViewHolder.kt
+++ b/app/src/main/java/org/futo/circles/feature/timeline/list/TimelineViewHolder.kt
@@ -86,7 +86,7 @@ class TextMediaPostViewHolder(
 
     private fun bindTextPost(content: TextContent) {
         binding.tvTextContent.apply {
-            setText(content.message, TextView.BufferType.SPANNABLE)
+            setText(content.messageSpanned, TextView.BufferType.SPANNABLE)
             visible()
         }
         binding.vMediaContent.lMedia.gone()
@@ -101,7 +101,7 @@ class TextMediaPostViewHolder(
 
     private fun bindMediaCaption(content: MediaContent) {
         binding.tvTextContent.apply {
-            val caption = content.caption
+            val caption = content.captionSpanned
             setIsVisible(caption != null)
             caption?.let { setText(it, TextView.BufferType.SPANNABLE) }
         }
diff --git a/app/src/main/java/org/futo/circles/feature/timeline/post/create/CreatePostDialogFragment.kt b/app/src/main/java/org/futo/circles/feature/timeline/post/create/CreatePostDialogFragment.kt
index 845be5b72f1d158db1a422c9cf9fb090d4848948..37b629d3aaeda0588c4623ce8598d9d707f9e43d 100644
--- a/app/src/main/java/org/futo/circles/feature/timeline/post/create/CreatePostDialogFragment.kt
+++ b/app/src/main/java/org/futo/circles/feature/timeline/post/create/CreatePostDialogFragment.kt
@@ -66,7 +66,7 @@ class CreatePostDialogFragment :
                 PostContentType.IMAGE_CONTENT, PostContentType.VIDEO_CONTENT ->
                     binding.vPostPreview.setMediaFromExistingPost(it as MediaContent)
 
-                else -> binding.vPostPreview.setText((it as TextContent).message.toString())
+                else -> binding.vPostPreview.setText((it as TextContent).message)
             }
         }
     }
diff --git a/core/src/main/java/org/futo/circles/core/feature/timeline/data_source/BaseTimelineDataSource.kt b/core/src/main/java/org/futo/circles/core/feature/timeline/data_source/BaseTimelineDataSource.kt
index 79975d7b5dc3c4855d90d3954d9094d48244aba3..b10208ac0f2ef53117d1f5ec0a294a0b034a1c4b 100644
--- a/core/src/main/java/org/futo/circles/core/feature/timeline/data_source/BaseTimelineDataSource.kt
+++ b/core/src/main/java/org/futo/circles/core/feature/timeline/data_source/BaseTimelineDataSource.kt
@@ -4,6 +4,10 @@ import android.content.Context
 import androidx.lifecycle.MutableLiveData
 import androidx.lifecycle.SavedStateHandle
 import dagger.hilt.android.qualifiers.ApplicationContext
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.flow.emptyFlow
+import kotlinx.coroutines.flow.flowOn
+import kotlinx.coroutines.runBlocking
 import org.futo.circles.core.extensions.getOrThrow
 import org.futo.circles.core.feature.timeline.builder.BaseTimelineBuilder
 import org.futo.circles.core.feature.timeline.builder.MultiTimelineBuilder
diff --git a/core/src/main/java/org/futo/circles/core/mapping/MediaPostContentMapping.kt b/core/src/main/java/org/futo/circles/core/mapping/MediaPostContentMapping.kt
index 36b694c50e8b98aba7fe65f893f190b4c4758272..ff8565f3ebd3f72655f8717e1e16844f34bcfe63 100644
--- a/core/src/main/java/org/futo/circles/core/mapping/MediaPostContentMapping.kt
+++ b/core/src/main/java/org/futo/circles/core/mapping/MediaPostContentMapping.kt
@@ -16,18 +16,22 @@ import org.matrix.android.sdk.api.session.room.model.message.getFileName
 import org.matrix.android.sdk.api.session.room.model.message.getFileUrl
 import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
 
-fun TimelineEvent.toMediaContent(mediaType: MediaType, markwon: Markwon): MediaContent = MediaContent(
-    type = if (mediaType == MediaType.Image) PostContentType.IMAGE_CONTENT else PostContentType.VIDEO_CONTENT,
-    caption = getCaption(markwon),
-    mediaFileData = toMediaFileData(mediaType),
-    thumbnailFileData = toThumbnailFileData(mediaType),
-    thumbHash = getThumbHash(mediaType)
-)
+fun TimelineEvent.toMediaContent(mediaType: MediaType, markwon: Markwon): MediaContent {
+    val caption = getCaption()
+    return MediaContent(
+        type = if (mediaType == MediaType.Image) PostContentType.IMAGE_CONTENT else PostContentType.VIDEO_CONTENT,
+        caption = caption,
+        captionSpanned = caption?.let { markwon.toMarkdown(caption) },
+        mediaFileData = toMediaFileData(mediaType),
+        thumbnailFileData = toThumbnailFileData(mediaType),
+        thumbHash = getThumbHash(mediaType)
+    )
+}
 
-private fun TimelineEvent.getCaption(markwon: Markwon): CharSequence? {
+private fun TimelineEvent.getCaption(): String? {
     val lastContent =
         annotations?.editSummary?.latestEdit?.getClearContent() ?: root.getClearContent()
-    return lastContent?.get(MediaCaptionFieldKey)?.toString()?.let { markwon.toMarkdown(it) }
+    return lastContent?.get(MediaCaptionFieldKey)?.toString()
 }
 
 private fun TimelineEvent.getThumbHash(mediaType: MediaType) = when (mediaType) {
diff --git a/core/src/main/java/org/futo/circles/core/mapping/TextPostContentMapping.kt b/core/src/main/java/org/futo/circles/core/mapping/TextPostContentMapping.kt
index 95634a367ec0b9c22570ad9dde12101993c2babd..e7811a563fcb39d748bf58029e5efa0d6310cfd4 100644
--- a/core/src/main/java/org/futo/circles/core/mapping/TextPostContentMapping.kt
+++ b/core/src/main/java/org/futo/circles/core/mapping/TextPostContentMapping.kt
@@ -5,9 +5,12 @@ import org.futo.circles.core.model.TextContent
 import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
 import org.matrix.android.sdk.api.session.room.timeline.getTextEditableContent
 
-fun TimelineEvent.toTextContent(markwon: Markwon): TextContent = TextContent(
-    message = markwon.toMarkdown(getTextEditableContent(false))
-
-)
+fun TimelineEvent.toTextContent(markwon: Markwon): TextContent {
+    val text = getTextEditableContent(false)
+    return TextContent(
+        message = text,
+        messageSpanned = markwon.toMarkdown(text)
+    )
+}
 
 
diff --git a/core/src/main/java/org/futo/circles/core/model/PostContent.kt b/core/src/main/java/org/futo/circles/core/model/PostContent.kt
index 8db795efd590bbbda400d6a9d2cc39ccbfa41c82..ffd7521acfa4d18ffb07269b80be143de625d722 100644
--- a/core/src/main/java/org/futo/circles/core/model/PostContent.kt
+++ b/core/src/main/java/org/futo/circles/core/model/PostContent.kt
@@ -1,5 +1,6 @@
 package org.futo.circles.core.model
 
+import android.text.Spanned
 import android.util.Size
 import org.matrix.android.sdk.api.session.room.model.message.MessageType
 
@@ -18,12 +19,14 @@ sealed class PostContent(open val type: PostContentType) {
 }
 
 data class TextContent(
-    val message: CharSequence
+    val message: String,
+    val messageSpanned: Spanned
 ) : PostContent(PostContentType.TEXT_CONTENT)
 
 data class MediaContent(
     override val type: PostContentType,
-    val caption: CharSequence?,
+    val caption: String?,
+    val captionSpanned: Spanned?,
     val mediaFileData: MediaFileData,
     val thumbnailFileData: MediaFileData?,
     val thumbHash: String?