Removed butter knife

This commit is contained in:
h4h13 2018-12-06 14:22:57 +05:30
parent d5f63b91ac
commit 63e3276098
194 changed files with 5984 additions and 7491 deletions

View file

@ -1,227 +0,0 @@
package code.name.monkey.retromusic.ui.activities;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import com.afollestad.materialdialogs.MaterialDialog;
import com.google.android.material.appbar.AppBarLayout;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import androidx.appcompat.widget.Toolbar;
import androidx.core.app.ShareCompat;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import code.name.monkey.appthemehelper.ThemeStore;
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper;
import code.name.monkey.retromusic.R;
import code.name.monkey.retromusic.model.Contributor;
import code.name.monkey.retromusic.ui.activities.base.AbsBaseActivity;
import code.name.monkey.retromusic.ui.adapter.ContributorAdapter;
import code.name.monkey.retromusic.util.NavigationUtil;
import static code.name.monkey.retromusic.Constants.APP_INSTAGRAM_LINK;
import static code.name.monkey.retromusic.Constants.APP_TELEGRAM_LINK;
import static code.name.monkey.retromusic.Constants.APP_TWITTER_LINK;
import static code.name.monkey.retromusic.Constants.DISCORD_LINK;
import static code.name.monkey.retromusic.Constants.FAQ_LINK;
import static code.name.monkey.retromusic.Constants.GITHUB_PROJECT;
import static code.name.monkey.retromusic.Constants.GOOGLE_PLUS_COMMUNITY;
import static code.name.monkey.retromusic.Constants.RATE_ON_GOOGLE_PLAY;
import static code.name.monkey.retromusic.Constants.TELEGRAM_CHANGE_LOG;
import static code.name.monkey.retromusic.Constants.TRANSLATE;
/**
* @author Hemanth S (h4h13)
*/
public class AboutActivity extends AbsBaseActivity {
@BindView(R.id.app_bar)
AppBarLayout appBarLayout;
@BindView(R.id.toolbar)
Toolbar toolbar;
@BindView(R.id.app_version)
TextView appVersion;
@BindView(R.id.title)
TextView title;
@BindView(R.id.recycler_view)
RecyclerView recyclerView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_about);
ButterKnife.bind(this);
setStatusbarColorAuto();
setNavigationbarColorAuto();
setLightNavigationBar(true);
loadContributors();
setUpToolbar();
appVersion.setText(getAppVersion());
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
private void setUpToolbar() {
appBarLayout.setBackgroundColor(ThemeStore.primaryColor(this));
toolbar.setBackgroundColor(ThemeStore.primaryColor(this));
setSupportActionBar(toolbar);
//noinspection ConstantConditions
//getSupportActionBar().setDisplayHomeAsUpEnabled(true);
setTitle(null);
ToolbarContentTintHelper.colorBackButton(toolbar, ThemeStore.accentColor(this));
}
private void openUrl(String url) {
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
}
@OnClick({R.id.app_github, R.id.faq_link, R.id.app_google_plus, R.id.app_translation,
R.id.app_rate, R.id.app_share, R.id.instagram_link, R.id.twitter_link, R.id.changelog,
R.id.open_source, R.id.discord_link, R.id.telegram_link, R.id.donate_link})
public void onViewClicked(View view) {
switch (view.getId()) {
case R.id.faq_link:
openUrl(FAQ_LINK);
break;
case R.id.telegram_link:
openUrl(APP_TELEGRAM_LINK);
break;
case R.id.discord_link:
openUrl(DISCORD_LINK);
break;
case R.id.app_github:
openUrl(GITHUB_PROJECT);
break;
case R.id.app_google_plus:
openUrl(GOOGLE_PLUS_COMMUNITY);
break;
case R.id.app_translation:
openUrl(TRANSLATE);
break;
case R.id.app_rate:
openUrl(RATE_ON_GOOGLE_PLAY);
break;
case R.id.app_share:
shareApp();
break;
case R.id.donate_link:
NavigationUtil.goToSupportDevelopment(this);
break;
case R.id.instagram_link:
openUrl(APP_INSTAGRAM_LINK);
break;
case R.id.twitter_link:
openUrl(APP_TWITTER_LINK);
break;
case R.id.changelog:
showChangeLogOptions();
break;
case R.id.open_source:
NavigationUtil.goToOpenSource(this);
break;
}
}
private void showChangeLogOptions() {
new MaterialDialog.Builder(this)
.items(new String[]{"Telegram Channel", "App"})
.itemsCallback(new MaterialDialog.ListCallback() {
@Override
public void onSelection(MaterialDialog dialog, View itemView, int position, CharSequence text) {
if (position == 0) {
openUrl(TELEGRAM_CHANGE_LOG);
} else {
NavigationUtil.gotoWhatNews(AboutActivity.this);
}
}
})
.build()
.show();
}
private String getAppVersion() {
try {
PackageInfo packageInfo = getPackageManager().getPackageInfo(getPackageName(), 0);
return packageInfo.versionName;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
return "0.0.0";
}
}
private void shareApp() {
Intent shareIntent = ShareCompat.IntentBuilder.from(this)
.setType("songText/plain")
.setText(String.format(getString(R.string.app_share), getPackageName()))
.getIntent();
if (shareIntent.resolveActivity(getPackageManager()) != null) {
startActivity(
Intent.createChooser(shareIntent, getResources().getText(R.string.action_share)));
}
}
public void loadContributors() {
String data = getAssetJsonData();
Type type = new TypeToken<List<Contributor>>() {
}.getType();
List<Contributor> contributors = new Gson().fromJson(data, type);
ContributorAdapter contributorAdapter = new ContributorAdapter((ArrayList<Contributor>) contributors);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(contributorAdapter);
}
public String getAssetJsonData() {
String json = null;
try {
InputStream is = getAssets().open("contributors.json");
int size = is.available();
byte[] buffer = new byte[size];
is.read(buffer);
is.close();
json = new String(buffer, StandardCharsets.UTF_8);
} catch (IOException ex) {
ex.printStackTrace();
return null;
}
return json;
}
}

View file

@ -0,0 +1,181 @@
package code.name.monkey.retromusic.ui.activities
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Bundle
import android.view.MenuItem
import android.view.View
import androidx.core.app.ShareCompat
import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.LinearLayoutManager
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
import code.name.monkey.retromusic.Constants.APP_INSTAGRAM_LINK
import code.name.monkey.retromusic.Constants.APP_TELEGRAM_LINK
import code.name.monkey.retromusic.Constants.APP_TWITTER_LINK
import code.name.monkey.retromusic.Constants.DISCORD_LINK
import code.name.monkey.retromusic.Constants.FAQ_LINK
import code.name.monkey.retromusic.Constants.GITHUB_PROJECT
import code.name.monkey.retromusic.Constants.GOOGLE_PLUS_COMMUNITY
import code.name.monkey.retromusic.Constants.RATE_ON_GOOGLE_PLAY
import code.name.monkey.retromusic.Constants.TELEGRAM_CHANGE_LOG
import code.name.monkey.retromusic.Constants.TRANSLATE
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.model.Contributor
import code.name.monkey.retromusic.ui.activities.base.AbsBaseActivity
import code.name.monkey.retromusic.ui.adapter.ContributorAdapter
import code.name.monkey.retromusic.util.NavigationUtil
import com.afollestad.materialdialogs.MaterialDialog
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import kotlinx.android.synthetic.main.activity_about.*
import kotlinx.android.synthetic.main.card_credit.*
import kotlinx.android.synthetic.main.card_other.*
import kotlinx.android.synthetic.main.card_retro_info.*
import kotlinx.android.synthetic.main.card_social.*
import java.io.IOException
import java.nio.charset.StandardCharsets
import java.util.*
class AboutActivity : AbsBaseActivity(), View.OnClickListener {
private val assetJsonData: String?
get() {
val json: String
try {
val inputStream = assets.open("contributors.json")
val size = inputStream.available()
val buffer = ByteArray(size)
inputStream.read(buffer)
inputStream.close()
json = String(buffer, StandardCharsets.UTF_8)
} catch (ex: IOException) {
ex.printStackTrace()
return null
}
return json
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_about)
setStatusbarColorAuto()
setNavigationbarColorAuto()
setLightNavigationBar(true)
loadContributors()
setUpToolbar()
appVersion.text = getAppVersion()
setUpView()
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (item.itemId == android.R.id.home) {
onBackPressed()
return true
}
return super.onOptionsItemSelected(item)
}
private fun setUpToolbar() {
appBarLayout.setBackgroundColor(ThemeStore.primaryColor(this))
toolbar.setBackgroundColor(ThemeStore.primaryColor(this))
setSupportActionBar(toolbar)
title = null
ToolbarContentTintHelper.colorBackButton(toolbar, ThemeStore.accentColor(this))
}
private fun openUrl(url: String) {
val i = Intent(Intent.ACTION_VIEW)
i.data = Uri.parse(url)
i.flags = Intent.FLAG_ACTIVITY_NEW_TASK
startActivity(i)
}
private fun setUpView() {
appGithub.setOnClickListener(this)
faqLink.setOnClickListener(this)
telegramLink.setOnClickListener(this)
appRate.setOnClickListener(this)
googlePlus.setOnClickListener(this)
appTranslation.setOnClickListener(this)
appShare.setOnClickListener(this)
donateLink.setOnClickListener(this)
instagramLink.setOnClickListener(this)
twitterLink.setOnClickListener(this)
changelog.setOnClickListener(this)
openSource.setOnClickListener(this)
}
override fun onClick(view: View) {
when (view.id) {
R.id.faqLink -> openUrl(FAQ_LINK)
R.id.telegramLink -> openUrl(APP_TELEGRAM_LINK)
R.id.discordLink -> openUrl(DISCORD_LINK)
R.id.appGithub -> openUrl(GITHUB_PROJECT)
R.id.googlePlus -> openUrl(GOOGLE_PLUS_COMMUNITY)
R.id.appTranslation -> openUrl(TRANSLATE)
R.id.appRate -> openUrl(RATE_ON_GOOGLE_PLAY)
R.id.appShare -> shareApp()
R.id.donateLink -> NavigationUtil.goToSupportDevelopment(this)
R.id.instagramLink -> openUrl(APP_INSTAGRAM_LINK)
R.id.twitterLink -> openUrl(APP_TWITTER_LINK)
R.id.changelog -> showChangeLogOptions()
R.id.openSource -> NavigationUtil.goToOpenSource(this)
}
}
private fun showChangeLogOptions() {
MaterialDialog.Builder(this)
.items("Telegram Channel", "App")
.itemsCallback { _, _, position, _ ->
if (position == 0) {
openUrl(TELEGRAM_CHANGE_LOG)
} else {
NavigationUtil.gotoWhatNews(this@AboutActivity)
}
}
.build()
.show()
}
private fun getAppVersion(): String {
return try {
val packageInfo = packageManager.getPackageInfo(packageName, 0)
packageInfo.versionName
} catch (e: PackageManager.NameNotFoundException) {
e.printStackTrace()
"0.0.0"
}
}
private fun shareApp() {
val shareIntent = ShareCompat.IntentBuilder.from(this)
.setType("songText/plain")
.setText(String.format(getString(R.string.app_share), packageName))
.intent
if (shareIntent.resolveActivity(packageManager) != null) {
startActivity(
Intent.createChooser(shareIntent, resources.getText(R.string.action_share)))
}
}
private fun loadContributors() {
val data = assetJsonData
val type = object : TypeToken<List<Contributor>>() {
}.type
val contributors = Gson().fromJson<List<Contributor>>(data, type)
val contributorAdapter = ContributorAdapter(contributors as ArrayList<Contributor>)
recyclerView.layoutManager = LinearLayoutManager(this)
recyclerView.itemAnimator = DefaultItemAnimator()
recyclerView.adapter = contributorAdapter
}
}

View file

@ -12,7 +12,6 @@ import androidx.core.widget.NestedScrollView
import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import butterknife.ButterKnife
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.ColorUtil
import code.name.monkey.appthemehelper.util.TintHelper
@ -71,7 +70,6 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsContrac
setDrawUnderStatusBar()
setupWindowTransition()
super.onCreate(savedInstanceState)
ButterKnife.bind(this)
toggleBottomNavigationView(true)
setLightNavigationBar(true)
@ -175,20 +173,20 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsContrac
ActivityCompat.startPostponedEnterTransition(this)
}
override fun showData(album: Album) {
if (album.songs!!.isEmpty()) {
override fun showData(list: Album) {
if (list.songs!!.isEmpty()) {
finish()
return
}
this.album = album
this.album = list
albumTitle.text = album.title
albumText.text = String.format("%s • %s • %s", album.artistName, MusicUtil.getYearString(album.year), MusicUtil.getReadableDurationString(MusicUtil.getTotalDuration(this, album.songs)))
albumTitle.text = list.title
albumText.text = String.format("%s • %s • %s", list.artistName, MusicUtil.getYearString(list.year), MusicUtil.getReadableDurationString(MusicUtil.getTotalDuration(this, list.songs)))
loadAlbumCover()
loadMoreFrom(album)
loadMoreFrom(list)
simpleSongAdapter.swapDataSet(album.songs)
simpleSongAdapter.swapDataSet(list.songs)
}
private fun loadMoreFrom(album: Album) {

View file

@ -16,7 +16,6 @@ import androidx.core.widget.NestedScrollView
import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import butterknife.ButterKnife
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.ColorUtil
import code.name.monkey.appthemehelper.util.TintHelper
@ -71,7 +70,7 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailContrac
setDrawUnderStatusBar()
setupWindowTransistion()
super.onCreate(savedInstanceState)
ButterKnife.bind(this)
toggleBottomNavigationView(true)
setNavigationbarColorAuto()
@ -273,7 +272,7 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailContrac
private fun loadArtistImage() {
ArtistGlideRequest.Builder.from(Glide.with(this), artist)
ArtistGlideRequest.Builder.from(Glide.with(this), artist!!)
.forceDownload(forceDownload)
.generatePalette(this).build()
.dontAnimate()

View file

@ -1,232 +0,0 @@
package code.name.monkey.retromusic.ui.activities;
import android.os.Bundle;
import com.google.android.material.appbar.AppBarLayout;
import androidx.appcompat.widget.SwitchCompat;
import androidx.appcompat.widget.Toolbar;
import android.transition.TransitionManager;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.CompoundButton;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.Spinner;
import android.widget.TextView;
import butterknife.BindView;
import butterknife.ButterKnife;
import code.name.monkey.appthemehelper.ThemeStore;
import code.name.monkey.retromusic.R;
import code.name.monkey.retromusic.helper.EqualizerHelper;
import code.name.monkey.retromusic.ui.activities.base.AbsMusicServiceActivity;
/**
* @author Hemanth S (h4h13).
*/
public class EqualizerActivity extends AbsMusicServiceActivity implements
AdapterView.OnItemSelectedListener {
@BindView(R.id.equalizer)
SwitchCompat mEnable;
@BindView(R.id.content)
LinearLayout mContent;
@BindView(R.id.bands)
LinearLayout mLinearLayout;
@BindView(R.id.bass_boost_strength)
SeekBar mBassBoostStrength;
@BindView(R.id.virtualizer_strength)
SeekBar mVirtualizerStrength;
@BindView(R.id.bass_boost)
TextView mBassBoost;
@BindView(R.id.virtualizer)
TextView mVirtualizer;
@BindView(R.id.toolbar)
Toolbar mToolbar;
@BindView(R.id.app_bar)
AppBarLayout mAppBar;
@BindView(R.id.presets)
Spinner mPresets;
@BindView(R.id.title)
TextView mTitle;
private CompoundButton.OnCheckedChangeListener mListener = (buttonView, isChecked) -> {
switch (buttonView.getId()) {
case R.id.equalizer:
EqualizerHelper.Companion.getInstance().getEqualizer().setEnabled(isChecked);
TransitionManager.beginDelayedTransition(mContent);
mContent.setVisibility(isChecked ? View.VISIBLE : View.GONE);
break;
}
};
private SeekBar.OnSeekBarChangeListener mSeekBarChangeListener = new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (fromUser) {
if (seekBar == mBassBoostStrength) {
mBassBoost.setEnabled(progress > 0);
EqualizerHelper.Companion.getInstance().setBassBoostStrength(progress);
EqualizerHelper.Companion.getInstance().setBassBoostEnabled(progress > 0);
} else if (seekBar == mVirtualizerStrength) {
mVirtualizer.setEnabled(progress > 0);
EqualizerHelper.Companion.getInstance().setVirtualizerEnabled(progress > 0);
EqualizerHelper.Companion.getInstance().setVirtualizerStrength(progress);
}
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
};
private ArrayAdapter<String> mPresetsNamesAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_equalizer);
ButterKnife.bind(this);
setStatusbarColorAuto();
setNavigationbarColorAuto();
setTaskDescriptionColorAuto();
setLightNavigationBar(true);
setupToolbar();
mEnable.setChecked(EqualizerHelper.Companion.getInstance().getEqualizer().getEnabled());
mEnable.setOnCheckedChangeListener(mListener);
mPresetsNamesAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1);
mPresets.setAdapter(mPresetsNamesAdapter);
mPresets.setOnItemSelectedListener(this);
mBassBoostStrength.setProgress(EqualizerHelper.Companion.getInstance().getBassBoostStrength());
mBassBoostStrength.setOnSeekBarChangeListener(mSeekBarChangeListener);
mVirtualizerStrength.setProgress(EqualizerHelper.Companion.getInstance().getVirtualizerStrength());
mVirtualizerStrength.setOnSeekBarChangeListener(mSeekBarChangeListener);
setupUI();
addPresets();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
private void setupToolbar() {
mTitle.setTextColor(ThemeStore.textColorPrimary(this));
int primaryColor = ThemeStore.primaryColor(this);
mToolbar.setBackgroundColor(primaryColor);
mAppBar.setBackgroundColor(primaryColor);
mToolbar.setNavigationIcon(R.drawable.ic_keyboard_backspace_black_24dp);
mToolbar.setNavigationOnClickListener(v -> onBackPressed());
setSupportActionBar(mToolbar);
setTitle(null);
}
private void addPresets() {
mPresetsNamesAdapter.clear();
mPresetsNamesAdapter.add("Custom");
for (int j = 0; j < EqualizerHelper.Companion.getInstance().getEqualizer().getNumberOfPresets(); j++) {
mPresetsNamesAdapter
.add(EqualizerHelper.Companion.getInstance().getEqualizer().getPresetName((short) j));
mPresetsNamesAdapter.notifyDataSetChanged();
}
mPresets
.setSelection((int) EqualizerHelper.Companion.getInstance().getEqualizer().getCurrentPreset() + 1);
}
private void setupUI() {
mLinearLayout.removeAllViews();
short bands;
try {
// get number of supported bands
bands = (short) EqualizerHelper.Companion.getInstance().getNumberOfBands();
// for each of the supported bands, we will set up a slider from -10dB to 10dB boost/attenuation,
// as well as text labels to assist the user
for (short i = 0; i < bands; i++) {
final short band = i;
View view = LayoutInflater.from(this).inflate(R.layout.retro_seekbar, mLinearLayout, false);
TextView freqTextView = view.findViewById(R.id.hurtz);
freqTextView.setText(
String.format("%d Hz", EqualizerHelper.Companion.getInstance().getCenterFreq((int) band) / 1000));
TextView minDbTextView = view.findViewById(R.id.minus_db);
minDbTextView
.setText(String.format("%d dB", EqualizerHelper.Companion.getInstance().getBandLevelLow() / 100));
TextView maxDbTextView = view.findViewById(R.id.plus_db);
maxDbTextView.setText(
String.format("%d dB", EqualizerHelper.Companion.getInstance().getBandLevelHigh() / 100));
SeekBar bar = view.findViewById(R.id.seekbar);
bar.setMax(EqualizerHelper.Companion.getInstance().getBandLevelHigh() - EqualizerHelper.Companion.getInstance()
.getBandLevelLow());
bar.setProgress(
EqualizerHelper.Companion.getInstance().getBandLevel((int) band) - EqualizerHelper.Companion.getInstance()
.getBandLevelLow());
bar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
EqualizerHelper.Companion.getInstance().setBandLevel((int) band,
(int) (progress + EqualizerHelper.Companion.getInstance().getBandLevelLow()));
if (fromUser) {
mPresets.setSelection(0);
}
}
public void onStartTrackingTouch(SeekBar seekBar) {
}
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
mLinearLayout.addView(view);
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if (position == 0) {
return;
}
EqualizerHelper.Companion.getInstance().getEqualizer().usePreset((short) (position - 1));
setupUI();
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
}

View file

@ -0,0 +1,189 @@
package code.name.monkey.retromusic.ui.activities
import android.os.Bundle
import android.transition.TransitionManager
import android.view.LayoutInflater
import android.view.MenuItem
import android.view.View
import android.widget.AdapterView
import android.widget.ArrayAdapter
import android.widget.SeekBar
import android.widget.TextView
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.helper.EqualizerHelper
import code.name.monkey.retromusic.ui.activities.base.AbsMusicServiceActivity
import kotlinx.android.synthetic.main.activity_equalizer.*
/**
* @author Hemanth S (h4h13).
*/
class EqualizerActivity : AbsMusicServiceActivity(), AdapterView.OnItemSelectedListener {
/*private val mListener = { buttonView, isChecked ->
when (buttonView.getId()) {
R.id.equalizerSwitch -> {
EqualizerHelper.instance!!.equalizer.enabled = isChecked
TransitionManager.beginDelayedTransition(content)
content.visibility = if (isChecked) View.VISIBLE else View.GONE
}
}
}*/
private val mSeekBarChangeListener = object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
if (fromUser) {
if (seekBar === bassBoostStrength) {
bassBoost.isEnabled = progress > 0
EqualizerHelper.instance!!.bassBoostStrength = progress
EqualizerHelper.instance!!.isBassBoostEnabled = progress > 0
} else if (seekBar === virtualizerStrength) {
virtualizer.isEnabled = progress > 0
EqualizerHelper.instance!!.isVirtualizerEnabled = progress > 0
EqualizerHelper.instance!!.virtualizerStrength = progress
}
}
}
override fun onStartTrackingTouch(seekBar: SeekBar) {
}
override fun onStopTrackingTouch(seekBar: SeekBar) {
}
}
private var mPresetsNamesAdapter: ArrayAdapter<String>? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_equalizer)
setStatusbarColorAuto()
setNavigationbarColorAuto()
setTaskDescriptionColorAuto()
setLightNavigationBar(true)
setupToolbar()
equalizerSwitch.isChecked = EqualizerHelper.instance!!.equalizer.enabled
equalizerSwitch.setOnCheckedChangeListener { buttonView, isChecked ->
when (buttonView.id) {
R.id.equalizerSwitch -> {
EqualizerHelper.instance!!.equalizer.enabled = isChecked
TransitionManager.beginDelayedTransition(content)
content.visibility = if (isChecked) View.VISIBLE else View.GONE
}
}
}
mPresetsNamesAdapter = ArrayAdapter(this, android.R.layout.simple_list_item_1)
presets.adapter = mPresetsNamesAdapter
presets.onItemSelectedListener = this
bassBoostStrength.progress = EqualizerHelper.instance!!.bassBoostStrength
bassBoostStrength.setOnSeekBarChangeListener(mSeekBarChangeListener)
virtualizerStrength.progress = EqualizerHelper.instance!!.virtualizerStrength
virtualizerStrength.setOnSeekBarChangeListener(mSeekBarChangeListener)
setupUI()
addPresets()
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (item.itemId == android.R.id.home) {
onBackPressed()
return true
}
return super.onOptionsItemSelected(item)
}
private fun setupToolbar() {
bannerTitle.setTextColor(ThemeStore.textColorPrimary(this))
val primaryColor = ThemeStore.primaryColor(this)
appBarLayout.setBackgroundColor(primaryColor)
toolbar.apply {
setBackgroundColor(primaryColor)
setNavigationIcon(R.drawable.ic_keyboard_backspace_black_24dp)
setNavigationOnClickListener { onBackPressed() }
setSupportActionBar(this)
}
title = null
}
private fun addPresets() {
mPresetsNamesAdapter!!.clear()
mPresetsNamesAdapter!!.add("Custom")
for (j in 0 until EqualizerHelper.instance!!.equalizer.numberOfPresets) {
mPresetsNamesAdapter!!
.add(EqualizerHelper.instance!!.equalizer.getPresetName(j.toShort()))
mPresetsNamesAdapter!!.notifyDataSetChanged()
}
presets.setSelection(EqualizerHelper.instance!!.equalizer.currentPreset.toInt() + 1)
}
private fun setupUI() {
frequencyBands.removeAllViews()
val bands: Short
try {
// get number of supported bands
bands = EqualizerHelper.instance!!.numberOfBands.toShort()
// for each of the supported bands, we will set up a slider from -10dB to 10dB boost/attenuation,
// as well as text labels to assist the user
for (i in 0 until bands) {
val view = LayoutInflater.from(this).inflate(R.layout.retro_seekbar, frequencyBands, false)
val freqTextView = view.findViewById<TextView>(R.id.hurtz)
freqTextView.text = String.format("%d Hz", EqualizerHelper.instance!!.getCenterFreq(i) / 1000)
val minDbTextView = view.findViewById<TextView>(R.id.minus_db)
minDbTextView.text = String.format("%d dB", EqualizerHelper.instance!!.bandLevelLow / 100)
val maxDbTextView = view.findViewById<TextView>(R.id.plus_db)
maxDbTextView.text = String.format("%d dB", EqualizerHelper.instance!!.bandLevelHigh / 100)
val bar = view.findViewById<SeekBar>(R.id.seekbar)
bar.max = EqualizerHelper.instance!!.bandLevelHigh - EqualizerHelper.instance!!
.bandLevelLow
bar.progress = EqualizerHelper.instance!!.getBandLevel(i) - EqualizerHelper.instance!!
.bandLevelLow
bar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
EqualizerHelper.instance!!.setBandLevel(i,
progress + EqualizerHelper.instance!!.bandLevelLow)
if (fromUser) {
presets.setSelection(0)
}
}
override fun onStartTrackingTouch(seekBar: SeekBar) {}
override fun onStopTrackingTouch(seekBar: SeekBar) {}
})
frequencyBands.addView(view)
}
} catch (e: Exception) {
e.printStackTrace()
}
}
override fun onItemSelected(parent: AdapterView<*>, view: View, position: Int, id: Long) {
if (position == 0) {
return
}
EqualizerHelper.instance!!.equalizer.usePreset((position - 1).toShort())
setupUI()
}
override fun onNothingSelected(parent: AdapterView<*>) {
}
}

