From 8c3ea7b556833024f919105d03dfe182dfcd73cf Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Tue, 31 Oct 2017 13:37:31 +0300 Subject: offline: implement fullscreen video player for article view --- .../fox/ttrss/offline/OfflineArticleFragment.java | 145 ++++++++++++++++++--- .../fox/ttrss/offline/OfflineDetailActivity.java | 8 ++ 2 files changed, 138 insertions(+), 15 deletions(-) (limited to 'org.fox.ttrss/src/main/java') diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineArticleFragment.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineArticleFragment.java index eb5e1f81..0b4b979b 100755 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineArticleFragment.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineArticleFragment.java @@ -6,6 +6,7 @@ import android.content.SharedPreferences; import android.database.Cursor; import android.graphics.Color; import android.net.Uri; +import android.os.Build; import android.os.Bundle; import android.preference.PreferenceManager; import android.provider.BaseColumns; @@ -20,16 +21,19 @@ import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; +import android.webkit.WebChromeClient; import android.webkit.WebSettings; import android.webkit.WebView; import android.webkit.WebView.HitTestResult; import android.webkit.WebViewClient; +import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.ScrollView; import android.widget.TextView; import com.shamanland.fab.ShowHideOnScroll; +import org.fox.ttrss.ArticleFragment; import org.fox.ttrss.CommonActivity; import org.fox.ttrss.R; import org.fox.ttrss.util.ImageCacheService; @@ -52,13 +56,80 @@ public class OfflineArticleFragment extends Fragment { private SharedPreferences m_prefs; private int m_articleId; private boolean m_isCat = false; // FIXME use + private WebView m_web; private Cursor m_cursor; - private OfflineActivity m_activity; + private OfflineDetailActivity m_activity; + + protected View m_customView; + protected FrameLayout m_customViewContainer; + protected View m_contentView; + protected FSVideoChromeClient m_chromeClient; + protected View m_fab; public void initialize(int articleId) { m_articleId = articleId; } + private class FSVideoChromeClient extends WebChromeClient { + //protected View m_videoChildView; + + private CustomViewCallback m_callback; + + public FSVideoChromeClient(View container) { + super(); + + } + + @Override + public void onShowCustomView(View view, CustomViewCallback callback) { + m_activity.getSupportActionBar().hide(); + + // if a view already exists then immediately terminate the new one + if (m_customView != null) { + callback.onCustomViewHidden(); + return; + } + m_customView = view; + m_contentView.setVisibility(View.GONE); + + m_customViewContainer.setVisibility(View.VISIBLE); + m_customViewContainer.addView(view); + + if (m_fab != null) m_fab.setVisibility(View.GONE); + + m_activity.showSidebar(false); + + m_callback = callback; + } + + @Override + public void onHideCustomView() { + super.onHideCustomView(); + + m_activity.getSupportActionBar().show(); + + if (m_customView == null) + return; + + m_contentView.setVisibility(View.VISIBLE); + m_customViewContainer.setVisibility(View.GONE); + + // Hide the custom view. + m_customView.setVisibility(View.GONE); + + // Remove the custom view from its container. + m_customViewContainer.removeView(m_customView); + m_callback.onCustomViewHidden(); + + if (m_fab != null && m_prefs.getBoolean("enable_article_fab", true)) + m_fab.setVisibility(View.VISIBLE); + + m_customView = null; + + m_activity.showSidebar(true); + } + } + @Override public boolean onContextItemSelected(MenuItem item) { /* AdapterContextMenuInfo info = (AdapterContextMenuInfo) item @@ -134,6 +205,9 @@ public class OfflineArticleFragment extends Fragment { m_cursor.moveToFirst(); if (m_cursor.isFirst()) { + m_contentView = view.findViewById(R.id.article_scrollview); + m_customViewContainer = (FrameLayout) view.findViewById(R.id.article_fullscreen_video); + final String link = m_cursor.getString(m_cursor.getColumnIndex("link")); NotifyingScrollView scrollView = (NotifyingScrollView) view.findViewById(R.id.article_scrollview); @@ -237,14 +311,14 @@ public class OfflineArticleFragment extends Fragment { note.setVisibility(View.GONE); } - final WebView web = (WebView)view.findViewById(R.id.article_content); + m_web = (WebView)view.findViewById(R.id.article_content); - if (web != null) { + if (m_web != null) { if (CommonActivity.THEME_DARK.equals(m_prefs.getString("theme", CommonActivity.THEME_DEFAULT))) { - web.setBackgroundColor(Color.BLACK); + m_web.setBackgroundColor(Color.BLACK); } - web.setWebViewClient(new WebViewClient() { + m_web.setWebViewClient(new WebViewClient() { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { try { @@ -259,15 +333,15 @@ public class OfflineArticleFragment extends Fragment { return false; } }); - web.setOnLongClickListener(new View.OnLongClickListener() { + m_web.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { HitTestResult result = ((WebView) v).getHitTestResult(); if (result != null && (result.getType() == HitTestResult.IMAGE_TYPE || result.getType() == HitTestResult.SRC_IMAGE_ANCHOR_TYPE)) { - registerForContextMenu(web); - m_activity.openContextMenu(web); - unregisterForContextMenu(web); + registerForContextMenu(m_web); + m_activity.openContextMenu(m_web); + unregisterForContextMenu(m_web); return true; } else { return false; @@ -278,16 +352,25 @@ public class OfflineArticleFragment extends Fragment { // prevent flicker in ics if (!m_prefs.getBoolean("webview_hardware_accel", true)) { if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) { - web.setLayerType(View.LAYER_TYPE_SOFTWARE, null); + m_web.setLayerType(View.LAYER_TYPE_SOFTWARE, null); } } String content; String cssOverride = ""; - WebSettings ws = web.getSettings(); + WebSettings ws = m_web.getSettings(); ws.setSupportZoom(false); + if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { + ws.setJavaScriptEnabled(true); + + m_chromeClient = new FSVideoChromeClient(getView()); + m_web.setWebChromeClient(m_chromeClient); + + ws.setMediaPlaybackRequiresUserGesture(false); + } + // we need to show "insecure" file:// urls if (m_prefs.getBoolean("offline_image_cache_enabled", false)) { ws.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW); @@ -372,8 +455,8 @@ public class OfflineArticleFragment extends Fragment { } catch (MalformedURLException e) { // } - - web.loadDataWithBaseURL(baseUrl, content, "text/html", "utf-8", null); + + m_web.loadDataWithBaseURL(baseUrl, content, "text/html", "utf-8", null); } catch (RuntimeException e) { e.printStackTrace(); } @@ -423,13 +506,45 @@ public class OfflineArticleFragment extends Fragment { return view; } + @Override + public void onPause() { + super.onPause(); + + if (m_web != null) m_web.onPause(); + } + + public boolean inCustomView() { + return (m_customView != null); + } + @Override public void onDestroy() { super.onDestroy(); m_cursor.close(); } - + + public void hideCustomView() { + if (m_chromeClient != null) { + m_chromeClient.onHideCustomView(); + } + } + + @Override + public void onResume() { + super.onResume(); + + if (m_web != null) m_web.onResume(); + } + + @Override + public void onStop() { + super.onStop(); + + if (inCustomView()) { + hideCustomView(); + } + } @Override public void onSaveInstanceState (Bundle out) { super.onSaveInstanceState(out); @@ -443,7 +558,7 @@ public class OfflineArticleFragment extends Fragment { m_prefs = PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext()); - m_activity = (OfflineActivity) activity; + m_activity = (OfflineDetailActivity) activity; } } diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineDetailActivity.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineDetailActivity.java index 4b484566..99fb83a4 100644 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineDetailActivity.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineDetailActivity.java @@ -218,4 +218,12 @@ public class OfflineDetailActivity extends OfflineActivity implements OfflineHea } } + + public void showSidebar(boolean show) { + if (!isSmallScreen() && !isPortrait()) { + findViewById(R.id.headlines_fragment).setVisibility(show ? View.VISIBLE : View.GONE); + invalidateOptionsMenu(); + } + } + } -- cgit v1.2.3