From 257913196b0aa7f971bad387359f49e391fe9ed3 Mon Sep 17 00:00:00 2001 From: daniel oeh Date: Fri, 18 Apr 2014 20:32:22 +0200 Subject: Added FeedItem dialog --- .../danoeh/antennapod/dialog/FeedItemDialog.java | 306 +++++++++++++++++++++ 1 file changed, 306 insertions(+) create mode 100644 src/de/danoeh/antennapod/dialog/FeedItemDialog.java (limited to 'src/de/danoeh/antennapod/dialog') diff --git a/src/de/danoeh/antennapod/dialog/FeedItemDialog.java b/src/de/danoeh/antennapod/dialog/FeedItemDialog.java new file mode 100644 index 000000000..62c274858 --- /dev/null +++ b/src/de/danoeh/antennapod/dialog/FeedItemDialog.java @@ -0,0 +1,306 @@ +package de.danoeh.antennapod.dialog; + +import android.app.Dialog; +import android.content.ActivityNotFoundException; +import android.content.Context; +import android.content.Intent; +import android.content.res.TypedArray; +import android.net.Uri; +import android.os.AsyncTask; +import android.os.Build; +import android.os.Bundle; +import android.support.v7.widget.PopupMenu; +import android.util.Log; +import android.util.TypedValue; +import android.view.MenuItem; +import android.view.View; +import android.webkit.WebSettings; +import android.webkit.WebView; +import android.webkit.WebViewClient; +import android.widget.ImageButton; +import android.widget.Toast; +import de.danoeh.antennapod.BuildConfig; +import de.danoeh.antennapod.R; +import de.danoeh.antennapod.adapter.DefaultActionButtonCallback; +import de.danoeh.antennapod.feed.FeedItem; +import de.danoeh.antennapod.feed.FeedMedia; +import de.danoeh.antennapod.preferences.UserPreferences; +import de.danoeh.antennapod.storage.DBTasks; +import de.danoeh.antennapod.storage.DBWriter; +import de.danoeh.antennapod.storage.DownloadRequestException; +import de.danoeh.antennapod.storage.DownloadRequester; +import de.danoeh.antennapod.util.QueueAccess; +import de.danoeh.antennapod.util.ShownotesProvider; +import de.danoeh.antennapod.util.menuhandler.FeedItemMenuHandler; +import org.apache.commons.lang3.StringEscapeUtils; + +import java.util.Collection; +import java.util.concurrent.Callable; + +/** + * Shows information about a specific FeedItem and provides actions like playing, downloading, etc. + */ +public class FeedItemDialog extends Dialog { + private static final String TAG = "FeedItemDialog"; + + private FeedItem item; + private QueueAccess queue; + + private View header; + private WebView webvDescription; + private ImageButton butAction1; + private ImageButton butAction2; + private ImageButton butMore; + private PopupMenu popupMenu; + + public FeedItemDialog(Context context, FeedItem item, QueueAccess queue) { + super(context); + if (item == null) throw new IllegalArgumentException("item = null"); + if (queue == null) throw new IllegalArgumentException("queue = null"); + this.item = item; + this.queue = queue; + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.feeditem_dialog); + + header = findViewById(R.id.header); + webvDescription = (WebView) findViewById(R.id.webview); + butAction1 = (ImageButton) findViewById(R.id.butAction1); + butAction2 = (ImageButton) findViewById(R.id.butAction2); + butMore = (ImageButton) findViewById(R.id.butMoreActions); + popupMenu = new PopupMenu(getContext(), butMore); + + webvDescription.setWebViewClient(new WebViewClient()); + setTitle(item.getTitle()); + + if (UserPreferences.getTheme() == R.style.Theme_AntennaPod_Dark) { + if (Build.VERSION.SDK_INT >= 11 + && Build.VERSION.SDK_INT <= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) { + webvDescription.setLayerType(View.LAYER_TYPE_SOFTWARE, null); + } + webvDescription.setBackgroundColor(getContext().getResources().getColor( + R.color.black)); + } + webvDescription.getSettings().setUseWideViewPort(false); + webvDescription.getSettings().setLayoutAlgorithm( + WebSettings.LayoutAlgorithm.NARROW_COLUMNS); + webvDescription.getSettings().setLoadWithOverviewMode(true); + webvDescription.setWebViewClient(new WebViewClient() { + + @Override + public boolean shouldOverrideUrlLoading(WebView view, String url) { + Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); + try { + getContext().startActivity(intent); + } catch (ActivityNotFoundException e) { + e.printStackTrace(); + return false; + } + return true; + } + }); + + loadDescriptionWebview(item); + + butAction1.setOnClickListener(new View.OnClickListener() { + DefaultActionButtonCallback actionButtonCallback = new DefaultActionButtonCallback(getContext()); + + @Override + + public void onClick(View v) { + FeedMedia media = item.getMedia(); + if (media == null) { + return; + } + actionButtonCallback.onActionButtonPressed(item); + + } + } + ); + + butAction2.setOnClickListener(new View.OnClickListener() + + { + @Override + public void onClick(View v) { + FeedMedia media = item.getMedia(); + if (media == null) { + return; + } + + if (!media.isDownloaded()) { + DBTasks.playMedia(getContext(), media, true, true, true); + dismiss(); + } else { + DBWriter.deleteFeedMediaOfItem(getContext(), media.getId()); + } + } + } + ); + + butMore.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + popupMenu.getMenu().clear(); + popupMenu.inflate(R.menu.feeditem_dialog); + FeedItemMenuHandler.onPrepareMenu(popupMenuInterface, item, true, queue); + popupMenu.show(); + } + } + ); + + popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem menuItem) { + + try { + return FeedItemMenuHandler.onMenuItemClicked(getContext(), menuItem.getItemId(), item); + } catch (DownloadRequestException e) { + e.printStackTrace(); + Toast.makeText(getContext(), e.getMessage(), Toast.LENGTH_LONG).show(); + return true; + } + } + } + ); + + updateMenuAppearance(); + } + + private final FeedItemMenuHandler.MenuInterface popupMenuInterface = new FeedItemMenuHandler.MenuInterface() { + @Override + public void setItemVisibility(int id, boolean visible) { + MenuItem item = popupMenu.getMenu().findItem(id); + if (item != null) { + item.setVisible(visible); + } + } + }; + + public void updateMenuAppearance() { + if (item == null || queue == null) { + Log.w(TAG, "UpdateMenuAppearance called while item or queue was null"); + return; + } + FeedMedia media = item.getMedia(); + if (media == null) { + header.setVisibility(View.GONE); + } else { + header.setVisibility(View.VISIBLE); + boolean isDownloading = DownloadRequester.getInstance().isDownloadingFile(media); + TypedArray drawables = getContext().obtainStyledAttributes(new int[]{R.attr.av_play, + R.attr.av_download, R.attr.action_stream, R.attr.content_discard, R.attr.navigation_cancel}); + + if (!media.isDownloaded()) { + butAction2.setImageDrawable(drawables.getDrawable(2)); + butAction2.setContentDescription(getContext().getString(R.string.stream_label)); + } else { + butAction2.setImageDrawable(drawables.getDrawable(3)); + butAction2.setContentDescription(getContext().getString(R.string.remove_episode_lable)); + } + + if (isDownloading) { + butAction1.setImageDrawable(drawables.getDrawable(4)); + butAction1.setContentDescription(getContext().getString(R.string.cancel_download_label)); + } else if (media.isDownloaded()) { + butAction1.setImageDrawable(drawables.getDrawable(0)); + butAction1.setContentDescription(getContext().getString(R.string.play_label)); + } else { + butAction1.setImageDrawable(drawables.getDrawable(1)); + butAction1.setContentDescription(getContext().getString(R.string.download_label)); + } + + drawables.recycle(); + } + } + + + private void loadDescriptionWebview(final ShownotesProvider shownotesProvider) { + AsyncTask loadTask = new AsyncTask() { + String data; + + + private String applyWebviewStyle(String textColor, String data) { + final String WEBVIEW_STYLE = "%s"; + final int pageMargin = (int) TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, 8, getContext().getResources() + .getDisplayMetrics() + ); + return String.format(WEBVIEW_STYLE, textColor, "100%", pageMargin, + pageMargin, pageMargin, pageMargin, data); + } + + + @Override + protected void onPostExecute(Void result) { + super.onPostExecute(result); + // /webvDescription.loadData(url, "text/html", "utf-8"); + if (FeedItemDialog.this.isShowing() && webvDescription != null) { + webvDescription.loadDataWithBaseURL(null, data, "text/html", + "utf-8", "about:blank"); + if (BuildConfig.DEBUG) + Log.d(TAG, "Webview loaded"); + } + } + + + @Override + protected Void doInBackground(Void... params) { + if (BuildConfig.DEBUG) + Log.d(TAG, "Loading Webview"); + try { + Callable shownotesLoadTask = shownotesProvider.loadShownotes(); + final String shownotes = shownotesLoadTask.call(); + + data = StringEscapeUtils.unescapeHtml4(shownotes); + TypedArray res = getContext() + .getTheme() + .obtainStyledAttributes( + new int[]{android.R.attr.textColorPrimary}); + int colorResource = res.getColor(0, 0); + String colorString = String.format("#%06X", + 0xFFFFFF & colorResource); + Log.i(TAG, "text color: " + colorString); + res.recycle(); + data = applyWebviewStyle(colorString, data); + + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + }; + loadTask.execute(); + } + + public void setItem(FeedItem item) { + if (item == null) throw new IllegalArgumentException("item = null"); + this.item = item; + } + + public void setItemFromCollection(Collection items) { + for (FeedItem item : items) { + if (item.getId() == this.item.getId()) { + setItem(item); + break; + } + } + } + + public void setQueue(QueueAccess queue) { + if (queue == null) throw new IllegalArgumentException("queue = null"); + this.queue = queue; + } + + public FeedItem getItem() { + return item; + } + + public QueueAccess getQueue() { + return queue; + } +} -- cgit v1.2.3 From 1fe2a8da456a3fbf3752c7a8ae218891b632d552 Mon Sep 17 00:00:00 2001 From: daniel oeh Date: Tue, 22 Apr 2014 13:55:20 +0200 Subject: Resolved dialog issues + fragment crashes --- .../danoeh/antennapod/dialog/FeedItemDialog.java | 35 ++++++++++++++++++++-- 1 file changed, 32 insertions(+), 3 deletions(-) (limited to 'src/de/danoeh/antennapod/dialog') diff --git a/src/de/danoeh/antennapod/dialog/FeedItemDialog.java b/src/de/danoeh/antennapod/dialog/FeedItemDialog.java index 62c274858..cb8e5b877 100644 --- a/src/de/danoeh/antennapod/dialog/FeedItemDialog.java +++ b/src/de/danoeh/antennapod/dialog/FeedItemDialog.java @@ -33,6 +33,7 @@ import de.danoeh.antennapod.util.QueueAccess; import de.danoeh.antennapod.util.ShownotesProvider; import de.danoeh.antennapod.util.menuhandler.FeedItemMenuHandler; import org.apache.commons.lang3.StringEscapeUtils; +import org.shredzone.flattr4j.model.User; import java.util.Collection; import java.util.concurrent.Callable; @@ -53,14 +54,35 @@ public class FeedItemDialog extends Dialog { private ImageButton butMore; private PopupMenu popupMenu; - public FeedItemDialog(Context context, FeedItem item, QueueAccess queue) { - super(context); + public static FeedItemDialog newInstace(Context context, FeedItem item, QueueAccess queue) { + if (useDarkThemeWorkAround()) { + return new FeedItemDialog(context, R.style.Theme_AntennaPod_Dark, item, queue); + } else { + return new FeedItemDialog(context, item, queue); + } + } + + public FeedItemDialog(Context context, int theme, FeedItem item, QueueAccess queue) { + super(context, theme); if (item == null) throw new IllegalArgumentException("item = null"); if (queue == null) throw new IllegalArgumentException("queue = null"); this.item = item; this.queue = queue; } + private FeedItemDialog(Context context, FeedItem item, QueueAccess queue) { + this(context, 0, item, queue); + } + + /** + * Returns true if the dialog should use a dark theme. This has to be done on Gingerbread devices + * because dialogs are only available in a dark theme. + */ + private static boolean useDarkThemeWorkAround() { + return Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD_MR1 + && UserPreferences.getTheme() != R.style.Theme_AntennaPod_Dark; + } + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -170,6 +192,8 @@ public class FeedItemDialog extends Dialog { updateMenuAppearance(); } + + private final FeedItemMenuHandler.MenuInterface popupMenuInterface = new FeedItemMenuHandler.MenuInterface() { @Override public void setItemVisibility(int id, boolean visible) { @@ -260,7 +284,12 @@ public class FeedItemDialog extends Dialog { .getTheme() .obtainStyledAttributes( new int[]{android.R.attr.textColorPrimary}); - int colorResource = res.getColor(0, 0); + int colorResource; + if (useDarkThemeWorkAround()) { + colorResource = getContext().getResources().getColor(R.color.black); + } else { + colorResource = res.getColor(0, 0); + } String colorString = String.format("#%06X", 0xFFFFFF & colorResource); Log.i(TAG, "text color: " + colorString); -- cgit v1.2.3 From a7c8438b158ac3800e28b3e0113872e65dbeb35b Mon Sep 17 00:00:00 2001 From: daniel oeh Date: Sat, 26 Apr 2014 23:07:11 +0200 Subject: Improved fonts --- src/de/danoeh/antennapod/dialog/FeedItemDialog.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/de/danoeh/antennapod/dialog') diff --git a/src/de/danoeh/antennapod/dialog/FeedItemDialog.java b/src/de/danoeh/antennapod/dialog/FeedItemDialog.java index cb8e5b877..932f9aec9 100644 --- a/src/de/danoeh/antennapod/dialog/FeedItemDialog.java +++ b/src/de/danoeh/antennapod/dialog/FeedItemDialog.java @@ -248,7 +248,7 @@ public class FeedItemDialog extends Dialog { private String applyWebviewStyle(String textColor, String data) { - final String WEBVIEW_STYLE = "%s"; + final String WEBVIEW_STYLE = "%s"; final int pageMargin = (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, 8, getContext().getResources() .getDisplayMetrics() -- cgit v1.2.3 From d0ff8999900ca7d294c46a425079b90f52365eaf Mon Sep 17 00:00:00 2001 From: daniel oeh Date: Sun, 11 May 2014 00:48:02 +0200 Subject: Fixed Download screen problems and download report notification --- .../danoeh/antennapod/dialog/FeedItemDialog.java | 38 +++++++++++++++++++--- 1 file changed, 34 insertions(+), 4 deletions(-) (limited to 'src/de/danoeh/antennapod/dialog') diff --git a/src/de/danoeh/antennapod/dialog/FeedItemDialog.java b/src/de/danoeh/antennapod/dialog/FeedItemDialog.java index 932f9aec9..25458399b 100644 --- a/src/de/danoeh/antennapod/dialog/FeedItemDialog.java +++ b/src/de/danoeh/antennapod/dialog/FeedItemDialog.java @@ -33,9 +33,9 @@ import de.danoeh.antennapod.util.QueueAccess; import de.danoeh.antennapod.util.ShownotesProvider; import de.danoeh.antennapod.util.menuhandler.FeedItemMenuHandler; import org.apache.commons.lang3.StringEscapeUtils; -import org.shredzone.flattr4j.model.User; import java.util.Collection; +import java.util.List; import java.util.concurrent.Callable; /** @@ -193,7 +193,6 @@ public class FeedItemDialog extends Dialog { } - private final FeedItemMenuHandler.MenuInterface popupMenuInterface = new FeedItemMenuHandler.MenuInterface() { @Override public void setItemVisibility(int id, boolean visible) { @@ -306,18 +305,49 @@ public class FeedItemDialog extends Dialog { loadTask.execute(); } + /** + * Convenience method that calls setQueue() and setItemFromCollection() with + * the given arguments. + * + * @return true if one of the calls to setItemFromCollection returned true, + * false otherwise. + */ + public boolean updateContent(QueueAccess queue, List... collections) { + setQueue(queue); + + boolean setItemFromCollectionResult = false; + if (collections != null) { + for (List list : collections) { + setItemFromCollectionResult |= setItemFromCollection(list); + } + } + if (isShowing()) { + updateMenuAppearance(); + } + + return setItemFromCollectionResult; + } + + public void setItem(FeedItem item) { if (item == null) throw new IllegalArgumentException("item = null"); this.item = item; } - public void setItemFromCollection(Collection items) { + /** + * Finds the FeedItem of this dialog in a collection and updates its state from that + * collection. + * + * @return true if the FeedItem was found, false otherwise. + */ + public boolean setItemFromCollection(Collection items) { for (FeedItem item : items) { if (item.getId() == this.item.getId()) { setItem(item); - break; + return true; } } + return false; } public void setQueue(QueueAccess queue) { -- cgit v1.2.3 From 155774557cd170cd88941c3daee0f3949c4e26b8 Mon Sep 17 00:00:00 2001 From: daniel oeh Date: Mon, 12 May 2014 18:55:58 +0200 Subject: Reopen episode dialog on configuration change --- .../danoeh/antennapod/dialog/FeedItemDialog.java | 30 +++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) (limited to 'src/de/danoeh/antennapod/dialog') diff --git a/src/de/danoeh/antennapod/dialog/FeedItemDialog.java b/src/de/danoeh/antennapod/dialog/FeedItemDialog.java index 25458399b..fdd0cd09b 100644 --- a/src/de/danoeh/antennapod/dialog/FeedItemDialog.java +++ b/src/de/danoeh/antennapod/dialog/FeedItemDialog.java @@ -54,7 +54,16 @@ public class FeedItemDialog extends Dialog { private ImageButton butMore; private PopupMenu popupMenu; - public static FeedItemDialog newInstace(Context context, FeedItem item, QueueAccess queue) { + public static FeedItemDialog newInstance(Context context, FeedItemDialogSavedInstance savedInstance) { + if (savedInstance == null) throw new IllegalArgumentException("savedInstance = null"); + FeedItemDialog dialog = newInstance(context, savedInstance.item, savedInstance.queueAccess); + if (savedInstance.isShowing) { + dialog.show(); + } + return dialog; + } + + public static FeedItemDialog newInstance(Context context, FeedItem item, QueueAccess queue) { if (useDarkThemeWorkAround()) { return new FeedItemDialog(context, R.style.Theme_AntennaPod_Dark, item, queue); } else { @@ -362,4 +371,23 @@ public class FeedItemDialog extends Dialog { public QueueAccess getQueue() { return queue; } + + public FeedItemDialogSavedInstance save() { + return new FeedItemDialogSavedInstance(item, queue, isShowing()); + } + + /** + * Used to save the FeedItemDialog's state across configuration changes + * */ + public static class FeedItemDialogSavedInstance { + final FeedItem item; + final QueueAccess queueAccess; + final boolean isShowing; + + private FeedItemDialogSavedInstance(FeedItem item, QueueAccess queueAccess, boolean isShowing) { + this.item = item; + this.queueAccess = queueAccess; + this.isShowing = isShowing; + } + } } -- cgit v1.2.3 From 0d1803413c19ec78a0f0a79e3d6e8d07cf1b8a2a Mon Sep 17 00:00:00 2001 From: daniel oeh Date: Sat, 17 May 2014 13:49:03 +0200 Subject: Improved space usage of title area in episode dialog --- src/de/danoeh/antennapod/dialog/FeedItemDialog.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src/de/danoeh/antennapod/dialog') diff --git a/src/de/danoeh/antennapod/dialog/FeedItemDialog.java b/src/de/danoeh/antennapod/dialog/FeedItemDialog.java index fdd0cd09b..8db4c9d19 100644 --- a/src/de/danoeh/antennapod/dialog/FeedItemDialog.java +++ b/src/de/danoeh/antennapod/dialog/FeedItemDialog.java @@ -14,10 +14,12 @@ import android.util.Log; import android.util.TypedValue; import android.view.MenuItem; import android.view.View; +import android.view.Window; import android.webkit.WebSettings; import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.ImageButton; +import android.widget.TextView; import android.widget.Toast; import de.danoeh.antennapod.BuildConfig; import de.danoeh.antennapod.R; @@ -48,6 +50,7 @@ public class FeedItemDialog extends Dialog { private QueueAccess queue; private View header; + private TextView txtvTitle; private WebView webvDescription; private ImageButton butAction1; private ImageButton butAction2; @@ -95,8 +98,10 @@ public class FeedItemDialog extends Dialog { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.feeditem_dialog); + txtvTitle = (TextView) findViewById(R.id.txtvTitle); header = findViewById(R.id.header); webvDescription = (WebView) findViewById(R.id.webview); butAction1 = (ImageButton) findViewById(R.id.butAction1); @@ -105,7 +110,7 @@ public class FeedItemDialog extends Dialog { popupMenu = new PopupMenu(getContext(), butMore); webvDescription.setWebViewClient(new WebViewClient()); - setTitle(item.getTitle()); + txtvTitle.setText(item.getTitle()); if (UserPreferences.getTheme() == R.style.Theme_AntennaPod_Dark) { if (Build.VERSION.SDK_INT >= 11 -- cgit v1.2.3