View file

@ -1 +1 @@
package code.name.monkey.retromusic.ui.activities; import android.os.Bundle; import androidx.appcompat.app.AppCompatActivity; import android.view.View; import butterknife.OnClick; import code.name.monkey.retromusic.R; import code.name.monkey.retromusic.App; public class ErrorHandlerActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_error_handler); } @OnClick(R.id.clear_app_data) void clearAppDate(View view) { App.Companion.deleteAppData(); } }
package code.name.monkey.retromusic.ui.activities; import android.os.Bundle; import androidx.appcompat.app.AppCompatActivity; import code.name.monkey.retromusic.R; public class ErrorHandlerActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_error_handler); } }

View file

@ -7,7 +7,6 @@ import android.view.View
import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import butterknife.ButterKnife
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
import code.name.monkey.retromusic.R
@ -44,7 +43,7 @@ class GenreDetailsActivity : AbsSlidingMusicPanelActivity(), GenreDetailsContrac
override fun onCreate(savedInstanceState: Bundle?) {
setDrawUnderStatusBar()
super.onCreate(savedInstanceState)
ButterKnife.bind(this)
setStatusbarColorAuto()
setNavigationbarColorAuto()
@ -140,8 +139,8 @@ class GenreDetailsActivity : AbsSlidingMusicPanelActivity(), GenreDetailsContrac
})
}
override fun showData(songs: ArrayList<Song>) {
songAdapter!!.swapDataSet(songs)
override fun showData(list: ArrayList<Song>) {
songAdapter!!.swapDataSet(list)
}
override fun openCab(menuRes: Int, callback: MaterialCab.Callback): MaterialCab {

View file

@ -1,62 +0,0 @@
package code.name.monkey.retromusic.ui.activities;
import android.os.Bundle;
import androidx.annotation.NonNull;
import com.google.android.material.appbar.AppBarLayout;
import androidx.appcompat.widget.Toolbar;
import android.view.MenuItem;
import android.webkit.WebView;
import android.widget.TextView;
import butterknife.BindView;
import butterknife.ButterKnife;
import code.name.monkey.appthemehelper.ThemeStore;
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper;
import code.name.monkey.retromusic.R;
import code.name.monkey.retromusic.ui.activities.base.AbsBaseActivity;
public class LicenseActivity extends AbsBaseActivity {
@BindView(R.id.license)
WebView mLicense;
@BindView(R.id.toolbar)
Toolbar toolbar;
@BindView(R.id.app_bar)
AppBarLayout mAppbar;
@BindView(R.id.title)
TextView title;
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
if (item.getItemId() == android.R.id.home) {
onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_license);
ButterKnife.bind(this);
setStatusbarColorAuto();
setNavigationbarColorAuto();
setTaskDescriptionColorAuto();
setLightNavigationBar(true);
mLicense.loadUrl("file:///android_asset/index.html");
title.setTextColor(ThemeStore.textColorPrimary(this));
toolbar.setNavigationIcon(R.drawable.ic_keyboard_backspace_black_24dp);
toolbar.setNavigationOnClickListener(view -> onBackPressed());
toolbar.setBackgroundColor(ThemeStore.primaryColor(this));
mAppbar.setBackgroundColor(ThemeStore.primaryColor(this));
setTitle(null);
setSupportActionBar(toolbar);
ToolbarContentTintHelper.colorBackButton(toolbar, ThemeStore.accentColor(this));
}
}

View file

@ -0,0 +1,44 @@
package code.name.monkey.retromusic.ui.activities
import android.os.Bundle
import android.view.MenuItem
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.ui.activities.base.AbsBaseActivity
import kotlinx.android.synthetic.main.activity_license.*
class LicenseActivity : AbsBaseActivity() {
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (item.itemId == android.R.id.home) {
onBackPressed()
return true
}
return super.onOptionsItemSelected(item)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_license)
setStatusbarColorAuto()
setNavigationbarColorAuto()
setTaskDescriptionColorAuto()
setLightNavigationBar(true)
license.loadUrl("file:///android_asset/index.html")
bannerTitle.setTextColor(ThemeStore.textColorPrimary(this))
toolbar!!.apply {
setNavigationIcon(R.drawable.ic_keyboard_backspace_black_24dp)
setNavigationOnClickListener { onBackPressed() }
setBackgroundColor(ThemeStore.primaryColor(this@LicenseActivity))
}
appBarLayout.setBackgroundColor(ThemeStore.primaryColor(this))
title = null
setSupportActionBar(toolbar)
ToolbarContentTintHelper.colorBackButton(toolbar!!, ThemeStore.accentColor(this))
}
}

View file

@ -1,367 +0,0 @@
package code.name.monkey.retromusic.ui.activities;
import android.annotation.SuppressLint;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.InputType;
import android.text.TextUtils;
import android.view.MenuItem;
import android.view.View;
import android.view.WindowManager;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;
import com.afollestad.materialdialogs.DialogAction;
import com.afollestad.materialdialogs.MaterialDialog;
import com.bumptech.glide.Glide;
import com.google.android.material.bottomappbar.BottomAppBar;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import org.jaudiotagger.tag.FieldKey;
import java.io.File;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.Map;
import java.util.Objects;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import code.name.monkey.appthemehelper.ThemeStore;
import code.name.monkey.appthemehelper.util.TintHelper;
import code.name.monkey.retromusic.R;
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget;
import code.name.monkey.retromusic.glide.SongGlideRequest;
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper;
import code.name.monkey.retromusic.model.Song;
import code.name.monkey.retromusic.model.lyrics.Lyrics;
import code.name.monkey.retromusic.ui.activities.base.AbsMusicServiceActivity;
import code.name.monkey.retromusic.ui.activities.tageditor.WriteTagsAsyncTask;
import code.name.monkey.retromusic.util.LyricUtil;
import code.name.monkey.retromusic.util.MusicUtil;
import code.name.monkey.retromusic.util.PreferenceUtil;
import code.name.monkey.retromusic.util.RetroUtil;
import code.name.monkey.retromusic.views.FitSystemWindowsLayout;
import code.name.monkey.retromusic.views.LyricView;
import io.reactivex.disposables.CompositeDisposable;
public class LyricsActivity extends AbsMusicServiceActivity implements
MusicProgressViewUpdateHelper.Callback {
@BindView(R.id.bottom_app_bar)
BottomAppBar bottomAppBar;
@BindView(R.id.lyrics_view)
LyricView lyricView;
@BindView(R.id.offline_lyrics)
TextView offlineLyrics;
@BindView(R.id.actions)
RadioGroup actionsLayout;
@BindView(R.id.fab)
FloatingActionButton actionButton;
@BindView(R.id.container)
FitSystemWindowsLayout fitSystemWindowsLayout;
private MusicProgressViewUpdateHelper updateHelper;
private AsyncTask updateLyricsAsyncTask;
private CompositeDisposable disposable;
private Song song;
private Lyrics lyrics;
@Override
protected void onCreate(Bundle savedInstanceState) {
setDrawUnderStatusBar();
//setDrawUnderNavigationBar();
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_lyrics);
ButterKnife.bind(this);
setTaskDescriptionColorAuto();
setNavigationbarColorAuto();
fitSystemWindowsLayout.setFit(!PreferenceUtil.getInstance().getFullScreenMode());
setSupportActionBar(bottomAppBar);
Objects.requireNonNull(bottomAppBar.getNavigationIcon())
.setColorFilter(ThemeStore.textColorPrimary(this), PorterDuff.Mode.SRC_IN);
bottomAppBar.setBackgroundTint(ColorStateList.valueOf(ThemeStore.primaryColor(this)));
TintHelper.setTintAuto(actionButton, ThemeStore.accentColor(this), true);
updateHelper = new MusicProgressViewUpdateHelper(this, 500, 1000);
setupLyricsView();
setupWakelock();
loadLrcFile();
actionsLayout.setOnCheckedChangeListener((group, checkedId) -> selectLyricsTye(checkedId));
actionsLayout.check(PreferenceUtil.getInstance().getLastLyricsType());
}
private void selectLyricsTye(int group) {
PreferenceUtil.getInstance().setLastLyricsType(group);
RadioButton radioButton = actionsLayout.findViewById(group);
if (radioButton != null) {
radioButton.setBackgroundTintList(ColorStateList.valueOf(Color.WHITE));
//radioButton.setTextColor(ThemeStore.textColorPrimary(this));
}
offlineLyrics.setVisibility(View.GONE);
lyricView.setVisibility(View.GONE);
switch (group) {
case R.id.synced_lyrics:
loadLRCLyrics();
lyricView.setVisibility(View.VISIBLE);
break;
default:
case R.id.normal_lyrics:
loadSongLyrics();
offlineLyrics.setVisibility(View.VISIBLE);
break;
}
}
private void loadLRCLyrics() {
if (LyricUtil.isLrcFileExist(song.getTitle(), song.getArtistName())) {
showLyricsLocal(LyricUtil.getLocalLyricFile(song.getTitle(), song.getArtistName()));
}
}
private void setupWakelock() {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
private void setupLyricsView() {
disposable = new CompositeDisposable();
lyricView
.setOnPlayerClickListener((progress, content) -> MusicPlayerRemote.INSTANCE.seekTo((int) progress));
//lyricView.setHighLightTextColor(ThemeStore.accentColor(this));
lyricView.setDefaultColor(ContextCompat.getColor(this, R.color.md_grey_400));
//lyricView.setTouchable(false);
lyricView.setHintColor(Color.WHITE);
}
@Override
public void onPlayingMetaChanged() {
super.onPlayingMetaChanged();
loadLrcFile();
}
@Override
protected void onResume() {
super.onResume();
updateHelper.start();
}
@Override
protected void onPause() {
super.onPause();
updateHelper.stop();
}
@Override
public void onServiceConnected() {
super.onServiceConnected();
loadLrcFile();
}
@Override
public void onDestroy() {
super.onDestroy();
disposable.clear();
if (updateLyricsAsyncTask != null && !updateLyricsAsyncTask.isCancelled()) {
updateLyricsAsyncTask.cancel(true);
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
onBackPressed();
}
return super.onOptionsItemSelected(item);
}
@Override
public void onUpdateProgressViews(int progress, int total) {
lyricView.setCurrentTimeMillis(progress);
}
private void loadLrcFile() {
song = MusicPlayerRemote.INSTANCE.getCurrentSong();
bottomAppBar.setTitle(song.getTitle());
bottomAppBar.setSubtitle(song.getArtistName());
SongGlideRequest.Builder.from(Glide.with(this), song)
.checkIgnoreMediaStore(this)
.generatePalette(this)
.build()
.into(new RetroMusicColoredTarget(findViewById(R.id.image)) {
@Override
public void onColorReady(int color) {
if (PreferenceUtil.getInstance().getAdaptiveColor()) {
//background.setBackgroundColor(color);
}
}
});
}
private void showLyricsLocal(File file) {
if (file == null) {
lyricView.reset();
} else {
lyricView.setLyricFile(file, "UTF-8");
}
}
@OnClick({R.id.fab})
public void onViewClicked(View view) {
switch (view.getId()) {
case R.id.back:
onBackPressed();
break;
case R.id.fab:
switch (actionsLayout.getCheckedRadioButtonId()) {
case R.id.synced_lyrics:
showSyncedLyrics();
break;
case R.id.normal_lyrics:
showLyricsSaveDialog();
break;
}
break;
}
}
@SuppressLint("StaticFieldLeak")
private void loadSongLyrics() {
if (updateLyricsAsyncTask != null) {
updateLyricsAsyncTask.cancel(false);
}
final Song song = MusicPlayerRemote.INSTANCE.getCurrentSong();
updateLyricsAsyncTask = new AsyncTask<Void, Void, Lyrics>() {
@Override
protected Lyrics doInBackground(Void... params) {
String data = MusicUtil.getLyrics(song);
if (TextUtils.isEmpty(data)) {
return null;
}
return Lyrics.parse(song, data);
}
@Override
protected void onPreExecute() {
super.onPreExecute();
lyrics = null;
}
@Override
protected void onPostExecute(Lyrics l) {
lyrics = l;
offlineLyrics.setVisibility(View.VISIBLE);
if (l == null) {
offlineLyrics.setText(R.string.no_lyrics_found);
return;
}
offlineLyrics.setText(l.data);
}
@Override
protected void onCancelled(Lyrics s) {
onPostExecute(null);
}
}.execute();
}
private void showSyncedLyrics() {
String content = "";
try {
content = LyricUtil.getStringFromFile(song.getTitle(), song.getArtistName());
} catch (Exception e) {
e.printStackTrace();
}
new MaterialDialog.Builder(this)
.title("Add lyrics")
.neutralText("Search")
.content("Add time frame lyrics")
.negativeText("Delete")
.onNegative((dialog, which) -> {
LyricUtil.deleteLrcFile(song.getTitle(), song.getArtistName());
loadLrcFile();
})
.onNeutral(
(dialog, which) -> RetroUtil.openUrl(LyricsActivity.this, getGoogleSearchLrcUrl()))
.inputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_MULTI_LINE)
.input("Paste lyrics here", content, (dialog, input) -> {
LyricUtil.writeLrcToLoc(song.getTitle(), song.getArtistName(), input.toString());
loadLrcFile();
}).show();
}
private String getGoogleSearchLrcUrl() {
String baseUrl = "http://www.google.com/search?";
String query = song.getTitle() + "+" + song.getArtistName();
query = "q=" + query.replace(" ", "+") + " .lrc";
baseUrl += query;
return baseUrl;
}
private void showLyricsSaveDialog() {
String content = "";
if (lyrics == null) {
content = "";
} else {
content = lyrics.data;
}
new MaterialDialog.Builder(this)
.title("Add lyrics")
.neutralText("Search")
.onNeutral(new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
RetroUtil.openUrl(LyricsActivity.this, getGoogleSearchUrl(song.getTitle(), song.getArtistName()));
}
})
.inputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_MULTI_LINE)
.input("Paste lyrics here", content, (dialog, input) -> {
Map<FieldKey, String> fieldKeyValueMap = new EnumMap<>(FieldKey.class);
fieldKeyValueMap.put(FieldKey.LYRICS, input.toString());
new WriteTagsAsyncTask(LyricsActivity.this)
.execute(
new WriteTagsAsyncTask.LoadingInfo(getSongPaths(song), fieldKeyValueMap, null));
loadLrcFile();
})
.show();
}
private ArrayList<String> getSongPaths(Song song) {
ArrayList<String> paths = new ArrayList<>(1);
paths.add(song.getData());
return paths;
}
private String getGoogleSearchUrl(String title, String text) {
String baseUrl = "http://www.google.com/search?";
String query = title + "+" + text;
query = "q=" + query.replace(" ", "+") + " lyrics";
baseUrl += query;
return baseUrl;
}
}

View file

@ -0,0 +1,307 @@
package code.name.monkey.retromusic.ui.activities
import android.annotation.SuppressLint
import android.content.res.ColorStateList
import android.graphics.Color
import android.graphics.PorterDuff
import android.graphics.drawable.Drawable
import android.os.AsyncTask
import android.os.Bundle
import android.text.InputType
import android.text.TextUtils
import android.view.MenuItem
import android.view.View
import android.view.WindowManager
import android.widget.RadioButton
import androidx.core.content.ContextCompat
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.TintHelper
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
import code.name.monkey.retromusic.glide.SongGlideRequest
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.model.lyrics.Lyrics
import code.name.monkey.retromusic.ui.activities.base.AbsMusicServiceActivity
import code.name.monkey.retromusic.ui.activities.tageditor.WriteTagsAsyncTask
import code.name.monkey.retromusic.util.LyricUtil
import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.util.RetroUtil
import com.afollestad.materialdialogs.MaterialDialog
import com.bumptech.glide.Glide
import io.reactivex.disposables.CompositeDisposable
import kotlinx.android.synthetic.main.activity_lyrics.*
import org.jaudiotagger.tag.FieldKey
import java.io.File
import java.util.*
class LyricsActivity : AbsMusicServiceActivity(), MusicProgressViewUpdateHelper.Callback, View.OnClickListener {
private var updateHelper: MusicProgressViewUpdateHelper? = null
private var updateLyricsAsyncTask: AsyncTask<*, *, *>? = null
private var disposable: CompositeDisposable? = null
private var song: Song? = null
private var lyrics: Lyrics? = null
private val googleSearchLrcUrl: String
get() {
var baseUrl = "http://www.google.com/search?"
var query = song!!.title + "+" + song!!.artistName
query = "q=" + query.replace(" ", "+") + " .lrc"
baseUrl += query
return baseUrl
}
override fun onCreate(savedInstanceState: Bundle?) {
setDrawUnderStatusBar()
//setDrawUnderNavigationBar();
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_lyrics)
setTaskDescriptionColorAuto()
setNavigationbarColorAuto()
container.isFit = !PreferenceUtil.getInstance().fullScreenMode
setSupportActionBar(bottomAppBar)
Objects.requireNonNull<Drawable>(bottomAppBar!!.navigationIcon)
.setColorFilter(ThemeStore.textColorPrimary(this), PorterDuff.Mode.SRC_IN)
bottomAppBar!!.backgroundTint = ColorStateList.valueOf(ThemeStore.primaryColor(this))
TintHelper.setTintAuto(fab, ThemeStore.accentColor(this), true)
updateHelper = MusicProgressViewUpdateHelper(this, 500, 1000)
setupLyricsView()
setupWakelock()
loadLrcFile()
actions.setOnCheckedChangeListener { _, checkedId -> selectLyricsTye(checkedId) }
actions.check(PreferenceUtil.getInstance().lastLyricsType)
fab.setOnClickListener(this)
}
private fun selectLyricsTye(group: Int) {
PreferenceUtil.getInstance().lastLyricsType = group
val radioButton = actions.findViewById<RadioButton>(group)
if (radioButton != null) {
radioButton.backgroundTintList = ColorStateList.valueOf(Color.WHITE)
//radioButton.setTextColor(ThemeStore.textColorPrimary(this));
}
offlineLyrics!!.visibility = View.GONE
lyricsView.visibility = View.GONE
when (group) {
R.id.syncedLyrics -> {
loadLRCLyrics()
lyricsView!!.visibility = View.VISIBLE
}
R.id.normalLyrics -> {
loadSongLyrics()
offlineLyrics!!.visibility = View.VISIBLE
}
else -> {
loadSongLyrics()
offlineLyrics!!.visibility = View.VISIBLE
}
}
}
private fun loadLRCLyrics() {
if (LyricUtil.isLrcFileExist(song!!.title, song!!.artistName)) {
showLyricsLocal(LyricUtil.getLocalLyricFile(song!!.title, song!!.artistName))
}
}
private fun setupWakelock() {
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
}
private fun setupLyricsView() {
disposable = CompositeDisposable()
lyricsView!!.apply {
setOnPlayerClickListener { progress, _ -> MusicPlayerRemote.seekTo(progress.toInt()) }
//lyricView.setHighLightTextColor(ThemeStore.accentColor(this));
setDefaultColor(ContextCompat.getColor(this@LyricsActivity, R.color.md_grey_400))
//lyricView.setTouchable(false);
setHintColor(Color.WHITE)
}
}
override fun onPlayingMetaChanged() {
super.onPlayingMetaChanged()
loadLrcFile()
}
override fun onResume() {
super.onResume()
updateHelper!!.start()
}
override fun onPause() {
super.onPause()
updateHelper!!.stop()
}
override fun onServiceConnected() {
super.onServiceConnected()
loadLrcFile()
}
override fun onDestroy() {
super.onDestroy()
disposable!!.clear()
if (updateLyricsAsyncTask != null && !updateLyricsAsyncTask!!.isCancelled) {
updateLyricsAsyncTask!!.cancel(true)
}
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (item.itemId == android.R.id.home) {
onBackPressed()
}
return super.onOptionsItemSelected(item)
}
override fun onUpdateProgressViews(progress: Int, total: Int) {
lyricsView!!.setCurrentTimeMillis(progress.toLong())
}
private fun loadLrcFile() {
song = MusicPlayerRemote.currentSong
bottomAppBar.title = song!!.title
bottomAppBar.subtitle = song!!.artistName
SongGlideRequest.Builder.from(Glide.with(this), song!!)
.checkIgnoreMediaStore(this)
.generatePalette(this)
.build()
.into(object : RetroMusicColoredTarget(findViewById(R.id.image)) {
override fun onColorReady(color: Int) {
if (PreferenceUtil.getInstance().adaptiveColor) {
//background.setBackgroundColor(color);
}
}
})
}
private fun showLyricsLocal(file: File?) {
if (file == null) {
lyricsView!!.reset()
} else {
lyricsView!!.setLyricFile(file, "UTF-8")
}
}
override fun onClick(view: View) {
when (view.id) {
android.R.id.home -> onBackPressed()
R.id.fab -> when (actions.checkedRadioButtonId) {
R.id.syncedLyrics -> showSyncedLyrics()
R.id.normalLyrics -> showLyricsSaveDialog()
}
}
}
@SuppressLint("StaticFieldLeak")
private fun loadSongLyrics() {
if (updateLyricsAsyncTask != null) {
updateLyricsAsyncTask!!.cancel(false)
}
val song = MusicPlayerRemote.currentSong
updateLyricsAsyncTask = object : AsyncTask<Void, Void, Lyrics>() {
override fun doInBackground(vararg params: Void): Lyrics? {
val data = MusicUtil.getLyrics(song)
return if (TextUtils.isEmpty(data)) {
null
} else Lyrics.parse(song, data)
}
override fun onPreExecute() {
super.onPreExecute()
lyrics = null
}
override fun onPostExecute(l: Lyrics?) {
lyrics = l
offlineLyrics!!.visibility = View.VISIBLE
if (l == null) {
offlineLyrics!!.setText(R.string.no_lyrics_found)
return
}
offlineLyrics!!.text = l.data
}
override fun onCancelled(s: Lyrics) {
onPostExecute(null)
}
}.execute()
}
private fun showSyncedLyrics() {
var content = ""
try {
content = LyricUtil.getStringFromFile(song!!.title, song!!.artistName)
} catch (e: Exception) {
e.printStackTrace()
}
MaterialDialog.Builder(this)
.title("Add lyrics")
.neutralText("Search")
.content("Add time frame lyrics")
.negativeText("Delete")
.onNegative { _, _ ->
LyricUtil.deleteLrcFile(song!!.title, song!!.artistName)
loadLrcFile()
}
.onNeutral { _, _ -> RetroUtil.openUrl(this@LyricsActivity, googleSearchLrcUrl) }
.inputType(InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_MULTI_LINE)
.input("Paste lyrics here", content) { _, input ->
LyricUtil.writeLrcToLoc(song!!.title, song!!.artistName, input.toString())
loadLrcFile()
}.show()
}
private fun showLyricsSaveDialog() {
val content: String = if (lyrics == null) {
""
} else {
lyrics!!.data
}
MaterialDialog.Builder(this)
.title("Add lyrics")
.neutralText("Search")
.onNeutral { _, _ -> RetroUtil.openUrl(this@LyricsActivity, getGoogleSearchUrl(song!!.title, song!!.artistName)) }
.inputType(InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_MULTI_LINE)
.input("Paste lyrics here", content) { _, input ->
val fieldKeyValueMap = EnumMap<FieldKey, String>(FieldKey::class.java)
fieldKeyValueMap[FieldKey.LYRICS] = input.toString()
WriteTagsAsyncTask(this@LyricsActivity).execute(WriteTagsAsyncTask.LoadingInfo(getSongPaths(song!!), fieldKeyValueMap, null))
loadLrcFile()
}
.show()
}
private fun getSongPaths(song: Song): ArrayList<String> {
val paths = ArrayList<String>(1)
paths.add(song.data!!)
return paths
}
private fun getGoogleSearchUrl(title: String?, text: String?): String {
var baseUrl = "http://www.google.com/search?"
var query = "$title+$text"
query = "q=" + query.replace(" ", "+") + " lyrics"
baseUrl += query
return baseUrl
}
}

View file

