Merge branch 'safeArgs2' into 'develop'

Finish SafeArgs

Closes #510

See merge request ultrasonic/ultrasonic!802
This commit is contained in:
birdbird 2022-08-18 13:20:07 +00:00
commit 1a354765f9
15 changed files with 218 additions and 213 deletions

View File

@ -1,103 +0,0 @@
package org.moire.ultrasonic.fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import org.moire.ultrasonic.R;
import org.moire.ultrasonic.domain.Lyrics;
import org.moire.ultrasonic.service.MusicService;
import org.moire.ultrasonic.service.MusicServiceFactory;
import org.moire.ultrasonic.util.BackgroundTask;
import org.moire.ultrasonic.util.CancellationToken;
import org.moire.ultrasonic.util.Constants;
import org.moire.ultrasonic.util.FragmentBackgroundTask;
import org.moire.ultrasonic.util.Util;
import timber.log.Timber;
/**
* Displays the lyrics of a song
*/
public class LyricsFragment extends Fragment {
private TextView artistView;
private TextView titleView;
private TextView textView;
private SwipeRefreshLayout swipe;
private CancellationToken cancellationToken;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
Util.applyTheme(this.getContext());
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.lyrics, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
cancellationToken = new CancellationToken();
Timber.d("Lyrics set title");
FragmentTitle.Companion.setTitle(this, R.string.download_menu_lyrics);
swipe = view.findViewById(R.id.lyrics_refresh);
swipe.setEnabled(false);
artistView = view.findViewById(R.id.lyrics_artist);
titleView = view.findViewById(R.id.lyrics_title);
textView = view.findViewById(R.id.lyrics_text);
load();
}
@Override
public void onDestroyView() {
cancellationToken.cancel();
super.onDestroyView();
}
private void load()
{
BackgroundTask<Lyrics> task = new FragmentBackgroundTask<Lyrics>(getActivity(), true, swipe, cancellationToken)
{
@Override
protected Lyrics doInBackground() throws Throwable
{
Bundle arguments = getArguments();
if (arguments == null) return null;
String artist = arguments.getString(Constants.INTENT_ARTIST);
String title = arguments.getString(Constants.INTENT_TITLE);
MusicService musicService = MusicServiceFactory.getMusicService();
return musicService.getLyrics(artist, title);
}
@Override
protected void done(Lyrics result)
{
if (result != null && result.getArtist() != null)
{
artistView.setText(result.getArtist());
titleView.setText(result.getTitle());
textView.setText(result.getText());
}
else
{
artistView.setText(R.string.lyrics_nomatch);
}
}
};
task.execute();
}
}

View File

@ -49,6 +49,7 @@ import org.moire.ultrasonic.R
import org.moire.ultrasonic.app.UApp
import org.moire.ultrasonic.data.ActiveServerProvider
import org.moire.ultrasonic.data.ServerSettingDao
import org.moire.ultrasonic.fragment.MainFragmentDirections
import org.moire.ultrasonic.fragment.OnBackPressedHandler
import org.moire.ultrasonic.model.ServerSettingsModel
import org.moire.ultrasonic.provider.SearchSuggestionProvider
@ -377,10 +378,8 @@ class NavigationActivity : AppCompatActivity() {
)
suggestions.saveRecentQuery(query, null)
val bundle = Bundle()
bundle.putString(Constants.INTENT_QUERY, query)
bundle.putBoolean(Constants.INTENT_AUTOPLAY, autoPlay)
findNavController(R.id.nav_host_fragment).navigate(R.id.searchFragment, bundle)
val action = MainFragmentDirections.toSearchFragment(query, autoPlay)
findNavController(R.id.nav_host_fragment).navigate(action)
}
}

View File

@ -109,7 +109,7 @@ class FolderSelectorBinder(context: Context) :
menuItem.isChecked = true
folderName.text = musicFolderName
RxBus.musicFolderChangedEventPublisher.onNext(selectedFolderId)
RxBus.musicFolderChangedEventPublisher.onNext(RxBus.Folder(selectedFolderId))
return true
}

