diff --git a/CHANGELOG.txt b/CHANGELOG.txt index b947b644e..fcf711753 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -2,6 +2,7 @@ musikcube: * added support for Ubuntu Artsy +* added preliminary audio encoders (MP3, OGG/Vorbis) * fixed and exposed album-level artwork. previously it was track-only. * fixed notification icon color @@ -9,10 +10,10 @@ musikdroid: * gapless playback (for supported media)! enable in settings > playback engine > "ExoPlayer Gapless (experimental)" +* playlist create / rename / update / delete support * album art is now displayed in album rows when browsing * context menus on most screens with the ability to switch between related content (e.g. albums by this artist, artists in this genre, etc) -* preliminary playlist creation support. more to come in the future * added a simple "spotlight" tutorial for new users that explains switching between remote and streaming playback modes. * major refactor to the entire code base, including the following: diff --git a/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/ui/shared/extension/Extensions.kt b/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/ui/shared/extension/Extensions.kt index d5139e4e5..a1e9691d0 100644 --- a/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/ui/shared/extension/Extensions.kt +++ b/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/ui/shared/extension/Extensions.kt @@ -203,6 +203,9 @@ fun showErrorSnackbar(view: View, stringId: Int) = fun AppCompatActivity.showErrorSnackbar(stringId: Int) = showErrorSnackbar(this.findViewById(android.R.id.content), stringId) +fun AppCompatActivity.showSnackbar(stringId: Int) = + showSnackbar(this.findViewById(android.R.id.content), stringId) + fun AppCompatActivity.showSnackbar(viewId: Int, stringId: Int) = showSnackbar(this.findViewById(viewId), stringId) diff --git a/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/ui/shared/mixin/ItemContextMenuMixin.kt b/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/ui/shared/mixin/ItemContextMenuMixin.kt index 36cb1fe1f..b543ab065 100644 --- a/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/ui/shared/mixin/ItemContextMenuMixin.kt +++ b/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/ui/shared/mixin/ItemContextMenuMixin.kt @@ -88,7 +88,11 @@ class ItemContextMenuMixin(private val activity: AppCompatActivity, pendingCode = -1 completion = null } - + else if (result == Activity.RESULT_OK && request == REQUEST_EDIT_PLAYLIST) { + showSnackbar( + activity.findViewById(android.R.id.content), + R.string.playlist_edit_add_success) + } super.onActivityResult(request, result, data) } @@ -235,7 +239,8 @@ class ItemContextMenuMixin(private val activity: AppCompatActivity, ConfirmDeletePlaylistDialog.show(activity, this, playlistName, playlistId) } R.id.menu_playlist_edit -> { - activity.startActivity(EditPlaylistActivity.getStartIntent(activity, playlistName, playlistId)) + activity.startActivityForResult(EditPlaylistActivity.getStartIntent( + activity, playlistName, playlistId), REQUEST_EDIT_PLAYLIST) } R.id.menu_playlist_rename -> { EnterPlaylistNameDialog.showForRename(activity, this, playlistName, playlistId) @@ -548,6 +553,7 @@ class ItemContextMenuMixin(private val activity: AppCompatActivity, } companion object { - private val REQUEST_ADD_TO_PLAYLIST = 128 + private val REQUEST_ADD_TO_PLAYLIST = 32 + private val REQUEST_EDIT_PLAYLIST = 33 } } \ No newline at end of file diff --git a/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/ui/tracks/activity/EditPlaylistActivity.kt b/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/ui/tracks/activity/EditPlaylistActivity.kt index 08da42405..30f255141 100644 --- a/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/ui/tracks/activity/EditPlaylistActivity.kt +++ b/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/ui/tracks/activity/EditPlaylistActivity.kt @@ -1,8 +1,11 @@ package io.casey.musikcube.remote.ui.tracks.activity +import android.app.Dialog import android.content.Context import android.content.Intent import android.os.Bundle +import android.support.v7.app.AlertDialog +import android.support.v7.app.AppCompatActivity import android.support.v7.widget.RecyclerView import android.support.v7.widget.helper.ItemTouchHelper import android.view.Menu @@ -12,6 +15,7 @@ import io.casey.musikcube.remote.framework.ViewModel import io.casey.musikcube.remote.ui.shared.activity.BaseActivity import io.casey.musikcube.remote.ui.shared.extension.setupDefaultRecyclerView import io.casey.musikcube.remote.ui.shared.extension.showErrorSnackbar +import io.casey.musikcube.remote.ui.shared.fragment.BaseDialogFragment import io.casey.musikcube.remote.ui.shared.mixin.DataProviderMixin import io.casey.musikcube.remote.ui.shared.mixin.ViewModelMixin import io.casey.musikcube.remote.ui.tracks.adapter.EditPlaylistAdapter @@ -38,6 +42,15 @@ class EditPlaylistActivity: BaseActivity() { touchHelper.attachToRecyclerView(recycler) adapter = EditPlaylistAdapter(viewModel, touchHelper) setupDefaultRecyclerView(recycler, adapter) + setResult(RESULT_CANCELED) + } + + override fun onBackPressed() { + if (viewModel.modified) { + ConfirmDiscardChangesDialog.show(this) + return + } + super.onBackPressed() } override fun onCreateOptionsMenu(menu: Menu): Boolean { @@ -47,18 +60,7 @@ class EditPlaylistActivity: BaseActivity() { override fun onOptionsItemSelected(item: MenuItem): Boolean { if (item.itemId == R.id.action_save) { - viewModel.save().subscribeBy( - onNext = { playlistId -> - if (playlistId != -1L) { - finish() - } - else { - showErrorSnackbar(R.string.playlist_edit_save_failed) - } - }, - onError = { - showErrorSnackbar(R.string.playlist_edit_save_failed) - }) + saveAndFinish() } return super.onOptionsItemSelected(item) } @@ -80,6 +82,26 @@ class EditPlaylistActivity: BaseActivity() { return EditPlaylistViewModel(intent.extras.getLong(EXTRA_PLAYLIST_ID, -1L)) as T } + private fun saveAndFinish() { + if (viewModel.modified) { + viewModel.save().subscribeBy( + onNext = { playlistId -> + if (playlistId != -1L) { + setResult(RESULT_OK) + finish() + } else { + showErrorSnackbar(R.string.playlist_edit_save_failed) + } + }, + onError = { + showErrorSnackbar(R.string.playlist_edit_save_failed) + }) + } + else { + finish() + } + } + private val touchHelperCallback = object:ItemTouchHelper.SimpleCallback( ItemTouchHelper.UP or ItemTouchHelper.DOWN, ItemTouchHelper.LEFT) @@ -98,6 +120,31 @@ class EditPlaylistActivity: BaseActivity() { } } + class ConfirmDiscardChangesDialog : BaseDialogFragment() { + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { + val editActivity = activity as EditPlaylistActivity + + val dlg = AlertDialog.Builder(activity) + .setTitle(R.string.playlist_edit_save_changes_title) + .setMessage(R.string.playlist_edit_save_changes_message) + .setNegativeButton(R.string.button_discard, { _, _ -> editActivity.finish() }) + .setPositiveButton(R.string.button_save, { _, _ -> editActivity.saveAndFinish() }) + .create() + + return dlg + } + + companion object { + val TAG = "confirm_discard_playlist_changes" + + fun show(activity: AppCompatActivity) { + dismiss(activity, TAG) + val result = ConfirmDiscardChangesDialog() + result.show(activity.supportFragmentManager, TAG) + } + } + } + companion object { private val EXTRA_PLAYLIST_ID = "extra_playlist_id" private val EXTRA_PLAYLIST_NAME = "extra_playlist_name" diff --git a/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/ui/tracks/activity/TrackListActivity.kt b/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/ui/tracks/activity/TrackListActivity.kt index b6f5af15e..43e101fa9 100644 --- a/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/ui/tracks/activity/TrackListActivity.kt +++ b/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/ui/tracks/activity/TrackListActivity.kt @@ -4,6 +4,7 @@ import android.content.Context import android.content.Intent import android.os.Bundle import android.view.Menu +import android.view.MenuItem import android.view.View import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView import io.casey.musikcube.remote.R @@ -27,7 +28,6 @@ import io.casey.musikcube.remote.util.Debouncer import io.casey.musikcube.remote.util.Strings import io.reactivex.Observable import io.reactivex.rxkotlin.subscribeBy -import java.util.* class TrackListActivity : BaseActivity(), Filterable { private lateinit var tracks: TrackListSlidingWindow @@ -86,12 +86,31 @@ class TrackListActivity : BaseActivity(), Filterable { } override fun onCreateOptionsMenu(menu: Menu): Boolean { - if (Messages.Category.PLAYLISTS != categoryType) { + if (Messages.Category.PLAYLISTS == categoryType) { + menuInflater.inflate(R.menu.view_playlist_menu, menu) + } + else { initSearchMenu(menu, this) } return true } + override fun onOptionsItemSelected(item: MenuItem): Boolean { + if (item.itemId == R.id.action_edit) { + val name = intent.getStringExtra(EXTRA_CATEGORY_VALUE) + startActivityForResult(EditPlaylistActivity.getStartIntent( + this, name, categoryId), REQUEST_CODE_EDIT_PLAYLIST) + } + return super.onOptionsItemSelected(item) + } + + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + if (requestCode == REQUEST_CODE_EDIT_PLAYLIST && resultCode == RESULT_OK) { + showSnackbar(R.string.playlist_edit_save_success) + } + super.onActivityResult(requestCode, resultCode, data) + } + override fun onPause() { super.onPause() tracks.pause() @@ -232,6 +251,8 @@ class TrackListActivity : BaseActivity(), Filterable { private val EXTRA_CATEGORY_TYPE = "extra_category_type" private val EXTRA_SELECTED_ID = "extra_selected_id" private val EXTRA_TITLE_ID = "extra_title_id" + private val EXTRA_CATEGORY_VALUE = "extra_category_value" + private val REQUEST_CODE_EDIT_PLAYLIST = 72 fun getStartIntent(context: Context, type: String, id: Long): Intent = getStartIntent(context, type, id, "") @@ -245,6 +266,7 @@ class TrackListActivity : BaseActivity(), Filterable { val intent = Intent(context, TrackListActivity::class.java) .putExtra(EXTRA_CATEGORY_TYPE, type) .putExtra(EXTRA_SELECTED_ID, id) + .putExtra(EXTRA_CATEGORY_VALUE, categoryValue) if (Strings.notEmpty(categoryValue)) { intent.putExtra( diff --git a/src/musikdroid/app/src/main/res/drawable-v21/ic_leftarrow.xml b/src/musikdroid/app/src/main/res/drawable-v21/ic_leftarrow.xml index 926c1394e..cc39ca92a 100644 --- a/src/musikdroid/app/src/main/res/drawable-v21/ic_leftarrow.xml +++ b/src/musikdroid/app/src/main/res/drawable-v21/ic_leftarrow.xml @@ -1,4 +1,4 @@ - + diff --git a/src/musikdroid/app/src/main/res/drawable-v21/ic_reorder.xml b/src/musikdroid/app/src/main/res/drawable-v21/ic_reorder.xml index d95a2e5d1..d1c57b8a2 100644 --- a/src/musikdroid/app/src/main/res/drawable-v21/ic_reorder.xml +++ b/src/musikdroid/app/src/main/res/drawable-v21/ic_reorder.xml @@ -4,6 +4,6 @@ android:viewportWidth="24.0" android:viewportHeight="24.0"> diff --git a/src/musikdroid/app/src/main/res/drawable-v21/ic_trashcan.xml b/src/musikdroid/app/src/main/res/drawable-v21/ic_trashcan.xml index b8b794e30..0e0557958 100644 --- a/src/musikdroid/app/src/main/res/drawable-v21/ic_trashcan.xml +++ b/src/musikdroid/app/src/main/res/drawable-v21/ic_trashcan.xml @@ -4,6 +4,6 @@ android:viewportWidth="24.0" android:viewportHeight="24.0"> diff --git a/src/musikdroid/app/src/main/res/menu/view_playlist_menu.xml b/src/musikdroid/app/src/main/res/menu/view_playlist_menu.xml new file mode 100644 index 000000000..6eeaef439 --- /dev/null +++ b/src/musikdroid/app/src/main/res/menu/view_playlist_menu.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/src/musikdroid/app/src/main/res/values/strings.xml b/src/musikdroid/app/src/main/res/values/strings.xml index d2ecb13de..08a311f03 100644 --- a/src/musikdroid/app/src/main/res/values/strings.xml +++ b/src/musikdroid/app/src/main/res/values/strings.xml @@ -33,6 +33,7 @@ repeat list repeat song save + edit create settings close @@ -47,6 +48,7 @@ save as load rename + discard learn more invalid password the server rejected your password.\n\nchange the password in the settings screen. @@ -147,6 +149,9 @@ could not delete playlist \'%s\' editing playlist \'%s\' could not save playlist + playlist saved + save changes? + do you want to save the changes you made to this playlist? confirm are you sure you want to remove \`%s\` from this playlist? playback mode