diff --git a/src/de/danoeh/antennapod/activity/AudioplayerActivity.java b/src/de/danoeh/antennapod/activity/AudioplayerActivity.java index 090c3f1f5..abd383152 100644 --- a/src/de/danoeh/antennapod/activity/AudioplayerActivity.java +++ b/src/de/danoeh/antennapod/activity/AudioplayerActivity.java @@ -33,11 +33,12 @@ import de.danoeh.antennapod.service.playback.PlaybackService; import de.danoeh.antennapod.storage.DBReader; import de.danoeh.antennapod.util.playback.ExternalMedia; import de.danoeh.antennapod.util.playback.Playable; +import de.danoeh.antennapod.util.playback.PlaybackController; /** * Activity for playing audio files. */ -public class AudioplayerActivity extends MediaplayerActivity { +public class AudioplayerActivity extends MediaplayerActivity implements ItemDescriptionFragment.ItemDescriptionFragmentCallback { private static final int POS_COVER = 0; private static final int POS_DESCR = 1; private static final int POS_CHAPTERS = 2; @@ -293,7 +294,7 @@ public class AudioplayerActivity extends MediaplayerActivity { case POS_DESCR: if (descriptionFragment == null) { descriptionFragment = ItemDescriptionFragment - .newInstance(media, true); + .newInstance(media, true, true); } currentlyShownFragment = descriptionFragment; break; @@ -603,6 +604,11 @@ public class AudioplayerActivity extends MediaplayerActivity { clearStatusMsg(); } + @Override + public PlaybackController getPlaybackController() { + return controller; + } + public interface AudioplayerContentFragment { public void onDataSetChanged(Playable media); } diff --git a/src/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java b/src/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java index bf6974982..e2d7f32a2 100644 --- a/src/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java +++ b/src/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java @@ -2,8 +2,11 @@ package de.danoeh.antennapod.fragment; import android.annotation.SuppressLint; import android.app.Activity; -import android.content.*; -import android.content.res.TypedArray; +import android.content.ActivityNotFoundException; +import android.content.ClipData; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; import android.net.Uri; import android.os.AsyncTask; import android.os.Build; @@ -12,12 +15,18 @@ import android.support.v4.app.Fragment; import android.support.v7.app.ActionBarActivity; import android.util.Log; import android.util.TypedValue; -import android.view.*; +import android.view.ContextMenu; import android.view.ContextMenu.ContextMenuInfo; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; import android.webkit.WebSettings.LayoutAlgorithm; import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.Toast; + import de.danoeh.antennapod.BuildConfig; import de.danoeh.antennapod.R; import de.danoeh.antennapod.feed.FeedItem; @@ -26,11 +35,12 @@ import de.danoeh.antennapod.storage.DBReader; import de.danoeh.antennapod.util.ShareUtils; import de.danoeh.antennapod.util.ShownotesProvider; import de.danoeh.antennapod.util.playback.Playable; -import org.apache.commons.lang3.StringEscapeUtils; +import de.danoeh.antennapod.util.playback.PlaybackController; +import de.danoeh.antennapod.util.playback.Timeline; -import java.util.concurrent.Callable; - -/** Displays the description of a Playable object in a Webview. */ +/** + * Displays the description of a Playable object in a Webview. + */ public class ItemDescriptionFragment extends Fragment { private static final String TAG = "ItemDescriptionFragment"; @@ -43,6 +53,7 @@ public class ItemDescriptionFragment extends Fragment { private static final String ARG_FEEDITEM_ID = "arg.feeditem"; private static final String ARG_SAVE_STATE = "arg.saveState"; + private static final String ARG_HIGHLIGHT_TIMECODES = "arg.highlightTimecodes"; private WebView webvDescription; @@ -63,21 +74,29 @@ public class ItemDescriptionFragment extends Fragment { */ private boolean saveState; + /** + * True if Fragment should highlight timecodes (e.g. time codes in the HH:MM:SS format). + */ + private boolean highlightTimecodes; + public static ItemDescriptionFragment newInstance(Playable media, - boolean saveState) { + boolean saveState, + boolean highlightTimecodes) { ItemDescriptionFragment f = new ItemDescriptionFragment(); Bundle args = new Bundle(); args.putParcelable(ARG_PLAYABLE, media); args.putBoolean(ARG_SAVE_STATE, saveState); + args.putBoolean(ARG_HIGHLIGHT_TIMECODES, highlightTimecodes); f.setArguments(args); return f; } - public static ItemDescriptionFragment newInstance(FeedItem item, boolean saveState) { + public static ItemDescriptionFragment newInstance(FeedItem item, boolean saveState, boolean highlightTimecodes) { ItemDescriptionFragment f = new ItemDescriptionFragment(); Bundle args = new Bundle(); args.putLong(ARG_FEEDITEM_ID, item.getId()); args.putBoolean(ARG_SAVE_STATE, saveState); + args.putBoolean(ARG_HIGHLIGHT_TIMECODES, highlightTimecodes); f.setArguments(args); return f; } @@ -106,12 +125,22 @@ public class ItemDescriptionFragment extends Fragment { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { - Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); - try { - startActivity(intent); - } catch (ActivityNotFoundException e) { - e.printStackTrace(); - return false; + if (Timeline.isTimecodeLink(url)) { + int time = Timeline.getTimecodeLinkTime(url); + if (getActivity() != null && getActivity() instanceof ItemDescriptionFragmentCallback) { + PlaybackController pc = ((ItemDescriptionFragmentCallback) getActivity()).getPlaybackController(); + if (pc != null) { + pc.seekTo(time); + } + } + } else { + Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); + try { + startActivity(intent); + } catch (ActivityNotFoundException e) { + e.printStackTrace(); + return true; + } } return true; } @@ -178,6 +207,7 @@ public class ItemDescriptionFragment extends Fragment { Log.d(TAG, "Creating fragment"); Bundle args = getArguments(); saveState = args.getBoolean(ARG_SAVE_STATE, false); + highlightTimecodes = args.getBoolean(ARG_HIGHLIGHT_TIMECODES, false); } @@ -229,21 +259,6 @@ public class ItemDescriptionFragment extends Fragment { } } - /** - * Return the CSS style of the Webview. - * - * @param textColor the default color to use for the text in the webview. This - * value is inserted directly into the CSS String. - */ - private String applyWebviewStyle(String textColor, String data) { - final String WEBVIEW_STYLE = "
%s"; - final int pageMargin = (int) TypedValue.applyDimension( - TypedValue.COMPLEX_UNIT_DIP, 8, getResources() - .getDisplayMetrics()); - return String.format(WEBVIEW_STYLE, textColor, "100%", pageMargin, - pageMargin, pageMargin, pageMargin, data); - } - private View.OnLongClickListener webViewLongClickListener = new View.OnLongClickListener() { @Override @@ -254,10 +269,13 @@ public class ItemDescriptionFragment extends Fragment { if (BuildConfig.DEBUG) Log.d(TAG, "Link of webview was long-pressed. Extra: " - + r.getExtra()); + + r.getExtra() + ); selectedURL = r.getExtra(); - webvDescription.showContextMenu(); - return true; + if (!Timeline.isTimecodeLink(selectedURL)) { + webvDescription.showContextMenu(); + return true; + } } selectedURL = null; return false; @@ -364,22 +382,10 @@ public class ItemDescriptionFragment extends Fragment { if (BuildConfig.DEBUG) Log.d(TAG, "Loading Webview"); try { - Callable