@ -11,8 +11,8 @@ import android.util.Log
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import androidx.core.app.ShareCompat
import androidx.fragment.app.Fragment
import butterknife.ButterKnife
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.ATHUtil
import code.name.monkey.appthemehelper.util.NavigationViewUtil
@ -29,6 +29,7 @@ import code.name.monkey.retromusic.ui.activities.base.AbsSlidingMusicPanelActivi
import code.name.monkey.retromusic.ui.fragments.mainactivity.LibraryFragment
import code.name.monkey.retromusic.ui.fragments.mainactivity.folders.FoldersFragment
import code.name.monkey.retromusic.ui.fragments.mainactivity.home.BannerHomeFragment
import code.name.monkey.retromusic.util.NavigationUtil
import code.name.monkey.retromusic.util.PreferenceUtil
import com.afollestad.materialdialogs.MaterialDialog
import io.reactivex.disposables.CompositeDisposable
@ -67,7 +68,6 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
override fun onCreate(savedInstanceState: Bundle?) {
setDrawUnderStatusBar()
super.onCreate(savedInstanceState)
ButterKnife.bind(this)
getBottomNavigationView()!!.setOnNavigationItemSelectedListener {
PreferenceUtil.getInstance().lastPage = it.itemId
@ -298,11 +298,31 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
R.id.nav_home -> Handler().postDelayed({ setMusicChooser(HOME) }, 200)
R.id.nav_folders -> Handler().postDelayed({ setMusicChooser(FOLDERS) }, 200)
R.id.buy_pro -> Handler().postDelayed({ startActivityForResult(Intent(this@MainActivity, ProVersionActivity::class.java), PURCHASE_REQUEST) }, 200)
R.id.nav_settings -> Handler().postDelayed({ NavigationUtil.goToSettings(this@MainActivity) }, 200)
R.id.nav_equalizer -> Handler().postDelayed({ NavigationUtil.openEqualizer(this@MainActivity) }, 200)
R.id.nav_share_app -> Handler().postDelayed({ shareApp() }, 200)
R.id.nav_report_bug -> Handler().postDelayed({ prepareBugReport() }, 200)
}
true
}
}
private fun prepareBugReport() {
}
private fun shareApp() {
val shareIntent = ShareCompat.IntentBuilder.from(this)
.setType("songText/plain")
.setText(String.format(getString(R.string.app_share), packageName))
.intent
if (shareIntent.resolveActivity(packageManager) != null) {
startActivity(
Intent.createChooser(shareIntent, resources.getText(R.string.action_share)))
}
}
private fun setMusicChooser(key: Int) {
PreferenceUtil.getInstance().lastMusicChooser = key
when (key) {

View file

@ -1,203 +0,0 @@
package code.name.monkey.retromusic.ui.activities;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.widget.TextView;
import com.google.android.material.appbar.AppBarLayout;
import com.h6ah4i.android.widget.advrecyclerview.animator.GeneralItemAnimator;
import com.h6ah4i.android.widget.advrecyclerview.animator.RefactoredDefaultItemAnimator;
import com.h6ah4i.android.widget.advrecyclerview.draggable.RecyclerViewDragDropManager;
import com.h6ah4i.android.widget.advrecyclerview.utils.WrapperAdapterUtils;
import androidx.annotation.NonNull;
import androidx.appcompat.widget.Toolbar;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import butterknife.BindDrawable;
import butterknife.BindString;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import code.name.monkey.appthemehelper.ThemeStore;
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper;
import code.name.monkey.retromusic.R;
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
import code.name.monkey.retromusic.ui.activities.base.AbsMusicServiceActivity;
import code.name.monkey.retromusic.ui.adapter.song.PlayingQueueAdapter;
import code.name.monkey.retromusic.util.MusicUtil;
import code.name.monkey.retromusic.views.CollapsingFAB;
public class PlayingQueueActivity extends AbsMusicServiceActivity {
@BindView(R.id.toolbar)
Toolbar toolbar;
@BindDrawable(R.drawable.ic_keyboard_backspace_black_24dp)
Drawable close;
@BindView(R.id.player_queue_sub_header)
TextView textView;
@BindString(R.string.queue)
String queue;
@BindView(R.id.app_bar)
AppBarLayout appBarLayout;
@BindView(R.id.title)
TextView title;
@BindView(R.id.recycler_view)
RecyclerView mRecyclerView;
@BindView(R.id.clear_queue)
CollapsingFAB clearQueue;
private RecyclerView.Adapter mWrappedAdapter;
private RecyclerViewDragDropManager mRecyclerViewDragDropManager;
private PlayingQueueAdapter mPlayingQueueAdapter;
private LinearLayoutManager mLayoutManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_playing_queue);
ButterKnife.bind(this);
setStatusbarColorAuto();
setNavigationbarColorAuto();
setTaskDescriptionColorAuto();
setLightNavigationBar(true);
setupToolbar();
setUpRecyclerView();
}
private void setUpRecyclerView() {
mRecyclerViewDragDropManager = new RecyclerViewDragDropManager();
final GeneralItemAnimator animator = new RefactoredDefaultItemAnimator();
mPlayingQueueAdapter = new PlayingQueueAdapter(
this,
MusicPlayerRemote.INSTANCE.getPlayingQueue(),
MusicPlayerRemote.INSTANCE.getPosition(),
R.layout.item_queue);
mWrappedAdapter = mRecyclerViewDragDropManager.createWrappedAdapter(mPlayingQueueAdapter);
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setAdapter(mWrappedAdapter);
mRecyclerView.setItemAnimator(animator);
mRecyclerViewDragDropManager.attachRecyclerView(mRecyclerView);
mLayoutManager.scrollToPositionWithOffset(MusicPlayerRemote.INSTANCE.getPosition() + 1, 0);
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (dy > 0) {
clearQueue.setShowTitle(false);
} else if (dy < 0) {
clearQueue.setShowTitle(true);
}
}
});
}
@Override
public void onQueueChanged() {
if (MusicPlayerRemote.INSTANCE.getPlayingQueue().isEmpty()) {
finish();
return;
}
updateQueue();
updateCurrentSong();
}
@Override
public void onMediaStoreChanged() {
updateQueue();
updateCurrentSong();
}
@SuppressWarnings("ConstantConditions")
private void updateCurrentSong() {
}
@Override
public void onPlayingMetaChanged() {
updateQueuePosition();
}
private void updateQueuePosition() {
mPlayingQueueAdapter.setCurrent(MusicPlayerRemote.INSTANCE.getPosition());
resetToCurrentPosition();
}
private void updateQueue() {
mPlayingQueueAdapter.swapDataSet(MusicPlayerRemote.INSTANCE.getPlayingQueue(), MusicPlayerRemote.INSTANCE.getPosition());
resetToCurrentPosition();
}
private void resetToCurrentPosition() {
mRecyclerView.stopScroll();
mLayoutManager.scrollToPositionWithOffset(MusicPlayerRemote.INSTANCE.getPosition() + 1, 0);
}
@Override
protected void onPause() {
if (mRecyclerViewDragDropManager != null) {
mRecyclerViewDragDropManager.cancelDrag();
}
super.onPause();
}
@Override
public void onDestroy() {
if (mRecyclerViewDragDropManager != null) {
mRecyclerViewDragDropManager.release();
mRecyclerViewDragDropManager = null;
}
if (mRecyclerView != null) {
mRecyclerView.setItemAnimator(null);
mRecyclerView.setAdapter(null);
mRecyclerView = null;
}
if (mWrappedAdapter != null) {
WrapperAdapterUtils.releaseAll(mWrappedAdapter);
mWrappedAdapter = null;
}
mPlayingQueueAdapter = null;
mLayoutManager = null;
super.onDestroy();
}
protected String getUpNextAndQueueTime() {
return getResources().getString(R.string.up_next) + "" + MusicUtil.getReadableDurationString(MusicPlayerRemote.INSTANCE.getQueueDurationMillis(MusicPlayerRemote.INSTANCE.getPosition()));
}
private void setupToolbar() {
title.setTextColor(ThemeStore.textColorPrimary(this));
textView.setText(getUpNextAndQueueTime());
textView.setTextColor(ThemeStore.accentColor(this));
appBarLayout.setBackgroundColor(ThemeStore.primaryColor(this));
toolbar.setBackgroundColor(ThemeStore.primaryColor(this));
toolbar.setNavigationIcon(close);
setSupportActionBar(toolbar);
setTitle(null);
toolbar.setNavigationOnClickListener(v -> onBackPressed());
ToolbarContentTintHelper.colorBackButton(toolbar, ThemeStore.accentColor(this));
clearQueue.setColor(ThemeStore.accentColor(this));
}
@OnClick(R.id.clear_queue)
void clearQueue() {
MusicPlayerRemote.INSTANCE.clearQueue();
}
}

View file

@ -0,0 +1,152 @@
package code.name.monkey.retromusic.ui.activities
import android.os.Bundle
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.ui.activities.base.AbsMusicServiceActivity
import code.name.monkey.retromusic.ui.adapter.song.PlayingQueueAdapter
import code.name.monkey.retromusic.util.MusicUtil
import com.h6ah4i.android.widget.advrecyclerview.animator.RefactoredDefaultItemAnimator
import com.h6ah4i.android.widget.advrecyclerview.draggable.RecyclerViewDragDropManager
import com.h6ah4i.android.widget.advrecyclerview.utils.WrapperAdapterUtils
import kotlinx.android.synthetic.main.activity_playing_queue.*
class PlayingQueueActivity : AbsMusicServiceActivity() {
private var wrappedAdapter: RecyclerView.Adapter<*>? = null
private var recyclerViewDragDropManager: RecyclerViewDragDropManager? = null
private var playingQueueAdapter: PlayingQueueAdapter? = null
private lateinit var layoutManager: LinearLayoutManager
private val upNextAndQueueTime: String
get() = resources.getString(R.string.up_next) + "" + MusicUtil.getReadableDurationString(MusicPlayerRemote.getQueueDurationMillis(MusicPlayerRemote.position))
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_playing_queue)
setStatusbarColorAuto()
setNavigationbarColorAuto()
setTaskDescriptionColorAuto()
setLightNavigationBar(true)
setupToolbar()
setUpRecyclerView()
clearQueue.setOnClickListener {
MusicPlayerRemote.clearQueue()
}
}
private fun setUpRecyclerView() {
recyclerViewDragDropManager = RecyclerViewDragDropManager()
val animator = RefactoredDefaultItemAnimator()
playingQueueAdapter = PlayingQueueAdapter(
this,
MusicPlayerRemote.playingQueue,
MusicPlayerRemote.position,
R.layout.item_queue)
wrappedAdapter = recyclerViewDragDropManager!!.createWrappedAdapter(playingQueueAdapter!!)
layoutManager = LinearLayoutManager(this)
recyclerView.apply {
layoutManager = layoutManager
adapter = wrappedAdapter
itemAnimator = animator
recyclerViewDragDropManager!!.attachRecyclerView(this)
}
layoutManager.scrollToPositionWithOffset(MusicPlayerRemote.position + 1, 0)
recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
if (dy > 0) {
clearQueue.setShowTitle(false)
} else if (dy < 0) {
clearQueue.setShowTitle(true)
}
}
})
}
override fun onQueueChanged() {
if (MusicPlayerRemote.playingQueue.isEmpty()) {
finish()
return
}
updateQueue()
updateCurrentSong()
}
override fun onMediaStoreChanged() {
updateQueue()
updateCurrentSong()
}
private fun updateCurrentSong() {}
override fun onPlayingMetaChanged() {
updateQueuePosition()
}
private fun updateQueuePosition() {
playingQueueAdapter!!.setCurrent(MusicPlayerRemote.position)
resetToCurrentPosition()
}
private fun updateQueue() {
playingQueueAdapter!!.swapDataSet(MusicPlayerRemote.playingQueue, MusicPlayerRemote.position)
resetToCurrentPosition()
}
private fun resetToCurrentPosition() {
recyclerView.stopScroll()
layoutManager.scrollToPositionWithOffset(MusicPlayerRemote.position + 1, 0)
}
override fun onPause() {
if (recyclerViewDragDropManager != null) {
recyclerViewDragDropManager!!.cancelDrag()
}
super.onPause()
}
override fun onDestroy() {
if (recyclerViewDragDropManager != null) {
recyclerViewDragDropManager!!.release()
recyclerViewDragDropManager = null
}
if (wrappedAdapter != null) {
WrapperAdapterUtils.releaseAll(wrappedAdapter)
wrappedAdapter = null
}
playingQueueAdapter = null
super.onDestroy()
}
private fun setupToolbar() {
bannerTitle.setTextColor(ThemeStore.textColorPrimary(this))
playerQueueSubHeader.text = upNextAndQueueTime
playerQueueSubHeader.setTextColor(ThemeStore.accentColor(this))
appBarLayout.setBackgroundColor(ThemeStore.primaryColor(this))
toolbar.setBackgroundColor(ThemeStore.primaryColor(this))
toolbar.setNavigationIcon(R.drawable.ic_close_white_24dp)
setSupportActionBar(toolbar)
title = null
toolbar.setNavigationOnClickListener { onBackPressed() }
ToolbarContentTintHelper.colorBackButton(toolbar, ThemeStore.accentColor(this))
clearQueue.setColor(ThemeStore.accentColor(this))
}
}

View file

@ -6,7 +6,6 @@ import android.view.MenuItem
import android.view.View
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import butterknife.ButterKnife
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
import code.name.monkey.retromusic.R
@ -46,7 +45,6 @@ class PlaylistDetailActivity : AbsSlidingMusicPanelActivity(), CabHolder, Playli
override fun onCreate(savedInstanceState: Bundle?) {
setDrawUnderStatusBar()
super.onCreate(savedInstanceState)
ButterKnife.bind(this)
setStatusbarColorAuto()
setNavigationbarColorAuto()
@ -243,8 +241,8 @@ class PlaylistDetailActivity : AbsSlidingMusicPanelActivity(), CabHolder, Playli
override fun completed() {}
override fun showData(songs: ArrayList<Song>) {
adapter.swapDataSet(songs)
override fun showData(list: ArrayList<Song>) {
adapter.swapDataSet(list)
}
companion object {

View file

@ -1,214 +0,0 @@
package code.name.monkey.retromusic.ui.activities;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import com.anjlab.android.iab.v3.BillingProcessor;
import com.anjlab.android.iab.v3.TransactionDetails;
import com.google.android.material.appbar.AppBarLayout;
import com.google.android.material.button.MaterialButton;
import java.lang.ref.WeakReference;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.Toolbar;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import code.name.monkey.appthemehelper.ThemeStore;
import code.name.monkey.appthemehelper.util.MaterialUtil;
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper;
import code.name.monkey.retromusic.BuildConfig;
import code.name.monkey.retromusic.R;
import code.name.monkey.retromusic.App;
import code.name.monkey.retromusic.ui.activities.base.AbsBaseActivity;
/**
* @author Hemanth S (h4h13).
*/
public class ProVersionActivity extends AbsBaseActivity implements
BillingProcessor.IBillingHandler {
private static final String TAG = "ProVersionActivity";
@BindView(R.id.toolbar)
Toolbar toolbar;
@BindView(R.id.restore_button)
MaterialButton restoreButton;
@BindView(R.id.purchase_button)
MaterialButton purchaseButton;
@BindView(R.id.app_bar)
AppBarLayout appBar;
@BindView(R.id.title)
TextView title;
private BillingProcessor billingProcessor;
private AsyncTask restorePurchaseAsyncTask;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pro_version);
setDrawUnderStatusBar();
ButterKnife.bind(this);
setStatusbarColorAuto();
setNavigationbarColorAuto();
setTaskDescriptionColorAuto();
setLightNavigationBar(true);
int primaryColor = ThemeStore.primaryColor(this);
toolbar.setBackgroundColor(primaryColor);
appBar.setBackgroundColor(primaryColor);
toolbar.setNavigationIcon(R.drawable.ic_keyboard_backspace_black_24dp);
toolbar.setNavigationOnClickListener(v -> onBackPressed());
title.setTextColor(ThemeStore.textColorPrimary(this));
setSupportActionBar(toolbar);
setTitle(null);
ToolbarContentTintHelper.colorBackButton(toolbar, ThemeStore.accentColor(this));
restoreButton.setEnabled(false);
purchaseButton.setEnabled(false);
billingProcessor = new BillingProcessor(this, BuildConfig.GOOGLE_PLAY_LICENSE_KEY, this);
MaterialUtil.setTint(restoreButton, false);
MaterialUtil.setTint(purchaseButton, true);
}
private void restorePurchase() {
if (restorePurchaseAsyncTask != null) {
restorePurchaseAsyncTask.cancel(false);
}
restorePurchaseAsyncTask = new RestorePurchaseAsyncTask(this).execute();
}
@OnClick({R.id.restore_button, R.id.purchase_button})
public void onViewClicked(View view) {
switch (view.getId()) {
case R.id.restore_button:
if (restorePurchaseAsyncTask == null
|| restorePurchaseAsyncTask.getStatus() != AsyncTask.Status.RUNNING) {
restorePurchase();
}
break;
case R.id.purchase_button:
billingProcessor.purchase(ProVersionActivity.this, App.PRO_VERSION_PRODUCT_ID);
break;
}
}
@Override
public void onProductPurchased(@NonNull String productId, @Nullable TransactionDetails details) {
Toast.makeText(this, R.string.thank_you, Toast.LENGTH_SHORT).show();
setResult(RESULT_OK);
}
@Override
public void onPurchaseHistoryRestored() {
if (App.Companion.isProVersion()) {
Toast.makeText(this, R.string.restored_previous_purchase_please_restart, Toast.LENGTH_LONG)
.show();
setResult(RESULT_OK);
} else {
Toast.makeText(this, R.string.no_purchase_found, Toast.LENGTH_SHORT).show();
}
}
@Override
public void onBillingError(int errorCode, @Nullable Throwable error) {
Log.e(TAG, "Billing error: code = " + errorCode, error);
}
@Override
public void onBillingInitialized() {
restoreButton.setEnabled(true);
purchaseButton.setEnabled(true);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (!billingProcessor.handleActivityResult(requestCode, resultCode, data)) {
super.onActivityResult(requestCode, resultCode, data);
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
break;
}
return super.onOptionsItemSelected(item);
}
@Override
public void onDestroy() {
if (billingProcessor != null) {
billingProcessor.release();
}
super.onDestroy();
}
private static class RestorePurchaseAsyncTask extends AsyncTask<Void, Void, Boolean> {
private final WeakReference<ProVersionActivity> buyActivityWeakReference;
RestorePurchaseAsyncTask(ProVersionActivity purchaseActivity) {
this.buyActivityWeakReference = new WeakReference<>(purchaseActivity);
}
@Override
protected void onPreExecute() {
super.onPreExecute();
ProVersionActivity purchaseActivity = buyActivityWeakReference.get();
if (purchaseActivity != null) {
Toast.makeText(purchaseActivity, R.string.restoring_purchase, Toast.LENGTH_SHORT).show();
} else {
cancel(false);
}
}
@Override
protected Boolean doInBackground(Void... params) {
ProVersionActivity purchaseActivity = buyActivityWeakReference.get();
if (purchaseActivity != null) {
return purchaseActivity.billingProcessor.loadOwnedPurchasesFromGoogle();
}
cancel(false);
return null;
}
@Override
protected void onPostExecute(Boolean b) {
super.onPostExecute(b);
ProVersionActivity purchaseActivity = buyActivityWeakReference.get();
if (purchaseActivity == null || b == null) {
return;
}
if (b) {
purchaseActivity.onPurchaseHistoryRestored();
} else {
Toast.makeText(purchaseActivity, R.string.could_not_restore_purchase, Toast.LENGTH_SHORT)
.show();
}
}
}
}

View file

@ -0,0 +1,167 @@
package code.name.monkey.retromusic.ui.activities
import android.app.Activity
import android.content.Intent
import android.os.AsyncTask
import android.os.Bundle
import android.util.Log
import android.view.MenuItem
import android.widget.Toast
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.MaterialUtil
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
import code.name.monkey.retromusic.App
import code.name.monkey.retromusic.BuildConfig
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.ui.activities.base.AbsBaseActivity
import com.anjlab.android.iab.v3.BillingProcessor
import com.anjlab.android.iab.v3.TransactionDetails
import kotlinx.android.synthetic.main.activity_pro_version.*
import kotlinx.android.synthetic.main.activity_pro_version_content.*
import java.lang.ref.WeakReference
class ProVersionActivity : AbsBaseActivity(), BillingProcessor.IBillingHandler {
private var billingProcessor: BillingProcessor? = null
private var restorePurchaseAsyncTask: AsyncTask<*, *, *>? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_pro_version)
setDrawUnderStatusBar()
setStatusbarColorAuto()
setNavigationbarColorAuto()
setTaskDescriptionColorAuto()
setLightNavigationBar(true)
val primaryColor = ThemeStore.primaryColor(this)
toolbar.setBackgroundColor(primaryColor)
appBarLayout.setBackgroundColor(primaryColor)
toolbar.setNavigationIcon(R.drawable.ic_keyboard_backspace_black_24dp)
toolbar.setNavigationOnClickListener { v -> onBackPressed() }
bannerTitle.setTextColor(ThemeStore.textColorPrimary(this))
setSupportActionBar(toolbar)
title = null
ToolbarContentTintHelper.colorBackButton(toolbar, ThemeStore.accentColor(this))
restoreButton.isEnabled = false
purchaseButton.isEnabled = false
billingProcessor = BillingProcessor(this, BuildConfig.GOOGLE_PLAY_LICENSE_KEY, this)
MaterialUtil.setTint(restoreButton, false)
MaterialUtil.setTint(purchaseButton, true)
restoreButton.setOnClickListener {
if (restorePurchaseAsyncTask == null || restorePurchaseAsyncTask!!.status != AsyncTask.Status.RUNNING) {
restorePurchase()
}
}
purchaseButton.setOnClickListener {
billingProcessor!!.purchase(this@ProVersionActivity, App.PRO_VERSION_PRODUCT_ID)
}
}
private fun restorePurchase() {
if (restorePurchaseAsyncTask != null) {
restorePurchaseAsyncTask!!.cancel(false)
}
restorePurchaseAsyncTask = RestorePurchaseAsyncTask(this).execute()
}
override fun onProductPurchased(productId: String, details: TransactionDetails?) {
Toast.makeText(this, R.string.thank_you, Toast.LENGTH_SHORT).show()
setResult(Activity.RESULT_OK)
}
override fun onPurchaseHistoryRestored() {
if (App.isProVersion) {
Toast.makeText(this, R.string.restored_previous_purchase_please_restart, Toast.LENGTH_LONG)
.show()
setResult(Activity.RESULT_OK)
} else {
Toast.makeText(this, R.string.no_purchase_found, Toast.LENGTH_SHORT).show()
}
}
override fun onBillingError(errorCode: Int, error: Throwable?) {
Log.e(TAG, "Billing error: code = $errorCode", error)
}
override fun onBillingInitialized() {
restoreButton.isEnabled = true
purchaseButton.isEnabled = true
}
public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (!billingProcessor!!.handleActivityResult(requestCode, resultCode, data)) {
super.onActivityResult(requestCode, resultCode, data)
}
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
android.R.id.home -> finish()
}
return super.onOptionsItemSelected(item)
}
override fun onDestroy() {
if (billingProcessor != null) {
billingProcessor!!.release()
}
super.onDestroy()
}
private class RestorePurchaseAsyncTask internal constructor(purchaseActivity: ProVersionActivity) : AsyncTask<Void, Void, Boolean>() {
private val buyActivityWeakReference: WeakReference<ProVersionActivity> = WeakReference(purchaseActivity)
override fun onPreExecute() {
super.onPreExecute()
val purchaseActivity = buyActivityWeakReference.get()
if (purchaseActivity != null) {
Toast.makeText(purchaseActivity, R.string.restoring_purchase, Toast.LENGTH_SHORT).show()
} else {
cancel(false)
}
}
override fun doInBackground(vararg params: Void): Boolean? {
val purchaseActivity = buyActivityWeakReference.get()
if (purchaseActivity != null) {
return purchaseActivity.billingProcessor!!.loadOwnedPurchasesFromGoogle()
}
cancel(false)
return null
}
override fun onPostExecute(b: Boolean?) {
super.onPostExecute(b)
val purchaseActivity = buyActivityWeakReference.get()
if (purchaseActivity == null || b == null) {
return
}
if (b) {
purchaseActivity.onPurchaseHistoryRestored()
} else {
Toast.makeText(purchaseActivity, R.string.could_not_restore_purchase, Toast.LENGTH_SHORT).show()
}
}
}
companion object {
private val TAG: String = "ProVersionActivity"
}
}

View file

@ -1,252 +0,0 @@
package code.name.monkey.retromusic.ui.activities;
import android.app.SearchManager;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.os.Bundle;
import android.speech.RecognizerIntent;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.appcompat.widget.SearchView.OnQueryTextListener;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.TextView.BufferType;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Locale;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import code.name.monkey.retromusic.R;
import code.name.monkey.retromusic.mvp.contract.SearchContract;
import code.name.monkey.retromusic.mvp.presenter.SearchPresenter;
import code.name.monkey.retromusic.ui.activities.base.AbsMusicServiceActivity;
import code.name.monkey.retromusic.ui.adapter.SearchAdapter;
import code.name.monkey.retromusic.util.RetroUtil;
import code.name.monkey.retromusic.util.ViewUtil;
public class SearchActivity extends AbsMusicServiceActivity implements OnQueryTextListener,
SearchContract.SearchView, TextWatcher {
public static final String TAG = SearchActivity.class.getSimpleName();
public static final String QUERY = "query";
private static final int REQ_CODE_SPEECH_INPUT = 9002;
@BindView(R.id.voice_search)
View micIcon;
@BindView(R.id.recycler_view)
RecyclerView recyclerView;
@BindView(android.R.id.empty)
TextView empty;
@BindView(R.id.search_view)
EditText searchView;
@BindView(R.id.status_bar)
View statusBar;
private SearchPresenter searchPresenter;
private SearchAdapter adapter;
private String query;
@Override
protected void onCreate(Bundle savedInstanceState) {
setDrawUnderStatusBar();
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search);
ButterKnife.bind(this);
ViewUtil.setStatusBarHeight(this, statusBar);
searchPresenter = new SearchPresenter(this);
setStatusbarColorAuto();
setNavigationbarColorAuto();
setTaskDescriptionColorAuto();
setLightNavigationBar(true);
setupRecyclerview();
setUpToolBar();
setupSearchView();
if (savedInstanceState != null) {
query = savedInstanceState.getString(QUERY);
searchPresenter.search(query);
}
if (getIntent().getBooleanExtra("mic_search", false)) {
startMicSearch();
boolean isMicSearch = true;
}
}
private void setupRecyclerview() {
recyclerView.setLayoutManager(new LinearLayoutManager(this));
adapter = new SearchAdapter(this, Collections.emptyList());
adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
@Override
public void onChanged() {
super.onChanged();
empty.setVisibility(adapter.getItemCount() < 1 ? View.VISIBLE : View.GONE);
}
});
recyclerView.setAdapter(adapter);
}
private void setupSearchView() {
SearchManager searchManager = (SearchManager) getSystemService(SEARCH_SERVICE);
if (searchManager != null) {
searchView.addTextChangedListener(this);
}
}
@Override
protected void onResume() {
super.onResume();
//Log.i(TAG, "onResume: " + query);
searchPresenter.subscribe();
searchPresenter.search(query);
}
@Override
public void onDestroy() {
super.onDestroy();
searchPresenter.unsubscribe();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString(QUERY, query);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
searchPresenter.search(savedInstanceState.getString(QUERY, ""));
}
private void setUpToolBar() {
setTitle(null);
}
private void search(@NonNull String query) {
this.query = query.trim();
micIcon.setVisibility(query.length() > 0 ? View.GONE : View.VISIBLE);
searchPresenter.search(query);
}
@Override
public void onMediaStoreChanged() {
super.onMediaStoreChanged();
searchPresenter.search(query);
}
@Override
public boolean onQueryTextSubmit(String query) {
hideSoftKeyboard();
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
search(newText);
return false;
}
private void hideSoftKeyboard() {
RetroUtil.hideSoftKeyboard(SearchActivity.this);
if (searchView != null) {
searchView.clearFocus();
}
}
@Override
public void loading() {
}
@Override
public void showEmptyView() {
adapter.swapDataSet(new ArrayList<>());
}
@Override
public void completed() {
}
@Override
public void showData(ArrayList<Object> list) {
adapter.swapDataSet(list);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case REQ_CODE_SPEECH_INPUT: {
if (resultCode == RESULT_OK && null != data) {
ArrayList<String> result = data
.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
query = result.get(0);
searchView.setText(query, BufferType.EDITABLE);
searchPresenter.search(query);
}
break;
}
}
}
@OnClick({R.id.voice_search, R.id.back})
void searchImageView(View view) {
switch (view.getId()) {
case R.id.voice_search:
startMicSearch();
break;
case R.id.back:
finish();
break;
}
}
private void startMicSearch() {
Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.getDefault());
intent.putExtra(RecognizerIntent.EXTRA_PROMPT, getString(R.string.speech_prompt));
try {
startActivityForResult(intent, REQ_CODE_SPEECH_INPUT);
} catch (ActivityNotFoundException e) {
e.printStackTrace();
Toast.makeText(this, getString(R.string.speech_not_supported), Toast.LENGTH_SHORT).show();
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence newText, int start, int before, int count) {
search(newText.toString());
}
@Override
public void afterTextChanged(Editable s) {
}
}

