Added the ability to specify title ellipsis mode (beginning/middle/end).

Fixes #209.
This commit is contained in:
casey langen 2018-12-28 23:17:36 -08:00
parent 81f2df6b1e
commit 3fb7882d89
15 changed files with 128 additions and 41 deletions

View File

@ -3,7 +3,6 @@ package io.casey.musikcube.remote.ui.home.activity
import android.app.Dialog import android.app.Dialog
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.SharedPreferences
import android.graphics.Color import android.graphics.Color
import android.net.Uri import android.net.Uri
import android.os.Bundle import android.os.Bundle
@ -15,7 +14,6 @@ import android.widget.*
import com.wooplr.spotlight.SpotlightView import com.wooplr.spotlight.SpotlightView
import io.casey.musikcube.remote.R import io.casey.musikcube.remote.R
import io.casey.musikcube.remote.service.playback.Playback import io.casey.musikcube.remote.service.playback.Playback
import io.casey.musikcube.remote.service.playback.PlaybackServiceFactory
import io.casey.musikcube.remote.service.playback.PlaybackState import io.casey.musikcube.remote.service.playback.PlaybackState
import io.casey.musikcube.remote.service.playback.RepeatMode import io.casey.musikcube.remote.service.playback.RepeatMode
import io.casey.musikcube.remote.service.websocket.Messages import io.casey.musikcube.remote.service.websocket.Messages
@ -48,7 +46,6 @@ class MainActivity : BaseActivity() {
private var seekbarValue = -1 private var seekbarValue = -1
private var blink = 0 private var blink = 0
private lateinit var prefs: SharedPreferences
private lateinit var data: DataProviderMixin private lateinit var data: DataProviderMixin
private lateinit var playback: PlaybackMixin private lateinit var playback: PlaybackMixin
@ -72,7 +69,7 @@ class MainActivity : BaseActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
component.inject(this) component.inject(this)
data = mixin(DataProviderMixin()) data = mixin(DataProviderMixin())
playback = mixin(PlaybackMixin({ rebindUi() })) playback = mixin(PlaybackMixin { rebindUi() })
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@ -565,11 +562,11 @@ class MainActivity : BaseActivity() {
val dlg = AlertDialog.Builder(activity) val dlg = AlertDialog.Builder(activity)
.setTitle(R.string.update_check_dialog_title) .setTitle(R.string.update_check_dialog_title)
.setMessage(getString(R.string.update_check_dialog_message, version)) .setMessage(getString(R.string.update_check_dialog_message, version))
.setNegativeButton(R.string.button_no, { _, _ -> .setNegativeButton(R.string.button_no) { _, _ ->
if (checkbox.isChecked) { if (checkbox.isChecked) {
silence() silence()
} }
}) }
.setPositiveButton(R.string.button_yes) { _, _ -> .setPositiveButton(R.string.button_yes) { _, _ ->
if (checkbox.isChecked) { if (checkbox.isChecked) {
silence() silence()

View File

@ -49,7 +49,7 @@ class PlayQueueActivity : BaseActivity() {
tracks = DefaultSlidingWindow(recyclerView, data.provider, queryFactory) tracks = DefaultSlidingWindow(recyclerView, data.provider, queryFactory)
tracks.setInitialPosition(intent.getIntExtra(EXTRA_PLAYING_INDEX, -1)) tracks.setInitialPosition(intent.getIntExtra(EXTRA_PLAYING_INDEX, -1))
tracks.setOnMetadataLoadedListener(slidingWindowListener) tracks.setOnMetadataLoadedListener(slidingWindowListener)
adapter = PlayQueueAdapter(tracks, playback, adapterListener) adapter = PlayQueueAdapter(tracks, playback, prefs, adapterListener)
setupDefaultRecyclerView(recyclerView, adapter) setupDefaultRecyclerView(recyclerView, adapter)
@ -58,18 +58,6 @@ class PlayQueueActivity : BaseActivity() {
emptyView.emptyMessage = getString(R.string.play_queue_empty) emptyView.emptyMessage = getString(R.string.play_queue_empty)
emptyView.alternateView = recyclerView emptyView.alternateView = recyclerView
data.provider.observeState().subscribeBy(
onNext = { states ->
if (states.first == IDataProvider.State.Connected) {
tracks.requery()
}
else {
emptyView.update(states.first, adapter.itemCount)
}
},
onError = {
})
setTitleFromIntent(R.string.play_queue_title) setTitleFromIntent(R.string.play_queue_title)
addTransportFragment() addTransportFragment()
enableUpNavigation() enableUpNavigation()
@ -82,14 +70,27 @@ class PlayQueueActivity : BaseActivity() {
override fun onResume() { override fun onResume() {
this.tracks.resume() /* needs to happen before */ this.tracks.resume() /* needs to happen before */
super.onResume() super.onResume()
initObservers()
if (offlineQueue) { if (offlineQueue) {
tracks.requery() tracks.requery()
} }
} }
private fun initObservers() {
disposables.add(data.provider.observeState().subscribeBy(
onNext = { states ->
if (states.first == IDataProvider.State.Connected) {
tracks.requery()
}
else {
emptyView.update(states.first, adapter.itemCount)
}
},
onError = {
}))
}
override fun onOptionsItemSelected(item: MenuItem): Boolean { override fun onOptionsItemSelected(item: MenuItem): Boolean {
val result = super.onOptionsItemSelected(item) val result = super.onOptionsItemSelected(item)

View File

@ -1,5 +1,6 @@
package io.casey.musikcube.remote.ui.playqueue.adapter package io.casey.musikcube.remote.ui.playqueue.adapter
import android.content.SharedPreferences
import android.support.v7.widget.RecyclerView import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
@ -9,13 +10,17 @@ import io.casey.musikcube.remote.R
import io.casey.musikcube.remote.service.websocket.model.ITrack import io.casey.musikcube.remote.service.websocket.model.ITrack
import io.casey.musikcube.remote.ui.shared.extension.fallback import io.casey.musikcube.remote.ui.shared.extension.fallback
import io.casey.musikcube.remote.ui.shared.extension.getColorCompat import io.casey.musikcube.remote.ui.shared.extension.getColorCompat
import io.casey.musikcube.remote.ui.shared.extension.titleEllipsizeMode
import io.casey.musikcube.remote.ui.shared.mixin.PlaybackMixin import io.casey.musikcube.remote.ui.shared.mixin.PlaybackMixin
import io.casey.musikcube.remote.ui.shared.model.DefaultSlidingWindow import io.casey.musikcube.remote.ui.shared.model.DefaultSlidingWindow
class PlayQueueAdapter(val tracks: DefaultSlidingWindow, class PlayQueueAdapter(val tracks: DefaultSlidingWindow,
val playback: PlaybackMixin, val playback: PlaybackMixin,
val prefs: SharedPreferences,
val listener: EventListener): RecyclerView.Adapter<PlayQueueAdapter.ViewHolder>() val listener: EventListener): RecyclerView.Adapter<PlayQueueAdapter.ViewHolder>()
{ {
private val ellipsizeMode = titleEllipsizeMode(prefs)
interface EventListener { interface EventListener {
fun onItemClicked(position: Int) fun onItemClicked(position: Int)
fun onActionClicked(view: View, value: ITrack) fun onActionClicked(view: View, value: ITrack)
@ -50,6 +55,7 @@ class PlayQueueAdapter(val tracks: DefaultSlidingWindow,
private val action = itemView.findViewById<View>(R.id.action) private val action = itemView.findViewById<View>(R.id.action)
internal fun bind(track: ITrack?, position: Int) { internal fun bind(track: ITrack?, position: Int) {
title.ellipsize = ellipsizeMode
trackNum.text = (position + 1).toString() trackNum.text = (position + 1).toString()
itemView.tag = position itemView.tag = position
action.tag = track action.tag = track

View File

@ -3,7 +3,6 @@ package io.casey.musikcube.remote.ui.settings.activity
import android.app.Dialog import android.app.Dialog
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.SharedPreferences
import android.net.Uri import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.support.v4.app.DialogFragment import android.support.v4.app.DialogFragment
@ -46,7 +45,7 @@ class SettingsActivity : BaseActivity() {
private lateinit var transferCheckbox: CheckBox private lateinit var transferCheckbox: CheckBox
private lateinit var bitrateSpinner: Spinner private lateinit var bitrateSpinner: Spinner
private lateinit var cacheSpinner: Spinner private lateinit var cacheSpinner: Spinner
private lateinit var prefs: SharedPreferences private lateinit var titleEllipsisSpinner: Spinner
private lateinit var playback: PlaybackMixin private lateinit var playback: PlaybackMixin
private lateinit var data: DataProviderMixin private lateinit var data: DataProviderMixin
@ -140,6 +139,16 @@ class SettingsActivity : BaseActivity() {
cacheSpinner.setSelection(prefs.getInt( cacheSpinner.setSelection(prefs.getInt(
Keys.DISK_CACHE_SIZE_INDEX, Defaults.DISK_CACHE_SIZE_INDEX)) Keys.DISK_CACHE_SIZE_INDEX, Defaults.DISK_CACHE_SIZE_INDEX))
/* title ellipsis mode */
val ellipsisModes = ArrayAdapter.createFromResource(
this, R.array.title_ellipsis_mode_array, android.R.layout.simple_spinner_item)
ellipsisModes.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
titleEllipsisSpinner.adapter = ellipsisModes
titleEllipsisSpinner.setSelection(prefs.getInt(
Keys.TITLE_ELLIPSIS_MODE_INDEX, Defaults.TITLE_ELLIPSIS_SIZE_INDEX))
/* advanced */ /* advanced */
transferCheckbox.isChecked = prefs.getBoolean( transferCheckbox.isChecked = prefs.getBoolean(
Keys.TRANSFER_TO_SERVER_ON_HEADSET_DISCONNECT, Keys.TRANSFER_TO_SERVER_ON_HEADSET_DISCONNECT,
@ -199,6 +208,7 @@ class SettingsActivity : BaseActivity() {
this.softwareVolume = findViewById(R.id.software_volume) this.softwareVolume = findViewById(R.id.software_volume)
this.bitrateSpinner = findViewById(R.id.transcoder_bitrate_spinner) this.bitrateSpinner = findViewById(R.id.transcoder_bitrate_spinner)
this.cacheSpinner = findViewById(R.id.streaming_disk_cache_spinner) this.cacheSpinner = findViewById(R.id.streaming_disk_cache_spinner)
this.titleEllipsisSpinner = findViewById(R.id.title_ellipsis_mode_spinner)
this.sslCheckbox = findViewById(R.id.ssl_checkbox) this.sslCheckbox = findViewById(R.id.ssl_checkbox)
this.certCheckbox = findViewById(R.id.cert_validation) this.certCheckbox = findViewById(R.id.cert_validation)
this.transferCheckbox = findViewById(R.id.transfer_on_disconnect_checkbox) this.transferCheckbox = findViewById(R.id.transfer_on_disconnect_checkbox)
@ -271,6 +281,7 @@ class SettingsActivity : BaseActivity() {
.putBoolean(Keys.TRANSFER_TO_SERVER_ON_HEADSET_DISCONNECT, transferCheckbox.isChecked) .putBoolean(Keys.TRANSFER_TO_SERVER_ON_HEADSET_DISCONNECT, transferCheckbox.isChecked)
.putInt(Keys.TRANSCODER_BITRATE_INDEX, bitrateSpinner.selectedItemPosition) .putInt(Keys.TRANSCODER_BITRATE_INDEX, bitrateSpinner.selectedItemPosition)
.putInt(Keys.DISK_CACHE_SIZE_INDEX, cacheSpinner.selectedItemPosition) .putInt(Keys.DISK_CACHE_SIZE_INDEX, cacheSpinner.selectedItemPosition)
.putInt(Keys.TITLE_ELLIPSIS_MODE_INDEX, titleEllipsisSpinner.selectedItemPosition)
.apply() .apply()
if (!softwareVolume.isChecked) { if (!softwareVolume.isChecked) {

View File

@ -15,6 +15,7 @@ class Prefs {
const val CERT_VALIDATION_DISABLED = "cert_validation_disabled" const val CERT_VALIDATION_DISABLED = "cert_validation_disabled"
const val TRANSCODER_BITRATE_INDEX = "transcoder_bitrate_index" const val TRANSCODER_BITRATE_INDEX = "transcoder_bitrate_index"
const val DISK_CACHE_SIZE_INDEX = "disk_cache_size_index" const val DISK_CACHE_SIZE_INDEX = "disk_cache_size_index"
const val TITLE_ELLIPSIS_MODE_INDEX = "title_ellipsis_mode_index"
const val UPDATE_DIALOG_SUPPRESSED_VERSION = "update_dialog_suppressed_version" const val UPDATE_DIALOG_SUPPRESSED_VERSION = "update_dialog_suppressed_version"
const val TRANSFER_TO_SERVER_ON_HEADSET_DISCONNECT = "transfer_to_server_on_headset_disconnect" const val TRANSFER_TO_SERVER_ON_HEADSET_DISCONNECT = "transfer_to_server_on_headset_disconnect"
const val DEVICE_ID = "device_id" const val DEVICE_ID = "device_id"
@ -36,6 +37,7 @@ class Prefs {
const val TRANSCODER_BITRATE_INDEX = 0 const val TRANSCODER_BITRATE_INDEX = 0
const val TRANSFER_TO_SERVER_ON_HEADSET_DISCONNECT = false const val TRANSFER_TO_SERVER_ON_HEADSET_DISCONNECT = false
const val DISK_CACHE_SIZE_INDEX = 2 const val DISK_CACHE_SIZE_INDEX = 2
const val TITLE_ELLIPSIS_SIZE_INDEX = 1
} }
} }

View File

@ -25,7 +25,7 @@ import io.reactivex.disposables.CompositeDisposable
abstract class BaseActivity : AppCompatActivity(), ViewModel.Provider, Runner.TaskCallbacks { abstract class BaseActivity : AppCompatActivity(), ViewModel.Provider, Runner.TaskCallbacks {
protected var disposables = CompositeDisposable() protected var disposables = CompositeDisposable()
private lateinit var prefs: SharedPreferences protected lateinit var prefs: SharedPreferences
private var paused = false private var paused = false
private val mixins = MixinSet() private val mixins = MixinSet()

View File

@ -2,6 +2,7 @@ package io.casey.musikcube.remote.ui.shared.extension
import android.app.SearchManager import android.app.SearchManager
import android.content.Context import android.content.Context
import android.content.SharedPreferences
import android.support.design.widget.Snackbar import android.support.design.widget.Snackbar
import android.support.v4.app.DialogFragment import android.support.v4.app.DialogFragment
import android.support.v4.app.Fragment import android.support.v4.app.Fragment
@ -12,6 +13,7 @@ import android.support.v7.widget.DividerItemDecoration
import android.support.v7.widget.LinearLayoutManager import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView import android.support.v7.widget.RecyclerView
import android.support.v7.widget.SearchView import android.support.v7.widget.SearchView
import android.text.TextUtils
import android.view.Menu import android.view.Menu
import android.view.View import android.view.View
import android.view.inputmethod.InputMethodManager import android.view.inputmethod.InputMethodManager
@ -21,6 +23,7 @@ import android.widget.EditText
import android.widget.TextView import android.widget.TextView
import io.casey.musikcube.remote.Application import io.casey.musikcube.remote.Application
import io.casey.musikcube.remote.R import io.casey.musikcube.remote.R
import io.casey.musikcube.remote.ui.settings.constants.Prefs
import io.casey.musikcube.remote.ui.shared.activity.Filterable import io.casey.musikcube.remote.ui.shared.activity.Filterable
import io.casey.musikcube.remote.ui.shared.fragment.TransportFragment import io.casey.musikcube.remote.ui.shared.fragment.TransportFragment
import io.casey.musikcube.remote.util.Strings import io.casey.musikcube.remote.util.Strings
@ -244,4 +247,16 @@ fun <T1: Any, T2: Any, T3: Any, T4: Any, R: Any> letMany(p1: T1?, p2: T2?, p3: T
} }
fun <T1: Any, T2: Any, T3: Any, T4: Any, T5: Any, R: Any> letMany(p1: T1?, p2: T2?, p3: T3?, p4: T4?, p5: T5?, block: (T1, T2, T3, T4, T5)->R?): R? { fun <T1: Any, T2: Any, T3: Any, T4: Any, T5: Any, R: Any> letMany(p1: T1?, p2: T2?, p3: T3?, p4: T4?, p5: T5?, block: (T1, T2, T3, T4, T5)->R?): R? {
return if (p1 != null && p2 != null && p3 != null && p4 != null && p5 != null) block(p1, p2, p3, p4, p5) else null return if (p1 != null && p2 != null && p3 != null && p4 != null && p5 != null) block(p1, p2, p3, p4, p5) else null
}
fun titleEllipsizeMode(prefs: SharedPreferences): TextUtils.TruncateAt {
val modeIndex = prefs.getInt(
Prefs.Key.TITLE_ELLIPSIS_MODE_INDEX,
Prefs.Default.TITLE_ELLIPSIS_SIZE_INDEX)
return when(modeIndex) {
0 -> TextUtils.TruncateAt.START
1 -> TextUtils.TruncateAt.MIDDLE
else -> TextUtils.TruncateAt.END
}
} }

View File

@ -41,7 +41,7 @@ class EditPlaylistActivity: BaseActivity() {
val recycler = findViewById<RecyclerView>(R.id.recycler_view) val recycler = findViewById<RecyclerView>(R.id.recycler_view)
val touchHelper = ItemTouchHelper(touchHelperCallback) val touchHelper = ItemTouchHelper(touchHelperCallback)
touchHelper.attachToRecyclerView(recycler) touchHelper.attachToRecyclerView(recycler)
adapter = EditPlaylistAdapter(viewModel, touchHelper) adapter = EditPlaylistAdapter(viewModel, touchHelper, prefs)
setupDefaultRecyclerView(recycler, adapter) setupDefaultRecyclerView(recycler, adapter)
setResult(RESULT_CANCELED) setResult(RESULT_CANCELED)
} }
@ -85,7 +85,7 @@ class EditPlaylistActivity: BaseActivity() {
private fun saveAndFinish() { private fun saveAndFinish() {
if (viewModel.modified) { if (viewModel.modified) {
viewModel.save().subscribeBy( disposables.add(viewModel.save().subscribeBy(
onNext = { playlistId -> onNext = { playlistId ->
if (playlistId != -1L) { if (playlistId != -1L) {
val data = Intent() val data = Intent()
@ -99,7 +99,7 @@ class EditPlaylistActivity: BaseActivity() {
}, },
onError = { onError = {
showErrorSnackbar(R.string.playlist_edit_save_failed) showErrorSnackbar(R.string.playlist_edit_save_failed)
}) }))
} }
else { else {
finish() finish()
@ -131,8 +131,8 @@ class EditPlaylistActivity: BaseActivity() {
return AlertDialog.Builder(editActivity) return AlertDialog.Builder(editActivity)
.setTitle(R.string.playlist_edit_save_changes_title) .setTitle(R.string.playlist_edit_save_changes_title)
.setMessage(R.string.playlist_edit_save_changes_message) .setMessage(R.string.playlist_edit_save_changes_message)
.setNegativeButton(R.string.button_discard, { _, _ -> editActivity.finish() }) .setNegativeButton(R.string.button_discard) { _, _ -> editActivity.finish() }
.setPositiveButton(R.string.button_save, { _, _ -> editActivity.saveAndFinish() }) .setPositiveButton(R.string.button_save) { _, _ -> editActivity.saveAndFinish() }
.create() .create()
} }
@ -148,8 +148,8 @@ class EditPlaylistActivity: BaseActivity() {
} }
companion object { companion object {
val EXTRA_PLAYLIST_ID = "extra_playlist_id" const val EXTRA_PLAYLIST_ID = "extra_playlist_id"
val EXTRA_PLAYLIST_NAME = "extra_playlist_name" const val EXTRA_PLAYLIST_NAME = "extra_playlist_name"
fun getStartIntent(context: Context, playlistName: String, playlistId: Long): Intent { fun getStartIntent(context: Context, playlistName: String, playlistId: Long): Intent {
return Intent(context, EditPlaylistActivity::class.java) return Intent(context, EditPlaylistActivity::class.java)

View File

@ -68,7 +68,7 @@ class TrackListActivity : BaseActivity(), Filterable {
val recyclerView = findViewById<FastScrollRecyclerView>(R.id.recycler_view) val recyclerView = findViewById<FastScrollRecyclerView>(R.id.recycler_view)
tracks = DefaultSlidingWindow(recyclerView, data.provider, queryFactory) tracks = DefaultSlidingWindow(recyclerView, data.provider, queryFactory)
adapter = TrackListAdapter(tracks, eventListener, playback) adapter = TrackListAdapter(tracks, eventListener, playback, prefs)
setupDefaultRecyclerView(recyclerView, adapter) setupDefaultRecyclerView(recyclerView, adapter)

View File

@ -1,7 +1,9 @@
package io.casey.musikcube.remote.ui.tracks.adapter package io.casey.musikcube.remote.ui.tracks.adapter
import android.content.SharedPreferences
import android.support.v7.widget.RecyclerView import android.support.v7.widget.RecyclerView
import android.support.v7.widget.helper.ItemTouchHelper import android.support.v7.widget.helper.ItemTouchHelper
import android.text.TextUtils
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.MotionEvent import android.view.MotionEvent
import android.view.View import android.view.View
@ -10,10 +12,17 @@ import android.widget.TextView
import io.casey.musikcube.remote.R import io.casey.musikcube.remote.R
import io.casey.musikcube.remote.service.websocket.model.ITrack import io.casey.musikcube.remote.service.websocket.model.ITrack
import io.casey.musikcube.remote.ui.shared.extension.fallback import io.casey.musikcube.remote.ui.shared.extension.fallback
import io.casey.musikcube.remote.ui.shared.extension.titleEllipsizeMode
import io.casey.musikcube.remote.ui.tracks.model.EditPlaylistViewModel import io.casey.musikcube.remote.ui.tracks.model.EditPlaylistViewModel
class EditPlaylistAdapter(private val viewModel: EditPlaylistViewModel, class EditPlaylistAdapter(
private val touchHelper: ItemTouchHelper): RecyclerView.Adapter<EditPlaylistAdapter.ViewHolder>() { private val viewModel: EditPlaylistViewModel,
private val touchHelper: ItemTouchHelper,
prefs: SharedPreferences)
: RecyclerView.Adapter<EditPlaylistAdapter.ViewHolder>()
{
private val ellipsizeMode = titleEllipsizeMode(prefs)
override fun getItemCount(): Int { override fun getItemCount(): Int {
return viewModel.count return viewModel.count
} }
@ -21,7 +30,7 @@ class EditPlaylistAdapter(private val viewModel: EditPlaylistViewModel,
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val inflater = LayoutInflater.from(parent.context) val inflater = LayoutInflater.from(parent.context)
val view = inflater.inflate(R.layout.edit_playlist_track_row, parent, false) val view = inflater.inflate(R.layout.edit_playlist_track_row, parent, false)
val holder = ViewHolder(view) val holder = ViewHolder(view, ellipsizeMode)
val drag = view.findViewById<View>(R.id.dragHandle) val drag = view.findViewById<View>(R.id.dragHandle)
val swipe = view.findViewById<View>(R.id.swipeHandle) val swipe = view.findViewById<View>(R.id.swipeHandle)
view.setOnClickListener(emptyClickListener) view.setOnClickListener(emptyClickListener)
@ -58,10 +67,14 @@ class EditPlaylistAdapter(private val viewModel: EditPlaylistViewModel,
} }
} }
class ViewHolder internal constructor(internal val view: View) : RecyclerView.ViewHolder(view) { class ViewHolder internal constructor(view: View, ellipsizeMode: TextUtils.TruncateAt) : RecyclerView.ViewHolder(view) {
private val title = itemView.findViewById<TextView>(R.id.title) private val title = itemView.findViewById<TextView>(R.id.title)
private val subtitle = itemView.findViewById<TextView>(R.id.subtitle) private val subtitle = itemView.findViewById<TextView>(R.id.subtitle)
init {
title.ellipsize = ellipsizeMode
}
fun bind(track: ITrack) { fun bind(track: ITrack) {
title.text = fallback(track.title, "-") title.text = fallback(track.title, "-")
subtitle.text = fallback(track.albumArtist, "-") subtitle.text = fallback(track.albumArtist, "-")

View File

@ -1,6 +1,8 @@
package io.casey.musikcube.remote.ui.tracks.adapter package io.casey.musikcube.remote.ui.tracks.adapter
import android.content.SharedPreferences
import android.support.v7.widget.RecyclerView import android.support.v7.widget.RecyclerView
import android.text.TextUtils
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
@ -10,13 +12,17 @@ import io.casey.musikcube.remote.service.websocket.model.ITrack
import io.casey.musikcube.remote.ui.shared.extension.fallback import io.casey.musikcube.remote.ui.shared.extension.fallback
import io.casey.musikcube.remote.ui.shared.extension.getColorCompat import io.casey.musikcube.remote.ui.shared.extension.getColorCompat
import io.casey.musikcube.remote.ui.shared.extension.letMany import io.casey.musikcube.remote.ui.shared.extension.letMany
import io.casey.musikcube.remote.ui.shared.extension.titleEllipsizeMode
import io.casey.musikcube.remote.ui.shared.mixin.PlaybackMixin import io.casey.musikcube.remote.ui.shared.mixin.PlaybackMixin
import io.casey.musikcube.remote.ui.shared.model.DefaultSlidingWindow import io.casey.musikcube.remote.ui.shared.model.DefaultSlidingWindow
class TrackListAdapter(private val tracks: DefaultSlidingWindow, class TrackListAdapter(private val tracks: DefaultSlidingWindow,
private val listener: EventListener?, private val listener: EventListener,
private var playback: PlaybackMixin) : RecyclerView.Adapter<TrackListAdapter.ViewHolder>() private var playback: PlaybackMixin,
prefs: SharedPreferences) : RecyclerView.Adapter<TrackListAdapter.ViewHolder>()
{ {
private val ellipsizeMode = titleEllipsizeMode(prefs)
interface EventListener { interface EventListener {
fun onItemClick(view: View, track: ITrack, position: Int) fun onItemClick(view: View, track: ITrack, position: Int)
fun onActionItemClick(view: View, track: ITrack, position: Int) fun onActionItemClick(view: View, track: ITrack, position: Int)
@ -43,7 +49,7 @@ class TrackListAdapter(private val tracks: DefaultSlidingWindow,
} }
} }
return ViewHolder(view, playback) return ViewHolder(view, playback, ellipsizeMode)
} }
override fun onBindViewHolder(holder: ViewHolder, position: Int) = override fun onBindViewHolder(holder: ViewHolder, position: Int) =
@ -51,13 +57,20 @@ class TrackListAdapter(private val tracks: DefaultSlidingWindow,
override fun getItemCount(): Int = tracks.count override fun getItemCount(): Int = tracks.count
class ViewHolder internal constructor(view: View, class ViewHolder internal constructor(
private val playback: PlaybackMixin) : RecyclerView.ViewHolder(view) view: View,
private val playback: PlaybackMixin,
ellipsizeMode: TextUtils.TruncateAt)
: RecyclerView.ViewHolder(view)
{ {
private val title: TextView = view.findViewById(R.id.title) private val title: TextView = view.findViewById(R.id.title)
private val subtitle: TextView = view.findViewById(R.id.subtitle) private val subtitle: TextView = view.findViewById(R.id.subtitle)
private val action: View = view.findViewById(R.id.action) private val action: View = view.findViewById(R.id.action)
init {
title.ellipsize = ellipsizeMode
}
internal fun bind(track: ITrack?, position: Int) { internal fun bind(track: ITrack?, position: Int) {
val tag = itemView.tag as Tag val tag = itemView.tag as Tag
tag.position = position tag.position = position

View File

@ -168,6 +168,23 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="16dp"/> android:layout_height="16dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginRight="8dp"
android:text="@string/title_ellipsis_mode"/>
<Spinner
android:id="@+id/title_ellipsis_mode_spinner"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="24dp"/>
<android.support.v4.widget.Space
android:layout_width="0dp"
android:layout_height="16dp"/>
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"

View File

@ -144,6 +144,10 @@
<string name="replaygain_mode_disabled">disabled</string> <string name="replaygain_mode_disabled">disabled</string>
<string name="replaygain_mode_track">track</string> <string name="replaygain_mode_track">track</string>
<string name="replaygain_mode_album">album</string> <string name="replaygain_mode_album">album</string>
<string name="title_ellipsis_mode">ellipsize titles:</string>
<string name="ellipsis_mode_beginning">beginning</string>
<string name="ellipsis_mode_middle">middle</string>
<string name="ellipsis_mode_end">end</string>
<string name="connections_no_presets">no saved connection presets.</string> <string name="connections_no_presets">no saved connection presets.</string>
<string name="empty_show_offline_tracks_button">show offline songs</string> <string name="empty_show_offline_tracks_button">show offline songs</string>
<string name="empty_no_offline_tracks_message">oops, you don\'t seem to have any songs available offline.\n\nnext time you\'re connected, stream some music!</string> <string name="empty_no_offline_tracks_message">oops, you don\'t seem to have any songs available offline.\n\nnext time you\'re connected, stream some music!</string>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="title_ellipsis_mode_array">
<item>@string/ellipsis_mode_beginning</item>
<item>@string/ellipsis_mode_middle</item>
<item>@string/ellipsis_mode_end</item>
</string-array>
</resources>