/*
This file is part of Subsonic.
Subsonic is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Subsonic is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
Copyright 2010 (C) Sindre Mehus
*/
package github.madmarty.madsonic.activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.TextView;
import github.madmarty.madsonic.R;
import github.madmarty.madsonic.domain.PodcastChannel;
import github.madmarty.madsonic.service.MusicService;
import github.madmarty.madsonic.service.MusicServiceFactory;
import github.madmarty.madsonic.service.OfflineException;
import github.madmarty.madsonic.service.RESTMusicService;
import github.madmarty.madsonic.service.ServerTooOldException;
import github.madmarty.madsonic.util.Constants;
import github.madmarty.madsonic.util.LoadingTask;
import github.madmarty.madsonic.util.PopupMenuHelper;
import github.madmarty.madsonic.util.SilentBackgroundTask;
import github.madmarty.madsonic.util.TabActivityBackgroundTask;
import github.madmarty.madsonic.util.Util;
import github.madmarty.madsonic.view.PodcastChannelAdapter;
import github.madmarty.madsonic.util.Logger;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/**
*
* @author Scott
*/
public class SelectPodcastsActivity extends SubsonicTabActivity implements AdapterView.OnItemClickListener {
private static final Logger LOG = new Logger(SelectPodcastsActivity.class);
private PodcastChannelAdapter podcastAdapter;
private ListView podcastListView;
private View emptyView;
private List<PodcastChannel> channels;
@Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.select_podcasts);
if(bundle != null) {
channels = (List<PodcastChannel>) bundle.getSerializable(Constants.CHANNEL_LIST);
}
try {
String theme = Util.getTheme(getBaseContext());
if ("Madsonic Flawless".equals(theme) || "Madsonic Flawless Fullscreen".equals(theme)) {
mainBar = findViewById(R.id.button_bar);
mainBar.setBackgroundResource(R.drawable.menubar_button_normal_green);
}
if ("Madsonic Pink".equals(theme) || "Madsonic Pink Fullscreen".equals(theme)) {
mainBar = findViewById(R.id.button_bar);
mainBar.setBackgroundResource(R.drawable.menubar_button_normal_pink);
}
if ("Madsonic Light".equals(theme) || "Madsonic Light Fullscreen".equals(theme)) {
mainBar = findViewById(R.id.button_bar);
mainBar.setBackgroundResource(R.drawable.menubar_button_light);
}
// Button 1: gone
ImageButton searchButton = (ImageButton) findViewById(R.id.action_button_1);
searchButton.setVisibility(View.GONE);
// Button 2: refresh
ImageButton refreshButton = (ImageButton) findViewById(R.id.action_button_2);
refreshButton.setImageResource(R.drawable.action_refresh);
refreshButton.setVisibility(View.VISIBLE);
refreshButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
refresh(true);
}
});
// Button 3: Settings
final ImageButton actionSettingsButton = (ImageButton)findViewById(R.id.action_button_3);
actionSettingsButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
new PopupMenuHelper().showMenu(SelectPodcastsActivity.this, actionSettingsButton, R.menu.select_podcasts);
}
});
} catch (Exception ex) {
// Log.e(TAG, ex.getCause().toString());
}
podcastListView = (ListView) findViewById(R.id.select_podcasts_list);
podcastListView.setOnItemClickListener(this);
registerForContextMenu(podcastListView);
emptyView = findViewById(R.id.select_podcasts_empty);
if(channels == null) {
refresh(true);
}
else {
podcastListView.setAdapter(podcastAdapter = new PodcastChannelAdapter(getBaseContext(), channels));
refresh(false);
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putSerializable(Constants.CHANNEL_LIST, (Serializable) channels);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.select_podcasts, menu);
super.onCreateOptionsMenu(menu);
return true;
}
public void onCreateOptionsMenu(Menu menu, MenuInflater menuInflater) {
menuInflater.inflate(R.menu.select_podcasts, menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if(super.onOptionsItemSelected(item)) {
return true;
}
switch (item.getItemId()) {
case R.id.menu_check:
refreshPodcasts();
break;
case R.id.menu_add_podcast:
addNewPodcast();
break;
}
return false;
}
@Override
public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, view, menuInfo);
if(!Util.isOffline(getBaseContext())) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.select_podcasts_context, menu);
}
}
@Override
public boolean onContextItemSelected(MenuItem menuItem) {
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuItem.getMenuInfo();
PodcastChannel channel = (PodcastChannel) podcastListView.getItemAtPosition(info.position);
switch (menuItem.getItemId()) {
case R.id.podcast_channel_info:
displayPodcastInfo(channel);
break;
case R.id.podcast_channel_delete:
deletePodcast(channel);
break;
}
return true;
}
protected void refresh(final boolean refresh) {
setTitle(R.string.button_bar_podcasts);
podcastListView.setVisibility(View.INVISIBLE);
emptyView.setVisibility(View.GONE);
TabActivityBackgroundTask<List<PodcastChannel>> task = new TabActivityBackgroundTask<List<PodcastChannel>>(this, refresh) {
@Override
protected List<PodcastChannel> doInBackground() throws Throwable {
MusicService musicService = MusicServiceFactory.getMusicService(getBaseContext());
channels = new ArrayList<PodcastChannel>();
try {
channels = musicService.getPodcastChannels(refresh, getBaseContext(), this);
} catch (Exception x) {
LOG.error("Failed to load podcasts", x);
}
return channels;
}
@Override
protected void done(List<PodcastChannel> result) {
emptyView.setVisibility(result == null || result.isEmpty() ? View.VISIBLE : View.GONE);
if (result != null) {
podcastListView.setAdapter(podcastAdapter = new PodcastChannelAdapter(getBaseContext(), result));
podcastListView.setVisibility(View.VISIBLE);
}
}
};
task.execute();
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
PodcastChannel channel = (PodcastChannel) parent.getItemAtPosition(position);
if("error".equals(channel.getStatus())) {
Util.toast(getBaseContext(), getBaseContext().getResources().getString(R.string.select_podcasts_invalid_podcast_channel, channel.getErrorMessage() == null ? "error" : channel.getErrorMessage()));
} else if("downloading".equals(channel.getStatus())) {
Util.toast(getBaseContext(), R.string.select_podcasts_initializing);
} else {
Intent intent = new Intent(this, SelectAlbumActivity.class);
intent.putExtra(Constants.INTENT_EXTRA_NAME_ID, channel.getId());
intent.putExtra(Constants.INTENT_EXTRA_NAME_NAME, channel.getName());
intent.putExtra(Constants.INTENT_EXTRA_NAME_PODCAST_ID, channel.getId());
intent.putExtra(Constants.INTENT_EXTRA_NAME_PODCAST_NAME, channel.getName());
intent.putExtra(Constants.INTENT_EXTRA_NAME_PODCAST_DESCRIPTION, channel.getDescription());
Util.startActivityWithoutTransition(this, intent);
}
}
public void refreshPodcasts() {
new SilentBackgroundTask<Void>(this) {
@Override
protected Void doInBackground() throws Throwable {
MusicService musicService = MusicServiceFactory.getMusicService(getBaseContext());
musicService.refreshPodcasts(getBaseContext(), null);
return null;
}
@Override
protected void done(Void result) {
Util.toast(getBaseContext(), R.string.select_podcasts_refreshing);
}
@Override
protected void error(Throwable error) {
Util.toast(getBaseContext(), getErrorMessage(error), false);
}
}.execute();
}
private void addNewPodcast() {
View dialogView = getLayoutInflater().inflate(R.layout.create_podcast, null);
final TextView urlBox = (TextView) dialogView.findViewById(R.id.create_podcast_url);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.menu_add_podcast)
.setView(dialogView)
.setPositiveButton(R.string.common_ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
addNewPodcast(urlBox.getText().toString());
}
})
.setNegativeButton(R.string.common_cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
})
.setCancelable(true);
AlertDialog dialog = builder.create();
dialog.show();
}
private void addNewPodcast(final String url) {
new LoadingTask<Void>(this, false) {
@Override
protected Void doInBackground() throws Throwable {
MusicService musicService = MusicServiceFactory.getMusicService(getBaseContext());
musicService.createPodcastChannel(url, getBaseContext(), null);
return null;
}
@Override
protected void done(Void result) {
refresh(false);
}
@Override
protected void error(Throwable error) {
String msg;
if (error instanceof OfflineException || error instanceof ServerTooOldException) {
msg = getErrorMessage(error);
} else {
msg = getBaseContext().getResources().getString(R.string.select_podcasts_created_error) + " " + getErrorMessage(error);
}
Util.toast(getBaseContext(), msg, false);
}
}.execute();
}
private void displayPodcastInfo(final PodcastChannel channel) {
String message = ((channel.getName()) == null ? "" : "Title: " + channel.getName()) +
"\nURL: " + channel.getUrl() + "\nStatus: " + channel.getStatus() +
((channel.getErrorMessage()) == null ? "" : "\nError Message: " + channel.getErrorMessage()) +
((channel.getDescription()) == null ? "" : "\nDescription: " + channel.getDescription());
Util.info(this, R.string.main_about, message);
}
private void deletePodcast(final PodcastChannel channel) {
Util.confirmDialog(this, R.string.common_delete, channel.getName(), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
new LoadingTask<Void>(SelectPodcastsActivity.this, false) {
@Override
protected Void doInBackground() throws Throwable {
MusicService musicService = MusicServiceFactory.getMusicService(SelectPodcastsActivity.this);
musicService.deletePodcastChannel(channel.getId(), SelectPodcastsActivity.this, null);
return null;
}
@Override
protected void done(Void result) {
podcastAdapter.remove(channel);
podcastAdapter.notifyDataSetChanged();
Util.toast(SelectPodcastsActivity.this, SelectPodcastsActivity.this.getResources().getString(R.string.select_podcasts_deleted, channel.getName()));
}
@Override
protected void error(Throwable error) {
String msg;
if (error instanceof OfflineException || error instanceof ServerTooOldException) {
msg = getErrorMessage(error);
} else {
msg = SelectPodcastsActivity.this.getResources().getString(R.string.select_podcasts_deleted_error, channel.getName()) + " " + getErrorMessage(error);
}
Util.toast(SelectPodcastsActivity.this, msg, false);
}
}.execute();
}
});
}
@Deprecated
public static void confirmDialog(Context context, int action, String subject, DialogInterface.OnClickListener onClick) {
confirmDialog(context, context.getResources().getString(action).toLowerCase(), subject, onClick);
}
@Deprecated
public static void confirmDialog(Context context, String action, String subject, DialogInterface.OnClickListener onClick) {
new AlertDialog.Builder(context)
.setIcon(android.R.drawable.ic_dialog_alert)
.setTitle(R.string.common_confirm)
.setMessage(context.getResources().getString(R.string.common_confirm_message, action, subject))
.setPositiveButton(R.string.common_ok, onClick)
.setNegativeButton(R.string.common_cancel, null)
.show();
}
}