View file

@ -0,0 +1,201 @@
package code.name.monkey.retromusic.ui.activities
import android.app.Activity
import android.app.SearchManager
import android.content.ActivityNotFoundException
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.speech.RecognizerIntent
import android.text.Editable
import android.text.TextWatcher
import android.view.View
import android.widget.TextView.BufferType
import android.widget.Toast
import androidx.appcompat.widget.SearchView.OnQueryTextListener
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.mvp.contract.SearchContract
import code.name.monkey.retromusic.mvp.presenter.SearchPresenter
import code.name.monkey.retromusic.ui.activities.base.AbsMusicServiceActivity
import code.name.monkey.retromusic.ui.adapter.SearchAdapter
import code.name.monkey.retromusic.util.RetroUtil
import kotlinx.android.synthetic.main.activity_search.*
import java.util.*
class SearchActivity : AbsMusicServiceActivity(), OnQueryTextListener, SearchContract.SearchView, TextWatcher {
private var searchPresenter: SearchPresenter? = null
private var searchAdapter: SearchAdapter? = null
private var query: String? = null
override fun onCreate(savedInstanceState: Bundle?) {
setDrawUnderStatusBar()
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_search)
searchPresenter = SearchPresenter(this)
setStatusbarColorAuto()
setNavigationbarColorAuto()
setTaskDescriptionColorAuto()
setLightNavigationBar(true)
setupRecyclerView()
setUpToolBar()
setupSearchView()
if (savedInstanceState != null) {
query = savedInstanceState.getString(QUERY)
searchPresenter!!.search(query!!)
}
if (intent.getBooleanExtra("mic_search", false)) {
startMicSearch()
}
voiceSearch.setOnClickListener { startMicSearch() }
}
private fun setupRecyclerView() {
searchAdapter = SearchAdapter(this, emptyList())
searchAdapter!!.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
override fun onChanged() {
super.onChanged()
empty.visibility = if (searchAdapter!!.itemCount < 1) View.VISIBLE else View.GONE
}
})
recyclerView.apply {
layoutManager = LinearLayoutManager(this@SearchActivity)
adapter = searchAdapter
}
}
private fun setupSearchView() {
getSystemService(Context.SEARCH_SERVICE) as SearchManager
searchView.addTextChangedListener(this)
}
override fun onResume() {
super.onResume()
searchPresenter!!.subscribe()
searchPresenter!!.search(query!!)
}
override fun onDestroy() {
super.onDestroy()
searchPresenter!!.unsubscribe()
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putString(QUERY, query)
}
override fun onRestoreInstanceState(savedInstanceState: Bundle) {
super.onRestoreInstanceState(savedInstanceState)
searchPresenter!!.search(savedInstanceState.getString(QUERY, ""))
}
private fun setUpToolBar() {
title = null
}
private fun search(query: String) {
this.query = query.trim { it <= ' ' }
voiceSearch.visibility = if (query.isNotEmpty()) View.GONE else View.VISIBLE
searchPresenter!!.search(query)
}
override fun onMediaStoreChanged() {
super.onMediaStoreChanged()
searchPresenter!!.search(query!!)
}
override fun onQueryTextSubmit(query: String): Boolean {
hideSoftKeyboard()
return false
}
override fun onQueryTextChange(newText: String): Boolean {
search(newText)
return false
}
private fun hideSoftKeyboard() {
RetroUtil.hideSoftKeyboard(this@SearchActivity)
if (searchView != null) {
searchView.clearFocus()
}
}
override fun loading() {
}
override fun showEmptyView() {
searchAdapter!!.swapDataSet(ArrayList())
}
override fun completed() {
}
override fun showData(list: ArrayList<Any>) {
searchAdapter!!.swapDataSet(list)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when (requestCode) {
REQ_CODE_SPEECH_INPUT -> {
if (resultCode == Activity.RESULT_OK && null != data) {
val result = data
.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS)
query = result[0]
searchView.setText(query, BufferType.EDITABLE)
searchPresenter!!.search(query!!)
}
}
}
}
private fun startMicSearch() {
val intent = Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH)
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM)
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.getDefault())
intent.putExtra(RecognizerIntent.EXTRA_PROMPT, getString(R.string.speech_prompt))
try {
startActivityForResult(intent, REQ_CODE_SPEECH_INPUT)
} catch (e: ActivityNotFoundException) {
e.printStackTrace()
Toast.makeText(this, getString(R.string.speech_not_supported), Toast.LENGTH_SHORT).show()
}
}
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(newText: CharSequence, start: Int, before: Int, count: Int) {
search(newText.toString())
}
override fun afterTextChanged(s: Editable) {
}
companion object {
val TAG: String = SearchActivity::class.java.simpleName
const val QUERY: String = "query"
private const val REQ_CODE_SPEECH_INPUT = 9002
}
}

View file

@ -6,7 +6,6 @@ import android.view.MenuItem
import androidx.annotation.ColorInt
import androidx.annotation.StringRes
import androidx.fragment.app.Fragment
import butterknife.ButterKnife
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.ColorUtil
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
@ -43,7 +42,6 @@ class SettingsActivity : AbsBaseActivity(), ColorChooserDialog.ColorCallback, Sh
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_settings)
ButterKnife.bind(this)
setStatusbarColorAuto()
setNavigationbarColorAuto()

View file

@ -1,379 +0,0 @@
package code.name.monkey.retromusic.ui.activities;
import android.content.Intent;
import android.content.res.ColorStateList;
import android.graphics.Paint;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.afollestad.materialdialogs.MaterialDialog;
import com.afollestad.materialdialogs.internal.MDTintHelper;
import com.anjlab.android.iab.v3.BillingProcessor;
import com.anjlab.android.iab.v3.SkuDetails;
import com.anjlab.android.iab.v3.TransactionDetails;
import com.google.android.material.appbar.AppBarLayout;
import com.google.android.material.button.MaterialButton;
import org.json.JSONException;
import org.json.JSONObject;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.Toolbar;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import code.name.monkey.appthemehelper.ThemeStore;
import code.name.monkey.appthemehelper.util.ATHUtil;
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper;
import code.name.monkey.retromusic.BuildConfig;
import code.name.monkey.retromusic.R;
import code.name.monkey.retromusic.ui.activities.base.AbsBaseActivity;
import code.name.monkey.retromusic.util.RetroUtil;
import code.name.monkey.retromusic.views.IconImageView;
import static code.name.monkey.retromusic.Constants.PAYPAL_ME_URL;
/**
* @author Hemanth S (h4h13).
*/
public class SupportDevelopmentActivity extends AbsBaseActivity implements BillingProcessor.IBillingHandler {
public static final String TAG = SupportDevelopmentActivity.class.getSimpleName();
private static final int DONATION_PRODUCT_IDS = R.array.donation_ids;
private static final int TEZ_REQUEST_CODE = 123;
private static final String GOOGLE_TEZ_PACKAGE_NAME = "com.google.android.apps.nbu.paisa.user";
@BindView(R.id.progress)
ProgressBar progressBar;
@BindView(R.id.progress_container)
View progressContainer;
@BindView(R.id.list)
RecyclerView recyclerView;
@BindView(R.id.toolbar)
Toolbar toolbar;
@BindView(R.id.app_bar)
AppBarLayout appBarLayout;
@BindView(R.id.root)
ViewGroup viewGroup;
@BindView(R.id.title)
TextView title;
@BindView(R.id.donate)
MaterialButton materialButton;
private BillingProcessor billingProcessor;
private AsyncTask skuDetailsLoadAsyncTask;
private static List<SkuDetails> getDetails() {
List<SkuDetails> skuDetails = new ArrayList<>();
JSONObject jsonObject = new JSONObject();
try {
for (int i = 0; i < 6; i++) {
jsonObject.put("songTitle", "Coffee");
jsonObject.put("price", "$100");
jsonObject.put("description", "" + i);
skuDetails.add(new SkuDetails(jsonObject));
}
} catch (JSONException e) {
e.printStackTrace();
}
return skuDetails;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
private void donate(int i) {
final String[] ids = getResources().getStringArray(DONATION_PRODUCT_IDS);
billingProcessor.purchase(this, ids[i]);
}
@OnClick(R.id.donate)
void donate() {
RetroUtil.openUrl(this,PAYPAL_ME_URL);
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_donation);
ButterKnife.bind(this);
setStatusbarColorAuto();
setNavigationbarColorAuto();
setTaskDescriptionColorAuto();
setLightNavigationBar(true);
setupToolbar();
billingProcessor = new BillingProcessor(this, BuildConfig.GOOGLE_PLAY_LICENSE_KEY, this);
MDTintHelper.setTint(progressBar, ThemeStore.accentColor(this));
((TextView) findViewById(R.id.donation)).setTextColor(ThemeStore.accentColor(this));
}
private void setupToolbar() {
title.setTextColor(ThemeStore.textColorPrimary(this));
int primaryColor = ThemeStore.primaryColor(this);
appBarLayout.setBackgroundColor(primaryColor);
toolbar.setBackgroundColor(primaryColor);
toolbar.setNavigationOnClickListener(view -> onBackPressed());
toolbar.setNavigationIcon(R.drawable.ic_keyboard_backspace_black_24dp);
setSupportActionBar(toolbar);
setTitle(null);
materialButton.setBackgroundTintList(ColorStateList.valueOf(ThemeStore.accentColor(this)));
ToolbarContentTintHelper.colorBackButton(toolbar, ThemeStore.accentColor(this));
}
@Override
public void onBillingInitialized() {
loadSkuDetails();
}
private void loadSkuDetails() {
if (skuDetailsLoadAsyncTask != null) {
skuDetailsLoadAsyncTask.cancel(false);
}
skuDetailsLoadAsyncTask = new SkuDetailsLoadAsyncTask(this).execute();
}
@Override
public void onProductPurchased(@NonNull String productId, TransactionDetails details) {
//loadSkuDetails();
Toast.makeText(this, R.string.thank_you, Toast.LENGTH_SHORT).show();
}
@Override
public void onBillingError(int errorCode, Throwable error) {
Log.e(TAG, "Billing error: code = " + errorCode, error);
}
@Override
public void onPurchaseHistoryRestored() {
//loadSkuDetails();
Toast.makeText(this, R.string.restored_previous_purchases, Toast.LENGTH_SHORT).show();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (!billingProcessor.handleActivityResult(requestCode, resultCode, data)) {
super.onActivityResult(requestCode, resultCode, data);
}
if (requestCode == TEZ_REQUEST_CODE) {
// Process based on the data in response.
Log.d("result", data.getStringExtra("Status"));
}
}
@Override
public void onDestroy() {
if (billingProcessor != null) {
billingProcessor.release();
}
if (skuDetailsLoadAsyncTask != null) {
skuDetailsLoadAsyncTask.cancel(true);
}
super.onDestroy();
}
@OnClick(R.id.google_pay)
void googlePay() {
new MaterialDialog.Builder(this)
.title(R.string.support_development)
.input("Enter amount", null, false, (dialog, input) -> {
Uri uri = new Uri.Builder()
.scheme("upi")
.authority("pay")
.appendQueryParameter("pa", "hemanth.vaniraviram@okaxis")
.appendQueryParameter("pn", "Retro Music")
.appendQueryParameter("mc", "1234")
.appendQueryParameter("tr", "7406201323")
.appendQueryParameter("tn", "Retro Music Player Donation")
.appendQueryParameter("am", "10.01")
.appendQueryParameter("cu", "INR")
.build();
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(uri);
intent.setPackage(GOOGLE_TEZ_PACKAGE_NAME);
startActivityForResult(intent, TEZ_REQUEST_CODE);
}).positiveText("Donate")
.onPositive((dialog, which) -> {
}).show();
}
private static class SkuDetailsLoadAsyncTask extends AsyncTask<Void, Void, List<SkuDetails>> {
private final WeakReference<SupportDevelopmentActivity> donationDialogWeakReference;
SkuDetailsLoadAsyncTask(SupportDevelopmentActivity donationsDialog) {
this.donationDialogWeakReference = new WeakReference<>(donationsDialog);
}
@Override
protected void onPreExecute() {
super.onPreExecute();
SupportDevelopmentActivity dialog = donationDialogWeakReference.get();
if (dialog == null) return;
dialog.progressContainer.setVisibility(View.VISIBLE);
dialog.recyclerView.setVisibility(View.GONE);
}
@Override
protected List<SkuDetails> doInBackground(Void... params) {
SupportDevelopmentActivity dialog = donationDialogWeakReference.get();
if (dialog != null) {
final String[] ids = dialog.getResources().getStringArray(DONATION_PRODUCT_IDS);
return dialog.billingProcessor.getPurchaseListingDetails(new ArrayList<>(Arrays.asList(ids)));
}
cancel(false);
return null;
}
@Override
protected void onPostExecute(List<SkuDetails> skuDetails) {
super.onPostExecute(skuDetails);
SupportDevelopmentActivity dialog = donationDialogWeakReference.get();
if (dialog == null) return;
if (skuDetails == null || skuDetails.isEmpty()) {
dialog.progressContainer.setVisibility(View.GONE);
return;
}
//noinspection ConstantConditions
dialog.progressContainer.setVisibility(View.GONE);
dialog.recyclerView.setItemAnimator(new DefaultItemAnimator());
dialog.recyclerView.setLayoutManager(new GridLayoutManager(dialog, 2));
dialog.recyclerView.setAdapter(new SkuDetailsAdapter(dialog, skuDetails));
dialog.recyclerView.setVisibility(View.VISIBLE);
}
}
static class SkuDetailsAdapter extends RecyclerView.Adapter<SkuDetailsAdapter.ViewHolder> {
@LayoutRes
private static int LAYOUT_RES_ID = R.layout.item_donation_option;
SupportDevelopmentActivity donationsDialog;
List<SkuDetails> skuDetailsList = new ArrayList<>();
SkuDetailsAdapter(@NonNull SupportDevelopmentActivity donationsDialog, @NonNull List<SkuDetails> objects) {
this.donationsDialog = donationsDialog;
skuDetailsList = objects;
}
private static void strikeThrough(TextView textView, boolean strikeThrough) {
textView.setPaintFlags(strikeThrough ? textView.getPaintFlags() |
Paint.STRIKE_THRU_TEXT_FLAG : textView.getPaintFlags() & ~Paint.STRIKE_THRU_TEXT_FLAG);
}
private int getIcon(int position) {
switch (position) {
case 0:
return R.drawable.ic_cookie_white_24dp;
case 1:
return R.drawable.ic_take_away_white_24dp;
case 2:
return R.drawable.ic_take_away_coffe_white_24dp;
case 3:
return R.drawable.ic_beer_white_24dp;
case 4:
return R.drawable.ic_fast_food_meal_white_24dp;
case 5:
return R.drawable.ic_popcorn_white_24dp;
case 6:
return R.drawable.ic_card_giftcard_white_24dp;
default:
return R.drawable.ic_card_giftcard_white_24dp;
}
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
return new ViewHolder(LayoutInflater.from(donationsDialog)
.inflate(LAYOUT_RES_ID, viewGroup, false));
}
@Override
public void onBindViewHolder(@NonNull ViewHolder viewHolder, int i) {
SkuDetails skuDetails = skuDetailsList.get(i);
if (skuDetails != null) {
viewHolder.title.setText(skuDetails.title.replace("(Retro Music Player)", "").trim());
viewHolder.text.setText(skuDetails.description);
viewHolder.text.setVisibility(View.GONE);
viewHolder.price.setText(skuDetails.priceText);
viewHolder.image.setImageResource(getIcon(i));
final boolean purchased = donationsDialog.billingProcessor.isPurchased(skuDetails.productId);
int titleTextColor = purchased ? ATHUtil.resolveColor(donationsDialog, android.R.attr.textColorHint) : ThemeStore.textColorPrimary(donationsDialog);
int contentTextColor = purchased ? titleTextColor : ThemeStore.textColorSecondary(donationsDialog);
//noinspection ResourceAsColor
viewHolder.title.setTextColor(titleTextColor);
viewHolder.text.setTextColor(contentTextColor);
viewHolder.price.setTextColor(titleTextColor);
strikeThrough(viewHolder.title, purchased);
strikeThrough(viewHolder.text, purchased);
strikeThrough(viewHolder.price, purchased);
viewHolder.itemView.setOnTouchListener((v, event) -> purchased);
viewHolder.itemView.setOnClickListener(v -> donationsDialog.donate(i));
}
}
@Override
public int getItemCount() {
return skuDetailsList.size();
}
static class ViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.title)
TextView title;
@BindView(R.id.text)
TextView text;
@BindView(R.id.price)
TextView price;
@BindView(R.id.image)
IconImageView image;
public ViewHolder(View view) {
super(view);
ButterKnife.bind(this, view);
}
}
}
}

View file

@ -0,0 +1,252 @@
package code.name.monkey.retromusic.ui.activities
import android.content.Intent
import android.content.res.ColorStateList
import android.graphics.Paint
import android.os.AsyncTask
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import android.widget.Toast
import androidx.annotation.LayoutRes
import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.ATHUtil
import code.name.monkey.appthemehelper.util.TintHelper
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
import code.name.monkey.retromusic.BuildConfig
import code.name.monkey.retromusic.Constants.PAYPAL_ME_URL
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.ui.activities.base.AbsBaseActivity
import code.name.monkey.retromusic.util.RetroUtil
import code.name.monkey.retromusic.views.IconImageView
import com.anjlab.android.iab.v3.BillingProcessor
import com.anjlab.android.iab.v3.SkuDetails
import com.anjlab.android.iab.v3.TransactionDetails
import kotlinx.android.synthetic.main.activity_donation.*
import java.lang.ref.WeakReference
import java.util.*
class SupportDevelopmentActivity : AbsBaseActivity(), BillingProcessor.IBillingHandler {
companion object {
val TAG: String = SupportDevelopmentActivity::class.java.simpleName
const val DONATION_PRODUCT_IDS = R.array.donation_ids
private const val TEZ_REQUEST_CODE = 123
}
var billingProcessor: BillingProcessor? = null
private var skuDetailsLoadAsyncTask: AsyncTask<*, *, *>? = null
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (item.itemId == android.R.id.home) {
onBackPressed()
return true
}
return super.onOptionsItemSelected(item)
}
fun donate(i: Int) {
val ids = resources.getStringArray(DONATION_PRODUCT_IDS)
billingProcessor!!.purchase(this, ids[i])
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_donation)
setStatusbarColorAuto()
setNavigationbarColorAuto()
setTaskDescriptionColorAuto()
setLightNavigationBar(true)
setupToolbar()
billingProcessor = BillingProcessor(this, BuildConfig.GOOGLE_PLAY_LICENSE_KEY, this)
TintHelper.setTint(progress, ThemeStore.accentColor(this))
donation.setTextColor(ThemeStore.accentColor(this))
donate.setOnClickListener {
RetroUtil.openUrl(this, PAYPAL_ME_URL)
}
}
private fun setupToolbar() {
bannerTitle.setTextColor(ThemeStore.textColorPrimary(this))
val primaryColor = ThemeStore.primaryColor(this)
appBarLayout.setBackgroundColor(primaryColor)
toolbar.setBackgroundColor(primaryColor)
toolbar.setNavigationOnClickListener { onBackPressed() }
toolbar.setNavigationIcon(R.drawable.ic_keyboard_backspace_black_24dp)
setSupportActionBar(toolbar)
title = null
donate.backgroundTintList = ColorStateList.valueOf(ThemeStore.accentColor(this))
ToolbarContentTintHelper.colorBackButton(toolbar, ThemeStore.accentColor(this))
}
override fun onBillingInitialized() {
loadSkuDetails()
}
private fun loadSkuDetails() {
if (skuDetailsLoadAsyncTask != null) {
skuDetailsLoadAsyncTask!!.cancel(false)
}
skuDetailsLoadAsyncTask = SkuDetailsLoadAsyncTask(this).execute()
}
override fun onProductPurchased(productId: String, details: TransactionDetails?) {
//loadSkuDetails();
Toast.makeText(this, R.string.thank_you, Toast.LENGTH_SHORT).show()
}
override fun onBillingError(errorCode: Int, error: Throwable?) {
Log.e(TAG, "Billing error: code = $errorCode", error)
}
override fun onPurchaseHistoryRestored() {
//loadSkuDetails();
Toast.makeText(this, R.string.restored_previous_purchases, Toast.LENGTH_SHORT).show()
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (!billingProcessor!!.handleActivityResult(requestCode, resultCode, data)) {
super.onActivityResult(requestCode, resultCode, data)
}
if (requestCode == TEZ_REQUEST_CODE) {
// Process based on the data in response.
Log.d("result", data!!.getStringExtra("Status"))
}
}
override fun onDestroy() {
if (billingProcessor != null) {
billingProcessor!!.release()
}
if (skuDetailsLoadAsyncTask != null) {
skuDetailsLoadAsyncTask!!.cancel(true)
}
super.onDestroy()
}
}
private class SkuDetailsLoadAsyncTask internal constructor(supportDevelopmentActivity: SupportDevelopmentActivity) : AsyncTask<Void, Void, List<SkuDetails>>() {
private val weakReference: WeakReference<SupportDevelopmentActivity> = WeakReference(supportDevelopmentActivity)
override fun onPreExecute() {
super.onPreExecute()
val supportDevelopmentActivity = weakReference.get() ?: return
supportDevelopmentActivity.progressContainer.visibility = View.VISIBLE
supportDevelopmentActivity.recyclerView.visibility = View.GONE
}
override fun doInBackground(vararg params: Void): List<SkuDetails>? {
val dialog = weakReference.get()
if (dialog != null) {
val ids = dialog.resources.getStringArray(SupportDevelopmentActivity.DONATION_PRODUCT_IDS)
return dialog.billingProcessor!!.getPurchaseListingDetails(ArrayList(Arrays.asList(*ids)))
}
cancel(false)
return null
}
override fun onPostExecute(skuDetails: List<SkuDetails>?) {
super.onPostExecute(skuDetails)
val dialog = weakReference.get() ?: return
if (skuDetails == null || skuDetails.isEmpty()) {
dialog.progressContainer.visibility = View.GONE
return
}
dialog.progressContainer.visibility = View.GONE
dialog.recyclerView.itemAnimator = DefaultItemAnimator()
dialog.recyclerView.layoutManager = GridLayoutManager(dialog, 2)
dialog.recyclerView.adapter = SkuDetailsAdapter(dialog, skuDetails)
dialog.recyclerView.visibility = View.VISIBLE
}
}
class SkuDetailsAdapter(private var donationsDialog: SupportDevelopmentActivity, objects: List<SkuDetails>) : RecyclerView.Adapter<SkuDetailsAdapter.ViewHolder>() {
private var skuDetailsList: List<SkuDetails> = ArrayList()
init {
skuDetailsList = objects
}
private fun getIcon(position: Int): Int {
return when (position) {
0 -> R.drawable.ic_cookie_white_24dp
1 -> R.drawable.ic_take_away_white_24dp
2 -> R.drawable.ic_take_away_coffe_white_24dp
3 -> R.drawable.ic_beer_white_24dp
4 -> R.drawable.ic_fast_food_meal_white_24dp
5 -> R.drawable.ic_popcorn_white_24dp
6 -> R.drawable.ic_card_giftcard_white_24dp
else -> R.drawable.ic_card_giftcard_white_24dp
}
}
override fun onCreateViewHolder(viewGroup: ViewGroup, i: Int): ViewHolder {
return ViewHolder(LayoutInflater.from(donationsDialog).inflate(LAYOUT_RES_ID, viewGroup, false))
}
override fun onBindViewHolder(viewHolder: ViewHolder, i: Int) {
val skuDetails = skuDetailsList[i]
viewHolder.title.text = skuDetails.title.replace("(Retro Music Player)", "").trim { it <= ' ' }
viewHolder.text.text = skuDetails.description
viewHolder.text.visibility = View.GONE
viewHolder.price.text = skuDetails.priceText
viewHolder.image.setImageResource(getIcon(i))
val purchased = donationsDialog.billingProcessor!!.isPurchased(skuDetails.productId)
val titleTextColor = if (purchased) ATHUtil.resolveColor(donationsDialog, android.R.attr.textColorHint) else ThemeStore.textColorPrimary(donationsDialog)
val contentTextColor = if (purchased) titleTextColor else ThemeStore.textColorSecondary(donationsDialog)
viewHolder.title.setTextColor(titleTextColor)
viewHolder.text.setTextColor(contentTextColor)
viewHolder.price.setTextColor(titleTextColor)
strikeThrough(viewHolder.title, purchased)
strikeThrough(viewHolder.text, purchased)
strikeThrough(viewHolder.price, purchased)
viewHolder.itemView.setOnTouchListener { _, _ -> purchased }
viewHolder.itemView.setOnClickListener { donationsDialog.donate(i) }
}
override fun getItemCount(): Int {
return skuDetailsList.size
}
class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
var title: TextView = view.findViewById(R.id.itemTitle)
var text: TextView = view.findViewById(R.id.itemText)
var price: TextView = view.findViewById(R.id.itemPrice)
var image: IconImageView = view.findViewById(R.id.itemImage)
}
companion object {
@LayoutRes
private val LAYOUT_RES_ID = R.layout.item_donation_option
private fun strikeThrough(textView: TextView, strikeThrough: Boolean) {
textView.paintFlags = if (strikeThrough)
textView.paintFlags or Paint.STRIKE_THRU_TEXT_FLAG
else
textView.paintFlags and Paint.STRIKE_THRU_TEXT_FLAG.inv()
}
}
}

View file

