mirror of
https://github.com/ultrasonic/ultrasonic
synced 2025-03-12 09:30:14 +01:00
Merge pull request #559 from Maxmystere/Improve-Offline-Support
Add better offline Support
This commit is contained in:
commit
029f0fa4da
@ -15,7 +15,12 @@ data class Share(
|
||||
private val entries: MutableList<Entry> = mutableListOf()
|
||||
) : Serializable, GenericEntry() {
|
||||
override val name: String?
|
||||
get() = url?.let { urlPattern.matcher(url).replaceFirst("$1") }
|
||||
get() {
|
||||
if (url != null) {
|
||||
return urlPattern.matcher(url!!).replaceFirst("$1")
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
fun getEntries(): List<Entry> {
|
||||
return entries.toList()
|
||||
|
@ -30,7 +30,6 @@
|
||||
<ID>LongMethod:EditServerFragment.kt$EditServerFragment$override fun onViewCreated(view: View, savedInstanceState: Bundle?)</ID>
|
||||
<ID>LongMethod:FilePickerAdapter.kt$FilePickerAdapter$private fun fileLister(currentDirectory: File)</ID>
|
||||
<ID>LongMethod:LocalMediaPlayer.kt$LocalMediaPlayer$@Synchronized private fun doPlay(downloadFile: DownloadFile, position: Int, start: Boolean)</ID>
|
||||
<ID>LongMethod:MediaPlayerService.kt$MediaPlayerService$private fun updateMediaSession(currentPlaying: DownloadFile?, playerState: PlayerState)</ID>
|
||||
<ID>LongMethod:NavigationActivity.kt$NavigationActivity$override fun onCreate(savedInstanceState: Bundle?)</ID>
|
||||
<ID>LongMethod:ShareHandler.kt$ShareHandler$private fun showDialog( fragment: Fragment, shareDetails: ShareDetails, swipe: SwipeRefreshLayout?, cancellationToken: CancellationToken )</ID>
|
||||
<ID>LongMethod:SongView.kt$SongView$fun setSong(song: MusicDirectory.Entry, checkable: Boolean, draggable: Boolean)</ID>
|
||||
@ -49,7 +48,6 @@
|
||||
<ID>MagicNumber:LocalMediaPlayer.kt$LocalMediaPlayer.BufferTask$86400L</ID>
|
||||
<ID>MagicNumber:LocalMediaPlayer.kt$LocalMediaPlayer.BufferTask$8L</ID>
|
||||
<ID>MagicNumber:LocalMediaPlayer.kt$LocalMediaPlayer.CheckCompletionTask$5000L</ID>
|
||||
<ID>MagicNumber:LocalMediaPlayer.kt$LocalMediaPlayer.PositionCache$50L</ID>
|
||||
<ID>MagicNumber:MediaPlayerService.kt$MediaPlayerService$256</ID>
|
||||
<ID>MagicNumber:MediaPlayerService.kt$MediaPlayerService$3</ID>
|
||||
<ID>MagicNumber:MediaPlayerService.kt$MediaPlayerService$4</ID>
|
||||
@ -70,11 +68,9 @@
|
||||
<ID>TooGenericExceptionCaught:LocalMediaPlayer.kt$LocalMediaPlayer$exception: Throwable</ID>
|
||||
<ID>TooGenericExceptionCaught:LocalMediaPlayer.kt$LocalMediaPlayer$x: Exception</ID>
|
||||
<ID>TooGenericExceptionCaught:LocalMediaPlayer.kt$LocalMediaPlayer.PositionCache$e: Exception</ID>
|
||||
<ID>TooGenericExceptionCaught:MediaPlayerService.kt$MediaPlayerService$e: Exception</ID>
|
||||
<ID>TooGenericExceptionCaught:SongView.kt$SongView$e: Exception</ID>
|
||||
<ID>TooGenericExceptionCaught:SubsonicUncaughtExceptionHandler.kt$SubsonicUncaughtExceptionHandler$x: Throwable</ID>
|
||||
<ID>TooGenericExceptionThrown:DownloadFile.kt$DownloadFile.DownloadTask$throw Exception(String.format("Download of '%s' was cancelled", song))</ID>
|
||||
<ID>TooManyFunctions:LocalMediaPlayer.kt$LocalMediaPlayer</ID>
|
||||
<ID>TooManyFunctions:MediaPlayerService.kt$MediaPlayerService : Service</ID>
|
||||
<ID>TooManyFunctions:RESTMusicService.kt$RESTMusicService : MusicService</ID>
|
||||
<ID>TooManyFunctions:TrackCollectionFragment.kt$TrackCollectionFragment : Fragment</ID>
|
||||
|
@ -1,265 +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.ListView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.navigation.Navigation;
|
||||
|
||||
import org.moire.ultrasonic.R;
|
||||
import org.moire.ultrasonic.data.ActiveServerProvider;
|
||||
import org.moire.ultrasonic.data.ServerSetting;
|
||||
import org.moire.ultrasonic.util.Constants;
|
||||
import org.moire.ultrasonic.util.MergeAdapter;
|
||||
import org.moire.ultrasonic.util.Util;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import kotlin.Lazy;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.koin.java.KoinJavaComponent.inject;
|
||||
|
||||
/**
|
||||
* Displays the Main screen of Ultrasonic, where the music library can be browsed
|
||||
*/
|
||||
public class MainFragment extends Fragment {
|
||||
|
||||
private static boolean shouldUseId3;
|
||||
private static String lastActiveServerProperties;
|
||||
|
||||
private ListView list;
|
||||
|
||||
private final Lazy<ActiveServerProvider> activeServerProvider = inject(ActiveServerProvider.class);
|
||||
|
||||
@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.main, container, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
|
||||
list = view.findViewById(R.id.main_list);
|
||||
setupMenuList(list);
|
||||
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
boolean shouldRestart = false;
|
||||
|
||||
boolean id3 = Util.getShouldUseId3Tags();
|
||||
String currentActiveServerProperties = getActiveServerProperties();
|
||||
|
||||
if (id3 != shouldUseId3)
|
||||
{
|
||||
shouldUseId3 = id3;
|
||||
shouldRestart = true;
|
||||
}
|
||||
|
||||
if (!currentActiveServerProperties.equals(lastActiveServerProperties))
|
||||
{
|
||||
lastActiveServerProperties = currentActiveServerProperties;
|
||||
shouldRestart = true;
|
||||
}
|
||||
|
||||
if (shouldRestart) {
|
||||
setupMenuList(list);
|
||||
}
|
||||
}
|
||||
|
||||
private void setupMenuList(ListView list)
|
||||
{
|
||||
final View buttons = getLayoutInflater().inflate(R.layout.main_buttons, list, false);
|
||||
final View serverButton = buttons.findViewById(R.id.main_select_server);
|
||||
final TextView serverTextView = serverButton.findViewById(R.id.main_select_server_2);
|
||||
|
||||
lastActiveServerProperties = getActiveServerProperties();
|
||||
String name = activeServerProvider.getValue().getActiveServer().getName();
|
||||
|
||||
serverTextView.setText(name);
|
||||
|
||||
final View musicTitle = buttons.findViewById(R.id.main_music);
|
||||
final View artistsButton = buttons.findViewById(R.id.main_artists_button);
|
||||
final View albumsButton = buttons.findViewById(R.id.main_albums_button);
|
||||
final View genresButton = buttons.findViewById(R.id.main_genres_button);
|
||||
final View videosTitle = buttons.findViewById(R.id.main_videos_title);
|
||||
final View songsTitle = buttons.findViewById(R.id.main_songs);
|
||||
final View randomSongsButton = buttons.findViewById(R.id.main_songs_button);
|
||||
final View songsStarredButton = buttons.findViewById(R.id.main_songs_starred);
|
||||
final View albumsTitle = buttons.findViewById(R.id.main_albums);
|
||||
final View albumsNewestButton = buttons.findViewById(R.id.main_albums_newest);
|
||||
final View albumsRandomButton = buttons.findViewById(R.id.main_albums_random);
|
||||
final View albumsHighestButton = buttons.findViewById(R.id.main_albums_highest);
|
||||
final View albumsStarredButton = buttons.findViewById(R.id.main_albums_starred);
|
||||
final View albumsRecentButton = buttons.findViewById(R.id.main_albums_recent);
|
||||
final View albumsFrequentButton = buttons.findViewById(R.id.main_albums_frequent);
|
||||
final View albumsAlphaByNameButton = buttons.findViewById(R.id.main_albums_alphaByName);
|
||||
final View albumsAlphaByArtistButton = buttons.findViewById(R.id.main_albums_alphaByArtist);
|
||||
final View videosButton = buttons.findViewById(R.id.main_videos);
|
||||
|
||||
final MergeAdapter adapter = new MergeAdapter();
|
||||
adapter.addViews(Collections.singletonList(serverButton), true);
|
||||
|
||||
if (!ActiveServerProvider.Companion.isOffline())
|
||||
{
|
||||
adapter.addView(musicTitle, false);
|
||||
adapter.addViews(asList(artistsButton, albumsButton, genresButton), true);
|
||||
adapter.addView(songsTitle, false);
|
||||
adapter.addViews(asList(randomSongsButton, songsStarredButton), true);
|
||||
adapter.addView(albumsTitle, false);
|
||||
|
||||
if (Util.getShouldUseId3Tags())
|
||||
{
|
||||
shouldUseId3 = true;
|
||||
adapter.addViews(asList(albumsNewestButton, albumsRecentButton, albumsFrequentButton, albumsRandomButton, albumsStarredButton, albumsAlphaByNameButton, albumsAlphaByArtistButton), true);
|
||||
}
|
||||
else
|
||||
{
|
||||
shouldUseId3 = false;
|
||||
adapter.addViews(asList(albumsNewestButton, albumsRecentButton, albumsFrequentButton, albumsHighestButton, albumsRandomButton, albumsStarredButton, albumsAlphaByNameButton, albumsAlphaByArtistButton), true);
|
||||
}
|
||||
|
||||
adapter.addView(videosTitle, false);
|
||||
adapter.addViews(Collections.singletonList(videosButton), true);
|
||||
}
|
||||
|
||||
list.setAdapter(adapter);
|
||||
list.setOnItemClickListener((parent, view, position, id) -> {
|
||||
if (view == serverButton)
|
||||
{
|
||||
showServers();
|
||||
}
|
||||
else if (view == albumsNewestButton)
|
||||
{
|
||||
showAlbumList("newest", R.string.main_albums_newest);
|
||||
}
|
||||
else if (view == albumsRandomButton)
|
||||
{
|
||||
showAlbumList("random", R.string.main_albums_random);
|
||||
}
|
||||
else if (view == albumsHighestButton)
|
||||
{
|
||||
showAlbumList("highest", R.string.main_albums_highest);
|
||||
}
|
||||
else if (view == albumsRecentButton)
|
||||
{
|
||||
showAlbumList("recent", R.string.main_albums_recent);
|
||||
}
|
||||
else if (view == albumsFrequentButton)
|
||||
{
|
||||
showAlbumList("frequent", R.string.main_albums_frequent);
|
||||
}
|
||||
else if (view == albumsStarredButton)
|
||||
{
|
||||
showAlbumList(Constants.STARRED, R.string.main_albums_starred);
|
||||
}
|
||||
else if (view == albumsAlphaByNameButton)
|
||||
{
|
||||
showAlbumList(Constants.ALPHABETICAL_BY_NAME, R.string.main_albums_alphaByName);
|
||||
}
|
||||
else if (view == albumsAlphaByArtistButton)
|
||||
{
|
||||
showAlbumList("alphabeticalByArtist", R.string.main_albums_alphaByArtist);
|
||||
}
|
||||
else if (view == songsStarredButton)
|
||||
{
|
||||
showStarredSongs();
|
||||
}
|
||||
else if (view == artistsButton)
|
||||
{
|
||||
showArtists();
|
||||
}
|
||||
else if (view == albumsButton)
|
||||
{
|
||||
showAlbumList(Constants.ALPHABETICAL_BY_NAME, R.string.main_albums_title);
|
||||
}
|
||||
else if (view == randomSongsButton)
|
||||
{
|
||||
showRandomSongs();
|
||||
}
|
||||
else if (view == genresButton)
|
||||
{
|
||||
showGenres();
|
||||
}
|
||||
else if (view == videosButton)
|
||||
{
|
||||
showVideos();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private String getActiveServerProperties()
|
||||
{
|
||||
ServerSetting currentSetting = activeServerProvider.getValue().getActiveServer();
|
||||
return String.format("%s;%s;%s;%s;%s;%s", currentSetting.getUrl(), currentSetting.getUserName(),
|
||||
currentSetting.getPassword(), currentSetting.getAllowSelfSignedCertificate(),
|
||||
currentSetting.getLdapSupport(), currentSetting.getMinimumApiVersion());
|
||||
}
|
||||
|
||||
private void showStarredSongs()
|
||||
{
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putInt(Constants.INTENT_EXTRA_NAME_STARRED, 1);
|
||||
Navigation.findNavController(getView()).navigate(R.id.mainToTrackCollection, bundle);
|
||||
}
|
||||
|
||||
private void showRandomSongs()
|
||||
{
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putInt(Constants.INTENT_EXTRA_NAME_RANDOM, 1);
|
||||
bundle.putInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_SIZE, Util.getMaxSongs());
|
||||
Navigation.findNavController(getView()).navigate(R.id.mainToTrackCollection, bundle);
|
||||
}
|
||||
|
||||
private void showArtists()
|
||||
{
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_TITLE, getContext().getResources().getString(R.string.main_artists_title));
|
||||
Navigation.findNavController(getView()).navigate(R.id.mainToArtistList, bundle);
|
||||
}
|
||||
|
||||
private void showAlbumList(final String type, final int titleIndex) {
|
||||
Bundle bundle = new Bundle();
|
||||
String title = getContext().getResources().getString(titleIndex, "");
|
||||
bundle.putString(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_TYPE, type);
|
||||
bundle.putString(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_TITLE, title);
|
||||
bundle.putInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_SIZE, Util.getMaxAlbums());
|
||||
bundle.putInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_OFFSET, 0);
|
||||
Navigation.findNavController(getView()).navigate(R.id.mainToAlbumList, bundle);
|
||||
}
|
||||
|
||||
private void showGenres()
|
||||
{
|
||||
Navigation.findNavController(getView()).navigate(R.id.mainToSelectGenre);
|
||||
}
|
||||
|
||||
private void showVideos()
|
||||
{
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putInt(Constants.INTENT_EXTRA_NAME_VIDEOS, 1);
|
||||
Navigation.findNavController(getView()).navigate(R.id.mainToTrackCollection, bundle);
|
||||
}
|
||||
|
||||
private void showServers()
|
||||
{
|
||||
Navigation.findNavController(getView()).navigate(R.id.mainToServerSelector);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,294 @@
|
||||
package org.moire.ultrasonic.fragment
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.AdapterView
|
||||
import android.widget.AdapterView.OnItemClickListener
|
||||
import android.widget.ListView
|
||||
import android.widget.TextView
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.navigation.Navigation
|
||||
import java.util.Locale
|
||||
import org.koin.core.component.KoinComponent
|
||||
import org.koin.core.component.inject
|
||||
import org.moire.ultrasonic.R
|
||||
import org.moire.ultrasonic.data.ActiveServerProvider
|
||||
import org.moire.ultrasonic.data.ActiveServerProvider.Companion.isOffline
|
||||
import org.moire.ultrasonic.util.Constants
|
||||
import org.moire.ultrasonic.util.MergeAdapter
|
||||
import org.moire.ultrasonic.util.Util.applyTheme
|
||||
import org.moire.ultrasonic.util.Util.getMaxAlbums
|
||||
import org.moire.ultrasonic.util.Util.getMaxSongs
|
||||
import org.moire.ultrasonic.util.Util.getShouldUseId3Tags
|
||||
|
||||
/**
|
||||
* Displays the Main screen of Ultrasonic, where the music library can be browsed
|
||||
*/
|
||||
class MainFragment : Fragment(), KoinComponent {
|
||||
private var list: ListView? = null
|
||||
|
||||
private lateinit var serverButton: View
|
||||
private lateinit var serverTextView: TextView
|
||||
private lateinit var musicTitle: View
|
||||
private lateinit var artistsButton: View
|
||||
private lateinit var albumsButton: View
|
||||
private lateinit var genresButton: View
|
||||
private lateinit var videosTitle: View
|
||||
private lateinit var songsTitle: View
|
||||
private lateinit var randomSongsButton: View
|
||||
private lateinit var songsStarredButton: View
|
||||
private lateinit var albumsTitle: View
|
||||
private lateinit var albumsNewestButton: View
|
||||
private lateinit var albumsRandomButton: View
|
||||
private lateinit var albumsHighestButton: View
|
||||
private lateinit var albumsStarredButton: View
|
||||
private lateinit var albumsRecentButton: View
|
||||
private lateinit var albumsFrequentButton: View
|
||||
private lateinit var albumsAlphaByNameButton: View
|
||||
private lateinit var albumsAlphaByArtistButton: View
|
||||
private lateinit var videosButton: View
|
||||
|
||||
private val activeServerProvider: ActiveServerProvider by inject()
|
||||
|
||||
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.main, container, false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
list = view.findViewById(R.id.main_list)
|
||||
cachedActiveServerProperties = getActiveServerProperties()
|
||||
|
||||
setupButtons()
|
||||
|
||||
if (list != null) setupMenuList(list!!)
|
||||
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
var shouldRestart = false
|
||||
val currentId3Setting = getShouldUseId3Tags()
|
||||
val currentActiveServerProperties = getActiveServerProperties()
|
||||
|
||||
// If setting has changed...
|
||||
if (currentId3Setting != shouldUseId3) {
|
||||
shouldUseId3 = currentId3Setting
|
||||
shouldRestart = true
|
||||
}
|
||||
|
||||
// or the server has changed...
|
||||
if (currentActiveServerProperties != cachedActiveServerProperties) {
|
||||
cachedActiveServerProperties = currentActiveServerProperties
|
||||
shouldRestart = true
|
||||
}
|
||||
|
||||
// then setup the list anew.
|
||||
if (shouldRestart) {
|
||||
if (list != null) setupMenuList(list!!)
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupButtons() {
|
||||
val buttons = layoutInflater.inflate(R.layout.main_buttons, list, false)
|
||||
serverButton = buttons.findViewById(R.id.main_select_server)
|
||||
serverTextView = serverButton.findViewById(R.id.main_select_server_2)
|
||||
musicTitle = buttons.findViewById(R.id.main_music)
|
||||
artistsButton = buttons.findViewById(R.id.main_artists_button)
|
||||
albumsButton = buttons.findViewById(R.id.main_albums_button)
|
||||
genresButton = buttons.findViewById(R.id.main_genres_button)
|
||||
videosTitle = buttons.findViewById(R.id.main_videos_title)
|
||||
songsTitle = buttons.findViewById(R.id.main_songs)
|
||||
randomSongsButton = buttons.findViewById(R.id.main_songs_button)
|
||||
songsStarredButton = buttons.findViewById(R.id.main_songs_starred)
|
||||
albumsTitle = buttons.findViewById(R.id.main_albums)
|
||||
albumsNewestButton = buttons.findViewById(R.id.main_albums_newest)
|
||||
albumsRandomButton = buttons.findViewById(R.id.main_albums_random)
|
||||
albumsHighestButton = buttons.findViewById(R.id.main_albums_highest)
|
||||
albumsStarredButton = buttons.findViewById(R.id.main_albums_starred)
|
||||
albumsRecentButton = buttons.findViewById(R.id.main_albums_recent)
|
||||
albumsFrequentButton = buttons.findViewById(R.id.main_albums_frequent)
|
||||
albumsAlphaByNameButton = buttons.findViewById(R.id.main_albums_alphaByName)
|
||||
albumsAlphaByArtistButton = buttons.findViewById(R.id.main_albums_alphaByArtist)
|
||||
videosButton = buttons.findViewById(R.id.main_videos)
|
||||
}
|
||||
|
||||
private fun setupMenuList(list: ListView) {
|
||||
// Set title
|
||||
val activeServerName = activeServerProvider.getActiveServer().name
|
||||
serverTextView.text = activeServerName
|
||||
|
||||
// TODO: Should use RecyclerView
|
||||
val adapter = MergeAdapter()
|
||||
|
||||
adapter.addView(serverButton, true)
|
||||
|
||||
shouldUseId3 = getShouldUseId3Tags()
|
||||
|
||||
if (!isOffline()) {
|
||||
adapter.addView(musicTitle, false)
|
||||
adapter.addViews(listOf(artistsButton, albumsButton, genresButton), true)
|
||||
adapter.addView(songsTitle, false)
|
||||
adapter.addViews(listOf(randomSongsButton, songsStarredButton), true)
|
||||
adapter.addView(albumsTitle, false)
|
||||
adapter.addViews(
|
||||
listOf(
|
||||
albumsNewestButton,
|
||||
albumsRecentButton,
|
||||
albumsFrequentButton
|
||||
),
|
||||
true
|
||||
)
|
||||
if (!shouldUseId3) {
|
||||
adapter.addView(albumsHighestButton, true)
|
||||
}
|
||||
adapter.addViews(
|
||||
listOf(
|
||||
albumsRandomButton,
|
||||
albumsStarredButton,
|
||||
albumsAlphaByNameButton,
|
||||
albumsAlphaByArtistButton
|
||||
),
|
||||
true
|
||||
)
|
||||
adapter.addView(videosTitle, false)
|
||||
adapter.addViews(listOf(videosButton), true)
|
||||
} else {
|
||||
// Offline supported calls
|
||||
adapter.addView(musicTitle, false)
|
||||
adapter.addViews(listOf(artistsButton, genresButton), true)
|
||||
adapter.addView(songsTitle, false)
|
||||
adapter.addView(randomSongsButton, true)
|
||||
}
|
||||
|
||||
list.adapter = adapter
|
||||
list.onItemClickListener = listListener
|
||||
}
|
||||
|
||||
private val listListener =
|
||||
OnItemClickListener { _: AdapterView<*>?, view: View, _: Int, _: Long ->
|
||||
when {
|
||||
view === serverButton -> {
|
||||
showServers()
|
||||
}
|
||||
view === albumsNewestButton -> {
|
||||
showAlbumList("newest", R.string.main_albums_newest)
|
||||
}
|
||||
view === albumsRandomButton -> {
|
||||
showAlbumList("random", R.string.main_albums_random)
|
||||
}
|
||||
view === albumsHighestButton -> {
|
||||
showAlbumList("highest", R.string.main_albums_highest)
|
||||
}
|
||||
view === albumsRecentButton -> {
|
||||
showAlbumList("recent", R.string.main_albums_recent)
|
||||
}
|
||||
view === albumsFrequentButton -> {
|
||||
showAlbumList("frequent", R.string.main_albums_frequent)
|
||||
}
|
||||
view === albumsStarredButton -> {
|
||||
showAlbumList(Constants.STARRED, R.string.main_albums_starred)
|
||||
}
|
||||
view === albumsAlphaByNameButton -> {
|
||||
showAlbumList(Constants.ALPHABETICAL_BY_NAME, R.string.main_albums_alphaByName)
|
||||
}
|
||||
view === albumsAlphaByArtistButton -> {
|
||||
showAlbumList("alphabeticalByArtist", R.string.main_albums_alphaByArtist)
|
||||
}
|
||||
view === songsStarredButton -> {
|
||||
showStarredSongs()
|
||||
}
|
||||
view === artistsButton -> {
|
||||
showArtists()
|
||||
}
|
||||
view === albumsButton -> {
|
||||
showAlbumList(Constants.ALPHABETICAL_BY_NAME, R.string.main_albums_title)
|
||||
}
|
||||
view === randomSongsButton -> {
|
||||
showRandomSongs()
|
||||
}
|
||||
view === genresButton -> {
|
||||
showGenres()
|
||||
}
|
||||
view === videosButton -> {
|
||||
showVideos()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getActiveServerProperties(): String {
|
||||
val server = activeServerProvider.getActiveServer()
|
||||
return String.format(
|
||||
Locale.ROOT,
|
||||
"%s;%s;%s;%s;%s;%s",
|
||||
server.url,
|
||||
server.userName,
|
||||
server.password,
|
||||
server.allowSelfSignedCertificate,
|
||||
server.ldapSupport,
|
||||
server.minimumApiVersion
|
||||
)
|
||||
}
|
||||
|
||||
private fun showStarredSongs() {
|
||||
val bundle = Bundle()
|
||||
bundle.putInt(Constants.INTENT_EXTRA_NAME_STARRED, 1)
|
||||
Navigation.findNavController(requireView()).navigate(R.id.mainToTrackCollection, bundle)
|
||||
}
|
||||
|
||||
private fun showRandomSongs() {
|
||||
val bundle = Bundle()
|
||||
bundle.putInt(Constants.INTENT_EXTRA_NAME_RANDOM, 1)
|
||||
bundle.putInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_SIZE, getMaxSongs())
|
||||
Navigation.findNavController(requireView()).navigate(R.id.mainToTrackCollection, bundle)
|
||||
}
|
||||
|
||||
private fun showArtists() {
|
||||
val bundle = Bundle()
|
||||
bundle.putString(
|
||||
Constants.INTENT_EXTRA_NAME_ALBUM_LIST_TITLE,
|
||||
requireContext().resources.getString(R.string.main_artists_title)
|
||||
)
|
||||
Navigation.findNavController(requireView()).navigate(R.id.mainToArtistList, bundle)
|
||||
}
|
||||
|
||||
private fun showAlbumList(type: String, titleIndex: Int) {
|
||||
val bundle = Bundle()
|
||||
val title = requireContext().resources.getString(titleIndex, "")
|
||||
bundle.putString(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_TYPE, type)
|
||||
bundle.putString(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_TITLE, title)
|
||||
bundle.putInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_SIZE, getMaxAlbums())
|
||||
bundle.putInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_OFFSET, 0)
|
||||
Navigation.findNavController(requireView()).navigate(R.id.mainToAlbumList, bundle)
|
||||
}
|
||||
|
||||
private fun showGenres() {
|
||||
Navigation.findNavController(requireView()).navigate(R.id.mainToSelectGenre)
|
||||
}
|
||||
|
||||
private fun showVideos() {
|
||||
val bundle = Bundle()
|
||||
bundle.putInt(Constants.INTENT_EXTRA_NAME_VIDEOS, 1)
|
||||
Navigation.findNavController(requireView()).navigate(R.id.mainToTrackCollection, bundle)
|
||||
}
|
||||
|
||||
private fun showServers() {
|
||||
Navigation.findNavController(requireView()).navigate(R.id.mainToServerSelector)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private var shouldUseId3 = false
|
||||
private var cachedActiveServerProperties: String? = null
|
||||
}
|
||||
}
|
@ -14,11 +14,11 @@ import java.io.FileReader
|
||||
import java.io.FileWriter
|
||||
import java.io.InputStream
|
||||
import java.io.Reader
|
||||
import java.lang.Math.min
|
||||
import java.util.ArrayList
|
||||
import java.util.HashSet
|
||||
import java.util.LinkedList
|
||||
import java.util.Locale
|
||||
import java.util.Random
|
||||
import java.util.concurrent.TimeUnit
|
||||
import java.util.regex.Pattern
|
||||
import org.koin.core.component.KoinComponent
|
||||
@ -257,9 +257,10 @@ class OfflineMusicService : MusicService, KoinComponent {
|
||||
if (children.isEmpty()) {
|
||||
return result
|
||||
}
|
||||
val random = Random()
|
||||
for (i in 0 until size) {
|
||||
val file = children[random.nextInt(children.size)]
|
||||
children.shuffle()
|
||||
val finalSize: Int = min(children.size, size)
|
||||
for (i in 0 until finalSize) {
|
||||
val file = children[i % children.size]
|
||||
result.addChild(createEntry(file, getName(file)))
|
||||
}
|
||||
return result
|
||||
|
@ -87,10 +87,10 @@ object Util {
|
||||
private var MEGA_BYTE_LOCALIZED_FORMAT: DecimalFormat? = null
|
||||
private var KILO_BYTE_LOCALIZED_FORMAT: DecimalFormat? = null
|
||||
private var BYTE_LOCALIZED_FORMAT: DecimalFormat? = null
|
||||
const val EVENT_META_CHANGED = "org.moire.ultrasonic.EVENT_META_CHANGED"
|
||||
const val EVENT_PLAYSTATE_CHANGED = "org.moire.ultrasonic.EVENT_PLAYSTATE_CHANGED"
|
||||
const val CM_AVRCP_PLAYSTATE_CHANGED = "com.android.music.playstatechanged"
|
||||
const val CM_AVRCP_METADATA_CHANGED = "com.android.music.metachanged"
|
||||
private const val EVENT_META_CHANGED = "org.moire.ultrasonic.EVENT_META_CHANGED"
|
||||
private const val EVENT_PLAYSTATE_CHANGED = "org.moire.ultrasonic.EVENT_PLAYSTATE_CHANGED"
|
||||
private const val CM_AVRCP_PLAYSTATE_CHANGED = "com.android.music.playstatechanged"
|
||||
private const val CM_AVRCP_METADATA_CHANGED = "com.android.music.metachanged"
|
||||
|
||||
// Used by hexEncode()
|
||||
private val HEX_DIGITS =
|
||||
@ -440,6 +440,7 @@ object Util {
|
||||
return BYTE_LOCALIZED_FORMAT!!.format(byteCount.toDouble())
|
||||
}
|
||||
|
||||
@Suppress("SuspiciousEqualsCombination")
|
||||
fun equals(object1: Any?, object2: Any?): Boolean {
|
||||
return object1 === object2 || !(object1 == null || object2 == null) && object1 == object2
|
||||
}
|
||||
@ -624,10 +625,10 @@ object Util {
|
||||
|
||||
// Assume the size given refers to the width of the image, so calculate the new height using
|
||||
// the previously determined aspect ratio
|
||||
return Math.round(newWidth * aspectRatio).toInt()
|
||||
return (newWidth * aspectRatio).roundToInt()
|
||||
}
|
||||
|
||||
fun getScaledHeight(bitmap: Bitmap, width: Int): Int {
|
||||
private fun getScaledHeight(bitmap: Bitmap, width: Int): Int {
|
||||
return getScaledHeight(bitmap.height.toDouble(), bitmap.width.toDouble(), width)
|
||||
}
|
||||
|
||||
@ -851,12 +852,12 @@ object Util {
|
||||
|
||||
fun getMinDisplayMetric(): Int {
|
||||
val metrics = appContext().resources.displayMetrics
|
||||
return Math.min(metrics.widthPixels, metrics.heightPixels)
|
||||
return min(metrics.widthPixels, metrics.heightPixels)
|
||||
}
|
||||
|
||||
fun getMaxDisplayMetric(): Int {
|
||||
val metrics = appContext().resources.displayMetrics
|
||||
return Math.max(metrics.widthPixels, metrics.heightPixels)
|
||||
return max(metrics.widthPixels, metrics.heightPixels)
|
||||
}
|
||||
|
||||
fun calculateInSampleSize(options: BitmapFactory.Options, reqWidth: Int, reqHeight: Int): Int {
|
||||
@ -868,14 +869,14 @@ object Util {
|
||||
|
||||
// Calculate ratios of height and width to requested height and
|
||||
// width
|
||||
val heightRatio = Math.round(height.toFloat() / reqHeight.toFloat())
|
||||
val widthRatio = Math.round(width.toFloat() / reqWidth.toFloat())
|
||||
val heightRatio = (height.toFloat() / reqHeight.toFloat()).roundToInt()
|
||||
val widthRatio = (width.toFloat() / reqWidth.toFloat()).roundToInt()
|
||||
|
||||
// Choose the smallest ratio as inSampleSize value, this will
|
||||
// guarantee
|
||||
// a final image with both dimensions larger than or equal to the
|
||||
// requested height and width.
|
||||
inSampleSize = Math.min(heightRatio, widthRatio)
|
||||
inSampleSize = min(heightRatio, widthRatio)
|
||||
}
|
||||
return inSampleSize
|
||||
}
|
||||
@ -1091,7 +1092,7 @@ object Util {
|
||||
)
|
||||
}
|
||||
|
||||
fun getShouldSendBluetoothAlbumArt(): Boolean {
|
||||
private fun getShouldSendBluetoothAlbumArt(): Boolean {
|
||||
val preferences = getPreferences()
|
||||
return preferences.getBoolean(Constants.PREFERENCES_KEY_SEND_BLUETOOTH_ALBUM_ART, true)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user