mirror of
https://github.com/ultrasonic/ultrasonic
synced 2025-03-03 19:08:54 +01:00
Refactored remaining Activities
This commit is contained in:
parent
cf90abb77e
commit
1b9b127424
@ -44,17 +44,6 @@
|
|||||||
android:name="android.app.searchable"
|
android:name="android.app.searchable"
|
||||||
android:resource="@xml/searchable"/>
|
android:resource="@xml/searchable"/>
|
||||||
</activity>
|
</activity>
|
||||||
<activity
|
|
||||||
android:name=".activity.EqualizerActivity"
|
|
||||||
android:configChanges="orientation|keyboardHidden"
|
|
||||||
android:label="@string/equalizer.label"
|
|
||||||
android:launchMode="singleTask"/>
|
|
||||||
<activity
|
|
||||||
android:name=".activity.ServerSelectorActivity"
|
|
||||||
android:label="@string/server_selector.label" />
|
|
||||||
<activity
|
|
||||||
android:name=".activity.EditServerActivity"
|
|
||||||
android:label="@string/server_editor.label" />
|
|
||||||
|
|
||||||
<service
|
<service
|
||||||
android:name=".service.MediaPlayerService"
|
android:name=".service.MediaPlayerService"
|
||||||
|
@ -1,280 +0,0 @@
|
|||||||
/*
|
|
||||||
This file is part of Subsonic.
|
|
||||||
|
|
||||||
Subsonic is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
Subsonic is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Copyright 2011 (C) Sindre Mehus
|
|
||||||
*/
|
|
||||||
package org.moire.ultrasonic.activity;
|
|
||||||
|
|
||||||
import android.media.audiofx.Equalizer;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.view.ContextMenu;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.MenuItem;
|
|
||||||
import android.view.View;
|
|
||||||
import android.widget.CheckBox;
|
|
||||||
import android.widget.CompoundButton;
|
|
||||||
import android.widget.LinearLayout;
|
|
||||||
import android.widget.SeekBar;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import androidx.lifecycle.Observer;
|
|
||||||
|
|
||||||
import org.moire.ultrasonic.R;
|
|
||||||
import org.moire.ultrasonic.audiofx.EqualizerController;
|
|
||||||
import org.moire.ultrasonic.service.MediaPlayerController;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import kotlin.Lazy;
|
|
||||||
import timber.log.Timber;
|
|
||||||
|
|
||||||
import static org.koin.java.KoinJavaComponent.inject;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Equalizer controls.
|
|
||||||
*
|
|
||||||
* @author Sindre Mehus
|
|
||||||
* @version $Id$
|
|
||||||
*/
|
|
||||||
public class EqualizerActivity extends ResultActivity
|
|
||||||
{
|
|
||||||
private static final int MENU_GROUP_PRESET = 100;
|
|
||||||
|
|
||||||
private final Map<Short, SeekBar> bars = new HashMap<Short, SeekBar>();
|
|
||||||
private EqualizerController equalizerController;
|
|
||||||
private Equalizer equalizer;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate(Bundle bundle)
|
|
||||||
{
|
|
||||||
super.onCreate(bundle);
|
|
||||||
setContentView(R.layout.equalizer);
|
|
||||||
|
|
||||||
EqualizerController.get().observe(this, new Observer<EqualizerController>() {
|
|
||||||
@Override
|
|
||||||
public void onChanged(EqualizerController controller) {
|
|
||||||
if (controller != null) {
|
|
||||||
Timber.d("EqualizerController Observer.onChanged received controller");
|
|
||||||
equalizerController = controller;
|
|
||||||
equalizer = controller.equalizer;
|
|
||||||
setup();
|
|
||||||
} else {
|
|
||||||
Timber.d("EqualizerController Observer.onChanged has no controller");
|
|
||||||
equalizerController = null;
|
|
||||||
equalizer = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPause()
|
|
||||||
{
|
|
||||||
super.onPause();
|
|
||||||
if (equalizerController == null) return;
|
|
||||||
equalizerController.saveSettings();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onResume()
|
|
||||||
{
|
|
||||||
super.onResume();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo)
|
|
||||||
{
|
|
||||||
super.onCreateContextMenu(menu, view, menuInfo);
|
|
||||||
if (equalizer == null) return;
|
|
||||||
|
|
||||||
short currentPreset;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
currentPreset = equalizer.getCurrentPreset();
|
|
||||||
}
|
|
||||||
catch (Exception x)
|
|
||||||
{
|
|
||||||
currentPreset = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (short preset = 0; preset < equalizer.getNumberOfPresets(); preset++)
|
|
||||||
{
|
|
||||||
MenuItem menuItem = menu.add(MENU_GROUP_PRESET, preset, preset, equalizer.getPresetName(preset));
|
|
||||||
if (preset == currentPreset)
|
|
||||||
{
|
|
||||||
menuItem.setChecked(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
menu.setGroupCheckable(MENU_GROUP_PRESET, true, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onContextItemSelected(MenuItem menuItem)
|
|
||||||
{
|
|
||||||
if (equalizer == null) return true;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
short preset = (short) menuItem.getItemId();
|
|
||||||
equalizer.usePreset(preset);
|
|
||||||
updateBars();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
//TODO: Show a dialog
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setup()
|
|
||||||
{
|
|
||||||
initEqualizer();
|
|
||||||
|
|
||||||
final View presetButton = findViewById(R.id.equalizer_preset);
|
|
||||||
registerForContextMenu(presetButton);
|
|
||||||
presetButton.setOnClickListener(new View.OnClickListener()
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void onClick(View view)
|
|
||||||
{
|
|
||||||
presetButton.showContextMenu();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
CheckBox enabledCheckBox = (CheckBox) findViewById(R.id.equalizer_enabled);
|
|
||||||
enabledCheckBox.setChecked(equalizer.getEnabled());
|
|
||||||
enabledCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void onCheckedChanged(CompoundButton compoundButton, boolean b)
|
|
||||||
{
|
|
||||||
setEqualizerEnabled(b);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setEqualizerEnabled(boolean enabled)
|
|
||||||
{
|
|
||||||
if (equalizer == null) return;
|
|
||||||
equalizer.setEnabled(enabled);
|
|
||||||
updateBars();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateBars()
|
|
||||||
{
|
|
||||||
if (equalizer == null) return;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
for (Map.Entry<Short, SeekBar> entry : bars.entrySet())
|
|
||||||
{
|
|
||||||
short band = entry.getKey();
|
|
||||||
SeekBar bar = entry.getValue();
|
|
||||||
bar.setEnabled(equalizer.getEnabled());
|
|
||||||
short minEQLevel = equalizer.getBandLevelRange()[0];
|
|
||||||
bar.setProgress(equalizer.getBandLevel(band) - minEQLevel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
//TODO: Show a dialog
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initEqualizer()
|
|
||||||
{
|
|
||||||
if (equalizer == null) return;
|
|
||||||
LinearLayout layout = (LinearLayout) findViewById(R.id.equalizer_layout);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
short[] bandLevelRange = equalizer.getBandLevelRange();
|
|
||||||
short numberOfBands = equalizer.getNumberOfBands();
|
|
||||||
|
|
||||||
final short minEQLevel = bandLevelRange[0];
|
|
||||||
final short maxEQLevel = bandLevelRange[1];
|
|
||||||
|
|
||||||
for (short i = 0; i < numberOfBands; i++)
|
|
||||||
{
|
|
||||||
final short band = i;
|
|
||||||
|
|
||||||
View bandBar = LayoutInflater.from(this).inflate(R.layout.equalizer_bar, null);
|
|
||||||
TextView freqTextView;
|
|
||||||
|
|
||||||
if (bandBar != null)
|
|
||||||
{
|
|
||||||
freqTextView = (TextView) bandBar.findViewById(R.id.equalizer_frequency);
|
|
||||||
final TextView levelTextView = (TextView) bandBar.findViewById(R.id.equalizer_level);
|
|
||||||
SeekBar bar = (SeekBar) bandBar.findViewById(R.id.equalizer_bar);
|
|
||||||
|
|
||||||
freqTextView.setText((equalizer.getCenterFreq(band) / 1000) + " Hz");
|
|
||||||
|
|
||||||
bars.put(band, bar);
|
|
||||||
bar.setMax(maxEQLevel - minEQLevel);
|
|
||||||
short level = equalizer.getBandLevel(band);
|
|
||||||
bar.setProgress(level - minEQLevel);
|
|
||||||
bar.setEnabled(equalizer.getEnabled());
|
|
||||||
updateLevelText(levelTextView, level);
|
|
||||||
|
|
||||||
bar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener()
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
|
|
||||||
{
|
|
||||||
short level = (short) (progress + minEQLevel);
|
|
||||||
if (fromUser)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
equalizer.setBandLevel(band, level);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
//TODO: Show a dialog
|
|
||||||
}
|
|
||||||
}
|
|
||||||
updateLevelText(levelTextView, level);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStartTrackingTouch(SeekBar seekBar)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStopTrackingTouch(SeekBar seekBar)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
layout.addView(bandBar);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
//TODO: Show a dialog
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void updateLevelText(TextView levelTextView, short level)
|
|
||||||
{
|
|
||||||
if (levelTextView != null)
|
|
||||||
{
|
|
||||||
levelTextView.setText(String.format("%s%d dB", level > 0 ? "+" : "", level / 100));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
package org.moire.ultrasonic.activity;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.content.Intent;
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
|
||||||
|
|
||||||
import org.moire.ultrasonic.util.Constants;
|
|
||||||
import org.moire.ultrasonic.util.Util;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Joshua Bahnsen on 12/30/13.
|
|
||||||
*/
|
|
||||||
public class ResultActivity extends AppCompatActivity
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
protected void onActivityResult(int requestCode, int resultCode, Intent data)
|
|
||||||
{
|
|
||||||
switch (resultCode)
|
|
||||||
{
|
|
||||||
case Constants.RESULT_CLOSE_ALL:
|
|
||||||
setResult(Constants.RESULT_CLOSE_ALL);
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
super.onActivityResult(requestCode, resultCode, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void startActivityForResultWithoutTransition(Activity currentActivity, Class<? extends Activity> newActivity)
|
|
||||||
{
|
|
||||||
startActivityForResultWithoutTransition(currentActivity, new Intent(currentActivity, newActivity));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void startActivityForResultWithoutTransition(Activity currentActivity, Intent intent)
|
|
||||||
{
|
|
||||||
startActivityForResult(intent, 0);
|
|
||||||
Util.disablePendingTransition(currentActivity);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,255 +0,0 @@
|
|||||||
/*
|
|
||||||
This file is part of Ultrasonic.
|
|
||||||
|
|
||||||
Subsonic is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
Subsonic is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Copyright 2009 (C) Sindre Mehus
|
|
||||||
*/
|
|
||||||
package org.moire.ultrasonic.activity;
|
|
||||||
|
|
||||||
import android.app.AlertDialog;
|
|
||||||
import android.app.Dialog;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.media.AudioManager;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Build;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import androidx.appcompat.app.ActionBar;
|
|
||||||
import timber.log.Timber;
|
|
||||||
import android.view.*;
|
|
||||||
import android.view.View.OnClickListener;
|
|
||||||
import android.view.View.OnTouchListener;
|
|
||||||
import android.widget.*;
|
|
||||||
import net.simonvt.menudrawer.MenuDrawer;
|
|
||||||
import net.simonvt.menudrawer.Position;
|
|
||||||
import static org.koin.java.KoinJavaComponent.inject;
|
|
||||||
|
|
||||||
import org.koin.java.KoinJavaComponent;
|
|
||||||
import org.moire.ultrasonic.R;
|
|
||||||
import org.moire.ultrasonic.data.ActiveServerProvider;
|
|
||||||
import org.moire.ultrasonic.domain.MusicDirectory;
|
|
||||||
import org.moire.ultrasonic.domain.MusicDirectory.Entry;
|
|
||||||
import org.moire.ultrasonic.domain.PlayerState;
|
|
||||||
import org.moire.ultrasonic.domain.Share;
|
|
||||||
import org.moire.ultrasonic.featureflags.Feature;
|
|
||||||
import org.moire.ultrasonic.featureflags.FeatureStorage;
|
|
||||||
import org.moire.ultrasonic.fragment.SelectAlbumFragment;
|
|
||||||
import org.moire.ultrasonic.service.*;
|
|
||||||
import org.moire.ultrasonic.subsonic.ImageLoaderProvider;
|
|
||||||
import org.moire.ultrasonic.subsonic.SubsonicImageLoaderProxy;
|
|
||||||
import org.moire.ultrasonic.subsonic.loader.image.SubsonicImageLoader;
|
|
||||||
import org.moire.ultrasonic.util.*;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.PrintWriter;
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
import kotlin.Lazy;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Sindre Mehus
|
|
||||||
*/
|
|
||||||
public class SubsonicTabActivity extends ResultActivity
|
|
||||||
{
|
|
||||||
private static final Pattern COMPILE = Pattern.compile(":");
|
|
||||||
protected static String theme;
|
|
||||||
private static SubsonicTabActivity instance;
|
|
||||||
|
|
||||||
private boolean destroyed;
|
|
||||||
|
|
||||||
private static final String STATE_MENUDRAWER = "org.moire.ultrasonic.menuDrawer";
|
|
||||||
private static final String STATE_ACTIVE_VIEW_ID = "org.moire.ultrasonic.activeViewId";
|
|
||||||
private static final String STATE_ACTIVE_POSITION = "org.moire.ultrasonic.activePosition";
|
|
||||||
private static final int DIALOG_ASK_FOR_SHARE_DETAILS = 102;
|
|
||||||
|
|
||||||
private final Lazy<MediaPlayerController> mediaPlayerControllerLazy = inject(MediaPlayerController.class);
|
|
||||||
private final Lazy<MediaPlayerLifecycleSupport> lifecycleSupport = inject(MediaPlayerLifecycleSupport.class);
|
|
||||||
protected Lazy<ImageLoaderProvider> imageLoader = inject(ImageLoaderProvider.class);
|
|
||||||
|
|
||||||
public MenuDrawer menuDrawer;
|
|
||||||
private int activePosition = 1;
|
|
||||||
private int menuActiveViewId;
|
|
||||||
private View nowPlayingView;
|
|
||||||
View chatMenuItem;
|
|
||||||
View bookmarksMenuItem;
|
|
||||||
View sharesMenuItem;
|
|
||||||
public static boolean nowPlayingHidden;
|
|
||||||
boolean licenseValid;
|
|
||||||
private EditText shareDescription;
|
|
||||||
TimeSpanPicker timeSpanPicker;
|
|
||||||
CheckBox hideDialogCheckBox;
|
|
||||||
CheckBox noExpirationCheckBox;
|
|
||||||
CheckBox saveAsDefaultsCheckBox;
|
|
||||||
ShareDetails shareDetails;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(Bundle bundle)
|
|
||||||
{
|
|
||||||
super.onCreate(bundle);
|
|
||||||
|
|
||||||
setVolumeControlStream(AudioManager.STREAM_MUSIC);
|
|
||||||
|
|
||||||
if (bundle != null)
|
|
||||||
{
|
|
||||||
activePosition = bundle.getInt(STATE_ACTIVE_POSITION);
|
|
||||||
menuActiveViewId = bundle.getInt(STATE_ACTIVE_VIEW_ID);
|
|
||||||
}
|
|
||||||
|
|
||||||
menuDrawer = MenuDrawer.attach(this, MenuDrawer.Type.BEHIND, Position.LEFT, MenuDrawer.MENU_DRAG_WINDOW);
|
|
||||||
menuDrawer.setMenuView(R.layout.menu_main);
|
|
||||||
|
|
||||||
chatMenuItem = findViewById(R.id.menu_chat);
|
|
||||||
bookmarksMenuItem = findViewById(R.id.menu_bookmarks);
|
|
||||||
sharesMenuItem = findViewById(R.id.menu_shares);
|
|
||||||
|
|
||||||
//setActionBarDisplayHomeAsUp(true);
|
|
||||||
|
|
||||||
TextView activeView = (TextView) findViewById(menuActiveViewId);
|
|
||||||
|
|
||||||
if (activeView != null)
|
|
||||||
{
|
|
||||||
menuDrawer.setActiveView(activeView);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPostCreate(Bundle bundle)
|
|
||||||
{
|
|
||||||
super.onPostCreate(bundle);
|
|
||||||
instance = this;
|
|
||||||
|
|
||||||
int visibility = ActiveServerProvider.Companion.isOffline(this) ? View.GONE : View.VISIBLE;
|
|
||||||
chatMenuItem.setVisibility(visibility);
|
|
||||||
bookmarksMenuItem.setVisibility(visibility);
|
|
||||||
sharesMenuItem.setVisibility(visibility);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onResume()
|
|
||||||
{
|
|
||||||
super.onResume();
|
|
||||||
Util.applyTheme(this);
|
|
||||||
instance = this;
|
|
||||||
|
|
||||||
Util.registerMediaButtonEventReceiver(this, false);
|
|
||||||
// Lifecycle support's constructor registers some event receivers so it should be created early
|
|
||||||
lifecycleSupport.getValue().onCreate();
|
|
||||||
|
|
||||||
// Make sure to update theme
|
|
||||||
if (theme != null && !theme.equals(Util.getTheme(this)))
|
|
||||||
{
|
|
||||||
theme = Util.getTheme(this);
|
|
||||||
restart();
|
|
||||||
}
|
|
||||||
|
|
||||||
// This must be filled here because onCreate is called before the derived objects would call setContentView
|
|
||||||
getNowPlayingView();
|
|
||||||
|
|
||||||
if (!nowPlayingHidden)
|
|
||||||
{
|
|
||||||
//showNowPlaying();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//hideNowPlaying();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onOptionsItemSelected(MenuItem item)
|
|
||||||
{
|
|
||||||
switch (item.getItemId())
|
|
||||||
{
|
|
||||||
case android.R.id.home:
|
|
||||||
menuDrawer.toggleMenu();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return super.onOptionsItemSelected(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onDestroy()
|
|
||||||
{
|
|
||||||
Util.unregisterMediaButtonEventReceiver(this, false);
|
|
||||||
super.onDestroy();
|
|
||||||
destroyed = true;
|
|
||||||
nowPlayingView = null;
|
|
||||||
imageLoader.getValue().clearImageLoader();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void restart()
|
|
||||||
{
|
|
||||||
Intent intent = new Intent(this, this.getClass());
|
|
||||||
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
|
||||||
intent.putExtras(getIntent());
|
|
||||||
startActivityForResultWithoutTransition(this, intent);
|
|
||||||
Timber.d("Restarting activity...");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void finish()
|
|
||||||
{
|
|
||||||
super.finish();
|
|
||||||
Util.disablePendingTransition(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isDestroyed()
|
|
||||||
{
|
|
||||||
return destroyed;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void getNowPlayingView()
|
|
||||||
{
|
|
||||||
if (nowPlayingView == null)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
nowPlayingView = findViewById(R.id.now_playing);
|
|
||||||
}
|
|
||||||
catch (Exception exception) {
|
|
||||||
Timber.w(exception, "An exception has occurred while trying to get the nowPlayingView by findViewById");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static SubsonicTabActivity getInstance()
|
|
||||||
{
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onRestoreInstanceState(Bundle inState)
|
|
||||||
{
|
|
||||||
super.onRestoreInstanceState(inState);
|
|
||||||
menuDrawer.restoreState(inState.getParcelable(STATE_MENUDRAWER));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onSaveInstanceState(Bundle outState)
|
|
||||||
{
|
|
||||||
super.onSaveInstanceState(outState);
|
|
||||||
outState.putParcelable(STATE_MENUDRAWER, menuDrawer.saveState());
|
|
||||||
outState.putInt(STATE_ACTIVE_VIEW_ID, menuActiveViewId);
|
|
||||||
outState.putInt(STATE_ACTIVE_POSITION, activePosition);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -0,0 +1,271 @@
|
|||||||
|
package org.moire.ultrasonic.fragment;
|
||||||
|
|
||||||
|
import android.media.audiofx.Equalizer;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.ContextMenu;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.CheckBox;
|
||||||
|
import android.widget.CompoundButton;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.SeekBar;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.lifecycle.Observer;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.moire.ultrasonic.R;
|
||||||
|
import org.moire.ultrasonic.audiofx.EqualizerController;
|
||||||
|
import org.moire.ultrasonic.util.Util;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import timber.log.Timber;
|
||||||
|
|
||||||
|
public class EqualizerFragment extends Fragment {
|
||||||
|
|
||||||
|
private static final int MENU_GROUP_PRESET = 100;
|
||||||
|
|
||||||
|
private final Map<Short, SeekBar> bars = new HashMap<>();
|
||||||
|
private EqualizerController equalizerController;
|
||||||
|
private Equalizer equalizer;
|
||||||
|
private LinearLayout equalizerLayout;
|
||||||
|
private View presetButton;
|
||||||
|
private CheckBox enabledCheckBox;
|
||||||
|
|
||||||
|
@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.equalizer, container, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||||
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
|
||||||
|
FragmentTitle.Companion.setTitle(this, R.string.equalizer_label);
|
||||||
|
equalizerLayout = view.findViewById(R.id.equalizer_layout);
|
||||||
|
presetButton = view.findViewById(R.id.equalizer_preset);
|
||||||
|
enabledCheckBox = view.findViewById(R.id.equalizer_enabled);
|
||||||
|
|
||||||
|
EqualizerController.get().observe(getViewLifecycleOwner(), new Observer<EqualizerController>() {
|
||||||
|
@Override
|
||||||
|
public void onChanged(EqualizerController controller) {
|
||||||
|
if (controller != null) {
|
||||||
|
Timber.d("EqualizerController Observer.onChanged received controller");
|
||||||
|
equalizerController = controller;
|
||||||
|
equalizer = controller.equalizer;
|
||||||
|
setup();
|
||||||
|
} else {
|
||||||
|
Timber.d("EqualizerController Observer.onChanged has no controller");
|
||||||
|
equalizerController = null;
|
||||||
|
equalizer = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPause()
|
||||||
|
{
|
||||||
|
super.onPause();
|
||||||
|
if (equalizerController == null) return;
|
||||||
|
equalizerController.saveSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreateContextMenu(@NotNull ContextMenu menu, @NotNull View view, ContextMenu.ContextMenuInfo menuInfo)
|
||||||
|
{
|
||||||
|
super.onCreateContextMenu(menu, view, menuInfo);
|
||||||
|
if (equalizer == null) return;
|
||||||
|
|
||||||
|
short currentPreset;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
currentPreset = equalizer.getCurrentPreset();
|
||||||
|
}
|
||||||
|
catch (Exception x)
|
||||||
|
{
|
||||||
|
currentPreset = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (short preset = 0; preset < equalizer.getNumberOfPresets(); preset++)
|
||||||
|
{
|
||||||
|
MenuItem menuItem = menu.add(MENU_GROUP_PRESET, preset, preset, equalizer.getPresetName(preset));
|
||||||
|
if (preset == currentPreset)
|
||||||
|
{
|
||||||
|
menuItem.setChecked(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
menu.setGroupCheckable(MENU_GROUP_PRESET, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onContextItemSelected(@NotNull MenuItem menuItem)
|
||||||
|
{
|
||||||
|
if (equalizer == null) return true;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
short preset = (short) menuItem.getItemId();
|
||||||
|
equalizer.usePreset(preset);
|
||||||
|
updateBars();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
//TODO: Show a dialog
|
||||||
|
Timber.i(ex, "An exception has occurred in EqualizerFragment onContextItemSelected");
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setup()
|
||||||
|
{
|
||||||
|
initEqualizer();
|
||||||
|
|
||||||
|
registerForContextMenu(presetButton);
|
||||||
|
presetButton.setOnClickListener(new View.OnClickListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void onClick(View view)
|
||||||
|
{
|
||||||
|
presetButton.showContextMenu();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
enabledCheckBox.setChecked(equalizer.getEnabled());
|
||||||
|
enabledCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void onCheckedChanged(CompoundButton compoundButton, boolean b)
|
||||||
|
{
|
||||||
|
setEqualizerEnabled(b);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setEqualizerEnabled(boolean enabled)
|
||||||
|
{
|
||||||
|
if (equalizer == null) return;
|
||||||
|
equalizer.setEnabled(enabled);
|
||||||
|
updateBars();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateBars()
|
||||||
|
{
|
||||||
|
if (equalizer == null) return;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
for (Map.Entry<Short, SeekBar> entry : bars.entrySet())
|
||||||
|
{
|
||||||
|
short band = entry.getKey();
|
||||||
|
SeekBar bar = entry.getValue();
|
||||||
|
bar.setEnabled(equalizer.getEnabled());
|
||||||
|
short minEQLevel = equalizer.getBandLevelRange()[0];
|
||||||
|
bar.setProgress(equalizer.getBandLevel(band) - minEQLevel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
//TODO: Show a dialog
|
||||||
|
Timber.i(ex, "An exception has occurred in EqualizerFragment updateBars");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initEqualizer()
|
||||||
|
{
|
||||||
|
if (equalizer == null) return;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
short[] bandLevelRange = equalizer.getBandLevelRange();
|
||||||
|
short numberOfBands = equalizer.getNumberOfBands();
|
||||||
|
|
||||||
|
final short minEQLevel = bandLevelRange[0];
|
||||||
|
final short maxEQLevel = bandLevelRange[1];
|
||||||
|
|
||||||
|
for (short i = 0; i < numberOfBands; i++)
|
||||||
|
{
|
||||||
|
final short band = i;
|
||||||
|
|
||||||
|
View bandBar = LayoutInflater.from(getContext()).inflate(R.layout.equalizer_bar, null);
|
||||||
|
TextView freqTextView;
|
||||||
|
|
||||||
|
if (bandBar != null)
|
||||||
|
{
|
||||||
|
freqTextView = (TextView) bandBar.findViewById(R.id.equalizer_frequency);
|
||||||
|
final TextView levelTextView = (TextView) bandBar.findViewById(R.id.equalizer_level);
|
||||||
|
SeekBar bar = (SeekBar) bandBar.findViewById(R.id.equalizer_bar);
|
||||||
|
|
||||||
|
freqTextView.setText((equalizer.getCenterFreq(band) / 1000) + " Hz");
|
||||||
|
|
||||||
|
bars.put(band, bar);
|
||||||
|
bar.setMax(maxEQLevel - minEQLevel);
|
||||||
|
short level = equalizer.getBandLevel(band);
|
||||||
|
bar.setProgress(level - minEQLevel);
|
||||||
|
bar.setEnabled(equalizer.getEnabled());
|
||||||
|
updateLevelText(levelTextView, level);
|
||||||
|
|
||||||
|
bar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
|
||||||
|
{
|
||||||
|
short level = (short) (progress + minEQLevel);
|
||||||
|
if (fromUser)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
equalizer.setBandLevel(band, level);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
//TODO: Show a dialog?
|
||||||
|
Timber.i(ex, "An exception has occurred in Equalizer onProgressChanged");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
updateLevelText(levelTextView, level);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStartTrackingTouch(SeekBar seekBar)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStopTrackingTouch(SeekBar seekBar)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
equalizerLayout.addView(bandBar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
//TODO: Show a dialog?
|
||||||
|
Timber.i(ex, "An exception has occurred while initializing Equalizer");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void updateLevelText(TextView levelTextView, short level)
|
||||||
|
{
|
||||||
|
if (levelTextView != null)
|
||||||
|
{
|
||||||
|
levelTextView.setText(String.format("%s%d dB", level > 0 ? "+" : "", level / 100));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -16,7 +16,6 @@ import androidx.fragment.app.Fragment;
|
|||||||
import androidx.navigation.Navigation;
|
import androidx.navigation.Navigation;
|
||||||
|
|
||||||
import org.moire.ultrasonic.R;
|
import org.moire.ultrasonic.R;
|
||||||
import org.moire.ultrasonic.activity.ServerSelectorActivity;
|
|
||||||
import org.moire.ultrasonic.data.ActiveServerProvider;
|
import org.moire.ultrasonic.data.ActiveServerProvider;
|
||||||
import org.moire.ultrasonic.data.ServerSetting;
|
import org.moire.ultrasonic.data.ServerSetting;
|
||||||
import org.moire.ultrasonic.util.Constants;
|
import org.moire.ultrasonic.util.Constants;
|
||||||
@ -265,14 +264,7 @@ public class MainFragment extends Fragment {
|
|||||||
|
|
||||||
private void showServers()
|
private void showServers()
|
||||||
{
|
{
|
||||||
final Intent intent = new Intent(getContext(), ServerSelectorActivity.class);
|
Navigation.findNavController(getView()).navigate(R.id.mainToServerSelector);
|
||||||
startActivityForResult(intent, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void startActivityForResultWithoutTransition(Activity currentActivity, Intent intent)
|
|
||||||
{
|
|
||||||
startActivityForResult(intent, 0);
|
|
||||||
Util.disablePendingTransition(currentActivity);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,7 +196,7 @@ public class NowPlayingFragment extends Fragment {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Navigation.findNavController(getView()).navigate(R.id.playerFragment);
|
Navigation.findNavController(getActivity(), R.id.nav_host_fragment).navigate(R.id.playerFragment);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@ package org.moire.ultrasonic.fragment;
|
|||||||
|
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
|
||||||
import android.graphics.Point;
|
import android.graphics.Point;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
@ -39,7 +38,6 @@ import com.mobeta.android.dslv.DragSortListView;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.koin.java.KoinJavaComponent;
|
import org.koin.java.KoinJavaComponent;
|
||||||
import org.moire.ultrasonic.R;
|
import org.moire.ultrasonic.R;
|
||||||
import org.moire.ultrasonic.activity.EqualizerActivity;
|
|
||||||
import org.moire.ultrasonic.audiofx.EqualizerController;
|
import org.moire.ultrasonic.audiofx.EqualizerController;
|
||||||
import org.moire.ultrasonic.audiofx.VisualizerController;
|
import org.moire.ultrasonic.audiofx.VisualizerController;
|
||||||
import org.moire.ultrasonic.data.ActiveServerProvider;
|
import org.moire.ultrasonic.data.ActiveServerProvider;
|
||||||
@ -960,7 +958,7 @@ public class PlayerFragment extends Fragment implements GestureDetector.OnGestur
|
|||||||
Util.toast(getContext(), R.string.download_menu_shuffle_notification);
|
Util.toast(getContext(), R.string.download_menu_shuffle_notification);
|
||||||
return true;
|
return true;
|
||||||
case R.id.menu_item_equalizer:
|
case R.id.menu_item_equalizer:
|
||||||
startActivity(new Intent(getContext(), EqualizerActivity.class));
|
Navigation.findNavController(getView()).navigate(R.id.playerToEqualizer);
|
||||||
return true;
|
return true;
|
||||||
case R.id.menu_item_visualizer:
|
case R.id.menu_item_visualizer:
|
||||||
final boolean active = !visualizerView.isActive();
|
final boolean active = !visualizerView.isActive();
|
||||||
|
@ -2,7 +2,6 @@ package org.moire.ultrasonic.fragment;
|
|||||||
|
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
@ -10,7 +9,7 @@ import android.provider.SearchRecentSuggestions;
|
|||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.annotation.StringRes;
|
import androidx.annotation.StringRes;
|
||||||
import androidx.fragment.app.DialogFragment;
|
import androidx.fragment.app.DialogFragment;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.navigation.Navigation;
|
||||||
import androidx.preference.CheckBoxPreference;
|
import androidx.preference.CheckBoxPreference;
|
||||||
import androidx.preference.EditTextPreference;
|
import androidx.preference.EditTextPreference;
|
||||||
import androidx.preference.ListPreference;
|
import androidx.preference.ListPreference;
|
||||||
@ -24,8 +23,6 @@ import android.view.View;
|
|||||||
|
|
||||||
import org.koin.java.KoinJavaComponent;
|
import org.koin.java.KoinJavaComponent;
|
||||||
import org.moire.ultrasonic.R;
|
import org.moire.ultrasonic.R;
|
||||||
import org.moire.ultrasonic.activity.ServerSelectorActivity;
|
|
||||||
import org.moire.ultrasonic.activity.SubsonicTabActivity;
|
|
||||||
import org.moire.ultrasonic.featureflags.Feature;
|
import org.moire.ultrasonic.featureflags.Feature;
|
||||||
import org.moire.ultrasonic.featureflags.FeatureStorage;
|
import org.moire.ultrasonic.featureflags.FeatureStorage;
|
||||||
import org.moire.ultrasonic.filepicker.FilePickerDialog;
|
import org.moire.ultrasonic.filepicker.FilePickerDialog;
|
||||||
@ -42,7 +39,7 @@ import java.io.File;
|
|||||||
import kotlin.Lazy;
|
import kotlin.Lazy;
|
||||||
|
|
||||||
import static org.koin.java.KoinJavaComponent.inject;
|
import static org.koin.java.KoinJavaComponent.inject;
|
||||||
import static org.moire.ultrasonic.activity.ServerSelectorActivity.SERVER_SELECTOR_MANAGE_MODE;
|
import static org.moire.ultrasonic.fragment.ServerSelectorFragment.SERVER_SELECTOR_MANAGE_MODE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shows main app settings.
|
* Shows main app settings.
|
||||||
@ -152,8 +149,10 @@ public class SettingsFragment extends PreferenceFragmentCompat
|
|||||||
// After API26 foreground services must be used for music playback, and they must have a notification
|
// After API26 foreground services must be used for music playback, and they must have a notification
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
PreferenceCategory notificationsCategory = findPreference(Constants.PREFERENCES_KEY_CATEGORY_NOTIFICATIONS);
|
PreferenceCategory notificationsCategory = findPreference(Constants.PREFERENCES_KEY_CATEGORY_NOTIFICATIONS);
|
||||||
notificationsCategory.removePreference(findPreference(Constants.PREFERENCES_KEY_SHOW_NOTIFICATION));
|
Preference preferenceToRemove = findPreference(Constants.PREFERENCES_KEY_SHOW_NOTIFICATION);
|
||||||
notificationsCategory.removePreference(findPreference(Constants.PREFERENCES_KEY_ALWAYS_SHOW_NOTIFICATION));
|
if (preferenceToRemove != null) notificationsCategory.removePreference(preferenceToRemove);
|
||||||
|
preferenceToRemove = findPreference(Constants.PREFERENCES_KEY_ALWAYS_SHOW_NOTIFICATION);
|
||||||
|
if (preferenceToRemove != null) notificationsCategory.removePreference(preferenceToRemove);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -416,9 +415,9 @@ public class SettingsFragment extends PreferenceFragmentCompat
|
|||||||
addServerPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
|
addServerPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public boolean onPreferenceClick(Preference preference) {
|
public boolean onPreferenceClick(Preference preference) {
|
||||||
final Intent intent = new Intent(getActivity(), ServerSelectorActivity.class);
|
Bundle bundle = new Bundle();
|
||||||
intent.putExtra(SERVER_SELECTOR_MANAGE_MODE, true);
|
bundle.putBoolean(SERVER_SELECTOR_MANAGE_MODE, true);
|
||||||
startActivityForResult(intent, 0);
|
Navigation.findNavController(getView()).navigate(R.id.settingsToServerSelector, bundle);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -470,9 +469,6 @@ public class SettingsFragment extends PreferenceFragmentCompat
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void setImageLoaderConcurrency(int concurrency) {
|
private void setImageLoaderConcurrency(int concurrency) {
|
||||||
SubsonicTabActivity instance = SubsonicTabActivity.getInstance();
|
|
||||||
|
|
||||||
if (instance != null) {
|
|
||||||
ImageLoader imageLoaderInstance = imageLoader.getValue().getImageLoader();
|
ImageLoader imageLoaderInstance = imageLoader.getValue().getImageLoader();
|
||||||
|
|
||||||
if (imageLoaderInstance != null) {
|
if (imageLoaderInstance != null) {
|
||||||
@ -480,7 +476,6 @@ public class SettingsFragment extends PreferenceFragmentCompat
|
|||||||
imageLoaderInstance.setConcurrency(concurrency);
|
imageLoaderInstance.setConcurrency(concurrency);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private void setHideMedia(boolean hide) {
|
private void setHideMedia(boolean hide) {
|
||||||
File nomediaDir = new File(FileUtil.getUltrasonicDirectory(getActivity()), ".nomedia");
|
File nomediaDir = new File(FileUtil.getUltrasonicDirectory(getActivity()), ".nomedia");
|
||||||
|
@ -21,7 +21,6 @@ import androidx.core.app.NotificationManagerCompat;
|
|||||||
import org.koin.java.KoinJavaComponent;
|
import org.koin.java.KoinJavaComponent;
|
||||||
import org.moire.ultrasonic.R;
|
import org.moire.ultrasonic.R;
|
||||||
import org.moire.ultrasonic.activity.NavigationActivity;
|
import org.moire.ultrasonic.activity.NavigationActivity;
|
||||||
import org.moire.ultrasonic.activity.SubsonicTabActivity;
|
|
||||||
import org.moire.ultrasonic.domain.MusicDirectory;
|
import org.moire.ultrasonic.domain.MusicDirectory;
|
||||||
import org.moire.ultrasonic.domain.PlayerState;
|
import org.moire.ultrasonic.domain.PlayerState;
|
||||||
import org.moire.ultrasonic.domain.RepeatMode;
|
import org.moire.ultrasonic.domain.RepeatMode;
|
||||||
|
@ -28,7 +28,6 @@ import android.text.TextUtils;
|
|||||||
import kotlin.Lazy;
|
import kotlin.Lazy;
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
||||||
import org.moire.ultrasonic.activity.SubsonicTabActivity;
|
|
||||||
import org.moire.ultrasonic.domain.MusicDirectory;
|
import org.moire.ultrasonic.domain.MusicDirectory;
|
||||||
import org.moire.ultrasonic.subsonic.ImageLoaderProvider;
|
import org.moire.ultrasonic.subsonic.ImageLoaderProvider;
|
||||||
|
|
||||||
@ -156,19 +155,15 @@ public class FileUtil
|
|||||||
|
|
||||||
File avatarFile = getAvatarFile(context, username);
|
File avatarFile = getAvatarFile(context, username);
|
||||||
|
|
||||||
SubsonicTabActivity subsonicTabActivity = SubsonicTabActivity.getInstance();
|
|
||||||
Bitmap bitmap = null;
|
Bitmap bitmap = null;
|
||||||
ImageLoader imageLoader = null;
|
ImageLoader imageLoader = null;
|
||||||
|
|
||||||
if (subsonicTabActivity != null)
|
|
||||||
{
|
|
||||||
imageLoader = imageLoaderProvider.getValue().getImageLoader();
|
imageLoader = imageLoaderProvider.getValue().getImageLoader();
|
||||||
|
|
||||||
if (imageLoader != null)
|
if (imageLoader != null)
|
||||||
{
|
{
|
||||||
bitmap = imageLoader.getImageBitmap(username, size);
|
bitmap = imageLoader.getImageBitmap(username, size);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (bitmap != null)
|
if (bitmap != null)
|
||||||
{
|
{
|
||||||
@ -226,19 +221,15 @@ public class FileUtil
|
|||||||
|
|
||||||
File albumArtFile = getAlbumArtFile(context, entry);
|
File albumArtFile = getAlbumArtFile(context, entry);
|
||||||
|
|
||||||
SubsonicTabActivity subsonicTabActivity = SubsonicTabActivity.getInstance();
|
|
||||||
Bitmap bitmap = null;
|
Bitmap bitmap = null;
|
||||||
ImageLoader imageLoader = null;
|
ImageLoader imageLoader = null;
|
||||||
|
|
||||||
if (subsonicTabActivity != null)
|
|
||||||
{
|
|
||||||
imageLoader = imageLoaderProvider.getValue().getImageLoader();
|
imageLoader = imageLoaderProvider.getValue().getImageLoader();
|
||||||
|
|
||||||
if (imageLoader != null)
|
if (imageLoader != null)
|
||||||
{
|
{
|
||||||
bitmap = imageLoader.getImageBitmap(entry, true, size);
|
bitmap = imageLoader.getImageBitmap(entry, true, size);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (bitmap != null)
|
if (bitmap != null)
|
||||||
{
|
{
|
||||||
|
@ -2,14 +2,9 @@ package org.moire.ultrasonic.util;
|
|||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.ProgressDialog;
|
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.os.Build;
|
|
||||||
|
|
||||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||||
|
|
||||||
import org.moire.ultrasonic.activity.SubsonicTabActivity;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Sindre Mehus
|
* @author Sindre Mehus
|
||||||
* @version $Id$
|
* @version $Id$
|
||||||
|
@ -31,6 +31,7 @@ import org.koin.android.viewmodel.ext.android.viewModel
|
|||||||
import org.moire.ultrasonic.R
|
import org.moire.ultrasonic.R
|
||||||
import org.moire.ultrasonic.data.ActiveServerProvider.Companion.isOffline
|
import org.moire.ultrasonic.data.ActiveServerProvider.Companion.isOffline
|
||||||
import org.moire.ultrasonic.domain.PlayerState
|
import org.moire.ultrasonic.domain.PlayerState
|
||||||
|
import org.moire.ultrasonic.fragment.ServerSettingsModel
|
||||||
import org.moire.ultrasonic.provider.SearchSuggestionProvider
|
import org.moire.ultrasonic.provider.SearchSuggestionProvider
|
||||||
import org.moire.ultrasonic.service.DownloadFile
|
import org.moire.ultrasonic.service.DownloadFile
|
||||||
import org.moire.ultrasonic.service.MediaPlayerController
|
import org.moire.ultrasonic.service.MediaPlayerController
|
||||||
@ -111,7 +112,7 @@ class NavigationActivity : AppCompatActivity() {
|
|||||||
if (currentFragmentId == R.id.playerFragment) {
|
if (currentFragmentId == R.id.playerFragment) {
|
||||||
hideNowPlaying()
|
hideNowPlaying()
|
||||||
} else {
|
} else {
|
||||||
showNowPlaying()
|
if (!nowPlayingHidden) showNowPlaying()
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Maybe we can find a better place for theme change. Currently the change occurs when navigating between fragments
|
// TODO: Maybe we can find a better place for theme change. Currently the change occurs when navigating between fragments
|
||||||
@ -136,7 +137,6 @@ class NavigationActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
nowPlayingEventListener = object : NowPlayingEventListener {
|
nowPlayingEventListener = object : NowPlayingEventListener {
|
||||||
override fun onDismissNowPlaying() {
|
override fun onDismissNowPlaying() {
|
||||||
// TODO: When will it be set back to false?
|
|
||||||
nowPlayingHidden = true;
|
nowPlayingHidden = true;
|
||||||
hideNowPlaying();
|
hideNowPlaying();
|
||||||
}
|
}
|
||||||
@ -164,11 +164,8 @@ class NavigationActivity : AppCompatActivity() {
|
|||||||
// Lifecycle support's constructor registers some event receivers so it should be created early
|
// Lifecycle support's constructor registers some event receivers so it should be created early
|
||||||
lifecycleSupport.onCreate()
|
lifecycleSupport.onCreate()
|
||||||
|
|
||||||
if (!nowPlayingHidden) {
|
if (!nowPlayingHidden) showNowPlaying()
|
||||||
showNowPlaying()
|
else hideNowPlaying()
|
||||||
} else {
|
|
||||||
hideNowPlaying()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
@ -297,11 +294,14 @@ class NavigationActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun showNowPlaying() {
|
private fun showNowPlaying() {
|
||||||
if (!Util.getShowNowPlayingPreference(this) || nowPlayingHidden) {
|
if (!Util.getShowNowPlayingPreference(this)) {
|
||||||
hideNowPlaying()
|
hideNowPlaying()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The logic for nowPlayingHidden is that the user can dismiss NowPlaying with a gesture,
|
||||||
|
// and when the MediaPlayerService requests that it should be shown, it returns
|
||||||
|
nowPlayingHidden = false;
|
||||||
// Do not show for Player fragment
|
// Do not show for Player fragment
|
||||||
if (currentFragmentId == R.id.playerFragment) {
|
if (currentFragmentId == R.id.playerFragment) {
|
||||||
hideNowPlaying()
|
hideNowPlaying()
|
||||||
|
@ -5,11 +5,9 @@ import org.koin.android.ext.koin.androidContext
|
|||||||
import org.koin.android.viewmodel.dsl.viewModel
|
import org.koin.android.viewmodel.dsl.viewModel
|
||||||
import org.koin.core.qualifier.named
|
import org.koin.core.qualifier.named
|
||||||
import org.koin.dsl.module
|
import org.koin.dsl.module
|
||||||
import org.moire.ultrasonic.activity.ServerSettingsModel
|
import org.moire.ultrasonic.fragment.ServerSettingsModel
|
||||||
import org.moire.ultrasonic.data.ActiveServerProvider
|
|
||||||
import org.moire.ultrasonic.data.AppDatabase
|
import org.moire.ultrasonic.data.AppDatabase
|
||||||
import org.moire.ultrasonic.data.MIGRATION_1_2
|
import org.moire.ultrasonic.data.MIGRATION_1_2
|
||||||
import org.moire.ultrasonic.subsonic.ImageLoaderProvider
|
|
||||||
import org.moire.ultrasonic.util.Util
|
import org.moire.ultrasonic.util.Util
|
||||||
|
|
||||||
const val SP_NAME = "Default_SP"
|
const val SP_NAME = "Default_SP"
|
||||||
|
@ -8,7 +8,7 @@ import org.koin.android.viewmodel.dsl.viewModel
|
|||||||
import org.koin.core.qualifier.named
|
import org.koin.core.qualifier.named
|
||||||
import org.koin.dsl.module
|
import org.koin.dsl.module
|
||||||
import org.moire.ultrasonic.BuildConfig
|
import org.moire.ultrasonic.BuildConfig
|
||||||
import org.moire.ultrasonic.activity.ArtistListModel
|
import org.moire.ultrasonic.fragment.ArtistListModel
|
||||||
import org.moire.ultrasonic.api.subsonic.SubsonicAPIClient
|
import org.moire.ultrasonic.api.subsonic.SubsonicAPIClient
|
||||||
import org.moire.ultrasonic.api.subsonic.SubsonicAPIVersions
|
import org.moire.ultrasonic.api.subsonic.SubsonicAPIVersions
|
||||||
import org.moire.ultrasonic.api.subsonic.SubsonicClientConfiguration
|
import org.moire.ultrasonic.api.subsonic.SubsonicClientConfiguration
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
Copyright 2020 (C) Jozsef Varga
|
Copyright 2020 (C) Jozsef Varga
|
||||||
*/
|
*/
|
||||||
package org.moire.ultrasonic.activity
|
package org.moire.ultrasonic.fragment
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.Handler
|
import android.os.Handler
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
Copyright 2020 (C) Jozsef Varga
|
Copyright 2020 (C) Jozsef Varga
|
||||||
*/
|
*/
|
||||||
package org.moire.ultrasonic.activity
|
package org.moire.ultrasonic.fragment
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.MenuInflater
|
import android.view.MenuInflater
|
@ -1,6 +0,0 @@
|
|||||||
package org.moire.ultrasonic.fragment
|
|
||||||
|
|
||||||
import androidx.fragment.app.Fragment
|
|
||||||
|
|
||||||
class DownloadFragment: Fragment() {
|
|
||||||
}
|
|
@ -1,16 +1,16 @@
|
|||||||
package org.moire.ultrasonic.activity
|
package org.moire.ultrasonic.fragment
|
||||||
|
|
||||||
import android.app.AlertDialog
|
import android.app.AlertDialog
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.MenuItem
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
import android.widget.Button
|
import android.widget.Button
|
||||||
import androidx.appcompat.app.ActionBar
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
|
||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
|
import androidx.navigation.fragment.findNavController
|
||||||
import com.google.android.material.switchmaterial.SwitchMaterial
|
import com.google.android.material.switchmaterial.SwitchMaterial
|
||||||
import com.google.android.material.textfield.TextInputLayout
|
import com.google.android.material.textfield.TextInputLayout
|
||||||
import java.net.MalformedURLException
|
|
||||||
import java.net.URL
|
|
||||||
import org.koin.android.ext.android.inject
|
import org.koin.android.ext.android.inject
|
||||||
import org.koin.android.viewmodel.ext.android.viewModel
|
import org.koin.android.viewmodel.ext.android.viewModel
|
||||||
import org.moire.ultrasonic.BuildConfig
|
import org.moire.ultrasonic.BuildConfig
|
||||||
@ -20,21 +20,17 @@ import org.moire.ultrasonic.api.subsonic.SubsonicAPIVersions
|
|||||||
import org.moire.ultrasonic.api.subsonic.SubsonicClientConfiguration
|
import org.moire.ultrasonic.api.subsonic.SubsonicClientConfiguration
|
||||||
import org.moire.ultrasonic.data.ActiveServerProvider
|
import org.moire.ultrasonic.data.ActiveServerProvider
|
||||||
import org.moire.ultrasonic.data.ServerSetting
|
import org.moire.ultrasonic.data.ServerSetting
|
||||||
import org.moire.ultrasonic.service.ApiCallResponseChecker.Companion.checkResponseSuccessful
|
import org.moire.ultrasonic.service.ApiCallResponseChecker
|
||||||
import org.moire.ultrasonic.service.MusicServiceFactory
|
import org.moire.ultrasonic.service.MusicServiceFactory
|
||||||
import org.moire.ultrasonic.util.Constants
|
import org.moire.ultrasonic.util.Constants
|
||||||
import org.moire.ultrasonic.util.ErrorDialog
|
import org.moire.ultrasonic.util.ErrorDialog
|
||||||
import org.moire.ultrasonic.util.ModalBackgroundTask
|
import org.moire.ultrasonic.util.ModalBackgroundTask
|
||||||
import org.moire.ultrasonic.util.Util
|
import org.moire.ultrasonic.util.Util
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
import java.net.MalformedURLException
|
||||||
|
import java.net.URL
|
||||||
|
|
||||||
/**
|
class EditServerFragment: Fragment() {
|
||||||
* This Activity provides a Form which can be used to edit the properties of a Server Setting.
|
|
||||||
* It can also be used to create a Server Setting from scratch.
|
|
||||||
* Contains functions for testing the configured Server Setting
|
|
||||||
*/
|
|
||||||
internal class EditServerActivity : AppCompatActivity() {
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val EDIT_SERVER_INTENT_INDEX = "index"
|
const val EDIT_SERVER_INTENT_INDEX = "index"
|
||||||
}
|
}
|
||||||
@ -55,32 +51,41 @@ internal class EditServerActivity : AppCompatActivity() {
|
|||||||
private var testButton: Button? = null
|
private var testButton: Button? = null
|
||||||
private var isInstanceStateSaved: Boolean = false
|
private var isInstanceStateSaved: Boolean = false
|
||||||
|
|
||||||
|
@Override
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
Util.applyTheme(this.context)
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
}
|
||||||
|
|
||||||
Util.applyTheme(this)
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||||
if (savedInstanceState == null) configureActionBar()
|
savedInstanceState: Bundle?): View? {
|
||||||
|
return inflater.inflate(R.layout.server_edit, container, false)
|
||||||
|
}
|
||||||
|
|
||||||
setContentView(R.layout.server_edit)
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
serverNameEditText = findViewById(R.id.edit_server_name)
|
serverNameEditText = view.findViewById(R.id.edit_server_name)
|
||||||
serverAddressEditText = findViewById(R.id.edit_server_address)
|
serverAddressEditText = view.findViewById(R.id.edit_server_address)
|
||||||
userNameEditText = findViewById(R.id.edit_server_username)
|
userNameEditText = view.findViewById(R.id.edit_server_username)
|
||||||
passwordEditText = findViewById(R.id.edit_server_password)
|
passwordEditText = view.findViewById(R.id.edit_server_password)
|
||||||
selfSignedSwitch = findViewById(R.id.edit_self_signed)
|
selfSignedSwitch = view.findViewById(R.id.edit_self_signed)
|
||||||
ldapSwitch = findViewById(R.id.edit_ldap)
|
ldapSwitch = view.findViewById(R.id.edit_ldap)
|
||||||
jukeboxSwitch = findViewById(R.id.edit_jukebox)
|
jukeboxSwitch = view.findViewById(R.id.edit_jukebox)
|
||||||
saveButton = findViewById(R.id.edit_save)
|
saveButton = view.findViewById(R.id.edit_save)
|
||||||
testButton = findViewById(R.id.edit_test)
|
testButton = view.findViewById(R.id.edit_test)
|
||||||
|
|
||||||
val index = intent.getIntExtra(EDIT_SERVER_INTENT_INDEX, -1)
|
val index = arguments?.getInt(
|
||||||
|
EDIT_SERVER_INTENT_INDEX,
|
||||||
|
-1
|
||||||
|
) ?: -1
|
||||||
|
|
||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
// Editing an existing server
|
// Editing an existing server
|
||||||
setTitle(R.string.server_editor_label)
|
FragmentTitle.setTitle(this, R.string.server_editor_label)
|
||||||
val serverSetting = serverSettingsModel.getServerSetting(index)
|
val serverSetting = serverSettingsModel.getServerSetting(index)
|
||||||
serverSetting.observe(
|
serverSetting.observe(
|
||||||
this,
|
viewLifecycleOwner,
|
||||||
Observer { t ->
|
Observer { t ->
|
||||||
if (t != null) {
|
if (t != null) {
|
||||||
currentServerSetting = t
|
currentServerSetting = t
|
||||||
@ -110,18 +115,18 @@ internal class EditServerActivity : AppCompatActivity() {
|
|||||||
) {
|
) {
|
||||||
MusicServiceFactory.resetMusicService()
|
MusicServiceFactory.resetMusicService()
|
||||||
}
|
}
|
||||||
finish()
|
findNavController().navigateUp()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Creating a new server
|
// Creating a new server
|
||||||
setTitle(R.string.server_editor_new_label)
|
FragmentTitle.setTitle(this, R.string.server_editor_new_label)
|
||||||
currentServerSetting = ServerSetting()
|
currentServerSetting = ServerSetting()
|
||||||
saveButton!!.setOnClickListener {
|
saveButton!!.setOnClickListener {
|
||||||
if (getFields()) {
|
if (getFields()) {
|
||||||
serverSettingsModel.saveNewItem(currentServerSetting)
|
serverSettingsModel.saveNewItem(currentServerSetting)
|
||||||
finish()
|
findNavController().navigateUp()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -162,8 +167,10 @@ internal class EditServerActivity : AppCompatActivity() {
|
|||||||
super.onSaveInstanceState(savedInstanceState)
|
super.onSaveInstanceState(savedInstanceState)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onRestoreInstanceState(savedInstanceState: Bundle) {
|
override fun onViewStateRestored(savedInstanceState: Bundle?) {
|
||||||
super.onRestoreInstanceState(savedInstanceState)
|
super.onViewStateRestored(savedInstanceState)
|
||||||
|
|
||||||
|
if (savedInstanceState == null) return
|
||||||
|
|
||||||
serverNameEditText!!.editText?.setText(
|
serverNameEditText!!.editText?.setText(
|
||||||
savedInstanceState.getString(::serverNameEditText.name)
|
savedInstanceState.getString(::serverNameEditText.name)
|
||||||
@ -183,26 +190,6 @@ internal class EditServerActivity : AppCompatActivity() {
|
|||||||
isInstanceStateSaved = savedInstanceState.getBoolean(::isInstanceStateSaved.name)
|
isInstanceStateSaved = savedInstanceState.getBoolean(::isInstanceStateSaved.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
|
||||||
if (item.itemId == android.R.id.home) {
|
|
||||||
finishActivity()
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return super.onOptionsItemSelected(item)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onBackPressed() {
|
|
||||||
finishActivity()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun configureActionBar() {
|
|
||||||
val actionBar: ActionBar? = supportActionBar
|
|
||||||
if (actionBar != null) {
|
|
||||||
actionBar.setDisplayShowHomeEnabled(true)
|
|
||||||
actionBar.setDisplayHomeAsUpEnabled(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the values of the Form from the current Server Setting instance
|
* Sets the values of the Form from the current Server Setting instance
|
||||||
*/
|
*/
|
||||||
@ -299,7 +286,7 @@ internal class EditServerActivity : AppCompatActivity() {
|
|||||||
*/
|
*/
|
||||||
private fun testConnection() {
|
private fun testConnection() {
|
||||||
val task: ModalBackgroundTask<Boolean> = object : ModalBackgroundTask<Boolean>(
|
val task: ModalBackgroundTask<Boolean> = object : ModalBackgroundTask<Boolean>(
|
||||||
this,
|
activity,
|
||||||
false
|
false
|
||||||
) {
|
) {
|
||||||
|
|
||||||
@ -331,10 +318,10 @@ internal class EditServerActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
// Execute a ping to check the authentication, now using the correct API version.
|
// Execute a ping to check the authentication, now using the correct API version.
|
||||||
pingResponse = subsonicApiClient.api.ping().execute()
|
pingResponse = subsonicApiClient.api.ping().execute()
|
||||||
checkResponseSuccessful(pingResponse)
|
ApiCallResponseChecker.checkResponseSuccessful(pingResponse)
|
||||||
|
|
||||||
val licenseResponse = subsonicApiClient.api.getLicense().execute()
|
val licenseResponse = subsonicApiClient.api.getLicense().execute()
|
||||||
checkResponseSuccessful(licenseResponse)
|
ApiCallResponseChecker.checkResponseSuccessful(licenseResponse)
|
||||||
return licenseResponse.body()!!.license.valid
|
return licenseResponse.body()!!.license.valid
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -367,20 +354,20 @@ internal class EditServerActivity : AppCompatActivity() {
|
|||||||
*/
|
*/
|
||||||
private fun finishActivity() {
|
private fun finishActivity() {
|
||||||
if (areFieldsChanged()) {
|
if (areFieldsChanged()) {
|
||||||
AlertDialog.Builder(this)
|
AlertDialog.Builder(context)
|
||||||
.setIcon(android.R.drawable.ic_dialog_alert)
|
.setIcon(android.R.drawable.ic_dialog_alert)
|
||||||
.setTitle(R.string.common_confirm)
|
.setTitle(R.string.common_confirm)
|
||||||
.setMessage(R.string.server_editor_leave_confirmation)
|
.setMessage(R.string.server_editor_leave_confirmation)
|
||||||
.setPositiveButton(R.string.common_ok) { dialog, _ ->
|
.setPositiveButton(R.string.common_ok) { dialog, _ ->
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
finish()
|
findNavController().navigateUp()
|
||||||
}
|
}
|
||||||
.setNegativeButton(R.string.common_cancel) { dialog, _ ->
|
.setNegativeButton(R.string.common_cancel) { dialog, _ ->
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
}
|
}
|
||||||
.show()
|
.show()
|
||||||
} else {
|
} else {
|
||||||
finish()
|
findNavController().navigateUp()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -15,9 +15,6 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
|||||||
import org.koin.android.ext.android.inject
|
import org.koin.android.ext.android.inject
|
||||||
import org.koin.android.viewmodel.ext.android.viewModel
|
import org.koin.android.viewmodel.ext.android.viewModel
|
||||||
import org.moire.ultrasonic.R
|
import org.moire.ultrasonic.R
|
||||||
import org.moire.ultrasonic.activity.ArtistListModel
|
|
||||||
import org.moire.ultrasonic.activity.ArtistRowAdapter
|
|
||||||
import org.moire.ultrasonic.activity.ServerSettingsModel
|
|
||||||
import org.moire.ultrasonic.data.ActiveServerProvider
|
import org.moire.ultrasonic.data.ActiveServerProvider
|
||||||
import org.moire.ultrasonic.domain.Artist
|
import org.moire.ultrasonic.domain.Artist
|
||||||
import org.moire.ultrasonic.domain.MusicFolder
|
import org.moire.ultrasonic.domain.MusicFolder
|
||||||
@ -40,9 +37,6 @@ class SelectArtistFragment : Fragment() {
|
|||||||
private lateinit var viewManager: RecyclerView.LayoutManager
|
private lateinit var viewManager: RecyclerView.LayoutManager
|
||||||
private lateinit var viewAdapter: ArtistRowAdapter
|
private lateinit var viewAdapter: ArtistRowAdapter
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when the activity is first created.
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
Util.applyTheme(this.context)
|
Util.applyTheme(this.context)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package org.moire.ultrasonic.activity
|
package org.moire.ultrasonic.fragment
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
@ -1,14 +1,15 @@
|
|||||||
package org.moire.ultrasonic.activity
|
package org.moire.ultrasonic.fragment
|
||||||
|
|
||||||
import android.app.AlertDialog
|
import android.app.AlertDialog
|
||||||
import android.content.Intent
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.MenuItem
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
import android.widget.AdapterView
|
import android.widget.AdapterView
|
||||||
import android.widget.ListView
|
import android.widget.ListView
|
||||||
import androidx.appcompat.app.ActionBar
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
|
||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
|
import androidx.navigation.fragment.findNavController
|
||||||
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
@ -16,21 +17,13 @@ import kotlinx.coroutines.withContext
|
|||||||
import org.koin.android.ext.android.inject
|
import org.koin.android.ext.android.inject
|
||||||
import org.koin.android.viewmodel.ext.android.viewModel
|
import org.koin.android.viewmodel.ext.android.viewModel
|
||||||
import org.moire.ultrasonic.R
|
import org.moire.ultrasonic.R
|
||||||
import org.moire.ultrasonic.activity.EditServerActivity.Companion.EDIT_SERVER_INTENT_INDEX
|
|
||||||
import org.moire.ultrasonic.data.ActiveServerProvider
|
import org.moire.ultrasonic.data.ActiveServerProvider
|
||||||
|
import org.moire.ultrasonic.fragment.EditServerFragment.Companion.EDIT_SERVER_INTENT_INDEX
|
||||||
import org.moire.ultrasonic.service.MediaPlayerController
|
import org.moire.ultrasonic.service.MediaPlayerController
|
||||||
import org.moire.ultrasonic.util.Util
|
import org.moire.ultrasonic.util.Util
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
||||||
/**
|
class ServerSelectorFragment: Fragment() {
|
||||||
* This Activity can be used to display all the configured Server Setting items.
|
|
||||||
* It also contains a FAB to add a new server.
|
|
||||||
* It has a Manage Mode and a Select Mode. In Select Mode, clicking the List Items will select
|
|
||||||
* the server, and a server can be edited using the context menu. In Manage Mode the default
|
|
||||||
* action when a List Item is clicked is to edit the server.
|
|
||||||
*/
|
|
||||||
internal class ServerSelectorActivity : AppCompatActivity() {
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val SERVER_SELECTOR_MANAGE_MODE = "manageMode"
|
const val SERVER_SELECTOR_MANAGE_MODE = "manageMode"
|
||||||
}
|
}
|
||||||
@ -41,24 +34,33 @@ internal class ServerSelectorActivity : AppCompatActivity() {
|
|||||||
private val activeServerProvider: ActiveServerProvider by inject()
|
private val activeServerProvider: ActiveServerProvider by inject()
|
||||||
private var serverRowAdapter: ServerRowAdapter? = null
|
private var serverRowAdapter: ServerRowAdapter? = null
|
||||||
|
|
||||||
|
@Override
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
Util.applyTheme(this.context)
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
Util.applyTheme(this)
|
|
||||||
if (savedInstanceState == null) configureActionBar()
|
|
||||||
|
|
||||||
setContentView(R.layout.server_selector)
|
|
||||||
|
|
||||||
val manageMode = intent.getBooleanExtra(SERVER_SELECTOR_MANAGE_MODE, false)
|
|
||||||
if (manageMode) {
|
|
||||||
setTitle(R.string.settings_server_manage_servers)
|
|
||||||
} else {
|
|
||||||
setTitle(R.string.server_selector_label)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
listView = findViewById(R.id.server_list)
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?): View? {
|
||||||
|
return inflater.inflate(R.layout.server_selector, container, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
|
val manageMode = arguments?.getBoolean(
|
||||||
|
SERVER_SELECTOR_MANAGE_MODE,
|
||||||
|
false
|
||||||
|
) ?: false
|
||||||
|
if (manageMode) {
|
||||||
|
FragmentTitle.setTitle(this, R.string.settings_server_manage_servers)
|
||||||
|
} else {
|
||||||
|
FragmentTitle.setTitle(this, R.string.server_selector_label)
|
||||||
|
}
|
||||||
|
|
||||||
|
listView = view.findViewById(R.id.server_list)
|
||||||
serverRowAdapter = ServerRowAdapter(
|
serverRowAdapter = ServerRowAdapter(
|
||||||
this,
|
view.context,
|
||||||
arrayOf(),
|
arrayOf(),
|
||||||
serverSettingsModel,
|
serverSettingsModel,
|
||||||
activeServerProvider,
|
activeServerProvider,
|
||||||
@ -81,24 +83,16 @@ internal class ServerSelectorActivity : AppCompatActivity() {
|
|||||||
editServer(position + 1)
|
editServer(position + 1)
|
||||||
} else {
|
} else {
|
||||||
setActiveServer(position)
|
setActiveServer(position)
|
||||||
finish()
|
findNavController().navigateUp()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val fab = findViewById<FloatingActionButton>(R.id.server_add_fab)
|
val fab = view.findViewById<FloatingActionButton>(R.id.server_add_fab)
|
||||||
fab.setOnClickListener {
|
fab.setOnClickListener {
|
||||||
editServer(-1)
|
editServer(-1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
|
||||||
if (item.itemId == android.R.id.home) {
|
|
||||||
finish()
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return super.onOptionsItemSelected(item)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
val serverList = serverSettingsModel.getServerList()
|
val serverList = serverSettingsModel.getServerList()
|
||||||
@ -110,14 +104,6 @@ internal class ServerSelectorActivity : AppCompatActivity() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun configureActionBar() {
|
|
||||||
val actionBar: ActionBar? = supportActionBar
|
|
||||||
if (actionBar != null) {
|
|
||||||
actionBar.setDisplayShowHomeEnabled(true)
|
|
||||||
actionBar.setDisplayHomeAsUpEnabled(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the active server when a list item is clicked
|
* Sets the active server when a list item is clicked
|
||||||
*/
|
*/
|
||||||
@ -141,7 +127,7 @@ internal class ServerSelectorActivity : AppCompatActivity() {
|
|||||||
* This Callback handles the deletion of a Server Setting
|
* This Callback handles the deletion of a Server Setting
|
||||||
*/
|
*/
|
||||||
private fun onServerDeleted(index: Int) {
|
private fun onServerDeleted(index: Int) {
|
||||||
AlertDialog.Builder(this)
|
AlertDialog.Builder(context)
|
||||||
.setIcon(android.R.drawable.ic_dialog_alert)
|
.setIcon(android.R.drawable.ic_dialog_alert)
|
||||||
.setTitle(R.string.server_menu_delete)
|
.setTitle(R.string.server_menu_delete)
|
||||||
.setMessage(R.string.server_selector_delete_confirmation)
|
.setMessage(R.string.server_selector_delete_confirmation)
|
||||||
@ -162,11 +148,11 @@ internal class ServerSelectorActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts the Edit Server Activity to edit the details of a server
|
* Starts the Edit Server Fragment to edit the details of a server
|
||||||
*/
|
*/
|
||||||
private fun editServer(index: Int) {
|
private fun editServer(index: Int) {
|
||||||
val intent = Intent(this, EditServerActivity::class.java)
|
val bundle = Bundle()
|
||||||
intent.putExtra(EDIT_SERVER_INTENT_INDEX, index)
|
bundle.putInt(EDIT_SERVER_INTENT_INDEX, index)
|
||||||
startActivityForResult(intent, 0)
|
findNavController().navigate(R.id.serverSelectorToEditServer, bundle)
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package org.moire.ultrasonic.activity
|
package org.moire.ultrasonic.fragment
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
@ -13,6 +13,9 @@
|
|||||||
<action
|
<action
|
||||||
android:id="@+id/mainToSelectGenre"
|
android:id="@+id/mainToSelectGenre"
|
||||||
app:destination="@id/selectGenreFragment" />
|
app:destination="@id/selectGenreFragment" />
|
||||||
|
<action
|
||||||
|
android:id="@+id/mainToServerSelector"
|
||||||
|
app:destination="@id/serverSelectorFragment" />
|
||||||
</fragment>
|
</fragment>
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/selectArtistFragment"
|
android:id="@+id/selectArtistFragment"
|
||||||
@ -62,7 +65,11 @@
|
|||||||
</fragment>
|
</fragment>
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/settingsFragment"
|
android:id="@+id/settingsFragment"
|
||||||
android:name="org.moire.ultrasonic.fragment.SettingsFragment" />
|
android:name="org.moire.ultrasonic.fragment.SettingsFragment" >
|
||||||
|
<action
|
||||||
|
android:id="@+id/settingsToServerSelector"
|
||||||
|
app:destination="@id/serverSelectorFragment" />
|
||||||
|
</fragment>
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/aboutFragment"
|
android:id="@+id/aboutFragment"
|
||||||
android:name="org.moire.ultrasonic.fragment.AboutFragment" />
|
android:name="org.moire.ultrasonic.fragment.AboutFragment" />
|
||||||
@ -78,8 +85,24 @@
|
|||||||
<action
|
<action
|
||||||
android:id="@+id/playerToLyrics"
|
android:id="@+id/playerToLyrics"
|
||||||
app:destination="@id/lyricsFragment" />
|
app:destination="@id/lyricsFragment" />
|
||||||
|
<action
|
||||||
|
android:id="@+id/playerToEqualizer"
|
||||||
|
app:destination="@id/equalizerFragment" />
|
||||||
</fragment>
|
</fragment>
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/lyricsFragment"
|
android:id="@+id/lyricsFragment"
|
||||||
android:name="org.moire.ultrasonic.fragment.LyricsFragment" />
|
android:name="org.moire.ultrasonic.fragment.LyricsFragment" />
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/equalizerFragment"
|
||||||
|
android:name="org.moire.ultrasonic.fragment.EqualizerFragment" />
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/serverSelectorFragment"
|
||||||
|
android:name="org.moire.ultrasonic.fragment.ServerSelectorFragment" >
|
||||||
|
<action
|
||||||
|
android:id="@+id/serverSelectorToEditServer"
|
||||||
|
app:destination="@id/editServerFragment" />
|
||||||
|
</fragment>
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/editServerFragment"
|
||||||
|
android:name="org.moire.ultrasonic.fragment.EditServerFragment" />
|
||||||
</navigation>
|
</navigation>
|
Loading…
x
Reference in New Issue
Block a user