Use database magic to make it easier to display conferences names and progress for events

This commit is contained in:
Felix 2020-04-04 22:39:36 +02:00
parent 7f74cd3795
commit 0d9787618c
19 changed files with 106 additions and 29 deletions

View file

@ -55,6 +55,9 @@ data class Event(
var recordings: List<Recording>? = null
) : Parcelable, Comparable<Event> {
@Ignore
var progress: Long = 0
override fun compareTo(other: Event): Int = title.compareTo(other.title)
constructor(parcel: Parcel) : this(

View file

@ -67,6 +67,17 @@ abstract class EventDao : BaseDao<Event>() {
@Query("SELECT * FROM event WHERE title LIKE :title LIMIT 1")
abstract fun findSingleEventByTitle(title: String): LiveData<Event?>
// @Query("SELECT * FROM event JOIN conference ON event.conferenceId=conference.id")
// abstract suspend fun getEventWithConference(eventId: Long): List<EventWithConference>
//
// @Query("SELECT * FROM event JOIN conference ON event.conferenceId=conference.id WHERE event.id = :eventId")
// abstract suspend fun getAllEventsWithConference(eventId: Long): List<EventWithConference>
@Query("""SELECT event.*, conference.title as conference
FROM event JOIN conference ON event.conferenceId=conference.id
WHERE conference.id = :confernceId""")
abstract fun getEventsWithConferenceForConfernce(confernceId: Long): LiveData<List<Event>>
override suspend fun updateOrInsertInternal(item: Event) {
if (item.id != 0L) {
update(item)

View file

@ -7,7 +7,7 @@ import androidx.room.PrimaryKey
import java.util.Date
@Entity(tableName = "playback_progress",
indices = arrayOf(Index(value = ["event_guid"], unique = true)))
indices = [Index(value = ["event_guid"], unique = true)])
data class PlaybackProgress(
@PrimaryKey(autoGenerate = true)
val id: Long = 0,

View file

@ -8,6 +8,13 @@ import androidx.room.Query
@Dao
interface PlaybackProgressDao {
@Query("""SELECT event.*, progress.progress, progress.watch_date, conference.title as conference
FROM playback_progress as progress
JOIN event ON event_guid = event.guid
JOIN conference ON event.conferenceId = conference.id""")
fun getInProgessEvents(): LiveData<List<ProgressEventView>>
@Query("SELECT * from playback_progress")
fun getAll(): LiveData<List<PlaybackProgress>>

View file

@ -0,0 +1,13 @@
package de.nicidienase.chaosflix.common.userdata.entities.progress
import androidx.room.ColumnInfo
import androidx.room.Embedded
import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.Event
class ProgressEventView(
val progress: Long,
@ColumnInfo(name = "watch_date")
val watchDate: Long,
@Embedded
val event: Event
)

View file

@ -18,7 +18,9 @@ abstract class WatchlistItemDao : BaseDao<WatchlistItem>() {
@Query("SELECT * FROM watchlist_item")
abstract fun getAllSync(): List<WatchlistItem>
@Query("SELECT * FROM watchlist_item JOIN event ON watchlist_item.event_guid=event.guid")
@Query("""SELECT event.*, conference.title as conference FROM watchlist_item
JOIN event ON watchlist_item.event_guid=event.guid
JOIN conference ON event.conferenceId = conference.id""")
abstract fun getWatchlistEvents(): LiveData<List<Event>>
@Query("SELECT * FROM watchlist_item WHERE event_guid = :guid LIMIT 1")

View file

@ -2,6 +2,7 @@ package de.nicidienase.chaosflix.common.viewmodel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Transformations
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import de.nicidienase.chaosflix.R
@ -49,8 +50,8 @@ class BrowseViewModel(
fun getConferencesByGroup(groupId: Long) =
database.conferenceDao().findConferenceByGroup(groupId)
fun getEventsforConference(conference: Conference) =
database.eventDao().findEventsByConference(conference.id)
fun getEventsforConference(conference: Conference): LiveData<List<Event>> =
database.eventDao().getEventsWithConferenceForConfernce(conference.id)
fun getUpdateState() =
mediaRepository.updateConferencesAndGroups()
@ -74,11 +75,18 @@ class BrowseViewModel(
return itemDao.getWatchlistEvents()
}
fun getInProgressEvents(): LiveData<List<Event>> = updateAndGetEventsForGuids {
database
.playbackProgressDao()
.getAllSync()
.map { it.eventGuid } }
fun getInProgressEvents(): LiveData<List<Event>> {
val dao = database.playbackProgressDao()
viewModelScope.launch(Dispatchers.IO) {
dao.getAllSync().forEach {
mediaRepository.updateSingleEvent(it.eventGuid)
}
}
return Transformations.map(dao.getInProgessEvents()) { list ->
list.forEach { it.event.progress = it.progress }
list.map { it.event }
}
}
fun getPromotedEvents(): LiveData<List<Event>> = database.eventDao().findPromotedEvents()

View file

@ -1,10 +1,13 @@
package de.nicidienase.chaosflix.touch
import android.view.View
import android.widget.ImageView
import android.widget.ProgressBar
import android.widget.TextView
import androidx.databinding.BindingAdapter
import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions
import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.Event
@BindingAdapter("imageUrl")
fun loadImage(imageView: ImageView, url: String?) {
@ -19,3 +22,15 @@ fun loadImage(imageView: ImageView, url: String?) {
fun setDuration(textView: TextView, duration: Long) {
textView.text = String.format("%d:%02d:%02d", duration / 3600, (duration % 3600) / 60, duration % 60)
}
@BindingAdapter("progress")
fun ProgressBar.eventProgress(event: Event) {
val progress = event.progress
if (progress > 0) {
this.visibility = View.VISIBLE
this.max = event.length.toInt()
this.progress = (progress / 1000).toInt()
} else {
this.visibility = View.GONE
}
}

View file

@ -1,6 +1,7 @@
package de.nicidienase.chaosflix.touch.browse.adapters
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.view.ViewCompat
import androidx.recyclerview.widget.RecyclerView
@ -10,6 +11,8 @@ import de.nicidienase.chaosflix.touch.databinding.ItemEventCardviewBinding
open class EventRecyclerViewAdapter(val listener: (Event) -> Unit) :
ItemRecyclerViewAdapter<Event, EventRecyclerViewAdapter.ViewHolder>() {
var showConferenceName: Boolean = false
override fun getComparator(): Comparator<in Event>? {
return Comparator { o1, o2 -> o1.title.compareTo(o2.title) }
}
@ -37,6 +40,9 @@ open class EventRecyclerViewAdapter(val listener: (Event) -> Unit) :
holder.binding.root.setOnClickListener {
listener(event)
}
if (showConferenceName) {
holder.binding.conferenceNameText.visibility = View.VISIBLE
}
ViewCompat.setTransitionName(holder.binding.titleText, "title_${event.guid}")
ViewCompat.setTransitionName(holder.binding.subtitleText, "subtitle_${event.guid}")

View file

@ -118,9 +118,11 @@ public class EventsListFragment extends BrowseFragment implements SearchView.OnQ
if (type == TYPE_BOOKMARKS) {
setupToolbar(binding.incToolbar.toolbar, R.string.bookmarks);
eventAdapter.setShowConferenceName(true);
getViewModel().getBookmarkedEvents().observe(this, listObserver);
} else if (type == TYPE_IN_PROGRESS) {
setupToolbar(binding.incToolbar.toolbar, R.string.continue_watching);
eventAdapter.setShowConferenceName(true);
getViewModel().getInProgressEvents().observe(this, listObserver);
} else if (type == TYPE_EVENTS) {
{

View file

@ -69,7 +69,7 @@
app:layout_constraintTop_toBottomOf="@+id/title_text"/>
<TextView
android:id="@+id/tag_text"
android:id="@+id/conference_name_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"

View file

@ -80,7 +80,7 @@
app:layout_constraintTop_toBottomOf="@+id/title_text"/>
<TextView
android:id="@+id/tag_text"
android:id="@+id/conference_name_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"

View file

@ -80,7 +80,7 @@
tools:text="subtitle"/>
<TextView
android:id="@+id/tag_text"
android:id="@+id/conference_name_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"

View file

@ -76,7 +76,7 @@
tools:text="Subtitles could be very long and span multiple lines, the rest of the layout should addapt accordingly" />
<ImageView
android:id="@+id/tag_text"
android:id="@+id/conference_name_text"
android:layout_width="0dp"
android:layout_height="0dp"
android:paddingEnd="8dp"

View file

@ -61,7 +61,7 @@
android:textAppearance="@style/Base.TextAppearance.AppCompat.Small"/>
<TextView
android:id="@+id/tag_text"
android:id="@+id/conference_name_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"

View file

@ -59,8 +59,8 @@
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/imageView"
app:layout_constraintTop_toTopOf="parent"
tools:text="This is a very long title text that propably won't fit in one line, maybe even need three."/>
app:layout_constraintTop_toBottomOf="@+id/conference_name_text"
tools:text="This is a very long title text that propably won't fit in one line, maybe even need three." />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/subtitle_text"
@ -74,25 +74,24 @@
android:textAppearance="@style/Base.TextAppearance.AppCompat.Small"
android:visibility="@{event.subtitle.length() == 0 ? View.GONE : View.VISIBLE}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/tag_text"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/imageView"
app:layout_constraintTop_toBottomOf="@+id/title_text"
app:layout_constraintVertical_bias="0.0"
tools:text="subtitle"/>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tag_text"
android:layout_width="wrap_content"
android:id="@+id/conference_name_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:gravity="bottom|end"
android:text="@{event.conference}"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/subtitle_text"
tools:text="TAGS"/>
app:layout_constraintEnd_toEndOf="@+id/title_text"
app:layout_constraintStart_toStartOf="@+id/title_text"
app:layout_constraintTop_toTopOf="parent"
tools:text="42c3: Don't panic"
tools:visibility="visible" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/duration"
@ -108,6 +107,17 @@
time="@{event.length}"
tools:text="1:23:45"/>
<ProgressBar
android:id="@+id/progressBar3"
style="?android:attr/progressBarStyleHorizontal"
progress="@{event}"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="@+id/imageView"
app:layout_constraintEnd_toEndOf="@+id/imageView"
app:layout_constraintStart_toStartOf="@+id/imageView"
app:layout_constraintTop_toBottomOf="@+id/imageView" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>

View file

@ -63,7 +63,7 @@
tools:text="Subtitle"/>
<TextView
android:id="@+id/tag_text"
android:id="@+id/conference_name_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"

View file

@ -83,7 +83,7 @@
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/tag_text"
android:id="@+id/conference_name_text"
android:layout_width="0dp"
android:layout_height="0dp"
android:gravity="bottom|end"

View file

@ -81,7 +81,7 @@
<!--android:maxLines="2"-->
<TextView
android:id="@+id/tag_text"
android:id="@+id/conference_name_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"