View File

@ -5,7 +5,9 @@ import android.content.Context
import android.view.LayoutInflater
import android.view.MenuItem
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.widget.PopupMenu
import androidx.lifecycle.LifecycleOwner
import com.drakeet.multitype.ItemViewBinder
import org.koin.core.component.KoinComponent
@ -13,6 +15,7 @@ import org.moire.ultrasonic.R
import org.moire.ultrasonic.domain.Identifiable
import org.moire.ultrasonic.domain.Track
@Suppress("LongParameterList")
class TrackViewBinder(
val onItemClick: (Track, Int) -> Unit,
val onContextMenuClick: ((MenuItem, Track) -> Boolean)? = null,
@ -20,13 +23,18 @@ class TrackViewBinder(
val draggable: Boolean,
context: Context,
val lifecycleOwner: LifecycleOwner,
val createContextMenu: (View, Track) -> PopupMenu = { view, _ ->
Utils.createPopupMenu(
view,
R.menu.context_menu_track
)
}
) : ItemViewBinder<Identifiable, TrackViewHolder>(), KoinComponent {
var startDrag: ((TrackViewHolder) -> Unit)? = null
// Set our layout files
val layout = R.layout.list_item_track
private val contextMenuLayout = R.menu.context_menu_track
private val imageHelper: Utils.ImageHelper = Utils.ImageHelper(context)
@ -62,7 +70,7 @@ class TrackViewBinder(
holder.itemView.setOnLongClickListener {
if (onContextMenuClick != null) {
val popup = Utils.createPopupMenu(holder.itemView, contextMenuLayout)
val popup = createContextMenu(holder.itemView, track)
popup.setOnMenuItemClickListener { menuItem ->
onContextMenuClick.invoke(menuItem, track)

View File

@ -16,6 +16,7 @@ import android.widget.ImageView
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import com.google.android.material.switchmaterial.SwitchMaterial
import com.google.android.material.textfield.TextInputLayout
import com.skydoves.colorpickerview.ColorPickerDialog
@ -56,9 +57,6 @@ private const val DIALOG_PADDING = 12
* Displays a form where server settings can be created / edited
*/
class EditServerFragment : Fragment(), OnBackPressedHandler {
companion object {
const val EDIT_SERVER_INTENT_INDEX = "index"
}
private val serverSettingsModel: ServerSettingsModel by viewModel()
private val activeServerProvider: ActiveServerProvider by inject()
@ -79,6 +77,8 @@ class EditServerFragment : Fragment(), OnBackPressedHandler {
private var currentColor: Int = 0
private var selectedColor: Int? = null
private val navArgs by navArgs<EditServerFragmentArgs>()
@Override
override fun onCreate(savedInstanceState: Bundle?) {
Util.applyTheme(this.context)
@ -107,15 +107,10 @@ class EditServerFragment : Fragment(), OnBackPressedHandler {
saveButton = view.findViewById(R.id.edit_save)
testButton = view.findViewById(R.id.edit_test)
val index = arguments?.getInt(
EDIT_SERVER_INTENT_INDEX,
-1
) ?: -1
if (index != -1) {
if (navArgs.index != -1) {
// Editing an existing server
FragmentTitle.setTitle(this, R.string.server_editor_label)
val serverSetting = serverSettingsModel.getServerSetting(index)
val serverSetting = serverSettingsModel.getServerSetting(navArgs.index)
serverSetting.observe(
viewLifecycleOwner
) { t ->

View File

@ -64,7 +64,7 @@ abstract class EntryListFragment<T : GenericEntry> : MultiListFragment<T>() {
RxBus.musicFolderChangedEventObservable.subscribe {
if (!listModel.isOffline()) {
val currentSetting = listModel.activeServer
currentSetting.musicFolderId = it
currentSetting.musicFolderId = it.id
serverSettingsModel.updateItem(currentSetting)
}
listModel.refresh(refreshListView!!)

View File

@ -14,8 +14,6 @@ import android.os.Build
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.view.ContextMenu
import android.view.ContextMenu.ContextMenuInfo
import android.view.GestureDetector
import android.view.LayoutInflater
import android.view.Menu
@ -26,10 +24,10 @@ import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import android.view.animation.AnimationUtils
import android.widget.AdapterView.AdapterContextMenuInfo
import android.widget.EditText
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.PopupMenu
import android.widget.SeekBar
import android.widget.SeekBar.OnSeekBarChangeListener
import android.widget.TextView
@ -71,9 +69,11 @@ import org.koin.core.component.KoinComponent
import org.moire.ultrasonic.R
import org.moire.ultrasonic.adapters.BaseAdapter
import org.moire.ultrasonic.adapters.TrackViewBinder
import org.moire.ultrasonic.api.subsonic.models.AlbumListType
import org.moire.ultrasonic.audiofx.EqualizerController
import org.moire.ultrasonic.data.ActiveServerProvider.Companion.isOffline
import org.moire.ultrasonic.domain.Identifiable
import org.moire.ultrasonic.domain.MusicDirectory
import org.moire.ultrasonic.domain.Track
import org.moire.ultrasonic.fragment.FragmentTitle.Companion.setTitle
import org.moire.ultrasonic.service.MediaPlayerController
@ -85,7 +85,6 @@ import org.moire.ultrasonic.subsonic.NetworkAndStorageChecker
import org.moire.ultrasonic.subsonic.ShareHandler
import org.moire.ultrasonic.util.CancellationToken
import org.moire.ultrasonic.util.CommunicationError
import org.moire.ultrasonic.util.Constants
import org.moire.ultrasonic.util.Settings
import org.moire.ultrasonic.util.Util
import org.moire.ultrasonic.util.toTrack
@ -346,8 +345,6 @@ class PlayerFragment :
initPlaylistDisplay()
registerForContextMenu(playlistView)
EqualizerController.get().observe(
requireActivity()
) { equalizerController ->
@ -546,55 +543,54 @@ class PlayerFragment :
}
}
override fun onCreateContextMenu(menu: ContextMenu, view: View, menuInfo: ContextMenuInfo?) {
super.onCreateContextMenu(menu, view, menuInfo)
if (view === playlistView) {
val info = menuInfo as AdapterContextMenuInfo?
val track = viewAdapter.getCurrentList()[info!!.position] as Track
val menuInflater = requireActivity().menuInflater
menuInflater.inflate(R.menu.nowplaying_context, menu)
private fun onCreateContextMenu(view: View, track: Track): PopupMenu {
val popup = PopupMenu(view.context, view)
val inflater: MenuInflater = popup.menuInflater
inflater.inflate(R.menu.nowplaying_context, popup.menu)
if (track.parent == null) {
val menuItem = menu.findItem(R.id.menu_show_album)
if (menuItem != null) {
menuItem.isVisible = false
}
}
if (isOffline() || !Settings.shouldUseId3Tags) {
menu.findItem(R.id.menu_show_artist)?.isVisible = false
}
if (isOffline()) {
menu.findItem(R.id.menu_lyrics)?.isVisible = false
if (track.parent == null) {
val menuItem = popup.menu.findItem(R.id.menu_show_album)
if (menuItem != null) {
menuItem.isVisible = false
}
}
if (isOffline() || !Settings.shouldUseId3Tags) {
popup.menu.findItem(R.id.menu_show_artist)?.isVisible = false
}
popup.menu.findItem(R.id.menu_lyrics)?.isVisible = !isOffline()
popup.show()
return popup
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
// TODO Why is Track null?
return menuItemSelected(item.itemId, null) || super.onOptionsItemSelected(item)
return menuItemSelected(item.itemId, currentSong) || super.onOptionsItemSelected(item)
}
private fun onContextMenuItemSelected(
menuItem: MenuItem,
item: MusicDirectory.Child
): Boolean {
if (item !is Track) return false
return menuItemSelected(menuItem.itemId, item)
}
@Suppress("ComplexMethod", "LongMethod", "ReturnCount")
private fun menuItemSelected(menuItemId: Int, track: Track?): Boolean {
val bundle: Bundle
when (menuItemId) {
R.id.menu_show_artist -> {
if (track == null) return false
if (Settings.shouldUseId3Tags) {
PlayerFragmentDirections.playerToSelectAlbum(
val action = PlayerFragmentDirections.playerToAlbumsList(
type = AlbumListType.BY_ARTIST,
id = track.artistId,
name = track.artist,
parentId = track.artistId,
isArtist = true,
title = track.artist,
offset = 0,
size = 1000
)
bundle = Bundle()
Navigation.findNavController(requireView())
.navigate(R.id.playerToSelectAlbum, bundle)
findNavController().navigate(action)
}
return true
}
@ -614,11 +610,9 @@ class PlayerFragment :
return true
}
R.id.menu_lyrics -> {
if (track == null) return false
bundle = Bundle()
bundle.putString(Constants.INTENT_ARTIST, track.artist)
bundle.putString(Constants.INTENT_TITLE, track.title)
Navigation.findNavController(requireView()).navigate(R.id.playerToLyrics, bundle)
if (track?.artist == null || track.title == null) return false
val action = PlayerFragmentDirections.playerToLyrics(track.artist!!, track.title!!)
Navigation.findNavController(requireView()).navigate(action)
return true
}
R.id.menu_remove -> {
@ -672,9 +666,9 @@ class PlayerFragment :
return true
}
R.id.menu_item_star -> {
if (currentSong == null) return true
if (track == null) return true
val isStarred = currentSong!!.starred
val isStarred = track.starred
mediaPlayerController.controller?.setRating(
HeartRating(!isStarred)
@ -685,10 +679,10 @@ class PlayerFragment :
override fun onSuccess(result: SessionResult?) {
if (isStarred) {
starMenuItem.setIcon(hollowStar)
currentSong!!.starred = false
track.starred = false
} else {
starMenuItem.setIcon(fullStar)
currentSong!!.starred = true
track.starred = true
}
}
@ -704,11 +698,11 @@ class PlayerFragment :
return true
}
R.id.menu_item_bookmark_set -> {
if (currentSong == null) return true
if (track == null) return true
val songId = currentSong!!.id
val songId = track.id
val playerPosition = mediaPlayerController.playerPosition
currentSong!!.bookmarkPosition = playerPosition
track.bookmarkPosition = playerPosition
val bookmarkTime = Util.formatTotalDuration(playerPosition.toLong(), true)
Thread {
val musicService = getMusicService()
@ -726,10 +720,10 @@ class PlayerFragment :
return true
}
R.id.menu_item_bookmark_delete -> {
if (currentSong == null) return true
if (track == null) return true
val bookmarkSongId = currentSong!!.id
currentSong!!.bookmarkPosition = 0
val bookmarkSongId = track.id
track.bookmarkPosition = 0
Thread {
val musicService = getMusicService()
try {
@ -758,10 +752,10 @@ class PlayerFragment :
return true
}
R.id.menu_item_share_song -> {
if (currentSong == null) return true
if (track == null) return true
val tracks: MutableList<Track?> = ArrayList()
tracks.add(currentSong)
tracks.add(track)
shareHandler.createShare(
this,
@ -856,6 +850,8 @@ class PlayerFragment :
draggable = true,
context = requireContext(),
lifecycleOwner = viewLifecycleOwner,
createContextMenu = { view, track -> onCreateContextMenu(view, track) },
onContextMenuClick = { menu, id -> onContextMenuItemSelected(menu, id) },
).apply {
this.startDrag = { holder ->
dragTouchHelper.startDrag(holder)

View File

@ -19,6 +19,7 @@ import androidx.core.view.isVisible
import androidx.fragment.app.viewModels
import androidx.lifecycle.viewModelScope
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import kotlinx.coroutines.launch
import org.koin.core.component.KoinComponent
@ -46,7 +47,6 @@ import org.moire.ultrasonic.subsonic.ShareHandler
import org.moire.ultrasonic.subsonic.VideoPlayer.Companion.playVideo
import org.moire.ultrasonic.util.CancellationToken
import org.moire.ultrasonic.util.CommunicationError
import org.moire.ultrasonic.util.Constants
import org.moire.ultrasonic.util.Settings
import org.moire.ultrasonic.util.Util
import org.moire.ultrasonic.util.Util.toast
@ -54,8 +54,6 @@ import timber.log.Timber
/**
* Initiates a search on the media library and displays the results
*
* TODO: Move to SafeArgs
*/
class SearchFragment : MultiListFragment<Identifiable>(), KoinComponent {
private var searchResult: SearchResult? = null
@ -69,6 +67,8 @@ class SearchFragment : MultiListFragment<Identifiable>(), KoinComponent {
private var cancellationToken: CancellationToken? = null
private val navArgs by navArgs<SearchFragmentArgs>()
override val listModel: SearchListModel by viewModels()
override val mainLayout: Int = R.layout.search
@ -133,14 +133,10 @@ class SearchFragment : MultiListFragment<Identifiable>(), KoinComponent {
MoreButtonBinder()
)
// Fragment was started with a query (e.g. from voice search), try to execute search right away
val arguments = arguments
if (arguments != null) {
val query = arguments.getString(Constants.INTENT_QUERY)
val autoPlay = arguments.getBoolean(Constants.INTENT_AUTOPLAY, false)
if (query != null) {
return search(query, autoPlay)
}
// If the fragment was started with a query (e.g. from voice search),
// try to execute search right away
if (navArgs.query != null) {
return search(navArgs.query!!, navArgs.autoplay)
}
}
@ -156,10 +152,8 @@ class SearchFragment : MultiListFragment<Identifiable>(), KoinComponent {
val searchableInfo = searchManager.getSearchableInfo(requireActivity().componentName)
searchView!!.setSearchableInfo(searchableInfo)
val arguments = arguments
val autoPlay = arguments != null &&
arguments.getBoolean(Constants.INTENT_AUTOPLAY, false)
val query = arguments?.getString(Constants.INTENT_QUERY)
val autoPlay = navArgs.autoplay
val query = navArgs.query
// If started with a query, enter it to the searchView
if (query != null) {

View File

@ -16,7 +16,6 @@ import org.moire.ultrasonic.adapters.ServerRowAdapter
import org.moire.ultrasonic.data.ActiveServerProvider
import org.moire.ultrasonic.data.ActiveServerProvider.Companion.OFFLINE_DB_ID
import org.moire.ultrasonic.data.ServerSetting
import org.moire.ultrasonic.fragment.EditServerFragment.Companion.EDIT_SERVER_INTENT_INDEX
import org.moire.ultrasonic.model.ServerSettingsModel
import org.moire.ultrasonic.service.MediaPlayerController
import org.moire.ultrasonic.util.ErrorDialog
@ -25,8 +24,6 @@ import timber.log.Timber
/**
* Displays the list of configured servers, they can be selected or edited
*
* TODO: Manage mode is unused. Remove it...
*/
class ServerSelectorFragment : Fragment() {
@ -143,8 +140,7 @@ class ServerSelectorFragment : Fragment() {
* Starts the Edit Server Fragment to edit the details of a server
*/
private fun editServerByIndex(index: Int) {
val bundle = Bundle()
bundle.putInt(EDIT_SERVER_INTENT_INDEX, index)
findNavController().navigate(R.id.serverSelectorToEditServer, bundle)
val action = ServerSelectorFragmentDirections.toEditServer(index)
findNavController().navigate(action)
}
}

View File

@ -0,0 +1,94 @@
/*
* LyricsFragment.kt
* Copyright (C) 2009-2022 Ultrasonic developers
*
* Distributed under terms of the GNU GPLv3 license.
*/
package org.moire.ultrasonic.fragment.legacy
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.navArgs
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import org.moire.ultrasonic.R
import org.moire.ultrasonic.domain.Lyrics
import org.moire.ultrasonic.fragment.FragmentTitle.Companion.setTitle
import org.moire.ultrasonic.service.MusicServiceFactory.getMusicService
import org.moire.ultrasonic.util.BackgroundTask
import org.moire.ultrasonic.util.CancellationToken
import org.moire.ultrasonic.util.FragmentBackgroundTask
import org.moire.ultrasonic.util.Util.applyTheme
import timber.log.Timber
/**
* Displays the lyrics of a song
*
* TODO: This file has been converted from Java, but not modernized yet.
*/
class LyricsFragment : Fragment() {
private var artistView: TextView? = null
private var titleView: TextView? = null
private var textView: TextView? = null
private var swipe: SwipeRefreshLayout? = null
private var cancellationToken: CancellationToken? = null
private val navArgs by navArgs<LyricsFragmentArgs>()
override fun onCreate(savedInstanceState: Bundle?) {
applyTheme(this.context)
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.lyrics, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
cancellationToken = CancellationToken()
Timber.d("Lyrics set title")
setTitle(this, R.string.download_menu_lyrics)
swipe = view.findViewById(R.id.lyrics_refresh)
swipe?.isEnabled = false
artistView = view.findViewById(R.id.lyrics_artist)
titleView = view.findViewById(R.id.lyrics_title)
textView = view.findViewById(R.id.lyrics_text)
load()
}
override fun onDestroyView() {
cancellationToken!!.cancel()
super.onDestroyView()
}
private fun load() {
val task: BackgroundTask<Lyrics> = object : FragmentBackgroundTask<Lyrics>(
activity, true, swipe, cancellationToken
) {
@Throws(Throwable::class)
override fun doInBackground(): Lyrics {
val musicService = getMusicService()
return musicService.getLyrics(navArgs.artist, navArgs.title)!!
}
override fun done(result: Lyrics) {
if (result.artist != null) {
artistView!!.text = result.artist
titleView!!.text = result.title
textView!!.text = result.text
} else {
artistView!!.setText(R.string.lyrics_nomatch)
}
}
}
task.execute()
}
}

View File

@ -28,9 +28,6 @@ import timber.log.Timber
/**
* This class is responsible for handling received events for the Media Player implementation
*
* TODO: Remove this class. Each component should listen to the lifecycleEvents and act on them
* independently
*/
class MediaPlayerLifecycleSupport : KoinComponent {
private val playbackStateSerializer by inject<PlaybackStateSerializer>()

View File

@ -25,9 +25,9 @@ class RxBus {
val themeChangedEventObservable: Observable<Unit> =
themeChangedEventPublisher.observeOn(mainThread())
val musicFolderChangedEventPublisher: PublishSubject<String> =
val musicFolderChangedEventPublisher: PublishSubject<Folder> =
PublishSubject.create()
val musicFolderChangedEventObservable: Observable<String> =
val musicFolderChangedEventObservable: Observable<Folder> =
musicFolderChangedEventPublisher.observeOn(mainThread())
val playerStatePublisher: PublishSubject<StateWithTrack> =
@ -93,6 +93,10 @@ class RxBus {
val state: DownloadStatus,
val progress: Int?
)
data class Folder(
val id: String?
)
}
operator fun CompositeDisposable.plusAssign(disposable: Disposable) {

View File

@ -15,14 +15,6 @@ object Constants {
const val REST_PROTOCOL_VERSION = "1.7.0"
const val REST_CLIENT_ID = "Ultrasonic"
// Legacy names for intent extras, in those fragments which don't use SafeArgs yet.
const val INTENT_ARTIST = "subsonic.artist"
const val INTENT_TITLE = "subsonic.title"
const val INTENT_AUTOPLAY = "subsonic.playall"
const val INTENT_QUERY = "subsonic.query"
const val INTENT_ALBUM_LIST_TYPE = "subsonic.albumlisttype"
const val INTENT_SHOW_PLAYER = "subsonic.showplayer"
// Names for Intent Actions
const val CMD_PROCESS_KEYCODE = "org.moire.ultrasonic.CMD_PROCESS_KEYCODE"
const val CMD_PLAY = "org.moire.ultrasonic.CMD_PLAY"
@ -32,6 +24,7 @@ object Constants {
const val CMD_STOP = "org.moire.ultrasonic.CMD_STOP"
const val CMD_PREVIOUS = "org.moire.ultrasonic.CMD_PREVIOUS"
const val CMD_NEXT = "org.moire.ultrasonic.CMD_NEXT"
const val INTENT_SHOW_PLAYER = "org.moire.ultrasonic.SHOW_PLAYER"
// Legacy Preferences keys
// Warning: Don't add any new here!

View File

@ -35,6 +35,11 @@
a:icon="@drawable/ic_menu_remove_all"
app:showAsAction="ifRoom|withText"
a:title="@string/download.menu_clear_playlist"/>
<item
a:id="@+id/menu_lyrics"
a:icon="@drawable/ic_library"
app:showAsAction="ifRoom|withText"
a:title="@string/download.menu_lyrics"/>
<item
a:id="@+id/menu_item_bookmark_set"
a:icon="@drawable/ic_menu_bookmark"

View File

@ -212,6 +212,15 @@
<action
android:id="@+id/searchToAlbumsList"
app:destination="@id/albumListFragment" />
<argument
android:name="query"
app:argType="string"
app:nullable="true"
android:defaultValue="@null" />
<argument
android:name="autoplay"
app:argType="boolean"
android:defaultValue="false" />
</fragment>
<fragment
android:id="@+id/playlistsFragment"
@ -263,6 +272,9 @@
<action
android:id="@+id/playerToSelectAlbum"
app:destination="@id/trackCollectionFragment" />
<action
android:id="@+id/playerToAlbumsList"
app:destination="@id/albumListFragment" />
<action
android:id="@+id/playerToLyrics"
app:destination="@id/lyricsFragment" />
@ -272,7 +284,14 @@
</fragment>
<fragment
android:id="@+id/lyricsFragment"
android:name="org.moire.ultrasonic.fragment.LyricsFragment" />
android:name="org.moire.ultrasonic.fragment.legacy.LyricsFragment" >
<argument
android:name="artist"
app:argType="string" />
<argument
android:name="title"
app:argType="string" />
</fragment>
<fragment
android:id="@+id/equalizerFragment"
android:name="org.moire.ultrasonic.fragment.EqualizerFragment" />
@ -280,10 +299,18 @@
android:id="@+id/serverSelectorFragment"
android:name="org.moire.ultrasonic.fragment.ServerSelectorFragment" >
<action
android:id="@+id/serverSelectorToEditServer"
android:id="@+id/toEditServer"
app:destination="@id/editServerFragment" />
</fragment>
<fragment
android:id="@+id/editServerFragment"
android:name="org.moire.ultrasonic.fragment.EditServerFragment" />
android:name="org.moire.ultrasonic.fragment.EditServerFragment" >
<argument
android:name="index"
app:argType="integer"
android:defaultValue="-1" />
</fragment>
<action
android:id="@+id/toSearchFragment"
app:destination="@id/searchFragment" />
</navigation>