@ -1,296 +0,0 @@
package code.name.monkey.retromusic.ui.activities;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.provider.MediaStore.Images.Media;
import android.text.TextUtils;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.afollestad.materialdialogs.MaterialDialog;
import com.google.android.material.appbar.AppBarLayout;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.textfield.TextInputEditText;
import com.google.android.material.textfield.TextInputLayout;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
import androidx.appcompat.widget.Toolbar;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import code.name.monkey.appthemehelper.ThemeStore;
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper;
import code.name.monkey.retromusic.R;
import code.name.monkey.retromusic.ui.activities.base.AbsBaseActivity;
import code.name.monkey.retromusic.util.Compressor;
import code.name.monkey.retromusic.util.ImageUtil;
import code.name.monkey.retromusic.util.PreferenceUtil;
import code.name.monkey.retromusic.views.CircularImageView;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.schedulers.Schedulers;
import static code.name.monkey.retromusic.Constants.USER_BANNER;
import static code.name.monkey.retromusic.Constants.USER_PROFILE;
public class UserInfoActivity extends AbsBaseActivity {
private static final int PICK_IMAGE_REQUEST = 9002;
private static final int PICK_BANNER_REQUEST = 9003;
private static final int PROFILE_ICON_SIZE = 400;
@BindView(R.id.title)
TextView title;
@BindView(R.id.name_container)
TextInputLayout nameLayout;
@BindView(R.id.name)
TextInputEditText name;
@BindView(R.id.user_image)
CircularImageView userImage;
@BindView(R.id.banner_image)
ImageView image;
@BindView(R.id.next)
FloatingActionButton nextButton;
@BindView(R.id.toolbar)
Toolbar toolbar;
@BindView(R.id.app_bar)
AppBarLayout appBarLayout;
private CompositeDisposable disposable;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_user_info);
ButterKnife.bind(this);
setStatusbarColorAuto();
setNavigationbarColorAuto();
setTaskDescriptionColorAuto();
setLightNavigationBar(true);
setupToolbar();
disposable = new CompositeDisposable();
title.setTextColor(ThemeStore.textColorPrimary(this));
nameLayout.setBoxStrokeColor(ThemeStore.accentColor(this));
name.setText(PreferenceUtil.getInstance().getUserName());
if (!PreferenceUtil.getInstance().getProfileImage().isEmpty()) {
loadImageFromStorage(PreferenceUtil.getInstance().getProfileImage());
}
if (!PreferenceUtil.getInstance().getBannerImage().isEmpty()) {
loadBannerFromStorage(PreferenceUtil.getInstance().getBannerImage());
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
onBackPressed();
}
return super.onOptionsItemSelected(item);
}
private void setupToolbar() {
int primaryColor = ThemeStore.primaryColor(this);
toolbar.setNavigationIcon(R.drawable.ic_keyboard_backspace_black_24dp);
toolbar.setBackgroundColor(primaryColor);
appBarLayout.setBackgroundColor(primaryColor);
ToolbarContentTintHelper.colorBackButton(toolbar, ThemeStore.accentColor(this));
setTitle(null);
setSupportActionBar(toolbar);
}
@OnClick({R.id.next, R.id.banner_select})
void next(View view) {
switch (view.getId()) {
case R.id.banner_select:
showBannerOptions();
break;
case R.id.next:
String nameString = name.getText().toString().trim();
if (TextUtils.isEmpty(nameString)) {
Toast.makeText(this, "Umm name is empty", Toast.LENGTH_SHORT).show();
return;
}
//noinspection ConstantConditions
PreferenceUtil.getInstance().setUserName(nameString);
setResult(RESULT_OK);
//((UserInfoActivity) getActivity()).setFragment(new ChooseThemeFragment(), true);
finish();
break;
}
}
private void showBannerOptions() {
//noinspection ConstantConditions
new MaterialDialog.Builder(this)
.title(R.string.select_banner_photo)
.items(Arrays.asList(getString(R.string.new_banner_photo),
getString(R.string.remove_banner_photo)))
.itemsCallback((dialog, itemView, position, text) -> {
switch (position) {
case 0:
selectBannerImage();
break;
case 1:
PreferenceUtil.getInstance().setBannerImagePath("");
break;
}
}).show();
}
private void selectBannerImage() {
//noinspection ConstantConditions
if (PreferenceUtil.getInstance().getBannerImage().isEmpty()) {
Intent pickImageIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
pickImageIntent.setType("image/*");
pickImageIntent.putExtra("crop", "true");
pickImageIntent.putExtra("outputX", 1290);
pickImageIntent.putExtra("outputY", 720);
pickImageIntent.putExtra("aspectX", 16);
pickImageIntent.putExtra("aspectY", 9);
pickImageIntent.putExtra("scale", true);
//intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(pickImageIntent,
"Select Picture"), PICK_BANNER_REQUEST);
} else {
PreferenceUtil.getInstance().setBannerImagePath("");
image.setImageResource(android.R.color.transparent);
}
}
@OnClick(R.id.user_image)
public void onViewClicked() {
//noinspection ConstantConditions
new MaterialDialog.Builder(this)
.title("Set a profile photo")
.items(Arrays.asList(getString(R.string.new_profile_photo), getString(R.string.remove_profile_photo)))
.itemsCallback((dialog, itemView, position, text) -> {
switch (position) {
case 0:
pickNewPhoto();
break;
case 1:
PreferenceUtil.getInstance().saveProfileImage("");
break;
}
}).show();
}
private void pickNewPhoto() {
Intent pickImageIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
pickImageIntent.setType("image/*");
pickImageIntent.putExtra("crop", "true");
pickImageIntent.putExtra("outputX", 512);
pickImageIntent.putExtra("outputY", 512);
pickImageIntent.putExtra("aspectX", 1);
pickImageIntent.putExtra("aspectY", 1);
pickImageIntent.putExtra("scale", true);
startActivityForResult(Intent.createChooser(pickImageIntent, "Select Picture"),
PICK_IMAGE_REQUEST);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null &&
data.getData() != null) {
Uri uri = data.getData();
try {
Bitmap bitmap = ImageUtil.getResizedBitmap(Media.getBitmap(getContentResolver(), uri), PROFILE_ICON_SIZE);
String profileImagePath = saveToInternalStorage(bitmap, USER_PROFILE);
PreferenceUtil.getInstance().saveProfileImage(profileImagePath);
loadImageFromStorage(profileImagePath);
} catch (IOException e) {
e.printStackTrace();
}
}
if (requestCode == PICK_BANNER_REQUEST && resultCode == RESULT_OK && data != null &&
data.getData() != null) {
Uri uri = data.getData();
try {
Bitmap bitmap = Media.getBitmap(getContentResolver(), uri);
String profileImagePath = saveToInternalStorage(bitmap, USER_BANNER);
PreferenceUtil.getInstance().setBannerImagePath(profileImagePath);
loadBannerFromStorage(profileImagePath);
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void loadBannerFromStorage(String profileImagePath) {
disposable.add(new Compressor(this)
.setQuality(100)
.setCompressFormat(Bitmap.CompressFormat.WEBP)
.compressToBitmapAsFlowable(new File(profileImagePath, USER_BANNER))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(bitmap -> {
image.setImageBitmap(bitmap);
}));
}
private void loadImageFromStorage(String path) {
disposable.add(new Compressor(this)
.setMaxHeight(300)
.setMaxWidth(300)
.setQuality(75)
.setCompressFormat(Bitmap.CompressFormat.WEBP)
.compressToBitmapAsFlowable(new File(path, USER_PROFILE))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(bitmap -> {
userImage.setImageBitmap(bitmap);
}));
}
private String saveToInternalStorage(Bitmap bitmapImage, String userBanner) {
ContextWrapper cw = new ContextWrapper(this);
// path to /data/data/yourapp/app_data/imageDir
File directory = cw.getDir("imageDir", Context.MODE_PRIVATE);
// Create imageDir
File mypath = new File(directory, userBanner);
FileOutputStream fos = null;
try {
fos = new FileOutputStream(mypath);
// Use the compress method on the BitMap object to write image to the OutputStream
bitmapImage.compress(Bitmap.CompressFormat.WEBP, 100, fos);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (fos != null) {
fos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return directory.getAbsolutePath();
}
}

View file

@ -0,0 +1,233 @@
package code.name.monkey.retromusic.ui.activities
import android.app.Activity
import android.content.Context
import android.content.ContextWrapper
import android.content.Intent
import android.graphics.Bitmap
import android.os.Bundle
import android.provider.MediaStore
import android.provider.MediaStore.Images.Media
import android.text.TextUtils
import android.view.MenuItem
import android.widget.Toast
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
import code.name.monkey.retromusic.Constants.USER_BANNER
import code.name.monkey.retromusic.Constants.USER_PROFILE
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.ui.activities.base.AbsBaseActivity
import code.name.monkey.retromusic.util.Compressor
import code.name.monkey.retromusic.util.ImageUtil
import code.name.monkey.retromusic.util.PreferenceUtil
import com.afollestad.materialdialogs.MaterialDialog
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.schedulers.Schedulers
import kotlinx.android.synthetic.main.activity_user_info.*
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.util.*
class UserInfoActivity : AbsBaseActivity() {
private var disposable: CompositeDisposable? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_user_info)
setStatusbarColorAuto()
setNavigationbarColorAuto()
setTaskDescriptionColorAuto()
setLightNavigationBar(true)
setupToolbar()
disposable = CompositeDisposable()
bannerTitle.setTextColor(ThemeStore.textColorPrimary(this))
nameContainer.boxStrokeColor = ThemeStore.accentColor(this)
name!!.setText(PreferenceUtil.getInstance().userName)
if (!PreferenceUtil.getInstance().profileImage.isEmpty()) {
loadImageFromStorage(PreferenceUtil.getInstance().profileImage)
}
if (!PreferenceUtil.getInstance().bannerImage.isEmpty()) {
loadBannerFromStorage(PreferenceUtil.getInstance().bannerImage)
}
bannerImage.setOnClickListener {
MaterialDialog.Builder(this)
.title("Set a profile photo")
.items(Arrays.asList(getString(R.string.new_profile_photo), getString(R.string.remove_profile_photo)))
.itemsCallback { _, _, position, _ ->
when (position) {
0 -> pickNewPhoto()
1 -> PreferenceUtil.getInstance().saveProfileImage("")
}
}.show()
}
bannerSelect.setOnClickListener {
showBannerOptions()
}
next.setOnClickListener {
val nameString = name!!.text!!.toString().trim { it <= ' ' }
if (TextUtils.isEmpty(nameString)) {
Toast.makeText(this, "Umm name is empty", Toast.LENGTH_SHORT).show()
return@setOnClickListener
}
PreferenceUtil.getInstance().userName = nameString
setResult(Activity.RESULT_OK)
finish()
}
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (item.itemId == android.R.id.home) {
onBackPressed()
}
return super.onOptionsItemSelected(item)
}
private fun setupToolbar() {
val primaryColor = ThemeStore.primaryColor(this)
toolbar.apply {
setNavigationIcon(R.drawable.ic_keyboard_backspace_black_24dp)
setBackgroundColor(primaryColor)
}
appBarLayout.setBackgroundColor(primaryColor)
ToolbarContentTintHelper.colorBackButton(toolbar, ThemeStore.accentColor(this))
title = null
setSupportActionBar(toolbar)
}
private fun showBannerOptions() {
MaterialDialog.Builder(this)
.title(R.string.select_banner_photo)
.items(Arrays.asList(getString(R.string.new_banner_photo),
getString(R.string.remove_banner_photo)))
.itemsCallback { _, _, position, _ ->
when (position) {
0 -> selectBannerImage()
1 -> PreferenceUtil.getInstance().setBannerImagePath("")
}
}.show()
}
private fun selectBannerImage() {
if (PreferenceUtil.getInstance().bannerImage.isEmpty()) {
val pickImageIntent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
pickImageIntent.type = "image/*"
pickImageIntent.putExtra("crop", "true")
pickImageIntent.putExtra("outputX", 1290)
pickImageIntent.putExtra("outputY", 720)
pickImageIntent.putExtra("aspectX", 16)
pickImageIntent.putExtra("aspectY", 9)
pickImageIntent.putExtra("scale", true)
//intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(pickImageIntent,
"Select Picture"), PICK_BANNER_REQUEST)
} else {
PreferenceUtil.getInstance().setBannerImagePath("")
bannerImage.setImageResource(android.R.color.transparent)
}
}
private fun pickNewPhoto() {
val pickImageIntent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
pickImageIntent.type = "image/*"
pickImageIntent.putExtra("crop", "true")
pickImageIntent.putExtra("outputX", 512)
pickImageIntent.putExtra("outputY", 512)
pickImageIntent.putExtra("aspectX", 1)
pickImageIntent.putExtra("aspectY", 1)
pickImageIntent.putExtra("scale", true)
startActivityForResult(Intent.createChooser(pickImageIntent, "Select Picture"), PICK_IMAGE_REQUEST)
}
public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == PICK_IMAGE_REQUEST && resultCode == Activity.RESULT_OK && data != null &&
data.data != null) {
val uri = data.data
try {
val bitmap = ImageUtil.getResizedBitmap(Media.getBitmap(contentResolver, uri), PROFILE_ICON_SIZE)
val profileImagePath = saveToInternalStorage(bitmap, USER_PROFILE)
PreferenceUtil.getInstance().saveProfileImage(profileImagePath)
loadImageFromStorage(profileImagePath)
} catch (e: IOException) {
e.printStackTrace()
}
}
if (requestCode == PICK_BANNER_REQUEST && resultCode == Activity.RESULT_OK && data != null &&
data.data != null) {
val uri = data.data
try {
val bitmap = Media.getBitmap(contentResolver, uri)
val profileImagePath = saveToInternalStorage(bitmap, USER_BANNER)
PreferenceUtil.getInstance().setBannerImagePath(profileImagePath)
loadBannerFromStorage(profileImagePath)
} catch (e: IOException) {
e.printStackTrace()
}
}
}
private fun loadBannerFromStorage(profileImagePath: String) {
disposable!!.add(Compressor(this)
.setQuality(100)
.setCompressFormat(Bitmap.CompressFormat.WEBP)
.compressToBitmapAsFlowable(File(profileImagePath, USER_BANNER))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe { bitmap -> bannerImage.setImageBitmap(bitmap) })
}
private fun loadImageFromStorage(path: String) {
disposable!!.add(Compressor(this)
.setMaxHeight(300)
.setMaxWidth(300)
.setQuality(75)
.setCompressFormat(Bitmap.CompressFormat.WEBP)
.compressToBitmapAsFlowable(File(path, USER_PROFILE))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe { bitmap -> userImage!!.setImageBitmap(bitmap) })
}
private fun saveToInternalStorage(bitmapImage: Bitmap, userBanner: String): String {
val cw = ContextWrapper(this)
val directory = cw.getDir("imageDir", Context.MODE_PRIVATE)
val myPath = File(directory, userBanner)
var fos: FileOutputStream? = null
try {
fos = FileOutputStream(myPath)
// Use the compress method on the BitMap object to write image to the OutputStream
bitmapImage.compress(Bitmap.CompressFormat.WEBP, 100, fos)
} catch (e: Exception) {
e.printStackTrace()
} finally {
try {
fos?.close()
} catch (e: IOException) {
e.printStackTrace()
}
}
return directory.absolutePath
}
companion object {
private val PICK_IMAGE_REQUEST = 9002
private val PICK_BANNER_REQUEST = 9003
private val PROFILE_ICON_SIZE = 400
}
}

View file

@ -3,7 +3,6 @@ package code.name.monkey.retromusic.ui.activities
import android.content.Context
import android.content.pm.PackageManager
import android.os.Bundle
import butterknife.ButterKnife
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.ColorUtil
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
@ -36,7 +35,7 @@ class WhatsNewActivity : AbsBaseActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_whats_new)
ButterKnife.bind(this)
setStatusbarColorAuto()
setNavigationbarColorAuto()

View file

@ -11,7 +11,6 @@ import android.view.ViewTreeObserver
import androidx.annotation.FloatRange
import androidx.annotation.LayoutRes
import androidx.fragment.app.Fragment
import butterknife.ButterKnife
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.ColorUtil
import code.name.monkey.retromusic.R
@ -63,7 +62,6 @@ abstract class AbsSlidingMusicPanelActivity protected constructor() : AbsMusicSe
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(createContentView())
ButterKnife.bind(this)
slidingUpPanelLayout = findViewById(R.id.sliding_layout);
bottomNavigationView = findViewById(R.id.bottom_navigation);

View file

@ -1,375 +0,0 @@
package code.name.monkey.retromusic.ui.activities.tageditor;
import android.app.SearchManager;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.view.animation.OvershootInterpolator;
import android.widget.FrameLayout;
import android.widget.ImageView;
import com.afollestad.materialdialogs.MaterialDialog;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import org.jaudiotagger.audio.AudioFile;
import org.jaudiotagger.audio.AudioFileIO;
import org.jaudiotagger.tag.FieldKey;
import org.jaudiotagger.tag.images.Artwork;
import java.io.File;
import java.util.List;
import java.util.Map;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import butterknife.BindView;
import butterknife.ButterKnife;
import code.name.monkey.appthemehelper.ThemeStore;
import code.name.monkey.appthemehelper.util.TintHelper;
import code.name.monkey.retromusic.R;
import code.name.monkey.retromusic.ui.activities.base.AbsBaseActivity;
import code.name.monkey.retromusic.util.RetroUtil;
public abstract class AbsTagEditorActivity extends AbsBaseActivity {
public static final String EXTRA_ID = "extra_id";
public static final String EXTRA_PALETTE = "extra_palette";
private static final String TAG = AbsTagEditorActivity.class.getSimpleName();
private static final int REQUEST_CODE_SELECT_IMAGE = 1000;
@BindView(R.id.save_fab)
FloatingActionButton save;
@BindView(R.id.image)
ImageView image;
@BindView(R.id.image_container)
FrameLayout imageContainer;
CharSequence[] items;
private int id;
private int paletteColorPrimary;
private boolean isInNoImageMode;
private List<String> songPaths;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(getContentViewLayout());
ButterKnife.bind(this);
getIntentExtras();
songPaths = getSongPaths();
if (songPaths.isEmpty()) {
finish();
return;
}
setUpViews();
setNavigationbarColorAuto();
setTaskDescriptionColorAuto();
}
private void setUpViews() {
setUpScrollView();
setUpFab();
setUpImageView();
}
private void setUpScrollView() {
//observableScrollView.setScrollViewCallbacks(observableScrollViewCallbacks);
}
private void setUpImageView() {
loadCurrentImage();
items = new CharSequence[]{
getString(R.string.download_from_last_fm),
getString(R.string.pick_from_local_storage),
getString(R.string.web_search),
getString(R.string.remove_cover)
};
image.setOnClickListener(v -> getShow());
}
protected MaterialDialog getShow() {
return new MaterialDialog.Builder(AbsTagEditorActivity.this)
.title(R.string.update_image)
.items(items)
.itemsCallback((dialog, itemView, position, text) -> {
switch (position) {
case 0:
getImageFromLastFM();
break;
case 1:
startImagePicker();
break;
case 2:
searchImageOnWeb();
break;
case 3:
deleteImage();
break;
}
}).show();
}
private void startImagePicker() {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
startActivityForResult(
Intent.createChooser(intent, getString(R.string.pick_from_local_storage)),
REQUEST_CODE_SELECT_IMAGE);
}
protected abstract void loadCurrentImage();
protected abstract void getImageFromLastFM();
protected abstract void searchImageOnWeb();
protected abstract void deleteImage();
private void setUpFab() {
save.setScaleX(0);
save.setScaleY(0);
save.setEnabled(false);
save.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
save();
}
});
TintHelper.setTintAuto(save, ThemeStore.accentColor(this), true);
}
protected abstract void save();
private void getIntentExtras() {
Bundle intentExtras = getIntent().getExtras();
if (intentExtras != null) {
id = intentExtras.getInt(EXTRA_ID);
}
}
protected abstract int getContentViewLayout();
@NonNull
protected abstract List<String> getSongPaths();
protected void searchWebFor(String... keys) {
StringBuilder stringBuilder = new StringBuilder();
for (String key : keys) {
stringBuilder.append(key);
stringBuilder.append(" ");
}
Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
intent.putExtra(SearchManager.QUERY, stringBuilder.toString());
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
int id = item.getItemId();
switch (id) {
case android.R.id.home:
super.onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
protected void setNoImageMode() {
isInNoImageMode = true;
imageContainer.setVisibility(View.GONE);
image.setVisibility(View.GONE);
image.setEnabled(false);
setColors(getIntent().getIntExtra(EXTRA_PALETTE, ThemeStore.primaryColor(this)));
}
protected void dataChanged() {
showFab();
}
private void showFab() {
save.animate()
.setDuration(500)
.setInterpolator(new OvershootInterpolator())
.scaleX(1)
.scaleY(1)
.start();
save.setEnabled(true);
}
protected void setImageBitmap(@Nullable final Bitmap bitmap, int bgColor) {
if (bitmap == null) {
image.setImageResource(R.drawable.default_album_art);
} else {
image.setImageBitmap(bitmap);
}
setColors(bgColor);
}
protected void setColors(int color) {
paletteColorPrimary = color;
}
protected void writeValuesToFiles(@NonNull final Map<FieldKey, String> fieldKeyValueMap,
@Nullable final ArtworkInfo artworkInfo) {
RetroUtil.hideSoftKeyboard(this);
new WriteTagsAsyncTask(this)
.execute(new WriteTagsAsyncTask.LoadingInfo(getSongPaths(), fieldKeyValueMap, artworkInfo));
}
protected int getId() {
return id;
}
@Override
protected void onActivityResult(int requestCode, int resultCode,
@NonNull Intent imageReturnedIntent) {
super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
switch (requestCode) {
case REQUEST_CODE_SELECT_IMAGE:
if (resultCode == RESULT_OK) {
Uri selectedImage = imageReturnedIntent.getData();
loadImageFromFile(selectedImage);
}
break;
}
}
protected abstract void loadImageFromFile(Uri selectedFile);
@NonNull
private AudioFile getAudioFile(@NonNull String path) {
try {
return AudioFileIO.read(new File(path));
} catch (Exception e) {
Log.e(TAG, "Could not read audio file " + path, e);
return new AudioFile();
}
}
@Nullable
String getAlbumArtist() {
try {
return getAudioFile(songPaths.get(0)).getTagOrCreateAndSetDefault()
.getFirst(FieldKey.ALBUM_ARTIST);
} catch (Exception ignored) {
return null;
}
}
@Nullable
protected String getSongTitle() {
try {
return getAudioFile(songPaths.get(0)).getTagOrCreateAndSetDefault().getFirst(FieldKey.TITLE);
} catch (Exception ignored) {
return null;
}
}
@Nullable
protected String getAlbumTitle() {
try {
return getAudioFile(songPaths.get(0)).getTagOrCreateAndSetDefault().getFirst(FieldKey.ALBUM);
} catch (Exception ignored) {
return null;
}
}
@Nullable
protected String getArtistName() {
try {
return getAudioFile(songPaths.get(0)).getTagOrCreateAndSetDefault().getFirst(FieldKey.ARTIST);
} catch (Exception ignored) {
return null;
}
}
@Nullable
protected String getAlbumArtistName() {
try {
return getAudioFile(songPaths.get(0)).getTagOrCreateAndSetDefault()
.getFirst(FieldKey.ALBUM_ARTIST);
} catch (Exception ignored) {
return null;
}
}
@Nullable
protected String getGenreName() {
try {
return getAudioFile(songPaths.get(0)).getTagOrCreateAndSetDefault().getFirst(FieldKey.GENRE);
} catch (Exception ignored) {
return null;
}
}
@Nullable
protected String getSongYear() {
try {
return getAudioFile(songPaths.get(0)).getTagOrCreateAndSetDefault().getFirst(FieldKey.YEAR);
} catch (Exception ignored) {
return null;
}
}
@Nullable
protected String getTrackNumber() {
try {
return getAudioFile(songPaths.get(0)).getTagOrCreateAndSetDefault().getFirst(FieldKey.TRACK);
} catch (Exception ignored) {
return null;
}
}
@Nullable
protected String getLyrics() {
try {
return getAudioFile(songPaths.get(0)).getTagOrCreateAndSetDefault().getFirst(FieldKey.LYRICS);
} catch (Exception ignored) {
return null;
}
}
@Nullable
protected Bitmap getAlbumArt() {
try {
Artwork artworkTag = getAudioFile(songPaths.get(0)).getTagOrCreateAndSetDefault()
.getFirstArtwork();
if (artworkTag != null) {
byte[] artworkBinaryData = artworkTag.getBinaryData();
return BitmapFactory.decodeByteArray(artworkBinaryData, 0, artworkBinaryData.length);
}
return null;
} catch (Exception ignored) {
return null;
}
}
public static class ArtworkInfo {
public final int albumId;
final Bitmap artwork;
ArtworkInfo(int albumId, Bitmap artwork) {
this.albumId = albumId;
this.artwork = artwork;
}
}
}

View file

@ -0,0 +1,332 @@
package code.name.monkey.retromusic.ui.activities.tageditor
import android.app.Activity
import android.app.SearchManager
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.net.Uri
import android.os.Bundle
import android.util.Log
import android.view.MenuItem
import android.view.View
import android.view.animation.OvershootInterpolator
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.TintHelper
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.ui.activities.base.AbsBaseActivity
import code.name.monkey.retromusic.util.RetroUtil
import com.afollestad.materialdialogs.MaterialDialog
import kotlinx.android.synthetic.main.activity_album_tag_editor.*
import org.jaudiotagger.audio.AudioFile
import org.jaudiotagger.audio.AudioFileIO
import org.jaudiotagger.tag.FieldKey
import java.io.File
abstract class AbsTagEditorActivity : AbsBaseActivity() {
private lateinit var items: Array<CharSequence>
protected var id: Int = 0
private set
private var paletteColorPrimary: Int = 0
private var isInNoImageMode: Boolean = false
private var songPaths: List<String>? = null
protected val show: MaterialDialog
get() = MaterialDialog.Builder(this@AbsTagEditorActivity)
.title(R.string.update_image)
.items(*items)
.itemsCallback { _, _, position, _ ->
when (position) {
0 -> getImageFromLastFM()
1 -> startImagePicker()
2 -> searchImageOnWeb()
3 -> deleteImage()
}
}.show()
protected abstract val contentViewLayout: Int
internal val albumArtist: String?
get() {
return try {
getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault
.getFirst(FieldKey.ALBUM_ARTIST)
} catch (ignored: Exception) {
null
}
}
protected val songTitle: String?
get() {
return try {
getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.TITLE)
} catch (ignored: Exception) {
null
}
}
protected val albumTitle: String?
get() {
return try {
getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.ALBUM)
} catch (ignored: Exception) {
null
}
}
protected val artistName: String?
get() {
return try {
getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.ARTIST)
} catch (ignored: Exception) {
null
}
}
protected val albumArtistName: String?
get() {
return try {
getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault
.getFirst(FieldKey.ALBUM_ARTIST)
} catch (ignored: Exception) {
null
}
}
protected val genreName: String?
get() {
return try {
getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.GENRE)
} catch (ignored: Exception) {
null
}
}
protected val songYear: String?
get() {
return try {
getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.YEAR)
} catch (ignored: Exception) {
null
}
}
protected val trackNumber: String?
get() {
return try {
getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.TRACK)
} catch (ignored: Exception) {
null
}
}
protected val lyrics: String?
get() {
return try {
getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.LYRICS)
} catch (ignored: Exception) {
null
}
}
protected val albumArt: Bitmap?
get() {
try {
val artworkTag = getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault
.firstArtwork
if (artworkTag != null) {
val artworkBinaryData = artworkTag.binaryData
return BitmapFactory.decodeByteArray(artworkBinaryData, 0, artworkBinaryData.size)
}
return null
} catch (ignored: Exception) {
return null
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(contentViewLayout)
getIntentExtras()
songPaths = getSongPaths()
if (songPaths!!.isEmpty()) {
finish()
return
}
setUpViews()
setNavigationbarColorAuto()
setTaskDescriptionColorAuto()
}
private fun setUpViews() {
setUpScrollView()
setUpFab()
setUpImageView()
}
private fun setUpScrollView() {
//observableScrollView.setScrollViewCallbacks(observableScrollViewCallbacks);
}
private fun setUpImageView() {
loadCurrentImage()
items = arrayOf(getString(R.string.download_from_last_fm), getString(R.string.pick_from_local_storage), getString(R.string.web_search), getString(R.string.remove_cover))
editorImage.setOnClickListener { show }
}
private fun startImagePicker() {
val intent = Intent(Intent.ACTION_GET_CONTENT)
intent.type = "image/*"
startActivityForResult(
Intent.createChooser(intent, getString(R.string.pick_from_local_storage)),
REQUEST_CODE_SELECT_IMAGE)
}
protected abstract fun loadCurrentImage()
protected abstract fun getImageFromLastFM()
protected abstract fun searchImageOnWeb()
protected abstract fun deleteImage()
private fun setUpFab() {
saveFab.apply {
scaleX = 0f
scaleY = 0f
isEnabled = false
setOnClickListener { save() }
TintHelper.setTintAuto(this, ThemeStore.accentColor(this@AbsTagEditorActivity), true)
}
}
protected abstract fun save()
private fun getIntentExtras() {
val intentExtras = intent.extras
if (intentExtras != null) {
id = intentExtras.getInt(EXTRA_ID)
}
}
protected abstract fun getSongPaths(): List<String>
protected fun searchWebFor(vararg keys: String) {
val stringBuilder = StringBuilder()
for (key in keys) {
stringBuilder.append(key)
stringBuilder.append(" ")
}
val intent = Intent(Intent.ACTION_WEB_SEARCH)
intent.putExtra(SearchManager.QUERY, stringBuilder.toString())
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
startActivity(intent)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
val id = item.itemId
when (id) {
android.R.id.home -> {
super.onBackPressed()
return true
}
}
return super.onOptionsItemSelected(item)
}
protected fun setNoImageMode() {
isInNoImageMode = true
imageContainer!!.visibility = View.GONE
editorImage.visibility = View.GONE
editorImage.isEnabled = false
setColors(intent.getIntExtra(EXTRA_PALETTE, ThemeStore.primaryColor(this)))
}
protected fun dataChanged() {
showFab()
}
private fun showFab() {
saveFab.animate()
.setDuration(500)
.setInterpolator(OvershootInterpolator())
.scaleX(1f)
.scaleY(1f)
.start()
saveFab.isEnabled = true
}
protected fun setImageBitmap(bitmap: Bitmap?, bgColor: Int) {
if (bitmap == null) {
editorImage.setImageResource(R.drawable.default_album_art)
} else {
editorImage.setImageBitmap(bitmap)
}
setColors(bgColor)
}
protected open fun setColors(color: Int) {
paletteColorPrimary = color
}
protected fun writeValuesToFiles(fieldKeyValueMap: Map<FieldKey, String>,
artworkInfo: ArtworkInfo?) {
RetroUtil.hideSoftKeyboard(this)
WriteTagsAsyncTask(this)
.execute(WriteTagsAsyncTask.LoadingInfo(getSongPaths(), fieldKeyValueMap, artworkInfo))
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when (requestCode) {
REQUEST_CODE_SELECT_IMAGE -> if (resultCode == Activity.RESULT_OK) {
val selectedImage = data!!.data
loadImageFromFile(selectedImage)
}
}
}
protected abstract fun loadImageFromFile(selectedFile: Uri?)
private fun getAudioFile(path: String): AudioFile {
try {
return AudioFileIO.read(File(path))
} catch (e: Exception) {
Log.e(TAG, "Could not read audio file $path", e)
return AudioFile()
}
}
class ArtworkInfo constructor(val albumId: Int, val artwork: Bitmap?)
companion object {
const val EXTRA_ID = "extra_id"
const val EXTRA_PALETTE = "extra_palette"
private val TAG = AbsTagEditorActivity::class.java.simpleName
private const val REQUEST_CODE_SELECT_IMAGE = 1000
}
}

