Skip to content

Instantly share code, notes, and snippets.

@samiuelson
samiuelson / LifecycleAwareLazy.kt
Created September 4, 2018 15:34
Property delegate useful for Android development. Allows to declare lazily evaluated properties dependant on Activity Context and avoid memory leaks.
class LifecycleAwareLazy<T>(lifecycle: Lifecycle, private val initializer: () -> T) :
Lazy<T>, GenericLifecycleObserver {
init {
lifecycle.addObserver(this)
}
private object UNINITIALIZED_VALUE
private var _value: Any? = UNINITIALIZED_VALUE
@samiuelson
samiuelson / MyUnitTest.kt
Created April 4, 2020 11:20
Coroutines setup with org.jetbrains.kotlinx:kotlinx-coroutines-test
class MyUnitTest {
@get:Rule
val coroutineRule = TestCoroutineRule()
@Test
fun `my test executed on TestCoroutineDispatcher`() = coroutineRule.runBlockingTest {
assertEquals(42, answer())
}
}
@samiuelson
samiuelson / activity_main.xml
Created May 6, 2020 12:34
Add chat list widget with translucent gradient
...
<com.pierfrancescosoffritti.androidyoutubeplayer.core.player.views.YouTubePlayerView ... />
<!-- Translucent gradient overlay background to make chat more visible -->
<View
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="@drawable/bg_chat"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="@+id/messagesList" />
package io.getstream.livestreamclone
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import io.getstream.chat.android.client.models.Message
import kotlinx.android.synthetic.main.item_message.view.*
<?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">
<androidx.cardview.widget.CardView
android:id="@+id/avatarWrapper"
android:layout_width="@dimen/avatar_size"
class LiveStreamActivity : AppCompatActivity(R.layout.activity_main) {
private val adapter = MessagesListAdapter()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
loadMockVideoStream()
messagesList.adapter = adapter
val viewModel: LiveStreamViewModel by viewModels()
class LiveStreamViewModel() : ViewModel() {
private val chatClient = ChatClient.instance()
private val _viewState = MutableLiveData<State>()
private lateinit var channelController: ChannelController
val viewState: LiveData<State> = _viewState
init {
chatClient.setUser(chatUser, USER_TOKEN, object : InitConnectionListener() {
companion object {
private const val USER_ID = "bob"
private const val CHANNEL_TYPE = "livestream"
private const val CHANNEL_ID = "livestream-clone-android" // You'll want to make it unique per video
private const val USER_TOKEN = BuildConfig.USER_TOKEN
private val chatUser = User(id = USER_ID).apply {
name = USER_ID
image = getDummyAvatar(USER_ID)
}
private fun requestChannel() {
val channelData = mapOf("name" to "Live stream chat")
val request = QueryChannelRequest()
.withData(channelData)
.withMessages(20)
.withWatch()
channelController.query(request).enqueue {
if (it.isSuccess) {
_viewState.postValue(State.Messages(it.data().messages))
class LiveStreamActivity : AppCompatActivity(R.layout.activity_main) {
private val adapter = MessagesListAdapter()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
loadMockVideoStream()
messagesList.adapter = adapter
val viewModel: LiveStreamViewModel by viewModels()