Antoine POPINEAU
4 years ago
16 changed files with 318 additions and 8 deletions
@ -0,0 +1,62 @@
@@ -0,0 +1,62 @@
|
||||
package com.github.apognu.otter.activities |
||||
|
||||
import android.os.Bundle |
||||
import androidx.appcompat.app.AppCompatActivity |
||||
import androidx.recyclerview.widget.LinearLayoutManager |
||||
import com.github.apognu.otter.R |
||||
import com.github.apognu.otter.adapters.DownloadsAdapter |
||||
import com.github.apognu.otter.utils.* |
||||
import com.google.gson.Gson |
||||
import kotlinx.android.synthetic.main.activity_downloads.* |
||||
import kotlinx.coroutines.Dispatchers.Main |
||||
import kotlinx.coroutines.GlobalScope |
||||
import kotlinx.coroutines.delay |
||||
import kotlinx.coroutines.launch |
||||
|
||||
class DownloadsActivity : AppCompatActivity() { |
||||
lateinit var adapter: DownloadsAdapter |
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) { |
||||
super.onCreate(savedInstanceState) |
||||
|
||||
setContentView(R.layout.activity_downloads) |
||||
|
||||
adapter = DownloadsAdapter(this, RefreshListener()).also { |
||||
downloads.layoutManager = LinearLayoutManager(this) |
||||
downloads.adapter = it |
||||
} |
||||
|
||||
GlobalScope.launch(Main) { |
||||
while (true) { |
||||
refresh() |
||||
delay(1000) |
||||
} |
||||
} |
||||
} |
||||
|
||||
private fun refresh() { |
||||
GlobalScope.launch(Main) { |
||||
RequestBus.send(Request.GetDownloads).wait<Response.Downloads>()?.let { response -> |
||||
adapter.downloads.clear() |
||||
|
||||
while (response.cursor.moveToNext()) { |
||||
val download = response.cursor.download |
||||
|
||||
Gson().fromJson(String(download.request.data), DownloadInfo::class.java)?.let { info -> |
||||
adapter.downloads.add(info.apply { |
||||
this.download = download |
||||
}) |
||||
} |
||||
} |
||||
|
||||
adapter.notifyDataSetChanged() |
||||
} |
||||
} |
||||
} |
||||
|
||||
inner class RefreshListener : DownloadsAdapter.OnRefreshListener { |
||||
override fun refresh() { |
||||
this@DownloadsActivity.refresh() |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,86 @@
@@ -0,0 +1,86 @@
|
||||
package com.github.apognu.otter.adapters |
||||
|
||||
import android.content.Context |
||||
import android.graphics.drawable.Icon |
||||
import android.view.LayoutInflater |
||||
import android.view.View |
||||
import android.view.ViewGroup |
||||
import androidx.recyclerview.widget.RecyclerView |
||||
import com.github.apognu.otter.R |
||||
import com.github.apognu.otter.playback.PinService |
||||
import com.github.apognu.otter.utils.DownloadInfo |
||||
import com.google.android.exoplayer2.offline.Download |
||||
import com.google.android.exoplayer2.offline.DownloadService |
||||
import kotlinx.android.synthetic.main.row_download.view.* |
||||
|
||||
class DownloadsAdapter(private val context: Context, private val listener: OnRefreshListener) : RecyclerView.Adapter<DownloadsAdapter.ViewHolder>() { |
||||
interface OnRefreshListener { |
||||
fun refresh() |
||||
} |
||||
|
||||
var downloads: MutableList<DownloadInfo> = mutableListOf() |
||||
|
||||
override fun getItemCount() = downloads.size |
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { |
||||
val view = LayoutInflater.from(context).inflate(R.layout.row_download, parent, false) |
||||
|
||||
return ViewHolder(view) |
||||
} |
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) { |
||||
val download = downloads[position] |
||||
|
||||
holder.title.text = download.title |
||||
holder.artist.text = download.artist |
||||
|
||||
download.download?.let { state -> |
||||
when (state.isTerminalState) { |
||||
true -> { |
||||
holder.progress.visibility = View.GONE |
||||
holder.toggle.visibility = View.GONE |
||||
} |
||||
|
||||
false -> { |
||||
holder.progress.visibility = View.VISIBLE |
||||
holder.toggle.visibility = View.VISIBLE |
||||
holder.progress.progress = state.percentDownloaded.toInt() |
||||
|
||||
when (state.state) { |
||||
Download.STATE_REMOVING -> { |
||||
holder.progress.visibility = View.GONE |
||||
holder.toggle.visibility = View.GONE |
||||
} |
||||
|
||||
Download.STATE_STOPPED -> holder.toggle.setImageIcon(Icon.createWithResource(context, R.drawable.play)) |
||||
else -> holder.toggle.setImageIcon(Icon.createWithResource(context, R.drawable.pause)) |
||||
} |
||||
} |
||||
} |
||||
|
||||
holder.toggle.setOnClickListener { |
||||
if (state.state == Download.STATE_DOWNLOADING) { |
||||
DownloadService.sendSetStopReason(context, PinService::class.java, download.id, 1, false) |
||||
} else { |
||||
DownloadService.sendSetStopReason(context, PinService::class.java, download.id, Download.STOP_REASON_NONE, false) |
||||
} |
||||
|
||||
listener.refresh() |
||||
} |
||||
|
||||
holder.delete.setOnClickListener { |
||||
DownloadService.sendRemoveDownload(context, PinService::class.java, download.id, false) |
||||
|
||||
listener.refresh() |
||||
} |
||||
} |
||||
} |
||||
|
||||
inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) { |
||||
val title = view.title |
||||
val artist = view.artist |
||||
val progress = view.progress |
||||
val toggle = view.toggle |
||||
val delete = view.delete |
||||
} |
||||
} |
@ -0,0 +1,9 @@
@@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android" |
||||
android:width="24dp" |
||||
android:height="24dp" |
||||
android:viewportWidth="24.0" |
||||
android:viewportHeight="24.0"> |
||||
<path |
||||
android:fillColor="#FF000000" |
||||
android:pathData="M6,19c0,1.1 0.9,2 2,2h8c1.1,0 2,-0.9 2,-2V7H6v12zM19,4h-3.5l-1,-1h-5l-1,1H5v2h14V4z"/> |
||||
</vector> |
@ -0,0 +1,9 @@
@@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android" |
||||
android:width="24dp" |
||||
android:height="24dp" |
||||
android:viewportWidth="24.0" |
||||
android:viewportHeight="24.0"> |
||||
<path |
||||
android:fillColor="#FF000000" |
||||
android:pathData="M19.35,10.04C18.67,6.59 15.64,4 12,4 9.11,4 6.6,5.64 5.35,8.04 2.34,8.36 0,10.91 0,14c0,3.31 2.69,6 6,6h13c2.76,0 5,-2.24 5,-5 0,-2.64 -2.05,-4.78 -4.65,-4.96zM17,13l-5,5 -5,-5h3V9h4v4h3z"/> |
||||
</vector> |
@ -0,0 +1,33 @@
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android" |
||||
xmlns:tools="http://schemas.android.com/tools" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent" |
||||
android:background="@color/surface" |
||||
android:fillViewport="true"> |
||||
|
||||
<LinearLayout |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent" |
||||
android:orientation="vertical"> |
||||
|
||||
<TextView |
||||
style="@style/AppTheme.Title" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginStart="16dp" |
||||
android:layout_marginTop="16dp" |
||||
android:layout_marginEnd="16dp" |
||||
android:layout_marginBottom="16dp" |
||||
android:text="@string/title_downloads" /> |
||||
|
||||
<androidx.recyclerview.widget.RecyclerView |
||||
android:id="@+id/downloads" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
tools:itemCount="10" |
||||
tools:listitem="@layout/row_download" /> |
||||
|
||||
</LinearLayout> |
||||
|
||||
</androidx.core.widget.NestedScrollView> |
@ -0,0 +1,57 @@
@@ -0,0 +1,57 @@
|
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||
xmlns:tools="http://schemas.android.com/tools" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:background="?android:attr/selectableItemBackground" |
||||
android:orientation="horizontal" |
||||
android:padding="16dp" |
||||
tools:showIn="@layout/activity_downloads"> |
||||
|
||||
<LinearLayout |
||||
android:layout_width="0dp" |
||||
android:layout_height="wrap_content" |
||||
android:layout_weight="1" |
||||
android:orientation="vertical"> |
||||
|
||||
<TextView |
||||
android:id="@+id/title" |
||||
style="@style/AppTheme.ItemTitle" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
tools:text="Track title" /> |
||||
|
||||
<TextView |
||||
android:id="@+id/artist" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
tools:text="Artist name" /> |
||||
|
||||
<ProgressBar |
||||
android:id="@+id/progress" |
||||
style="@style/Widget.AppCompat.ProgressBar.Horizontal" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" /> |
||||
|
||||
</LinearLayout> |
||||
|
||||
<ImageButton |
||||
android:id="@+id/toggle" |
||||
style="@style/IconButton" |
||||
android:layout_width="24dp" |
||||
android:layout_height="24dp" |
||||
android:layout_marginStart="4dp" |
||||
android:layout_marginEnd="8dp" |
||||
android:src="@drawable/pause" /> |
||||
|
||||
<ImageButton |
||||
android:id="@+id/delete" |
||||
style="@style/IconButton" |
||||
android:layout_width="24dp" |
||||
android:layout_height="24dp" |
||||
android:layout_marginStart="4dp" |
||||
android:layout_marginEnd="8dp" |
||||
android:src="@drawable/delete" |
||||
android:tint="@color/colorAccent" /> |
||||
|
||||
</LinearLayout> |
Loading…
Reference in new issue