View file

@ -1,307 +0,0 @@
package code.name.monkey.retromusic.ui.activities.tageditor;
import android.content.res.ColorStateList;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.request.animation.GlideAnimation;
import com.bumptech.glide.request.target.SimpleTarget;
import com.google.android.material.appbar.AppBarLayout;
import com.google.android.material.textfield.TextInputEditText;
import com.google.android.material.textfield.TextInputLayout;
import org.jaudiotagger.tag.FieldKey;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.Toolbar;
import androidx.core.content.ContextCompat;
import butterknife.BindView;
import butterknife.BindViews;
import butterknife.ButterKnife;
import code.name.monkey.appthemehelper.ThemeStore;
import code.name.monkey.appthemehelper.util.ATHUtil;
import code.name.monkey.appthemehelper.util.TintHelper;
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper;
import code.name.monkey.retromusic.R;
import code.name.monkey.retromusic.glide.palette.BitmapPaletteTranscoder;
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper;
import code.name.monkey.retromusic.loaders.AlbumLoader;
import code.name.monkey.retromusic.model.Song;
import code.name.monkey.retromusic.rest.LastFMRestClient;
import code.name.monkey.retromusic.rest.model.LastFmAlbum;
import code.name.monkey.retromusic.util.ImageUtil;
import code.name.monkey.retromusic.util.LastFMUtil;
import code.name.monkey.retromusic.util.RetroColorUtil;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.schedulers.Schedulers;
public class AlbumTagEditorActivity extends AbsTagEditorActivity implements TextWatcher {
public static final String TAG = AlbumTagEditorActivity.class.getSimpleName();
@BindView(R.id.toolbar)
Toolbar toolbar;
@BindView(R.id.title)
TextView title;
@BindView(R.id.app_bar)
@Nullable
AppBarLayout appBarLayout;
@BindViews({R.id.album_title_container, R.id.album_artist_container, R.id.genre_container, R.id.year_container})
List<TextInputLayout> textInputLayouts;
@BindView(R.id.album_title)
TextInputEditText albumTitle;
@BindView(R.id.album_artist)
TextInputEditText albumArtist;
@BindView(R.id.genre)
TextInputEditText genre;
@BindView(R.id.year)
TextInputEditText year;
@BindView(R.id.gradient_background)
View background;
@BindView(R.id.content)
View content;
ButterKnife.Setter<TextInputLayout, Integer> textColor = (view, value, index) -> {
view.setBoxStrokeColor(value);
};
private Bitmap albumArtBitmap;
private boolean deleteAlbumArt;
private LastFMRestClient lastFMRestClient;
private CompositeDisposable disposable = new CompositeDisposable();
private void setupToolbar() {
title.setTextColor(Color.WHITE);
toolbar.setNavigationOnClickListener(v -> onBackPressed());
ToolbarContentTintHelper.setToolbarContentColorBasedOnToolbarColor(this, toolbar, Color.TRANSPARENT);
setTitle(null);
setSupportActionBar(toolbar);
TintHelper.setTintAuto(content, ThemeStore.primaryColor(this), true);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
setDrawUnderStatusBar();
super.onCreate(savedInstanceState);
ButterKnife.bind(this);
ButterKnife.apply(textInputLayouts, textColor, ThemeStore.accentColor((this)));
lastFMRestClient = new LastFMRestClient(this);
setUpViews();
setupToolbar();
}
@Override
protected int getContentViewLayout() {
return R.layout.activity_album_tag_editor;
}
private void setUpViews() {
fillViewsWithFileTags();
albumTitle.addTextChangedListener(this);
albumArtist.addTextChangedListener(this);
genre.addTextChangedListener(this);
year.addTextChangedListener(this);
}
private void fillViewsWithFileTags() {
albumTitle.setText(getAlbumTitle());
albumArtist.setText(getAlbumArtistName());
genre.setText(getGenreName());
year.setText(getSongYear());
}
@Override
protected void loadCurrentImage() {
Bitmap bitmap = getAlbumArt();
setImageBitmap(bitmap, RetroColorUtil.getColor(RetroColorUtil.generatePalette(bitmap),
ATHUtil.resolveColor(this, R.attr.defaultFooterColor)));
deleteAlbumArt = false;
}
@Override
protected void getImageFromLastFM() {
String albumTitleStr = albumTitle.getText().toString();
String albumArtistNameStr = albumArtist.getText().toString();
if (albumArtistNameStr.trim().equals("") || albumTitleStr.trim().equals("")) {
Toast.makeText(this, getResources().getString(R.string.album_or_artist_empty),
Toast.LENGTH_SHORT).show();
return;
}
disposable.add(lastFMRestClient.getApiService()
.getAlbumInfo(albumTitleStr, albumArtistNameStr, null)
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.computation())
.subscribe(this::extractDetails));
}
@Override
protected void onPause() {
super.onPause();
disposable.clear();
}
private void extractDetails(@NonNull LastFmAlbum lastFmAlbum) {
if (lastFmAlbum.getAlbum() != null) {
String url = LastFMUtil.getLargestAlbumImageUrl(lastFmAlbum.getAlbum().getImage());
if (!TextUtils.isEmpty(url) && url.trim().length() > 0) {
Glide.with(this)
.load(url)
.asBitmap()
.transcode(new BitmapPaletteTranscoder(this), BitmapPaletteWrapper.class)
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
.error(R.drawable.default_album_art)
.into(new SimpleTarget<BitmapPaletteWrapper>() {
@Override
public void onLoadFailed(Exception e, Drawable errorDrawable) {
super.onLoadFailed(e, errorDrawable);
e.printStackTrace();
Toast.makeText(AlbumTagEditorActivity.this, e.toString(), Toast.LENGTH_LONG).show();
}
@Override
public void onResourceReady(BitmapPaletteWrapper resource,
GlideAnimation<? super BitmapPaletteWrapper> glideAnimation) {
albumArtBitmap = ImageUtil.resizeBitmap(resource.getBitmap(), 2048);
setImageBitmap(albumArtBitmap, RetroColorUtil.getColor(resource.getPalette(),
ContextCompat.getColor(AlbumTagEditorActivity.this, R.color.md_grey_500)));
deleteAlbumArt = false;
dataChanged();
setResult(RESULT_OK);
}
});
return;
}
if (lastFmAlbum.getAlbum().getTags().getTag().size() > 0) {
genre.setText(lastFmAlbum.getAlbum().getTags().getTag().get(0).getName());
}
}
toastLoadingFailed();
}
private void toastLoadingFailed() {
Toast.makeText(AlbumTagEditorActivity.this,
R.string.could_not_download_album_cover, Toast.LENGTH_SHORT).show();
}
@Override
protected void searchImageOnWeb() {
searchWebFor(albumTitle.getText().toString(), albumArtist.getText().toString());
}
@Override
protected void deleteImage() {
setImageBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.default_album_art),
ATHUtil.resolveColor(this, R.attr.defaultFooterColor));
deleteAlbumArt = true;
dataChanged();
}
@Override
protected void save() {
Map<FieldKey, String> fieldKeyValueMap = new EnumMap<>(FieldKey.class);
fieldKeyValueMap.put(FieldKey.ALBUM, albumTitle.getText().toString());
//android seems not to recognize album_artist field so we additionally write the normal artist field
fieldKeyValueMap.put(FieldKey.ARTIST, albumArtist.getText().toString());
fieldKeyValueMap.put(FieldKey.ALBUM_ARTIST, albumArtist.getText().toString());
fieldKeyValueMap.put(FieldKey.GENRE, genre.getText().toString());
fieldKeyValueMap.put(FieldKey.YEAR, year.getText().toString());
writeValuesToFiles(fieldKeyValueMap, deleteAlbumArt ? new ArtworkInfo(getId(), null)
: albumArtBitmap == null ? null : new ArtworkInfo(getId(), albumArtBitmap));
}
@NonNull
@Override
protected List<String> getSongPaths() {
ArrayList<Song> songs = AlbumLoader.Companion.getAlbum(this, getId()).blockingFirst().getSongs();
ArrayList<String> paths = new ArrayList<>(songs.size());
for (Song song : songs) {
paths.add(song.getData());
}
return paths;
}
@Override
protected void loadImageFromFile(@NonNull final Uri selectedFileUri) {
Glide.with(AlbumTagEditorActivity.this)
.load(selectedFileUri)
.asBitmap()
.transcode(new BitmapPaletteTranscoder(AlbumTagEditorActivity.this),
BitmapPaletteWrapper.class)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.into(new SimpleTarget<BitmapPaletteWrapper>() {
@Override
public void onLoadFailed(Exception e, Drawable errorDrawable) {
super.onLoadFailed(e, errorDrawable);
e.printStackTrace();
Toast.makeText(AlbumTagEditorActivity.this, e.toString(), Toast.LENGTH_LONG).show();
}
@Override
public void onResourceReady(BitmapPaletteWrapper resource,
GlideAnimation<? super BitmapPaletteWrapper> glideAnimation) {
RetroColorUtil.getColor(resource.getPalette(), Color.TRANSPARENT);
albumArtBitmap = ImageUtil.resizeBitmap(resource.getBitmap(), 2048);
setImageBitmap(albumArtBitmap, RetroColorUtil.getColor(resource.getPalette(),
ATHUtil.resolveColor(AlbumTagEditorActivity.this, R.attr.defaultFooterColor)));
deleteAlbumArt = false;
dataChanged();
setResult(RESULT_OK);
}
});
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
dataChanged();
}
@Override
protected void setColors(int color) {
super.setColors(color);
save.setBackgroundTintList(ColorStateList.valueOf(color));
}
}

View file

@ -0,0 +1,232 @@
package code.name.monkey.retromusic.ui.activities.tageditor
import android.app.Activity
import android.content.res.ColorStateList
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Color
import android.graphics.drawable.Drawable
import android.net.Uri
import android.os.Bundle
import android.text.Editable
import android.text.TextUtils
import android.text.TextWatcher
import android.widget.Toast
import androidx.core.content.ContextCompat
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.ATHUtil
import code.name.monkey.appthemehelper.util.TintHelper
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.glide.palette.BitmapPaletteTranscoder
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
import code.name.monkey.retromusic.loaders.AlbumLoader
import code.name.monkey.retromusic.rest.LastFMRestClient
import code.name.monkey.retromusic.rest.model.LastFmAlbum
import code.name.monkey.retromusic.util.ImageUtil
import code.name.monkey.retromusic.util.LastFMUtil
import code.name.monkey.retromusic.util.RetroColorUtil
import com.bumptech.glide.Glide
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.request.animation.GlideAnimation
import com.bumptech.glide.request.target.SimpleTarget
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.schedulers.Schedulers
import kotlinx.android.synthetic.main.activity_album_tag_editor.*
import org.jaudiotagger.tag.FieldKey
import java.util.*
class AlbumTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
override val contentViewLayout: Int
get() = R.layout.activity_album_tag_editor
override fun loadImageFromFile(selectedFile: Uri?) {
Glide.with(this@AlbumTagEditorActivity)
.load(selectedFile)
.asBitmap()
.transcode(BitmapPaletteTranscoder(this@AlbumTagEditorActivity), BitmapPaletteWrapper::class.java)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.into(object : SimpleTarget<BitmapPaletteWrapper>() {
override fun onLoadFailed(e: Exception?, errorDrawable: Drawable?) {
super.onLoadFailed(e, errorDrawable)
e!!.printStackTrace()
Toast.makeText(this@AlbumTagEditorActivity, e.toString(), Toast.LENGTH_LONG).show()
}
override fun onResourceReady(resource: BitmapPaletteWrapper, glideAnimation: GlideAnimation<in BitmapPaletteWrapper>) {
RetroColorUtil.getColor(resource.palette, Color.TRANSPARENT)
albumArtBitmap = ImageUtil.resizeBitmap(resource.bitmap, 2048)
setImageBitmap(albumArtBitmap, RetroColorUtil.getColor(resource.palette, ATHUtil.resolveColor(this@AlbumTagEditorActivity, R.attr.defaultFooterColor)))
deleteAlbumArt = false
dataChanged()
setResult(Activity.RESULT_OK)
}
})
}
private var albumArtBitmap: Bitmap? = null
private var deleteAlbumArt: Boolean = false
private var lastFMRestClient: LastFMRestClient? = null
private val disposable = CompositeDisposable()
private fun setupToolbar() {
bannerTitle.setTextColor(Color.WHITE)
toolbar.setNavigationOnClickListener { onBackPressed() }
ToolbarContentTintHelper.setToolbarContentColorBasedOnToolbarColor(this, toolbar, Color.TRANSPARENT)
title = null
setSupportActionBar(toolbar)
TintHelper.setTintAuto(content, ThemeStore.primaryColor(this), true)
}
override fun onCreate(savedInstanceState: Bundle?) {
setDrawUnderStatusBar()
super.onCreate(savedInstanceState)
lastFMRestClient = LastFMRestClient(this)
setUpViews()
setupToolbar()
}
private fun setUpViews() {
fillViewsWithFileTags()
albumText.addTextChangedListener(this)
albumArtistText.addTextChangedListener(this)
genreTitle.addTextChangedListener(this)
yearTitle.addTextChangedListener(this)
}
private fun fillViewsWithFileTags() {
albumText.setText(albumTitle)
albumArtistText.setText(albumArtistName)
genreTitle.setText(genreName)
yearTitle.setText(songYear)
}
override fun loadCurrentImage() {
val bitmap = albumArt
setImageBitmap(bitmap, RetroColorUtil.getColor(RetroColorUtil.generatePalette(bitmap), ATHUtil.resolveColor(this, R.attr.defaultFooterColor)))
deleteAlbumArt = false
}
override fun getImageFromLastFM() {
val albumTitleStr = albumText.text.toString()
val albumArtistNameStr = albumArtistText.text.toString()
if (albumArtistNameStr.trim { it <= ' ' } == "" || albumTitleStr.trim { it <= ' ' } == "") {
Toast.makeText(this, resources.getString(R.string.album_or_artist_empty), Toast.LENGTH_SHORT).show()
return
}
disposable.add(lastFMRestClient!!.apiService
.getAlbumInfo(albumTitleStr, albumArtistNameStr, null)
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.computation())
.subscribe { this.extractDetails(it) })
}
override fun onPause() {
super.onPause()
disposable.clear()
}
private fun extractDetails(lastFmAlbum: LastFmAlbum) {
if (lastFmAlbum.album != null) {
val url = LastFMUtil.getLargestAlbumImageUrl(lastFmAlbum.album.image)
if (!TextUtils.isEmpty(url) && url.trim { it <= ' ' }.isNotEmpty()) {
Glide.with(this)
.load(url)
.asBitmap()
.transcode(BitmapPaletteTranscoder(this), BitmapPaletteWrapper::class.java)
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
.error(R.drawable.default_album_art)
.into(object : SimpleTarget<BitmapPaletteWrapper>() {
override fun onLoadFailed(e: Exception?, errorDrawable: Drawable?) {
super.onLoadFailed(e, errorDrawable)
e!!.printStackTrace()
Toast.makeText(this@AlbumTagEditorActivity, e.toString(), Toast.LENGTH_LONG).show()
}
override fun onResourceReady(resource: BitmapPaletteWrapper,
glideAnimation: GlideAnimation<in BitmapPaletteWrapper>) {
albumArtBitmap = ImageUtil.resizeBitmap(resource.bitmap, 2048)
setImageBitmap(albumArtBitmap, RetroColorUtil.getColor(resource.palette,
ContextCompat.getColor(this@AlbumTagEditorActivity, R.color.md_grey_500)))
deleteAlbumArt = false
dataChanged()
setResult(Activity.RESULT_OK)
}
})
return
}
if (lastFmAlbum.album.tags.tag.size > 0) {
genreTitle.setText(lastFmAlbum.album.tags.tag[0].name)
}
}
toastLoadingFailed()
}
private fun toastLoadingFailed() {
Toast.makeText(this@AlbumTagEditorActivity, R.string.could_not_download_album_cover, Toast.LENGTH_SHORT).show()
}
override fun searchImageOnWeb() {
searchWebFor(albumText.text.toString(), albumArtistText.text.toString())
}
override fun deleteImage() {
setImageBitmap(BitmapFactory.decodeResource(resources, R.drawable.default_album_art), ATHUtil.resolveColor(this, R.attr.defaultFooterColor))
deleteAlbumArt = true
dataChanged()
}
override fun save() {
val fieldKeyValueMap = EnumMap<FieldKey, String>(FieldKey::class.java)
fieldKeyValueMap[FieldKey.ALBUM] = albumText.text.toString()
//android seems not to recognize album_artist field so we additionally write the normal artist field
fieldKeyValueMap[FieldKey.ARTIST] = albumArtistText.text.toString()
fieldKeyValueMap[FieldKey.ALBUM_ARTIST] = albumArtistText.text.toString()
fieldKeyValueMap[FieldKey.GENRE] = genreTitle.text.toString()
fieldKeyValueMap[FieldKey.YEAR] = yearTitle.text.toString()
writeValuesToFiles(fieldKeyValueMap, if (deleteAlbumArt) AbsTagEditorActivity.ArtworkInfo(id, null)
else if (albumArtBitmap == null) null else AbsTagEditorActivity.ArtworkInfo(id, albumArtBitmap!!))
}
override fun getSongPaths(): List<String> {
val songs = AlbumLoader.getAlbum(this, id).blockingFirst().songs
val paths = ArrayList<String>(songs!!.size)
for (song in songs) {
paths.add(song.data!!)
}
return paths
}
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
}
override fun afterTextChanged(s: Editable) {
dataChanged()
}
override fun setColors(color: Int) {
super.setColors(color)
saveFab.backgroundTintList = ColorStateList.valueOf(color)
}
companion object {
val TAG: String = AlbumTagEditorActivity::class.java.simpleName
}
}

View file

@ -1,179 +0,0 @@
package code.name.monkey.retromusic.ui.activities.tageditor;
import android.net.Uri;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.widget.EditText;
import android.widget.TextView;
import com.google.android.material.appbar.AppBarLayout;
import org.jaudiotagger.tag.FieldKey;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
import androidx.annotation.NonNull;
import androidx.appcompat.widget.Toolbar;
import butterknife.BindView;
import butterknife.ButterKnife;
import code.name.monkey.appthemehelper.ThemeStore;
import code.name.monkey.retromusic.R;
import code.name.monkey.retromusic.loaders.SongLoader;
public class SongTagEditorActivity extends AbsTagEditorActivity implements TextWatcher {
public static final String TAG = SongTagEditorActivity.class.getSimpleName();
@BindView(R.id.toolbar)
Toolbar toolbar;
@BindView(R.id.app_bar)
AppBarLayout appBarLayout;
@BindView(R.id.title)
TextView title;
@BindView(R.id.title1)
EditText songTitle;
@BindView(R.id.title2)
EditText albumTitle;
@BindView(R.id.artist)
EditText artist;
@BindView(R.id.genre)
EditText genre;
@BindView(R.id.year)
EditText year;
@BindView(R.id.image_text)
EditText trackNumber;
@BindView(R.id.lyrics)
EditText lyrics;
@BindView(R.id.album_artist)
EditText albumArtist;
private void setupToolbar() {
appBarLayout.setBackgroundColor(ThemeStore.primaryColor(this));
toolbar.setBackgroundColor(ThemeStore.primaryColor(this));
toolbar.setNavigationOnClickListener(v -> onBackPressed());
setTitle(null);
title.setTextColor(ThemeStore.textColorPrimary(this));
setSupportActionBar(toolbar);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ButterKnife.bind(this);
setNoImageMode();
setUpViews();
setupToolbar();
setStatusbarColorAuto();
}
private void setUpViews() {
fillViewsWithFileTags();
albumArtist.addTextChangedListener(this);
songTitle.addTextChangedListener(this);
albumTitle.addTextChangedListener(this);
artist.addTextChangedListener(this);
genre.addTextChangedListener(this);
year.addTextChangedListener(this);
trackNumber.addTextChangedListener(this);
lyrics.addTextChangedListener(this);
}
private void fillViewsWithFileTags() {
songTitle.setText(getSongTitle());
albumArtist.setText(getAlbumArtist());
albumTitle.setText(getAlbumTitle());
artist.setText(getArtistName());
genre.setText(getGenreName());
year.setText(getSongYear());
trackNumber.setText(getTrackNumber());
lyrics.setText(getLyrics());
}
@Override
protected void loadCurrentImage() {
}
@Override
protected void getImageFromLastFM() {
}
@Override
protected void searchImageOnWeb() {
}
@Override
protected void deleteImage() {
}
@Override
protected void save() {
Map<FieldKey, String> fieldKeyValueMap = new EnumMap<>(FieldKey.class);
fieldKeyValueMap.put(FieldKey.TITLE, songTitle.getText().toString());
fieldKeyValueMap.put(FieldKey.ALBUM, albumTitle.getText().toString());
fieldKeyValueMap.put(FieldKey.ARTIST, artist.getText().toString());
fieldKeyValueMap.put(FieldKey.GENRE, genre.getText().toString());
fieldKeyValueMap.put(FieldKey.YEAR, year.getText().toString());
fieldKeyValueMap.put(FieldKey.TRACK, trackNumber.getText().toString());
fieldKeyValueMap.put(FieldKey.LYRICS, lyrics.getText().toString());
fieldKeyValueMap.put(FieldKey.ALBUM_ARTIST, albumArtist.getText().toString());
writeValuesToFiles(fieldKeyValueMap, null);
}
@Override
protected int getContentViewLayout() {
return R.layout.activity_song_tag_editor;
}
@NonNull
@Override
protected List<String> getSongPaths() {
ArrayList<String> paths = new ArrayList<>(1);
paths.add(SongLoader.INSTANCE.getSong(this, getId()).blockingFirst().getData());
return paths;
}
@Override
protected void loadImageFromFile(Uri imageFilePath) {
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
dataChanged();
}
@Override
protected void setColors(int color) {
super.setColors(color);
}
}

