diff --git a/ultrasonic/src/main/AndroidManifest.xml b/ultrasonic/src/main/AndroidManifest.xml index 30de8b56..2e6c4223 100644 --- a/ultrasonic/src/main/AndroidManifest.xml +++ b/ultrasonic/src/main/AndroidManifest.xml @@ -44,17 +44,6 @@ android:name="android.app.searchable" android:resource="@xml/searchable"/> - - - . - - 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 bars = new HashMap(); - 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() { - @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 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)); - } - } -} diff --git a/ultrasonic/src/main/java/org/moire/ultrasonic/activity/ResultActivity.java b/ultrasonic/src/main/java/org/moire/ultrasonic/activity/ResultActivity.java deleted file mode 100644 index 9dc9f7f5..00000000 --- a/ultrasonic/src/main/java/org/moire/ultrasonic/activity/ResultActivity.java +++ /dev/null @@ -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 newActivity) - { - startActivityForResultWithoutTransition(currentActivity, new Intent(currentActivity, newActivity)); - } - - public void startActivityForResultWithoutTransition(Activity currentActivity, Intent intent) - { - startActivityForResult(intent, 0); - Util.disablePendingTransition(currentActivity); - } -} diff --git a/ultrasonic/src/main/java/org/moire/ultrasonic/activity/SubsonicTabActivity.java b/ultrasonic/src/main/java/org/moire/ultrasonic/activity/SubsonicTabActivity.java deleted file mode 100644 index 94267c1e..00000000 --- a/ultrasonic/src/main/java/org/moire/ultrasonic/activity/SubsonicTabActivity.java +++ /dev/null @@ -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 . - - 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 mediaPlayerControllerLazy = inject(MediaPlayerController.class); - private final Lazy lifecycleSupport = inject(MediaPlayerLifecycleSupport.class); - protected Lazy 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); - } - - -} diff --git a/ultrasonic/src/main/java/org/moire/ultrasonic/fragment/EqualizerFragment.java b/ultrasonic/src/main/java/org/moire/ultrasonic/fragment/EqualizerFragment.java new file mode 100644 index 00000000..bde92bf9 --- /dev/null +++ b/ultrasonic/src/main/java/org/moire/ultrasonic/fragment/EqualizerFragment.java @@ -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 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() { + @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 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)); + } + } +} diff --git a/ultrasonic/src/main/java/org/moire/ultrasonic/fragment/MainFragment.java b/ultrasonic/src/main/java/org/moire/ultrasonic/fragment/MainFragment.java index 008d5284..1dba2c0b 100644 --- a/ultrasonic/src/main/java/org/moire/ultrasonic/fragment/MainFragment.java +++ b/ultrasonic/src/main/java/org/moire/ultrasonic/fragment/MainFragment.java @@ -16,7 +16,6 @@ import androidx.fragment.app.Fragment; import androidx.navigation.Navigation; import org.moire.ultrasonic.R; -import org.moire.ultrasonic.activity.ServerSelectorActivity; import org.moire.ultrasonic.data.ActiveServerProvider; import org.moire.ultrasonic.data.ServerSetting; import org.moire.ultrasonic.util.Constants; @@ -265,14 +264,7 @@ public class MainFragment extends Fragment { private void showServers() { - final Intent intent = new Intent(getContext(), ServerSelectorActivity.class); - startActivityForResult(intent, 0); - } - - public void startActivityForResultWithoutTransition(Activity currentActivity, Intent intent) - { - startActivityForResult(intent, 0); - Util.disablePendingTransition(currentActivity); + Navigation.findNavController(getView()).navigate(R.id.mainToServerSelector); } } diff --git a/ultrasonic/src/main/java/org/moire/ultrasonic/fragment/NowPlayingFragment.java b/ultrasonic/src/main/java/org/moire/ultrasonic/fragment/NowPlayingFragment.java index 4f9882f6..15c4517f 100644 --- a/ultrasonic/src/main/java/org/moire/ultrasonic/fragment/NowPlayingFragment.java +++ b/ultrasonic/src/main/java/org/moire/ultrasonic/fragment/NowPlayingFragment.java @@ -196,7 +196,7 @@ public class NowPlayingFragment extends Fragment { return false; } } - Navigation.findNavController(getView()).navigate(R.id.playerFragment); + Navigation.findNavController(getActivity(), R.id.nav_host_fragment).navigate(R.id.playerFragment); return false; } } diff --git a/ultrasonic/src/main/java/org/moire/ultrasonic/fragment/PlayerFragment.java b/ultrasonic/src/main/java/org/moire/ultrasonic/fragment/PlayerFragment.java index 7f794c02..c91eeb22 100644 --- a/ultrasonic/src/main/java/org/moire/ultrasonic/fragment/PlayerFragment.java +++ b/ultrasonic/src/main/java/org/moire/ultrasonic/fragment/PlayerFragment.java @@ -2,7 +2,6 @@ package org.moire.ultrasonic.fragment; import android.app.AlertDialog; import android.content.DialogInterface; -import android.content.Intent; import android.graphics.Point; import android.graphics.drawable.Drawable; import android.os.Bundle; @@ -39,7 +38,6 @@ import com.mobeta.android.dslv.DragSortListView; import org.jetbrains.annotations.NotNull; import org.koin.java.KoinJavaComponent; import org.moire.ultrasonic.R; -import org.moire.ultrasonic.activity.EqualizerActivity; import org.moire.ultrasonic.audiofx.EqualizerController; import org.moire.ultrasonic.audiofx.VisualizerController; 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); return true; case R.id.menu_item_equalizer: - startActivity(new Intent(getContext(), EqualizerActivity.class)); + Navigation.findNavController(getView()).navigate(R.id.playerToEqualizer); return true; case R.id.menu_item_visualizer: final boolean active = !visualizerView.isActive(); diff --git a/ultrasonic/src/main/java/org/moire/ultrasonic/fragment/SettingsFragment.java b/ultrasonic/src/main/java/org/moire/ultrasonic/fragment/SettingsFragment.java index 39b6bedd..2c0b758b 100644 --- a/ultrasonic/src/main/java/org/moire/ultrasonic/fragment/SettingsFragment.java +++ b/ultrasonic/src/main/java/org/moire/ultrasonic/fragment/SettingsFragment.java @@ -2,7 +2,6 @@ package org.moire.ultrasonic.fragment; import android.app.AlertDialog; import android.content.DialogInterface; -import android.content.Intent; import android.content.SharedPreferences; import android.os.Build; import android.os.Bundle; @@ -10,7 +9,7 @@ import android.provider.SearchRecentSuggestions; import androidx.annotation.Nullable; import androidx.annotation.StringRes; import androidx.fragment.app.DialogFragment; -import androidx.fragment.app.Fragment; +import androidx.navigation.Navigation; import androidx.preference.CheckBoxPreference; import androidx.preference.EditTextPreference; import androidx.preference.ListPreference; @@ -24,8 +23,6 @@ import android.view.View; import org.koin.java.KoinJavaComponent; 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.FeatureStorage; import org.moire.ultrasonic.filepicker.FilePickerDialog; @@ -42,7 +39,7 @@ import java.io.File; import kotlin.Lazy; 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. @@ -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 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { PreferenceCategory notificationsCategory = findPreference(Constants.PREFERENCES_KEY_CATEGORY_NOTIFICATIONS); - notificationsCategory.removePreference(findPreference(Constants.PREFERENCES_KEY_SHOW_NOTIFICATION)); - notificationsCategory.removePreference(findPreference(Constants.PREFERENCES_KEY_ALWAYS_SHOW_NOTIFICATION)); + Preference preferenceToRemove = findPreference(Constants.PREFERENCES_KEY_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() { @Override public boolean onPreferenceClick(Preference preference) { - final Intent intent = new Intent(getActivity(), ServerSelectorActivity.class); - intent.putExtra(SERVER_SELECTOR_MANAGE_MODE, true); - startActivityForResult(intent, 0); + Bundle bundle = new Bundle(); + bundle.putBoolean(SERVER_SELECTOR_MANAGE_MODE, true); + Navigation.findNavController(getView()).navigate(R.id.settingsToServerSelector, bundle); return true; } }); @@ -470,15 +469,11 @@ public class SettingsFragment extends PreferenceFragmentCompat } private void setImageLoaderConcurrency(int concurrency) { - SubsonicTabActivity instance = SubsonicTabActivity.getInstance(); + ImageLoader imageLoaderInstance = imageLoader.getValue().getImageLoader(); - if (instance != null) { - ImageLoader imageLoaderInstance = imageLoader.getValue().getImageLoader(); - - if (imageLoaderInstance != null) { - imageLoaderInstance.stopImageLoader(); - imageLoaderInstance.setConcurrency(concurrency); - } + if (imageLoaderInstance != null) { + imageLoaderInstance.stopImageLoader(); + imageLoaderInstance.setConcurrency(concurrency); } } diff --git a/ultrasonic/src/main/java/org/moire/ultrasonic/service/MediaPlayerService.java b/ultrasonic/src/main/java/org/moire/ultrasonic/service/MediaPlayerService.java index 39800635..f6201b44 100644 --- a/ultrasonic/src/main/java/org/moire/ultrasonic/service/MediaPlayerService.java +++ b/ultrasonic/src/main/java/org/moire/ultrasonic/service/MediaPlayerService.java @@ -21,7 +21,6 @@ import androidx.core.app.NotificationManagerCompat; import org.koin.java.KoinJavaComponent; import org.moire.ultrasonic.R; import org.moire.ultrasonic.activity.NavigationActivity; -import org.moire.ultrasonic.activity.SubsonicTabActivity; import org.moire.ultrasonic.domain.MusicDirectory; import org.moire.ultrasonic.domain.PlayerState; import org.moire.ultrasonic.domain.RepeatMode; diff --git a/ultrasonic/src/main/java/org/moire/ultrasonic/util/FileUtil.java b/ultrasonic/src/main/java/org/moire/ultrasonic/util/FileUtil.java index eca5d830..de638001 100644 --- a/ultrasonic/src/main/java/org/moire/ultrasonic/util/FileUtil.java +++ b/ultrasonic/src/main/java/org/moire/ultrasonic/util/FileUtil.java @@ -28,7 +28,6 @@ import android.text.TextUtils; import kotlin.Lazy; import timber.log.Timber; -import org.moire.ultrasonic.activity.SubsonicTabActivity; import org.moire.ultrasonic.domain.MusicDirectory; import org.moire.ultrasonic.subsonic.ImageLoaderProvider; @@ -156,18 +155,14 @@ public class FileUtil File avatarFile = getAvatarFile(context, username); - SubsonicTabActivity subsonicTabActivity = SubsonicTabActivity.getInstance(); Bitmap bitmap = null; ImageLoader imageLoader = null; - if (subsonicTabActivity != null) - { - imageLoader = imageLoaderProvider.getValue().getImageLoader(); + imageLoader = imageLoaderProvider.getValue().getImageLoader(); - if (imageLoader != null) - { - bitmap = imageLoader.getImageBitmap(username, size); - } + if (imageLoader != null) + { + bitmap = imageLoader.getImageBitmap(username, size); } if (bitmap != null) @@ -226,18 +221,14 @@ public class FileUtil File albumArtFile = getAlbumArtFile(context, entry); - SubsonicTabActivity subsonicTabActivity = SubsonicTabActivity.getInstance(); Bitmap bitmap = null; ImageLoader imageLoader = null; - if (subsonicTabActivity != null) - { - imageLoader = imageLoaderProvider.getValue().getImageLoader(); + imageLoader = imageLoaderProvider.getValue().getImageLoader(); - if (imageLoader != null) - { - bitmap = imageLoader.getImageBitmap(entry, true, size); - } + if (imageLoader != null) + { + bitmap = imageLoader.getImageBitmap(entry, true, size); } if (bitmap != null) diff --git a/ultrasonic/src/main/java/org/moire/ultrasonic/util/LoadingTask.java b/ultrasonic/src/main/java/org/moire/ultrasonic/util/LoadingTask.java index b1acb058..d0c9ee63 100644 --- a/ultrasonic/src/main/java/org/moire/ultrasonic/util/LoadingTask.java +++ b/ultrasonic/src/main/java/org/moire/ultrasonic/util/LoadingTask.java @@ -2,14 +2,9 @@ package org.moire.ultrasonic.util; import android.annotation.SuppressLint; import android.app.Activity; -import android.app.ProgressDialog; -import android.content.DialogInterface; -import android.os.Build; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; -import org.moire.ultrasonic.activity.SubsonicTabActivity; - /** * @author Sindre Mehus * @version $Id$ diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/activity/NavigationActivity.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/activity/NavigationActivity.kt index 6b2ccdb1..183d3af6 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/activity/NavigationActivity.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/activity/NavigationActivity.kt @@ -31,6 +31,7 @@ import org.koin.android.viewmodel.ext.android.viewModel import org.moire.ultrasonic.R import org.moire.ultrasonic.data.ActiveServerProvider.Companion.isOffline import org.moire.ultrasonic.domain.PlayerState +import org.moire.ultrasonic.fragment.ServerSettingsModel import org.moire.ultrasonic.provider.SearchSuggestionProvider import org.moire.ultrasonic.service.DownloadFile import org.moire.ultrasonic.service.MediaPlayerController @@ -111,7 +112,7 @@ class NavigationActivity : AppCompatActivity() { if (currentFragmentId == R.id.playerFragment) { hideNowPlaying() } else { - showNowPlaying() + if (!nowPlayingHidden) showNowPlaying() } // 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 { override fun onDismissNowPlaying() { - // TODO: When will it be set back to false? nowPlayingHidden = true; hideNowPlaying(); } @@ -164,11 +164,8 @@ class NavigationActivity : AppCompatActivity() { // Lifecycle support's constructor registers some event receivers so it should be created early lifecycleSupport.onCreate() - if (!nowPlayingHidden) { - showNowPlaying() - } else { - hideNowPlaying() - } + if (!nowPlayingHidden) showNowPlaying() + else hideNowPlaying() } override fun onDestroy() { @@ -297,11 +294,14 @@ class NavigationActivity : AppCompatActivity() { } private fun showNowPlaying() { - if (!Util.getShowNowPlayingPreference(this) || nowPlayingHidden) { + if (!Util.getShowNowPlayingPreference(this)) { hideNowPlaying() 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 if (currentFragmentId == R.id.playerFragment) { hideNowPlaying() diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/di/AppPermanentStorageModule.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/di/AppPermanentStorageModule.kt index ef4deede..f785406d 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/di/AppPermanentStorageModule.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/di/AppPermanentStorageModule.kt @@ -5,11 +5,9 @@ import org.koin.android.ext.koin.androidContext import org.koin.android.viewmodel.dsl.viewModel import org.koin.core.qualifier.named import org.koin.dsl.module -import org.moire.ultrasonic.activity.ServerSettingsModel -import org.moire.ultrasonic.data.ActiveServerProvider +import org.moire.ultrasonic.fragment.ServerSettingsModel import org.moire.ultrasonic.data.AppDatabase import org.moire.ultrasonic.data.MIGRATION_1_2 -import org.moire.ultrasonic.subsonic.ImageLoaderProvider import org.moire.ultrasonic.util.Util const val SP_NAME = "Default_SP" diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/di/MusicServiceModule.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/di/MusicServiceModule.kt index 153b8efc..168756d9 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/di/MusicServiceModule.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/di/MusicServiceModule.kt @@ -8,7 +8,7 @@ import org.koin.android.viewmodel.dsl.viewModel import org.koin.core.qualifier.named import org.koin.dsl.module 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.SubsonicAPIVersions import org.moire.ultrasonic.api.subsonic.SubsonicClientConfiguration diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/activity/ArtistListModel.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/ArtistListModel.kt similarity index 99% rename from ultrasonic/src/main/kotlin/org/moire/ultrasonic/activity/ArtistListModel.kt rename to ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/ArtistListModel.kt index a12e6a43..7afaa882 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/activity/ArtistListModel.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/ArtistListModel.kt @@ -16,7 +16,7 @@ Copyright 2020 (C) Jozsef Varga */ -package org.moire.ultrasonic.activity +package org.moire.ultrasonic.fragment import android.content.Context import android.os.Handler diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/activity/ArtistRowAdapter.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/ArtistRowAdapter.kt similarity index 99% rename from ultrasonic/src/main/kotlin/org/moire/ultrasonic/activity/ArtistRowAdapter.kt rename to ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/ArtistRowAdapter.kt index 28105012..671ff8d5 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/activity/ArtistRowAdapter.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/ArtistRowAdapter.kt @@ -16,7 +16,7 @@ Copyright 2020 (C) Jozsef Varga */ -package org.moire.ultrasonic.activity +package org.moire.ultrasonic.fragment import android.view.LayoutInflater import android.view.MenuInflater diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/DownloadFragment.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/DownloadFragment.kt deleted file mode 100644 index bec1e973..00000000 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/DownloadFragment.kt +++ /dev/null @@ -1,6 +0,0 @@ -package org.moire.ultrasonic.fragment - -import androidx.fragment.app.Fragment - -class DownloadFragment: Fragment() { -} \ No newline at end of file diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/activity/EditServerActivity.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/EditServerFragment.kt similarity index 85% rename from ultrasonic/src/main/kotlin/org/moire/ultrasonic/activity/EditServerActivity.kt rename to ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/EditServerFragment.kt index 7641afe3..d00461fe 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/activity/EditServerActivity.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/EditServerFragment.kt @@ -1,16 +1,16 @@ -package org.moire.ultrasonic.activity +package org.moire.ultrasonic.fragment import android.app.AlertDialog 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 androidx.appcompat.app.ActionBar -import androidx.appcompat.app.AppCompatActivity +import androidx.fragment.app.Fragment import androidx.lifecycle.Observer +import androidx.navigation.fragment.findNavController import com.google.android.material.switchmaterial.SwitchMaterial 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.viewmodel.ext.android.viewModel 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.data.ActiveServerProvider 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.util.Constants import org.moire.ultrasonic.util.ErrorDialog import org.moire.ultrasonic.util.ModalBackgroundTask import org.moire.ultrasonic.util.Util import timber.log.Timber +import java.net.MalformedURLException +import java.net.URL -/** - * 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() { - +class EditServerFragment: Fragment() { companion object { const val EDIT_SERVER_INTENT_INDEX = "index" } @@ -55,32 +51,41 @@ internal class EditServerActivity : AppCompatActivity() { private var testButton: Button? = null private var isInstanceStateSaved: Boolean = false + @Override override fun onCreate(savedInstanceState: Bundle?) { + Util.applyTheme(this.context) super.onCreate(savedInstanceState) + } - Util.applyTheme(this) - if (savedInstanceState == null) configureActionBar() + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, + 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) - serverAddressEditText = findViewById(R.id.edit_server_address) - userNameEditText = findViewById(R.id.edit_server_username) - passwordEditText = findViewById(R.id.edit_server_password) - selfSignedSwitch = findViewById(R.id.edit_self_signed) - ldapSwitch = findViewById(R.id.edit_ldap) - jukeboxSwitch = findViewById(R.id.edit_jukebox) - saveButton = findViewById(R.id.edit_save) - testButton = findViewById(R.id.edit_test) + serverNameEditText = view.findViewById(R.id.edit_server_name) + serverAddressEditText = view.findViewById(R.id.edit_server_address) + userNameEditText = view.findViewById(R.id.edit_server_username) + passwordEditText = view.findViewById(R.id.edit_server_password) + selfSignedSwitch = view.findViewById(R.id.edit_self_signed) + ldapSwitch = view.findViewById(R.id.edit_ldap) + jukeboxSwitch = view.findViewById(R.id.edit_jukebox) + saveButton = view.findViewById(R.id.edit_save) + 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) { // Editing an existing server - setTitle(R.string.server_editor_label) + FragmentTitle.setTitle(this, R.string.server_editor_label) val serverSetting = serverSettingsModel.getServerSetting(index) serverSetting.observe( - this, + viewLifecycleOwner, Observer { t -> if (t != null) { currentServerSetting = t @@ -110,18 +115,18 @@ internal class EditServerActivity : AppCompatActivity() { ) { MusicServiceFactory.resetMusicService() } - finish() + findNavController().navigateUp() } } } } else { // Creating a new server - setTitle(R.string.server_editor_new_label) + FragmentTitle.setTitle(this, R.string.server_editor_new_label) currentServerSetting = ServerSetting() saveButton!!.setOnClickListener { if (getFields()) { serverSettingsModel.saveNewItem(currentServerSetting) - finish() + findNavController().navigateUp() } } } @@ -162,8 +167,10 @@ internal class EditServerActivity : AppCompatActivity() { super.onSaveInstanceState(savedInstanceState) } - override fun onRestoreInstanceState(savedInstanceState: Bundle) { - super.onRestoreInstanceState(savedInstanceState) + override fun onViewStateRestored(savedInstanceState: Bundle?) { + super.onViewStateRestored(savedInstanceState) + + if (savedInstanceState == null) return serverNameEditText!!.editText?.setText( savedInstanceState.getString(::serverNameEditText.name) @@ -183,26 +190,6 @@ internal class EditServerActivity : AppCompatActivity() { 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 */ @@ -299,7 +286,7 @@ internal class EditServerActivity : AppCompatActivity() { */ private fun testConnection() { val task: ModalBackgroundTask = object : ModalBackgroundTask( - this, + activity, false ) { @@ -331,10 +318,10 @@ internal class EditServerActivity : AppCompatActivity() { // Execute a ping to check the authentication, now using the correct API version. pingResponse = subsonicApiClient.api.ping().execute() - checkResponseSuccessful(pingResponse) + ApiCallResponseChecker.checkResponseSuccessful(pingResponse) val licenseResponse = subsonicApiClient.api.getLicense().execute() - checkResponseSuccessful(licenseResponse) + ApiCallResponseChecker.checkResponseSuccessful(licenseResponse) return licenseResponse.body()!!.license.valid } @@ -367,20 +354,20 @@ internal class EditServerActivity : AppCompatActivity() { */ private fun finishActivity() { if (areFieldsChanged()) { - AlertDialog.Builder(this) + AlertDialog.Builder(context) .setIcon(android.R.drawable.ic_dialog_alert) .setTitle(R.string.common_confirm) .setMessage(R.string.server_editor_leave_confirmation) .setPositiveButton(R.string.common_ok) { dialog, _ -> dialog.dismiss() - finish() + findNavController().navigateUp() } .setNegativeButton(R.string.common_cancel) { dialog, _ -> dialog.dismiss() } .show() } else { - finish() + findNavController().navigateUp() } } -} +} \ No newline at end of file diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SelectArtistFragment.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SelectArtistFragment.kt index ed5bde28..06d19358 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SelectArtistFragment.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SelectArtistFragment.kt @@ -15,9 +15,6 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout import org.koin.android.ext.android.inject import org.koin.android.viewmodel.ext.android.viewModel 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.domain.Artist import org.moire.ultrasonic.domain.MusicFolder @@ -40,9 +37,6 @@ class SelectArtistFragment : Fragment() { private lateinit var viewManager: RecyclerView.LayoutManager private lateinit var viewAdapter: ArtistRowAdapter - /** - * Called when the activity is first created. - */ @Override override fun onCreate(savedInstanceState: Bundle?) { Util.applyTheme(this.context) diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/activity/ServerRowAdapter.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/ServerRowAdapter.kt similarity index 99% rename from ultrasonic/src/main/kotlin/org/moire/ultrasonic/activity/ServerRowAdapter.kt rename to ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/ServerRowAdapter.kt index bd78295f..5bc27b0c 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/activity/ServerRowAdapter.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/ServerRowAdapter.kt @@ -1,4 +1,4 @@ -package org.moire.ultrasonic.activity +package org.moire.ultrasonic.fragment import android.content.Context import android.graphics.Color diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/activity/ServerSelectorActivity.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/ServerSelectorFragment.kt similarity index 67% rename from ultrasonic/src/main/kotlin/org/moire/ultrasonic/activity/ServerSelectorActivity.kt rename to ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/ServerSelectorFragment.kt index 40577911..9187f67b 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/activity/ServerSelectorActivity.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/ServerSelectorFragment.kt @@ -1,14 +1,15 @@ -package org.moire.ultrasonic.activity +package org.moire.ultrasonic.fragment import android.app.AlertDialog -import android.content.Intent 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.ListView -import androidx.appcompat.app.ActionBar -import androidx.appcompat.app.AppCompatActivity +import androidx.fragment.app.Fragment import androidx.lifecycle.Observer +import androidx.navigation.fragment.findNavController import com.google.android.material.floatingactionbutton.FloatingActionButton import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.runBlocking @@ -16,21 +17,13 @@ import kotlinx.coroutines.withContext import org.koin.android.ext.android.inject import org.koin.android.viewmodel.ext.android.viewModel 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.fragment.EditServerFragment.Companion.EDIT_SERVER_INTENT_INDEX import org.moire.ultrasonic.service.MediaPlayerController import org.moire.ultrasonic.util.Util import timber.log.Timber -/** - * 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() { - +class ServerSelectorFragment: Fragment() { companion object { const val SERVER_SELECTOR_MANAGE_MODE = "manageMode" } @@ -41,24 +34,33 @@ internal class ServerSelectorActivity : AppCompatActivity() { private val activeServerProvider: ActiveServerProvider by inject() private var serverRowAdapter: ServerRowAdapter? = null + @Override override fun onCreate(savedInstanceState: Bundle?) { + Util.applyTheme(this.context) super.onCreate(savedInstanceState) + } - Util.applyTheme(this) - if (savedInstanceState == null) configureActionBar() + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle?): View? { + return inflater.inflate(R.layout.server_selector, container, false) + } - setContentView(R.layout.server_selector) + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) - val manageMode = intent.getBooleanExtra(SERVER_SELECTOR_MANAGE_MODE, false) + val manageMode = arguments?.getBoolean( + SERVER_SELECTOR_MANAGE_MODE, + false + ) ?: false if (manageMode) { - setTitle(R.string.settings_server_manage_servers) + FragmentTitle.setTitle(this, R.string.settings_server_manage_servers) } else { - setTitle(R.string.server_selector_label) + FragmentTitle.setTitle(this, R.string.server_selector_label) } - listView = findViewById(R.id.server_list) + listView = view.findViewById(R.id.server_list) serverRowAdapter = ServerRowAdapter( - this, + view.context, arrayOf(), serverSettingsModel, activeServerProvider, @@ -81,24 +83,16 @@ internal class ServerSelectorActivity : AppCompatActivity() { editServer(position + 1) } else { setActiveServer(position) - finish() + findNavController().navigateUp() } } - val fab = findViewById(R.id.server_add_fab) + val fab = view.findViewById(R.id.server_add_fab) fab.setOnClickListener { 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() { super.onResume() 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 */ @@ -141,7 +127,7 @@ internal class ServerSelectorActivity : AppCompatActivity() { * This Callback handles the deletion of a Server Setting */ private fun onServerDeleted(index: Int) { - AlertDialog.Builder(this) + AlertDialog.Builder(context) .setIcon(android.R.drawable.ic_dialog_alert) .setTitle(R.string.server_menu_delete) .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) { - val intent = Intent(this, EditServerActivity::class.java) - intent.putExtra(EDIT_SERVER_INTENT_INDEX, index) - startActivityForResult(intent, 0) + val bundle = Bundle() + bundle.putInt(EDIT_SERVER_INTENT_INDEX, index) + findNavController().navigate(R.id.serverSelectorToEditServer, bundle) } -} +} \ No newline at end of file diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/activity/ServerSettingsModel.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/ServerSettingsModel.kt similarity index 99% rename from ultrasonic/src/main/kotlin/org/moire/ultrasonic/activity/ServerSettingsModel.kt rename to ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/ServerSettingsModel.kt index 5357a9f5..8db8570b 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/activity/ServerSettingsModel.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/ServerSettingsModel.kt @@ -1,4 +1,4 @@ -package org.moire.ultrasonic.activity +package org.moire.ultrasonic.fragment import android.content.Context import android.content.SharedPreferences diff --git a/ultrasonic/src/main/res/navigation/navigation_graph.xml b/ultrasonic/src/main/res/navigation/navigation_graph.xml index 2cf7360d..a33cf59a 100644 --- a/ultrasonic/src/main/res/navigation/navigation_graph.xml +++ b/ultrasonic/src/main/res/navigation/navigation_graph.xml @@ -13,6 +13,9 @@ + + android:name="org.moire.ultrasonic.fragment.SettingsFragment" > + + @@ -78,8 +85,24 @@ + + + + + + \ No newline at end of file