Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • circles/circles-android
1 result
Show changes
Commits on Source (4)
......@@ -57,10 +57,12 @@ android {
buildTypes {
named("debug") {
isMinifyEnabled = false
manifestPlaceholders["crashlyticsEnabled"] = false
}
named("release") {
signingConfig = signingConfigs.getByName("release")
isMinifyEnabled = true
manifestPlaceholders["crashlyticsEnabled"] = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
......
......@@ -27,6 +27,9 @@
android:theme="@style/Theme.Circles"
tools:ignore="DataExtractionRules"
tools:targetApi="tiramisu">
<meta-data
android:name="firebase_crashlytics_collection_enabled"
android:value="${crashlyticsEnabled}" />
<activity
android:name=".settings.feature.active_sessions.verify.qr.QrScannerActivity"
android:exported="false" />
......
......@@ -19,8 +19,8 @@ import org.futo.circles.core.extensions.withConfirmation
import org.futo.circles.core.feature.share.ShareProvider
import org.futo.circles.core.model.PostContent
import org.futo.circles.databinding.DialogFragmentDmTimelineBinding
import org.futo.circles.feature.direct.timeline.list.DMTimelineAdapter
import org.futo.circles.feature.timeline.list.PostOptionsListener
import org.futo.circles.feature.timeline.list.TimelineAdapter
import org.futo.circles.feature.timeline.post.create.PostSentListener
import org.futo.circles.feature.timeline.post.emoji.EmojiPickerListener
import org.futo.circles.feature.timeline.post.menu.PostMenuListener
......@@ -43,7 +43,7 @@ class DMTimelineDialogFragment :
private val navigator by lazy { DMTimelineNavigator(this) }
private val listAdapter by lazy {
TimelineAdapter(this, false, videoPlayer).apply {
DMTimelineAdapter(this, videoPlayer).apply {
setHasStableIds(true)
}
}
......
package org.futo.circles.feature.direct.timeline.list
import androidx.media3.exoplayer.ExoPlayer
import androidx.recyclerview.widget.RecyclerView
import org.futo.circles.core.base.list.BaseRvAdapter
import org.futo.circles.core.model.Post
import org.futo.circles.core.model.PostListItem
import org.futo.circles.feature.timeline.list.OnVideoPlayBackStateListener
import org.futo.circles.feature.timeline.list.holder.PostViewHolder
import org.futo.circles.feature.timeline.list.holder.VideoPostViewHolder
import org.futo.circles.model.PostItemPayload
abstract class BaseTimelineAdapter<VH : RecyclerView.ViewHolder>(
private val videoPlayer: ExoPlayer
) : BaseRvAdapter<PostListItem, VH>(
PayloadIdEntityCallback { old, new ->
if (new is Post && old is Post)
PostItemPayload(
readByCount = new.readByCount,
repliesCount = new.repliesCount,
reactions = new.reactionsData,
needToUpdateFullItem = new.content != old.content || new.postInfo != old.postInfo
)
else null
}), OnVideoPlayBackStateListener {
private var currentPlayingVideoHolder: VideoPostViewHolder? = null
override fun getItemId(position: Int): Long = getItem(position).id.hashCode().toLong()
override fun onBindViewHolder(holder: VH, position: Int) {
holder.bind(getItem(position))
}
override fun onBindViewHolder(
holder: VH,
position: Int,
payloads: MutableList<Any>
) {
(holder as? PostViewHolder) ?: run {
super.onBindViewHolder(holder, position, payloads)
return
}
if (payloads.isEmpty()) {
super.onBindViewHolder(holder, position, payloads)
} else {
payloads.forEach {
val payload = (it as? PostItemPayload) ?: return@forEach
if (payload.needToUpdateFullItem) holder.bind(getItem(position))
else holder.bindPayload(payload)
}
}
}
override fun onViewDetachedFromWindow(holder: VH) {
super.onViewDetachedFromWindow(holder)
if (holder == currentPlayingVideoHolder) stopVideoPlayback()
}
override fun onVideoPlaybackStateChanged(holder: VideoPostViewHolder, isPlaying: Boolean) {
currentPlayingVideoHolder = if (isPlaying) {
stopVideoPlayback(false)
holder
} else null
}
fun stopVideoPlayback(shouldNotify: Boolean = true) {
currentPlayingVideoHolder?.stopVideo(shouldNotify)
}
}
\ No newline at end of file
package org.futo.circles.feature.direct.timeline.list
class DMTimelineAdapter {
import android.view.ViewGroup
import androidx.media3.exoplayer.ExoPlayer
import org.futo.circles.core.model.Post
import org.futo.circles.core.model.PostContentType
import org.futo.circles.core.model.TimelineLoadingItem
import org.futo.circles.feature.timeline.list.PostOptionsListener
import org.futo.circles.feature.timeline.list.holder.OtherEventPostViewHolder
import org.futo.circles.feature.timeline.list.holder.PostListItemViewHolder
import org.futo.circles.feature.timeline.list.holder.TimelineLoadingViewHolder
private enum class DmTimelineViewType {
MY_TEXT, OTHER_TEXT,
MY_IMAGE, OTHER_IMAGE,
MY_VIDEO, OTHER_VIDEO,
OTHER, LOADING
}
class DMTimelineAdapter(
private val postOptionsListener: PostOptionsListener,
videoPlayer: ExoPlayer
) : BaseTimelineAdapter<PostListItemViewHolder>(videoPlayer) {
override fun getItemViewType(position: Int): Int = when (val item = getItem(position)) {
is Post -> {
val isMyMessage = item.isMyPost()
when (item.content.type) {
PostContentType.TEXT_CONTENT -> if (isMyMessage) DmTimelineViewType.MY_TEXT.ordinal
else DmTimelineViewType.OTHER_TEXT.ordinal
PostContentType.IMAGE_CONTENT -> if (isMyMessage) DmTimelineViewType.MY_IMAGE.ordinal
else DmTimelineViewType.OTHER_IMAGE.ordinal
PostContentType.VIDEO_CONTENT -> if (isMyMessage) DmTimelineViewType.MY_VIDEO.ordinal
else DmTimelineViewType.OTHER_VIDEO.ordinal
else -> DmTimelineViewType.OTHER.ordinal
}
}
is TimelineLoadingItem -> DmTimelineViewType.LOADING.ordinal
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PostListItemViewHolder {
return when (DmTimelineViewType.entries[viewType]) {
// TimelineViewType.TEXT -> TextPostViewHolder(
// parent, postOptionsListener, isThread
// )
//
// TimelineViewType.IMAGE -> ImagePostViewHolder(parent, postOptionsListener, isThread)
//
// TimelineViewType.VIDEO -> VideoPostViewHolder(
// parent,
// postOptionsListener,
// isThread,
// videoPlayer,
// this
// )
DmTimelineViewType.MY_TEXT -> TODO()
DmTimelineViewType.OTHER_TEXT -> TODO()
DmTimelineViewType.MY_IMAGE -> TODO()
DmTimelineViewType.OTHER_IMAGE -> TODO()
DmTimelineViewType.MY_VIDEO -> TODO()
DmTimelineViewType.OTHER_VIDEO -> TODO()
DmTimelineViewType.OTHER -> OtherEventPostViewHolder(parent, postOptionsListener)
DmTimelineViewType.LOADING -> TimelineLoadingViewHolder(parent)
}
}
}
\ No newline at end of file
......@@ -2,20 +2,17 @@ package org.futo.circles.feature.timeline.list
import android.view.ViewGroup
import androidx.media3.exoplayer.ExoPlayer
import org.futo.circles.core.base.list.BaseRvAdapter
import org.futo.circles.core.model.Post
import org.futo.circles.core.model.PostContentType
import org.futo.circles.core.model.PostListItem
import org.futo.circles.core.model.TimelineLoadingItem
import org.futo.circles.feature.direct.timeline.list.BaseTimelineAdapter
import org.futo.circles.feature.timeline.list.holder.ImagePostViewHolder
import org.futo.circles.feature.timeline.list.holder.OtherEventPostViewHolder
import org.futo.circles.feature.timeline.list.holder.PollPostViewHolder
import org.futo.circles.feature.timeline.list.holder.PostListItemViewHolder
import org.futo.circles.feature.timeline.list.holder.PostViewHolder
import org.futo.circles.feature.timeline.list.holder.TextPostViewHolder
import org.futo.circles.feature.timeline.list.holder.TimelineLoadingViewHolder
import org.futo.circles.feature.timeline.list.holder.VideoPostViewHolder
import org.futo.circles.model.PostItemPayload
private enum class TimelineViewType { TEXT, IMAGE, VIDEO, POLL, OTHER, LOADING }
......@@ -23,20 +20,8 @@ class TimelineAdapter(
private val postOptionsListener: PostOptionsListener,
private val isThread: Boolean,
private val videoPlayer: ExoPlayer
) : BaseRvAdapter<PostListItem, PostListItemViewHolder>(PayloadIdEntityCallback { old, new ->
if (new is Post && old is Post)
PostItemPayload(
readByCount = new.readByCount,
repliesCount = new.repliesCount,
reactions = new.reactionsData,
needToUpdateFullItem = new.content != old.content || new.postInfo != old.postInfo
)
else null
}), OnVideoPlayBackStateListener {
) : BaseTimelineAdapter<PostListItemViewHolder>(videoPlayer) {
private var currentPlayingVideoHolder: VideoPostViewHolder? = null
override fun getItemId(position: Int): Long = getItem(position).id.hashCode().toLong()
override fun getItemViewType(position: Int): Int = when (val item = getItem(position)) {
is Post -> when (item.content.type) {
......@@ -75,46 +60,4 @@ class TimelineAdapter(
TimelineViewType.LOADING -> TimelineLoadingViewHolder(parent)
}
}
override fun onBindViewHolder(holder: PostListItemViewHolder, position: Int) {
holder.bind(getItem(position))
}
override fun onBindViewHolder(
holder: PostListItemViewHolder,
position: Int,
payloads: MutableList<Any>
) {
(holder as? PostViewHolder) ?: run {
super.onBindViewHolder(holder, position, payloads)
return
}
if (payloads.isEmpty()) {
super.onBindViewHolder(holder, position, payloads)
} else {
payloads.forEach {
val payload = (it as? PostItemPayload) ?: return@forEach
if (payload.needToUpdateFullItem) holder.bind(getItem(position))
else holder.bindPayload(payload)
}
}
}
override fun onViewDetachedFromWindow(holder: PostListItemViewHolder) {
super.onViewDetachedFromWindow(holder)
if (holder == currentPlayingVideoHolder) stopVideoPlayback()
}
override fun onVideoPlaybackStateChanged(holder: VideoPostViewHolder, isPlaying: Boolean) {
currentPlayingVideoHolder = if (isPlaying) {
stopVideoPlayback(false)
holder
} else null
}
fun stopVideoPlayback(shouldNotify: Boolean = true) {
currentPlayingVideoHolder?.stopVideo(shouldNotify)
}
}
\ No newline at end of file
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="36dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp">
<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/ivBackground"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@color/chip_selected_color"
app:layout_constraintBottom_toBottomOf="@id/tvTime"
app:layout_constraintEnd_toEndOf="@id/tvMessage"
app:layout_constraintStart_toStartOf="@id/tvMessage"
app:layout_constraintTop_toTopOf="@id/tvMessage"
app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlay.App.Message.My" />
<TextView
android:id="@+id/tvMessage"
style="@style/body"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:autoLink="web"
android:padding="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="sadasdasdasdasdasdasdasdasdasd" />
<TextView
android:id="@+id/tvTime"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:paddingBottom="4dp"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvMessage"
tools:text="sadasdasdasdasdasdasdasdasdasd" />
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
......@@ -12,12 +12,12 @@
android:id="@+id/ivBackground"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@color/chip_selected_color"
android:background="@color/post_card_background_color"
app:layout_constraintBottom_toBottomOf="@id/tvTime"
app:layout_constraintEnd_toEndOf="@id/tvMessage"
app:layout_constraintStart_toStartOf="@id/tvMessage"
app:layout_constraintTop_toTopOf="@id/tvMessage"
app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlay.App.Message" />
app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlay.App.Message.Other" />
<TextView
android:id="@+id/tvMessage"
......
......@@ -105,11 +105,18 @@
<item name="android:windowExitAnimation">@anim/slide_out</item>
</style>
<style name="ShapeAppearanceOverlay.App.Message" parent="">
<style name="ShapeAppearanceOverlay.App.Message.Other" parent="">
<item name="cornerSizeTopRight">10dp</item>
<item name="cornerSizeBottomRight">10dp</item>
<item name="cornerSizeTopLeft">10dp</item>
<item name="cornerFamilyTopRight">rounded</item>
</style>
<style name="ShapeAppearanceOverlay.App.Message.My" parent="">
<item name="cornerSizeBottomLeft">10dp</item>
<item name="cornerSizeTopRight">10dp</item>
<item name="cornerSizeTopLeft">10dp</item>
<item name="cornerFamilyTopRight">rounded</item>
</style>
</resources>
\ No newline at end of file