View file

@ -0,0 +1,117 @@
package code.name.monkey.retromusic.ui.activities.tageditor
import android.net.Uri
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.loaders.SongLoader
import kotlinx.android.synthetic.main.activity_song_tag_editor.*
import org.jaudiotagger.tag.FieldKey
import java.util.*
class SongTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
override val contentViewLayout: Int
get() = R.layout.activity_song_tag_editor
private fun setupToolbar() {
appBarLayout.setBackgroundColor(ThemeStore.primaryColor(this))
toolbar.setBackgroundColor(ThemeStore.primaryColor(this))
toolbar.setNavigationOnClickListener { onBackPressed() }
title = null
bannerTitle!!.setTextColor(ThemeStore.textColorPrimary(this))
setSupportActionBar(toolbar)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setNoImageMode()
setUpViews()
setupToolbar()
setStatusbarColorAuto()
}
private fun setUpViews() {
fillViewsWithFileTags()
albumText.addTextChangedListener(this)
songText.addTextChangedListener(this)
albumText.addTextChangedListener(this)
artistText.addTextChangedListener(this)
genreText.addTextChangedListener(this)
yearText.addTextChangedListener(this)
trackNumberText.addTextChangedListener(this)
lyricsText.addTextChangedListener(this)
}
private fun fillViewsWithFileTags() {
songText.setText(songTitle)
albumArtistText.setText(albumArtist)
albumText.setText(albumTitle)
artistText.setText(artistName)
genreText.setText(genreName)
yearText.setText(songYear)
trackNumberText.setText(trackNumber)
lyricsText.setText(lyrics)
}
override fun loadCurrentImage() {
}
override fun getImageFromLastFM() {
}
override fun searchImageOnWeb() {
}
override fun deleteImage() {
}
override fun save() {
val fieldKeyValueMap = EnumMap<FieldKey, String>(FieldKey::class.java)
fieldKeyValueMap[FieldKey.TITLE] = songText.text.toString()
fieldKeyValueMap[FieldKey.ALBUM] = albumText.text.toString()
fieldKeyValueMap[FieldKey.ARTIST] = artistText.text.toString()
fieldKeyValueMap[FieldKey.GENRE] = genreText.text.toString()
fieldKeyValueMap[FieldKey.YEAR] = yearText.text.toString()
fieldKeyValueMap[FieldKey.TRACK] = trackNumberText.text.toString()
fieldKeyValueMap[FieldKey.LYRICS] = lyricsText.text.toString()
fieldKeyValueMap[FieldKey.ALBUM_ARTIST] = albumArtistText.text.toString()
writeValuesToFiles(fieldKeyValueMap, null)
}
override fun getSongPaths(): List<String> {
val paths = ArrayList<String>(1)
paths.add(SongLoader.getSong(this, id).blockingFirst().data!!)
return paths
}
override fun loadImageFromFile(selectedFile: Uri?) {
}
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
}
override fun afterTextChanged(s: Editable) {
dataChanged()
}
companion object {
val TAG: String = SongTagEditorActivity::class.java.simpleName
}
}

View file

@ -50,10 +50,10 @@ public class WriteTagsAsyncTask extends
Artwork artwork = null;
File albumArtFile = null;
if (info.artworkInfo != null && info.artworkInfo.artwork != null) {
if (info.artworkInfo != null && info.artworkInfo.getArtwork() != null) {
try {
albumArtFile = MusicUtil.createAlbumArtFile().getCanonicalFile();
info.artworkInfo.artwork
info.artworkInfo.getArtwork()
.compress(Bitmap.CompressFormat.PNG, 0, new FileOutputStream(albumArtFile));
artwork = ArtworkFactory.createArtworkFromFile(albumArtFile);
} catch (IOException e) {
@ -81,7 +81,7 @@ public class WriteTagsAsyncTask extends
}
if (info.artworkInfo != null) {
if (info.artworkInfo.artwork == null) {
if (info.artworkInfo.getArtwork() == null) {
tag.deleteArtworkField();
deletedArtwork = true;
} else if (artwork != null) {
@ -100,9 +100,9 @@ public class WriteTagsAsyncTask extends
Context context = getContext();
if (context != null) {
if (wroteArtwork) {
MusicUtil.insertAlbumArt(context, info.artworkInfo.albumId, albumArtFile.getPath());
MusicUtil.insertAlbumArt(context, info.artworkInfo.getAlbumId(), albumArtFile.getPath());
} else if (deletedArtwork) {
MusicUtil.deleteAlbumArt(context, info.artworkInfo.albumId);
MusicUtil.deleteAlbumArt(context, info.artworkInfo.getAlbumId());
}
}

View file

@ -1,102 +0,0 @@
package code.name.monkey.retromusic.ui.adapter;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import java.util.ArrayList;
import java.util.List;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
import butterknife.BindView;
import butterknife.BindViews;
import butterknife.ButterKnife;
import code.name.monkey.appthemehelper.ThemeStore;
import code.name.monkey.appthemehelper.util.ColorUtil;
import code.name.monkey.appthemehelper.util.MaterialValueHelper;
import code.name.monkey.retromusic.R;
import code.name.monkey.retromusic.glide.SongGlideRequest;
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
import code.name.monkey.retromusic.model.Song;
import code.name.monkey.retromusic.ui.adapter.CollageSongAdapter.CollageSongViewHolder;
import code.name.monkey.retromusic.ui.adapter.base.MediaEntryViewHolder;
/**
* @author Hemanth S (h4h13).
*/
public class CollageSongAdapter extends RecyclerView.Adapter<CollageSongViewHolder> {
private Activity activity;
private ArrayList<Song> dataSet;
public CollageSongAdapter(Activity activity, ArrayList<Song> dataSet) {
this.activity = activity;
this.dataSet = dataSet;
}
@Override
public void onBindViewHolder(@NonNull CollageSongViewHolder holder, int position) {
holder.bindSongs();
if (dataSet.size() > 8) {
for (int i = 0; i < dataSet.subList(0, 8).size(); i++) {
if (holder.imageViews != null) {
SongGlideRequest.Builder.from(Glide.with(activity), dataSet.get(i))
.checkIgnoreMediaStore(activity)
.build()
.into(holder.imageViews.get(i));
}
}
}
}
@Override
public int getItemCount() {
return 1;
}
@NonNull
@Override
public CollageSongViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new CollageSongViewHolder(LayoutInflater.from(activity).inflate(R.layout.item_collage, parent, false));
}
class CollageSongViewHolder extends MediaEntryViewHolder {
@BindViews({R.id.image_2, R.id.image_3, R.id.image_4, R.id.image_5, R.id.image_6, R.id.image_7, R.id.image_8, R.id.image_9})
@Nullable
List<ImageView> imageViews;
@BindView(R.id.image_1)
TextView view;
CollageSongViewHolder(View itemView) {
super(itemView);
//ButterKnife.bind(this, itemView);
//Context context = itemView.getContext();
//int color = ThemeStore.accentColor(context);
//view.setOnClickListener(v -> MusicPlayerRemote.INSTANCE.openQueue(dataSet, 0, true));
//view.setBackgroundColor(color);
//view.setTextColor(MaterialValueHelper.getPrimaryTextColor(context, ColorUtil.isColorLight(color)));
}
void bindSongs() {
if (imageViews != null) {
for (int i = 0; i < imageViews.size(); i++) {
final int startPosition = i;
ImageView imageView = imageViews.get(i);
imageView.setOnClickListener(view -> {
MusicPlayerRemote.INSTANCE.playNext(dataSet.get(startPosition));
});
}
}
}
}
}

View file

@ -0,0 +1,68 @@
package code.name.monkey.retromusic.ui.adapter
import android.app.Activity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.ColorUtil
import code.name.monkey.appthemehelper.util.MaterialValueHelper
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.glide.SongGlideRequest
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.ui.adapter.CollageSongAdapter.CollageSongViewHolder
import code.name.monkey.retromusic.ui.adapter.base.MediaEntryViewHolder
import com.bumptech.glide.Glide
import java.util.*
/**
* @author Hemanth S (h4h13).
*/
class CollageSongAdapter(private val activity: Activity, private val dataSet: ArrayList<Song>) : RecyclerView.Adapter<CollageSongViewHolder>() {
override fun onBindViewHolder(holder: CollageSongViewHolder, position: Int) {
holder.bindSongs()
if (dataSet.size > 8) {
for (i in 0 until dataSet.subList(0, 8).size) {
SongGlideRequest.Builder.from(Glide.with(activity), dataSet[i])
.checkIgnoreMediaStore(activity)
.build()
.into(holder.itemView.findViewById(holder.ids[i]) as ImageView)
}
}
}
override fun getItemCount(): Int {
return 1
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CollageSongViewHolder {
return CollageSongViewHolder(LayoutInflater.from(activity).inflate(R.layout.item_collage, parent, false))
}
inner class CollageSongViewHolder(itemView: View) : MediaEntryViewHolder(itemView) {
val ids = arrayListOf(R.id.image_2, R.id.image_3, R.id.image_4, R.id.image_5, R.id.image_6, R.id.image_7, R.id.image_8, R.id.image_9)
private var textView: TextView = itemView.findViewById(R.id.image_1)
fun bindSongs() {
for (i in ids) {
val imageView = itemView.findViewById<ImageView>(i)
imageView.setOnClickListener {
textView.setOnClickListener { MusicPlayerRemote.openQueue(dataSet, 0, true) }
}
}
val context = itemView.context
val color = ThemeStore.accentColor(context);
textView.setOnClickListener { MusicPlayerRemote.openQueue(dataSet, 0, true) }
textView.setBackgroundColor(color);
textView.setTextColor(MaterialValueHelper.getPrimaryTextColor(context, ColorUtil.isColorLight(color)))
}
}
}

View file

@ -118,9 +118,9 @@ class AlbumCoverPagerAdapter(fm: FragmentManager, private val dataSet: ArrayList
}
private fun loadAlbumCover() {
SongGlideRequest.Builder.from(Glide.with(context), song)
.checkIgnoreMediaStore(activity)
.generatePalette(activity).build()
SongGlideRequest.Builder.from(Glide.with(context), song!!)
.checkIgnoreMediaStore(activity!!)
.generatePalette(activity!!).build()
.into(object : RetroMusicColoredTarget(albumCover) {
override fun onColorReady(color: Int) {
setColor(color)

View file

@ -10,7 +10,6 @@ import android.view.ViewGroup
import androidx.annotation.LayoutRes
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.PopupMenu
import butterknife.ButterKnife
import code.name.monkey.appthemehelper.util.ATHUtil
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.dialogs.ClearSmartPlaylistDialog
@ -207,7 +206,6 @@ class PlaylistAdapter(protected val activity: AppCompatActivity, dataSet: ArrayL
inner class ViewHolder(itemView: View) : MediaEntryViewHolder(itemView) {
init {
ButterKnife.bind(this, itemView)
if (image != null) {
val iconPadding = activity.resources
.getDimensionPixelSize(R.dimen.list_item_image_icon_padding)

View file

@ -1,28 +0,0 @@
package code.name.monkey.retromusic.ui.fragments;
import androidx.annotation.DrawableRes;
import androidx.annotation.StringRes;
import code.name.monkey.retromusic.R;
public enum AlbumCoverStyle {
NORMAL(R.string.normal, R.drawable.album_cover_normal, 0),
FLAT(R.string.flat, R.drawable.album_cover_square, 1),
CIRCLE(R.string.circular, R.drawable.album_cover_circle, 2),
MATERIAL(R.string.material, R.drawable.album_cover_normal, 3),
CARD(R.string.card, R.drawable.album_cover_card, 4),
FULL(R.string.full, R.drawable.album_cover_full, 5),
FULL_CARD(R.string.full_card, R.drawable.album_cover_full_card, 6);
@StringRes
public final int titleRes;
@DrawableRes
public final int drawableResId;
public final int id;
AlbumCoverStyle(@StringRes int titleRes, @DrawableRes int drawableResId, int id) {
this.titleRes = titleRes;
this.drawableResId = drawableResId;
this.id = id;
}
}

View file

@ -0,0 +1,19 @@
package code.name.monkey.retromusic.ui.fragments
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import code.name.monkey.retromusic.R
enum class AlbumCoverStyle(@param:StringRes @field:StringRes
val titleRes: Int,
@param:DrawableRes @field:DrawableRes
val drawableResId: Int, val id: Int) {
NORMAL(R.string.normal, R.drawable.album_cover_normal, 0),
FLAT(R.string.flat, R.drawable.album_cover_square, 1),
CIRCLE(R.string.circular, R.drawable.album_cover_circle, 2),
MATERIAL(R.string.material, R.drawable.album_cover_normal, 3),
CARD(R.string.card, R.drawable.album_cover_card, 4),
FULL(R.string.full, R.drawable.album_cover_full, 5),
FULL_CARD(R.string.full_card, R.drawable.album_cover_full_card, 6)
}

View file

@ -1,11 +1,14 @@
package code.name.monkey.retromusic.ui.fragments;
package code.name.monkey.retromusic.ui.fragments
import androidx.annotation.DrawableRes;
import androidx.annotation.StringRes;
import code.name.monkey.retromusic.R;
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import code.name.monkey.retromusic.R
public enum NowPlayingScreen {
enum class NowPlayingScreen constructor(@param:StringRes @field:StringRes
val titleRes: Int,
@param:DrawableRes @field:DrawableRes val drawableResId: Int,
val id: Int) {
NORMAL(R.string.normal, R.drawable.np_normal, 0),
FLAT(R.string.flat, R.drawable.np_flat, 1),
FULL(R.string.full, R.drawable.np_full, 2),
@ -18,17 +21,5 @@ public enum NowPlayingScreen {
BLUR_CARD(R.string.blur_card, R.drawable.np_blur_card, 9),
ADAPTIVE(R.string.adaptive, R.drawable.np_adaptive, 10),
MATERIAL(R.string.material, R.drawable.np_material, 11),
FIT(R.string.fit, R.drawable.np_adaptive, 12);
@StringRes
public final int titleRes;
@DrawableRes
public final int drawableResId;
public final int id;
NowPlayingScreen(@StringRes int titleRes, @DrawableRes int drawableResId, int id) {
this.titleRes = titleRes;
this.drawableResId = drawableResId;
this.id = id;
}
FIT(R.string.fit, R.drawable.np_adaptive, 12)
}

View file

@ -130,8 +130,8 @@ open class AlbumsFragment : AbsLibraryPagerRecyclerViewCustomGridSizeFragment<Al
override fun completed() {}
override fun showData(albums: ArrayList<Album>) {
adapter!!.swapDataSet(albums)
override fun showData(list: ArrayList<Album>) {
adapter!!.swapDataSet(list)
}
companion object {

View file

@ -122,8 +122,8 @@ class ArtistsFragment : AbsLibraryPagerRecyclerViewCustomGridSizeFragment<Artist
}
override fun showData(artists: ArrayList<Artist>) {
adapter!!.swapDataSet(artists)
override fun showData(list: ArrayList<Artist>) {
adapter!!.swapDataSet(list)
}
companion object {

View file

@ -60,8 +60,8 @@ class GenreFragment : AbsLibraryPagerRecyclerViewFragment<GenreAdapter, LinearLa
}
override fun showData(songs: ArrayList<Genre>) {
adapter!!.swapDataSet(songs)
override fun showData(list: ArrayList<Genre>) {
adapter!!.swapDataSet(list)
}
override fun showEmptyView() {

View file

@ -56,11 +56,22 @@ class LibraryFragment : AbsMainActivityFragment(), CabHolder, MainActivityFragme
val totalAppBarScrollingRange: Int
get() = appbar.totalScrollRange
private val currentFragment: Fragment?
get() = if (fragmentManager == null) {
private fun getCurrentFragment(): Fragment? {
return if (fragmentManager == null) {
SongsFragment.newInstance()
} else fragmentManager!!.findFragmentByTag(LibraryFragment.TAG)
} else fragmentManager!!.findFragmentById(R.id.fragment_container)
}
private fun selectedFragment(fragment: Fragment) {
val fragmentManager = childFragmentManager
val fragmentTransaction = fragmentManager.beginTransaction()
fragmentTransaction
.replace(R.id.fragment_container, fragment, TAG)
.commit()
fragmentManager.executePendingTransactions()
}
fun setTitle(@StringRes name: Int) {
title.text = getString(name)
@ -120,14 +131,6 @@ class LibraryFragment : AbsMainActivityFragment(), CabHolder, MainActivityFragme
return false
}
private fun selectedFragment(fragment: Fragment) {
val fragmentManager = childFragmentManager
val fragmentTransaction = fragmentManager.beginTransaction()
fragmentTransaction
.replace(R.id.fragment_container, fragment, TAG)
.commit()
}
override fun openCab(menuRes: Int, callback: MaterialCab.Callback): MaterialCab {
if (cab != null && cab!!.isActive) {
@ -143,12 +146,17 @@ class LibraryFragment : AbsMainActivityFragment(), CabHolder, MainActivityFragme
return cab as MaterialCab
}
private fun isPlaylistFragment(): Boolean {
return true
}
override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) {
super.onCreateOptionsMenu(menu, inflater)
inflater!!.inflate(R.menu.menu_main, menu)
val currentFragment = currentFragment
if (isPlaylistFragment()) {
menu!!.add(0, R.id.action_new_playlist, 0, R.string.new_playlist_title)
}
val currentFragment = getCurrentFragment()
if (currentFragment is AbsLibraryPagerRecyclerViewCustomGridSizeFragment<*, *> && currentFragment.isAdded) {
val fragment = currentFragment as AbsLibraryPagerRecyclerViewCustomGridSizeFragment<*, *>?
@ -161,11 +169,9 @@ class LibraryFragment : AbsMainActivityFragment(), CabHolder, MainActivityFragme
setUpSortOrderMenu(fragment, menu.findItem(R.id.action_sort_order).subMenu)
} else {
menu!!.add(0, R.id.action_new_playlist, 0, R.string.new_playlist_title)
menu.removeItem(R.id.action_grid_size)
menu!!.removeItem(R.id.action_grid_size)
}
activity ?: return
ToolbarContentTintHelper.handleOnCreateOptionsMenu(getActivity(), toolbar, menu, ATHToolbarActivity.getToolbarBackgroundColor(toolbar))
ToolbarContentTintHelper.handleOnCreateOptionsMenu(activity!!, toolbar, menu, ATHToolbarActivity.getToolbarBackgroundColor(toolbar))
}
override fun onPrepareOptionsMenu(menu: Menu?) {
@ -181,22 +187,26 @@ class LibraryFragment : AbsMainActivityFragment(), CabHolder, MainActivityFragme
val currentSortOrder = fragment.getSortOrder()
sortOrderMenu.clear()
if (fragment is AlbumsFragment) {
sortOrderMenu.add(0, R.id.action_album_sort_order_asc, 0, R.string.sort_order_a_z).isChecked = currentSortOrder == SortOrder.AlbumSortOrder.ALBUM_A_Z
sortOrderMenu.add(0, R.id.action_album_sort_order_desc, 1, R.string.sort_order_z_a).isChecked = currentSortOrder == SortOrder.AlbumSortOrder.ALBUM_Z_A
sortOrderMenu.add(0, R.id.action_album_sort_order_artist, 2, R.string.sort_order_artist).isChecked = currentSortOrder == SortOrder.AlbumSortOrder.ALBUM_ARTIST
sortOrderMenu.add(0, R.id.action_album_sort_order_year, 3, R.string.sort_order_year).isChecked = currentSortOrder == SortOrder.AlbumSortOrder.ALBUM_YEAR
} else if (fragment is ArtistsFragment) {
sortOrderMenu.add(0, R.id.action_artist_sort_order_asc, 0, R.string.sort_order_a_z).isChecked = currentSortOrder == SortOrder.ArtistSortOrder.ARTIST_A_Z
sortOrderMenu.add(0, R.id.action_artist_sort_order_desc, 1, R.string.sort_order_z_a).isChecked = currentSortOrder == SortOrder.ArtistSortOrder.ARTIST_Z_A
} else if (fragment is SongsFragment) {
sortOrderMenu.add(0, R.id.action_song_sort_order_asc, 0, R.string.sort_order_a_z).isChecked = currentSortOrder == SortOrder.SongSortOrder.SONG_A_Z
sortOrderMenu.add(0, R.id.action_song_sort_order_desc, 1, R.string.sort_order_z_a).isChecked = currentSortOrder == SortOrder.SongSortOrder.SONG_Z_A
sortOrderMenu.add(0, R.id.action_song_sort_order_artist, 2, R.string.sort_order_artist).isChecked = currentSortOrder == SortOrder.SongSortOrder.SONG_ARTIST
sortOrderMenu.add(0, R.id.action_song_sort_order_album, 3, R.string.sort_order_album).isChecked = currentSortOrder == SortOrder.SongSortOrder.SONG_ALBUM
sortOrderMenu.add(0, R.id.action_song_sort_order_year, 4, R.string.sort_order_year).isChecked = currentSortOrder == SortOrder.SongSortOrder.SONG_YEAR
sortOrderMenu.add(0, R.id.action_song_sort_order_date, 4, R.string.sort_order_date).isChecked = currentSortOrder == SortOrder.SongSortOrder.SONG_DATE
when (fragment) {
is AlbumsFragment -> {
sortOrderMenu.add(0, R.id.action_album_sort_order_asc, 0, R.string.sort_order_a_z).isChecked = currentSortOrder == SortOrder.AlbumSortOrder.ALBUM_A_Z
sortOrderMenu.add(0, R.id.action_album_sort_order_desc, 1, R.string.sort_order_z_a).isChecked = currentSortOrder == SortOrder.AlbumSortOrder.ALBUM_Z_A
sortOrderMenu.add(0, R.id.action_album_sort_order_artist, 2, R.string.sort_order_artist).isChecked = currentSortOrder == SortOrder.AlbumSortOrder.ALBUM_ARTIST
sortOrderMenu.add(0, R.id.action_album_sort_order_year, 3, R.string.sort_order_year).isChecked = currentSortOrder == SortOrder.AlbumSortOrder.ALBUM_YEAR
}
is ArtistsFragment -> {
sortOrderMenu.add(0, R.id.action_artist_sort_order_asc, 0, R.string.sort_order_a_z).isChecked = currentSortOrder == SortOrder.ArtistSortOrder.ARTIST_A_Z
sortOrderMenu.add(0, R.id.action_artist_sort_order_desc, 1, R.string.sort_order_z_a).isChecked = currentSortOrder == SortOrder.ArtistSortOrder.ARTIST_Z_A
}
is SongsFragment -> {
sortOrderMenu.add(0, R.id.action_song_sort_order_asc, 0, R.string.sort_order_a_z).isChecked = currentSortOrder == SortOrder.SongSortOrder.SONG_A_Z
sortOrderMenu.add(0, R.id.action_song_sort_order_desc, 1, R.string.sort_order_z_a).isChecked = currentSortOrder == SortOrder.SongSortOrder.SONG_Z_A
sortOrderMenu.add(0, R.id.action_song_sort_order_artist, 2, R.string.sort_order_artist).isChecked = currentSortOrder == SortOrder.SongSortOrder.SONG_ARTIST
sortOrderMenu.add(0, R.id.action_song_sort_order_album, 3, R.string.sort_order_album).isChecked = currentSortOrder == SortOrder.SongSortOrder.SONG_ALBUM
sortOrderMenu.add(0, R.id.action_song_sort_order_year, 4, R.string.sort_order_year).isChecked = currentSortOrder == SortOrder.SongSortOrder.SONG_YEAR
sortOrderMenu.add(0, R.id.action_song_sort_order_date, 4, R.string.sort_order_date).isChecked = currentSortOrder == SortOrder.SongSortOrder.SONG_DATE
}
}
sortOrderMenu.setGroupCheckable(0, true, true)
@ -205,20 +215,18 @@ class LibraryFragment : AbsMainActivityFragment(), CabHolder, MainActivityFragme
private fun handleSortOrderMenuItem(
fragment: AbsLibraryPagerRecyclerViewCustomGridSizeFragment<*, *>, item: MenuItem): Boolean {
var sortOrder: String? = null
if (fragment is AlbumsFragment) {
when (item.itemId) {
when (fragment) {
is AlbumsFragment -> when (item.itemId) {
R.id.action_album_sort_order_asc -> sortOrder = SortOrder.AlbumSortOrder.ALBUM_A_Z
R.id.action_album_sort_order_desc -> sortOrder = SortOrder.AlbumSortOrder.ALBUM_Z_A
R.id.action_album_sort_order_artist -> sortOrder = SortOrder.AlbumSortOrder.ALBUM_ARTIST
R.id.action_album_sort_order_year -> sortOrder = SortOrder.AlbumSortOrder.ALBUM_YEAR
}
} else if (fragment is ArtistsFragment) {
when (item.itemId) {
is ArtistsFragment -> when (item.itemId) {
R.id.action_artist_sort_order_asc -> sortOrder = SortOrder.ArtistSortOrder.ARTIST_A_Z
R.id.action_artist_sort_order_desc -> sortOrder = SortOrder.ArtistSortOrder.ARTIST_Z_A
}
} else if (fragment is SongsFragment) {
when (item.itemId) {
is SongsFragment -> when (item.itemId) {
R.id.action_song_sort_order_asc -> sortOrder = SortOrder.SongSortOrder.SONG_A_Z
R.id.action_song_sort_order_desc -> sortOrder = SortOrder.SongSortOrder.SONG_Z_A
R.id.action_song_sort_order_artist -> sortOrder = SortOrder.SongSortOrder.SONG_ARTIST
@ -240,7 +248,7 @@ class LibraryFragment : AbsMainActivityFragment(), CabHolder, MainActivityFragme
override fun onOptionsItemSelected(item: MenuItem): Boolean {
//if (pager == null) return false;
val currentFragment = currentFragment
val currentFragment = getCurrentFragment()
if (currentFragment is AbsLibraryPagerRecyclerViewCustomGridSizeFragment<*, *>) {
val fragment = currentFragment as AbsLibraryPagerRecyclerViewCustomGridSizeFragment<*, *>?
if (handleGridSizeMenuItem(fragment!!, item)) {

View file

@ -4,7 +4,6 @@ import android.os.Bundle
import androidx.recyclerview.widget.LinearLayoutManager
import android.view.Menu
import android.view.MenuInflater
import android.view.View
import java.util.ArrayList
@ -76,8 +75,8 @@ class PlaylistsFragment : AbsLibraryPagerRecyclerViewFragment<PlaylistAdapter, L
}
override fun showData(playlists: ArrayList<Playlist>) {
adapter!!.swapDataSet(playlists)
override fun showData(list: ArrayList<Playlist>) {
adapter!!.swapDataSet(list)
}
override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) {

View file

@ -105,8 +105,8 @@ class SongsFragment : AbsLibraryPagerRecyclerViewCustomGridSizeFragment<SongAdap
}
override fun showData(songs: ArrayList<Song>) {
adapter!!.swapDataSet(songs)
override fun showData(list: ArrayList<Song>) {
adapter!!.swapDataSet(list)
}
override fun showEmptyView() {

View file

@ -32,6 +32,7 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@ -40,8 +41,6 @@ import androidx.loader.app.LoaderManager;
import androidx.loader.content.Loader;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import butterknife.ButterKnife;
import butterknife.Unbinder;
import code.name.monkey.appthemehelper.ThemeStore;
import code.name.monkey.appthemehelper.common.ATHToolbarActivity;
import code.name.monkey.appthemehelper.util.ATHUtil;
@ -106,6 +105,7 @@ public class FoldersFragment extends AbsMainActivityFragment implements
};
private SongFileAdapter adapter;
private MaterialCab cab;
public FoldersFragment() {
}
@ -515,8 +515,8 @@ public class FoldersFragment extends AbsMainActivityFragment implements
private WeakReference<FoldersFragment> fragmentWeakReference;
public AsyncFileLoader(FoldersFragment foldersFragment) {
super(foldersFragment.getActivity());
AsyncFileLoader(FoldersFragment foldersFragment) {
super(Objects.requireNonNull(foldersFragment.getActivity()));
fragmentWeakReference = new WeakReference<>(foldersFragment);
}

View file

@ -265,10 +265,10 @@ class BannerHomeFragment : AbsMainActivityFragment(), MainActivityFragmentCallba
}
override fun geners(genres: ArrayList<Genre>) {
override fun geners(songs: ArrayList<Genre>) {
genreContainer.visibility = View.VISIBLE
genresRecyclerView.apply {
val genreAdapter = GenreAdapter(activity!!, genres, R.layout.item_list)
val genreAdapter = GenreAdapter(activity!!, songs, R.layout.item_list)
layoutManager = LinearLayoutManager(context)
adapter = genreAdapter
}

View file

@ -133,7 +133,7 @@ class ColorFragment : AbsPlayerFragment() {
val activity = activity
SongGlideRequest.Builder.from(Glide.with(activity), MusicPlayerRemote.currentSong)
.checkIgnoreMediaStore(activity)
.checkIgnoreMediaStore(activity!!)
.generatePalette(activity).build().dontAnimate()
.into(object : RetroMusicColoredTarget(playerImage) {
override fun onColorReady(color: Int) {

View file

@ -67,11 +67,11 @@ public abstract class AbsSettingsFragment extends ATEPreferenceFragmentCompat {
@Override
public DialogFragment onCreatePreferenceDialog(Preference preference) {
if (preference instanceof NowPlayingScreenPreference) {
return NowPlayingScreenPreferenceDialog.newInstance();
return NowPlayingScreenPreferenceDialog.Companion.newInstance();
} else if (preference instanceof BlacklistPreference) {
return BlacklistPreferenceDialog.newInstance();
} else if (preference instanceof AlbumCoverStylePreference) {
return AlbumCoverStylePreferenceDialog.newInstance();
return AlbumCoverStylePreferenceDialog.Companion.newInstance();
}
return super.onCreatePreferenceDialog(preference);
}

View file

@ -1,49 +0,0 @@
package code.name.monkey.retromusic.ui.fragments.settings;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.media.audiofx.AudioEffect;
import android.os.Bundle;
import androidx.preference.Preference;
import code.name.monkey.retromusic.R;
import code.name.monkey.retromusic.util.NavigationUtil;
import code.name.monkey.retromusic.util.PreferenceUtil;
/**
* @author Hemanth S (h4h13).
*/
public class AudioSettings extends AbsSettingsFragment {
@Override
public void invalidateSettings() {
Preference findPreference = findPreference("equalizer");
if (!hasEqualizer() && !PreferenceUtil.getInstance().getSelectedEqualizer().equals("retro")) {
findPreference.setEnabled(false);
findPreference.setSummary(getResources().getString(R.string.no_equalizer));
} else {
findPreference.setEnabled(true);
}
findPreference.setOnPreferenceClickListener(preference -> {
//noinspection ConstantConditions
NavigationUtil.openEqualizer(getActivity());
return true;
});
}
private boolean hasEqualizer() {
final Intent effects = new Intent(AudioEffect.ACTION_DISPLAY_AUDIO_EFFECT_CONTROL_PANEL);
//noinspection ConstantConditions
PackageManager pm = getActivity().getPackageManager();
ResolveInfo ri = pm.resolveActivity(effects, 0);
return ri != null;
}
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
addPreferencesFromResource(R.xml.pref_audio);
}
}

View file

@ -0,0 +1,46 @@
package code.name.monkey.retromusic.ui.fragments.settings
import android.content.Intent
import android.content.pm.PackageManager
import android.content.pm.ResolveInfo
import android.media.audiofx.AudioEffect
import android.os.Bundle
import androidx.preference.Preference
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.util.NavigationUtil
import code.name.monkey.retromusic.util.PreferenceUtil
/**
* @author Hemanth S (h4h13).
*/
class AudioSettings : AbsSettingsFragment() {
override fun invalidateSettings() {
val findPreference = findPreference("equalizer")
if (!hasEqualizer() && PreferenceUtil.getInstance().selectedEqualizer != "retro") {
findPreference.isEnabled = false
findPreference.summary = resources.getString(R.string.no_equalizer)
} else {
findPreference.isEnabled = true
}
findPreference.setOnPreferenceClickListener {
NavigationUtil.openEqualizer(activity!!)
true
}
}
private fun hasEqualizer(): Boolean {
val effects = Intent(AudioEffect.ACTION_DISPLAY_AUDIO_EFFECT_CONTROL_PANEL)
val pm = activity!!.packageManager
val ri = pm.resolveActivity(effects, 0)
return ri != null
}
override fun onCreatePreferences(savedInstanceState: Bundle, rootKey: String) {
addPreferencesFromResource(R.xml.pref_audio)
}
}

View file

@ -1,28 +0,0 @@
package code.name.monkey.retromusic.ui.fragments.settings;
import android.os.Bundle;
import androidx.preference.Preference;
import code.name.monkey.retromusic.R;
/**
* @author Hemanth S (h4h13).
*/
public class ImageSettingFragment extends AbsSettingsFragment {
@Override
public void invalidateSettings() {
final Preference autoDownloadImagesPolicy = findPreference("auto_download_images_policy");
setSummary(autoDownloadImagesPolicy);
autoDownloadImagesPolicy.setOnPreferenceChangeListener((preference, o) -> {
setSummary(autoDownloadImagesPolicy, o);
return true;
});
}
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
addPreferencesFromResource(R.xml.pref_images);
}
}

View file

@ -0,0 +1,26 @@
package code.name.monkey.retromusic.ui.fragments.settings
import android.os.Bundle
import androidx.preference.Preference
import code.name.monkey.retromusic.R
/**
* @author Hemanth S (h4h13).
*/
class ImageSettingFragment : AbsSettingsFragment() {
override fun invalidateSettings() {
val autoDownloadImagesPolicy = findPreference("auto_download_images_policy")
setSummary(autoDownloadImagesPolicy)
autoDownloadImagesPolicy.setOnPreferenceChangeListener { _, o ->
setSummary(autoDownloadImagesPolicy, o)
true
}
}
override fun onCreatePreferences(savedInstanceState: Bundle, rootKey: String) {
addPreferencesFromResource(R.xml.pref_images)
}
}

View file

@ -1,43 +0,0 @@
package code.name.monkey.retromusic.ui.fragments.settings;
import android.os.Build;
import android.os.Bundle;
import androidx.preference.TwoStatePreference;
import code.name.monkey.retromusic.R;
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
import code.name.monkey.retromusic.service.MusicService;
import code.name.monkey.retromusic.util.PreferenceUtil;
/**
* @author Hemanth S (h4h13).
*/
public class NotificationSettingsFragment extends AbsSettingsFragment {
@Override
public void invalidateSettings() {
final TwoStatePreference classicNotification = (TwoStatePreference) findPreference("classic_notification");
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
classicNotification.setVisible(false);
} else {
classicNotification.setChecked(PreferenceUtil.getInstance().classicNotification());
classicNotification.setOnPreferenceChangeListener((preference, newValue) -> {
// Save preference
PreferenceUtil.getInstance().setClassicNotification((Boolean) newValue);
final MusicService service = MusicPlayerRemote.INSTANCE.getMusicService();
if (service != null) {
service.initNotification();
service.updateNotification();
}
return true;
});
}
}
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
addPreferencesFromResource(R.xml.pref_notification);
}
}

View file

@ -0,0 +1,41 @@
package code.name.monkey.retromusic.ui.fragments.settings
import android.os.Build
import android.os.Bundle
import androidx.preference.TwoStatePreference
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.service.MusicService
import code.name.monkey.retromusic.util.PreferenceUtil
/**
* @author Hemanth S (h4h13).
*/
class NotificationSettingsFragment : AbsSettingsFragment() {
override fun invalidateSettings() {
val classicNotification = findPreference("classic_notification") as TwoStatePreference
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
classicNotification.isVisible = false
} else {
classicNotification.isChecked = PreferenceUtil.getInstance().classicNotification()
classicNotification.setOnPreferenceChangeListener { _, newValue ->
// Save preference
PreferenceUtil.getInstance().setClassicNotification(newValue as Boolean)
val service = MusicPlayerRemote.musicService
if (service != null) {
service.initNotification()
service.updateNotification()
}
true
}
}
}
override fun onCreatePreferences(savedInstanceState: Bundle, rootKey: String) {
addPreferencesFromResource(R.xml.pref_notification)
}
}

View file

@ -1,80 +0,0 @@
package code.name.monkey.retromusic.ui.fragments.settings;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.preference.TwoStatePreference;
import code.name.monkey.retromusic.R;
import code.name.monkey.retromusic.App;
import code.name.monkey.retromusic.util.PreferenceUtil;
/**
* @author Hemanth S (h4h13).
*/
public class NowPlayingSettingsFragment extends AbsSettingsFragment implements
SharedPreferences.OnSharedPreferenceChangeListener {
@SuppressWarnings("ConstantConditions")
@Override
public void invalidateSettings() {
updateNowPlayingScreenSummary();
updateAlbumCoverStyleSummary();
final TwoStatePreference carouselEffect = (TwoStatePreference) findPreference("carousel_effect");
carouselEffect.setOnPreferenceChangeListener((preference, newValue) -> {
if ((Boolean) newValue && !App.Companion.isProVersion()) {
showProToastAndNavigate(getActivity().getString(R.string.pref_title_toggle_carousel_effect));
return false;
}
return true;
});
}
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
addPreferencesFromResource(R.xml.pref_now_playing_screen);
}
private void updateNowPlayingScreenSummary() {
//noinspection ConstantConditions
findPreference("now_playing_screen_id").setSummary(PreferenceUtil.getInstance().getNowPlayingScreen().titleRes);
}
@Override
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
//noinspection ConstantConditions
PreferenceUtil.getInstance().registerOnSharedPreferenceChangedListener(this);
}
@Override
public void onDestroyView() {
super.onDestroyView();
//noinspection ConstantConditions
PreferenceUtil.getInstance().unregisterOnSharedPreferenceChangedListener(this);
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
switch (key) {
case PreferenceUtil.NOW_PLAYING_SCREEN_ID:
updateNowPlayingScreenSummary();
break;
case PreferenceUtil.ALBUM_COVER_STYLE:
updateAlbumCoverStyleSummary();
break;
case PreferenceUtil.CIRCULAR_ALBUM_ART:
case PreferenceUtil.CAROUSEL_EFFECT:
invalidateSettings();
break;
}
}
private void updateAlbumCoverStyleSummary() {
findPreference("album_cover_style_id").setSummary(PreferenceUtil.getInstance().getAlbumCoverStyle().titleRes);
}
}

View file

@ -0,0 +1,64 @@
package code.name.monkey.retromusic.ui.fragments.settings
import android.content.SharedPreferences
import android.os.Bundle
import android.view.View
import androidx.preference.TwoStatePreference
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.App
import code.name.monkey.retromusic.util.PreferenceUtil
/**
* @author Hemanth S (h4h13).
*/
class NowPlayingSettingsFragment : AbsSettingsFragment(), SharedPreferences.OnSharedPreferenceChangeListener {
override fun invalidateSettings() {
updateNowPlayingScreenSummary()
updateAlbumCoverStyleSummary()
val carouselEffect = findPreference("carousel_effect") as TwoStatePreference
carouselEffect.setOnPreferenceChangeListener { _, newValue ->
if (newValue as Boolean && !App.isProVersion) {
showProToastAndNavigate(activity!!.getString(R.string.pref_title_toggle_carousel_effect))
return@setOnPreferenceChangeListener false
}
true
}
}
override fun onCreatePreferences(savedInstanceState: Bundle, rootKey: String) {
addPreferencesFromResource(R.xml.pref_now_playing_screen)
}
private fun updateNowPlayingScreenSummary() {
findPreference("now_playing_screen_id").setSummary(PreferenceUtil.getInstance().nowPlayingScreen.titleRes)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
PreferenceUtil.getInstance().registerOnSharedPreferenceChangedListener(this)
}
override fun onDestroyView() {
super.onDestroyView()
PreferenceUtil.getInstance().unregisterOnSharedPreferenceChangedListener(this)
}
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) {
when (key) {
PreferenceUtil.NOW_PLAYING_SCREEN_ID -> updateNowPlayingScreenSummary()
PreferenceUtil.ALBUM_COVER_STYLE -> updateAlbumCoverStyleSummary()
PreferenceUtil.CIRCULAR_ALBUM_ART, PreferenceUtil.CAROUSEL_EFFECT -> invalidateSettings()
}
}
private fun updateAlbumCoverStyleSummary() {
findPreference("album_cover_style_id").setSummary(PreferenceUtil.getInstance().albumCoverStyle.titleRes)
}
}

View file

@ -1,23 +0,0 @@
package code.name.monkey.retromusic.ui.fragments.settings;
import android.os.Bundle;
import code.name.monkey.retromusic.R;
/**
* @author Hemanth S (h4h13).
*/
public class OtherSettingsFragment extends AbsSettingsFragment {
@Override
public void invalidateSettings() {
}
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
addPreferencesFromResource(R.xml.pref_blacklist);
addPreferencesFromResource(R.xml.pref_playlists);
addPreferencesFromResource(R.xml.pref_advanced);
}
}

View file

@ -0,0 +1,21 @@
package code.name.monkey.retromusic.ui.fragments.settings
import android.os.Bundle
import code.name.monkey.retromusic.R
/**
* @author Hemanth S (h4h13).
*/
class OtherSettingsFragment : AbsSettingsFragment() {
override fun invalidateSettings() {
}
override fun onCreatePreferences(savedInstanceState: Bundle, rootKey: String) {
addPreferencesFromResource(R.xml.pref_blacklist)
addPreferencesFromResource(R.xml.pref_playlists)
addPreferencesFromResource(R.xml.pref_advanced)
}
}

View file

@ -1,65 +0,0 @@
package code.name.monkey.retromusic.ui.fragments.settings;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.preference.TwoStatePreference;
import code.name.monkey.retromusic.R;
import code.name.monkey.retromusic.App;
import code.name.monkey.retromusic.util.PreferenceUtil;
public class PersonaizeSettingsFragment extends AbsSettingsFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
@SuppressWarnings("ConstantConditions")
@Override
public void invalidateSettings() {
final TwoStatePreference cornerWindow = (TwoStatePreference) findPreference("corner_window");
cornerWindow.setOnPreferenceChangeListener((preference, newValue) -> {
if ((Boolean) newValue && !App.Companion.isProVersion()) {
showProToastAndNavigate(getActivity().getString(R.string.pref_title_round_corners));
return false;
}
getActivity().recreate();
return true;
});
final TwoStatePreference toggleFullScreen = (TwoStatePreference) findPreference("toggle_full_screen");
toggleFullScreen.setOnPreferenceChangeListener((preference, newValue) -> {
getActivity().recreate();
return true;
});
}
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
addPreferencesFromResource(R.xml.pref_ui);
addPreferencesFromResource(R.xml.pref_window);
addPreferencesFromResource(R.xml.pref_lockscreen);
}
@Override
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
//noinspection ConstantConditions
PreferenceUtil.getInstance().registerOnSharedPreferenceChangedListener(this);
}
@Override
public void onDestroyView() {
super.onDestroyView();
//noinspection ConstantConditions
PreferenceUtil.getInstance().unregisterOnSharedPreferenceChangedListener(this);
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
switch (key) {
case PreferenceUtil.CAROUSEL_EFFECT:
invalidateSettings();
break;
}
}
}

View file

@ -0,0 +1,55 @@
package code.name.monkey.retromusic.ui.fragments.settings
import android.content.SharedPreferences
import android.os.Bundle
import android.view.View
import androidx.preference.TwoStatePreference
import code.name.monkey.retromusic.App
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.util.PreferenceUtil
class PersonaizeSettingsFragment : AbsSettingsFragment(), SharedPreferences.OnSharedPreferenceChangeListener {
override fun invalidateSettings() {
val cornerWindow = findPreference("corner_window") as TwoStatePreference
cornerWindow.setOnPreferenceChangeListener { _, newValue ->
if (newValue as Boolean && !App.isProVersion) {
showProToastAndNavigate(activity!!.getString(R.string.pref_title_round_corners))
return@setOnPreferenceChangeListener false
}
activity!!.recreate()
true
}
val toggleFullScreen = findPreference("toggle_full_screen") as TwoStatePreference
toggleFullScreen.setOnPreferenceChangeListener { _, newValue ->
activity!!.recreate()
true
}
}
override fun onCreatePreferences(savedInstanceState: Bundle, rootKey: String) {
addPreferencesFromResource(R.xml.pref_ui)
addPreferencesFromResource(R.xml.pref_window)
addPreferencesFromResource(R.xml.pref_lockscreen)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
PreferenceUtil.getInstance().registerOnSharedPreferenceChangedListener(this)
}
override fun onDestroyView() {
super.onDestroyView()
PreferenceUtil.getInstance().unregisterOnSharedPreferenceChangedListener(this)
}
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) {
when (key) {
PreferenceUtil.CAROUSEL_EFFECT -> invalidateSettings()
}
}
}

View file

@ -1,122 +0,0 @@
package code.name.monkey.retromusic.ui.fragments.settings;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import com.afollestad.materialdialogs.color.ColorChooserDialog;
import androidx.core.content.ContextCompat;
import androidx.preference.Preference;
import androidx.preference.TwoStatePreference;
import code.name.monkey.appthemehelper.ThemeStore;
import code.name.monkey.appthemehelper.common.prefs.supportv7.ATEColorPreference;
import code.name.monkey.appthemehelper.util.ColorUtil;
import code.name.monkey.appthemehelper.util.VersionUtils;
import code.name.monkey.retromusic.R;
import code.name.monkey.retromusic.App;
import code.name.monkey.retromusic.ui.activities.SettingsActivity;
import code.name.monkey.retromusic.util.PreferenceUtil;
/**
* @author Hemanth S (h4h13).
*/
public class ThemeSettingsFragment extends AbsSettingsFragment {
@Override
public void invalidateSettings() {
final ATEColorPreference primaryColorPref = (ATEColorPreference) findPreference(
"primary_color");
//noinspection ConstantConditions
primaryColorPref.setVisible(PreferenceUtil.getInstance().getGeneralTheme() == R.style.Theme_RetroMusic_Color);
final int primaryColor = ThemeStore.primaryColor(getActivity());
primaryColorPref.setColor(primaryColor, ColorUtil.darkenColor(primaryColor));
primaryColorPref.setOnPreferenceClickListener(preference -> {
new ColorChooserDialog.Builder(getActivity(), R.string.primary_color)
.accentMode(false)
.allowUserColorInput(true)
.allowUserColorInputAlpha(false)
.preselect(primaryColor)
.show(getActivity());
return true;
});
final Preference generalTheme = findPreference("general_theme");
setSummary(generalTheme);
generalTheme.setOnPreferenceChangeListener((preference, newValue) -> {
String theme = (String) newValue;
if (theme.equals("color") && !App.Companion.isProVersion()) {
primaryColorPref.setVisible(false);
showProToastAndNavigate("Color theme");
return false;
} else {
primaryColorPref.setVisible(true);
}
setSummary(generalTheme, newValue);
switch (theme) {
case "light":
ThemeStore.editTheme(getContext()).primaryColor(Color.WHITE).commit();
break;
case "black":
ThemeStore.editTheme(getContext()).primaryColor(Color.BLACK).commit();
break;
case "dark":
ThemeStore.editTheme(getContext()).primaryColor(ContextCompat.getColor(getContext(), R.color.md_grey_900)).commit();
break;
case "color":
ThemeStore.editTheme(getContext()).primaryColor(ContextCompat.getColor(getContext(), R.color.md_blue_grey_800)).commit();
break;
}
ThemeStore.editTheme(getActivity())
.activityTheme(PreferenceUtil.getThemeResFromPrefValue(theme))
.commit();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
getActivity().setTheme(PreferenceUtil.getThemeResFromPrefValue(theme));
}
getActivity().recreate();
//invalidateSettings();
return true;
});
ATEColorPreference accentColorPref = (ATEColorPreference) findPreference("accent_color");
final int accentColor = ThemeStore.accentColor(getActivity());
accentColorPref.setColor(accentColor, ColorUtil.darkenColor(accentColor));
accentColorPref.setOnPreferenceClickListener(preference -> {
new ColorChooserDialog.Builder(((SettingsActivity) getActivity()), R.string.accent_color)
.accentMode(true)
.allowUserColorInput(true)
.allowUserColorInputAlpha(false)
.preselect(accentColor)
.show(getActivity());
return true;
});
TwoStatePreference colorAppShortcuts = (TwoStatePreference) findPreference(
"should_color_app_shortcuts");
if (!VersionUtils.hasNougatMR()) {
colorAppShortcuts.setVisible(false);
} else {
colorAppShortcuts.setChecked(PreferenceUtil.getInstance().coloredAppShortcuts());
colorAppShortcuts.setOnPreferenceChangeListener((preference, newValue) -> {
// Save preference
PreferenceUtil.getInstance().setColoredAppShortcuts((Boolean) newValue);
return true;
});
}
}
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
addPreferencesFromResource(R.xml.pref_general);
}
}

View file

@ -0,0 +1,108 @@
package code.name.monkey.retromusic.ui.fragments.settings
import android.graphics.Color
import android.os.Build
import android.os.Bundle
import androidx.core.content.ContextCompat
import androidx.preference.TwoStatePreference
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.common.prefs.supportv7.ATEColorPreference
import code.name.monkey.appthemehelper.util.ColorUtil
import code.name.monkey.appthemehelper.util.VersionUtils
import code.name.monkey.retromusic.App
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.util.PreferenceUtil
import com.afollestad.materialdialogs.color.ColorChooserDialog
/**
* @author Hemanth S (h4h13).
*/
class ThemeSettingsFragment : AbsSettingsFragment() {
override fun invalidateSettings() {
val primaryColorPref = findPreference(
"primary_color") as ATEColorPreference
primaryColorPref.isVisible = PreferenceUtil.getInstance().generalTheme == R.style.Theme_RetroMusic_Color
val primaryColor = ThemeStore.primaryColor(activity!!)
primaryColorPref.setColor(primaryColor, ColorUtil.darkenColor(primaryColor))
primaryColorPref.setOnPreferenceClickListener {
ColorChooserDialog.Builder(activity!!, R.string.primary_color)
.accentMode(false)
.allowUserColorInput(true)
.allowUserColorInputAlpha(false)
.preselect(primaryColor)
.show(activity!!)
true
}
val generalTheme = findPreference("general_theme")
setSummary(generalTheme)
generalTheme.setOnPreferenceChangeListener { _, newValue ->
val theme = newValue as String
if (theme == "color" && !App.isProVersion) {
primaryColorPref.isVisible = false
showProToastAndNavigate("Color theme")
return@setOnPreferenceChangeListener false
} else {
primaryColorPref.isVisible = true
}
setSummary(generalTheme, newValue)
when (theme) {
"light" -> ThemeStore.editTheme(context!!).primaryColor(Color.WHITE).commit()
"black" -> ThemeStore.editTheme(context!!).primaryColor(Color.BLACK).commit()
"dark" -> ThemeStore.editTheme(context!!).primaryColor(ContextCompat.getColor(context!!, R.color.md_grey_900)).commit()
"color" -> ThemeStore.editTheme(context!!).primaryColor(ContextCompat.getColor(context!!, R.color.md_blue_grey_800)).commit()
}
ThemeStore.editTheme(activity!!)
.activityTheme(PreferenceUtil.getThemeResFromPrefValue(theme))
.commit()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
activity!!.setTheme(PreferenceUtil.getThemeResFromPrefValue(theme))
}
activity!!.recreate()
//invalidateSettings();
true
}
val accentColorPref = findPreference("accent_color") as ATEColorPreference
val accentColor = ThemeStore.accentColor(activity!!)
accentColorPref.setColor(accentColor, ColorUtil.darkenColor(accentColor))
accentColorPref.setOnPreferenceClickListener {
ColorChooserDialog.Builder(context!!, R.string.accent_color)
.accentMode(true)
.allowUserColorInput(true)
.allowUserColorInputAlpha(false)
.preselect(accentColor)
.show(activity!!)
true
}
val colorAppShortcuts = findPreference(
"should_color_app_shortcuts") as TwoStatePreference
if (!VersionUtils.hasNougatMR()) {
colorAppShortcuts.isVisible = false
} else {
colorAppShortcuts.isChecked = PreferenceUtil.getInstance().coloredAppShortcuts()
colorAppShortcuts.setOnPreferenceChangeListener { _, newValue ->
// Save preference
PreferenceUtil.getInstance().setColoredAppShortcuts(newValue as Boolean)
true
}
}
}
override fun onCreatePreferences(savedInstanceState: Bundle, rootKey: String) {
addPreferencesFromResource(R.xml.pref_general)
}
}