From 6f1afb1ef00e9c700832c33f71d008549740c2c0 Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Fri, 2 Jun 2017 14:51:11 +0300 Subject: rename article pager and related stuff to gallery --- org.fox.ttrss/src/main/AndroidManifest.xml | 2 +- .../java/org/fox/ttrss/ArticleImageFragment.java | 131 -------- .../org/fox/ttrss/ArticleImagesPagerActivity.java | 296 ------------------ .../java/org/fox/ttrss/ArticleVideoFragment.java | 335 --------------------- .../main/java/org/fox/ttrss/GalleryActivity.java | 288 ++++++++++++++++++ .../java/org/fox/ttrss/GalleryBaseFragment.java | 4 +- .../java/org/fox/ttrss/GalleryImageFragment.java | 128 ++++++++ .../java/org/fox/ttrss/GalleryVideoFragment.java | 326 ++++++++++++++++++++ .../main/java/org/fox/ttrss/HeadlinesFragment.java | 5 +- .../src/main/res/layout/activity_gallery.xml | 43 +++ .../src/main/res/layout/article_images_pager.xml | 43 --- .../src/main/res/layout/fragment_article_image.xml | 49 --- .../src/main/res/layout/fragment_gallery_entry.xml | 49 +++ 13 files changed, 838 insertions(+), 861 deletions(-) delete mode 100644 org.fox.ttrss/src/main/java/org/fox/ttrss/ArticleImageFragment.java delete mode 100755 org.fox.ttrss/src/main/java/org/fox/ttrss/ArticleImagesPagerActivity.java delete mode 100644 org.fox.ttrss/src/main/java/org/fox/ttrss/ArticleVideoFragment.java create mode 100644 org.fox.ttrss/src/main/java/org/fox/ttrss/GalleryActivity.java create mode 100644 org.fox.ttrss/src/main/java/org/fox/ttrss/GalleryImageFragment.java create mode 100644 org.fox.ttrss/src/main/java/org/fox/ttrss/GalleryVideoFragment.java create mode 100644 org.fox.ttrss/src/main/res/layout/activity_gallery.xml delete mode 100755 org.fox.ttrss/src/main/res/layout/article_images_pager.xml delete mode 100644 org.fox.ttrss/src/main/res/layout/fragment_article_image.xml create mode 100644 org.fox.ttrss/src/main/res/layout/fragment_gallery_entry.xml (limited to 'org.fox.ttrss') diff --git a/org.fox.ttrss/src/main/AndroidManifest.xml b/org.fox.ttrss/src/main/AndroidManifest.xml index 4aa7a64f..f1685820 100755 --- a/org.fox.ttrss/src/main/AndroidManifest.xml +++ b/org.fox.ttrss/src/main/AndroidManifest.xml @@ -248,7 +248,7 @@ diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/ArticleImageFragment.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/ArticleImageFragment.java deleted file mode 100644 index d55ee127..00000000 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/ArticleImageFragment.java +++ /dev/null @@ -1,131 +0,0 @@ -package org.fox.ttrss; - -import android.app.Activity; -import android.net.Uri; -import android.os.Bundle; -import android.support.v4.app.ActivityCompat; -import android.support.v4.app.Fragment; -import android.support.v4.view.ViewCompat; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.MenuInflater; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ImageView; -import android.widget.PopupMenu; -import android.widget.ProgressBar; - -import com.bogdwellers.pinchtozoom.ImageMatrixTouchHandler; -import com.bumptech.glide.Glide; -import com.bumptech.glide.load.engine.DiskCacheStrategy; -import com.bumptech.glide.load.resource.drawable.GlideDrawable; -import com.bumptech.glide.request.RequestListener; -import com.bumptech.glide.request.target.GlideDrawableImageViewTarget; -import com.bumptech.glide.request.target.Target; - -public class ArticleImageFragment extends GalleryBaseFragment { - private final String TAG = this.getClass().getSimpleName(); - - String m_url; - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View view = inflater.inflate(R.layout.fragment_article_image, container, false); - - if (savedInstanceState != null) { - m_url = savedInstanceState.getString("url"); - } - - Log.d(TAG, "called for URL: " + m_url); - - ImageView imgView = (ImageView) view.findViewById(R.id.flavor_image); - - ImageMatrixTouchHandler touchHandler = new ImageMatrixTouchHandler(view.getContext()); - - imgView.setOnTouchListener(touchHandler); - - // shared element transitions stop GIFs from playing - if (m_url.toLowerCase().indexOf(".gif") == -1) { - ViewCompat.setTransitionName(imgView, "gallery:" + m_url); - } - - //registerForContextMenu(imgView); - - view.findViewById(R.id.flavor_image_overflow).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - PopupMenu popup = new PopupMenu(getContext(), v); - MenuInflater inflater = popup.getMenuInflater(); - inflater.inflate(R.menu.context_article_content_img, popup.getMenu()); - - popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { - @Override - public boolean onMenuItemClick(MenuItem item) { - return onImageMenuItemSelected(item, m_url); - } - }); - - popup.show(); - - } - }); - - final ProgressBar progressBar = (ProgressBar) view.findViewById(R.id.flavor_image_progress); - final View errorMessage = view.findViewById(R.id.flavor_image_error); - - final GlideDrawableImageViewTarget glideImage = new GlideDrawableImageViewTarget(imgView); - - Glide.with(this) - .load(m_url) - .dontAnimate() - .diskCacheStrategy(DiskCacheStrategy.ALL) - .skipMemoryCache(false) - .listener(new RequestListener() { - @Override - public boolean onException(Exception e, String model, Target target, boolean isFirstResource) { - progressBar.setVisibility(View.GONE); - errorMessage.setVisibility(View.VISIBLE); - - ActivityCompat.startPostponedEnterTransition(m_activity); - return false; - } - - @Override - public boolean onResourceReady(GlideDrawable resource, String model, Target target, boolean isFromMemoryCache, boolean isFirstResource) { - progressBar.setVisibility(View.GONE); - errorMessage.setVisibility(View.GONE); - - ActivityCompat.startPostponedEnterTransition(m_activity); - return false; - } - }) - .into(glideImage); - - return view; - } - - public void initialize(String url) { - m_url = url; - } - - /*@Override - public boolean onContextItemSelected(MenuItem item) { - int position = m_pager.getCurrentItem(); - String url = m_checkedUrls.get(position); - - if (!onImageMenuItemSelected(item, url)) - return super.onContextItemSelected(item); - else - return true; - }*/ - - @Override - public void onSaveInstanceState (Bundle out) { - super.onSaveInstanceState(out); - - out.setClassLoader(getClass().getClassLoader()); - out.putString("url", m_url); - } - -} diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/ArticleImagesPagerActivity.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/ArticleImagesPagerActivity.java deleted file mode 100755 index ff2bbed9..00000000 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/ArticleImagesPagerActivity.java +++ /dev/null @@ -1,296 +0,0 @@ -package org.fox.ttrss; - -import android.annotation.SuppressLint; -import android.graphics.Bitmap; -import android.os.AsyncTask; -import android.os.Bundle; -import android.preference.PreferenceManager; -import android.support.v4.app.ActivityCompat; -import android.support.v4.app.Fragment; -import android.support.v4.app.FragmentManager; -import android.support.v4.app.FragmentStatePagerAdapter; -import android.support.v4.view.ViewPager; -import android.support.v7.widget.Toolbar; -import android.util.Log; -import android.view.ContextMenu; -import android.view.View; -import android.widget.ProgressBar; - -import com.ToxicBakery.viewpager.transforms.DepthPageTransformer; -import com.bumptech.glide.Glide; - -import org.jsoup.Jsoup; -import org.jsoup.nodes.Document; -import org.jsoup.nodes.Element; -import org.jsoup.select.Elements; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.ExecutionException; - -import me.relex.circleindicator.CircleIndicator; - -public class ArticleImagesPagerActivity extends CommonActivity { - private final String TAG = this.getClass().getSimpleName(); - - private ArrayList m_items; - //private ArrayList m_checkedItems; - private String m_title; - private ArticleImagesPagerAdapter m_adapter; - public String m_content; - private ProgressBar m_progress; - private ViewPager m_pager; - - private enum GalleryEntryType { TYPE_IMAGE, TYPE_VIDEO }; - - private class GalleryEntry implements Serializable { - String url; - GalleryEntryType type; - String coverUrl; - } - - private class ArticleImagesPagerAdapter extends FragmentStatePagerAdapter { - private List m_items; - - public ArticleImagesPagerAdapter(FragmentManager fm, List items) { - super(fm); - m_items = items; - } - - @Override - public int getCount() { - return m_items.size(); - } - - @Override - public Fragment getItem(int position) { - - //Log.d(TAG, "getItem: " + position + " " + m_urls.get(position)); - - GalleryEntry item = m_items.get(position); - - switch (item.type) { - case TYPE_IMAGE: - if (true) { - ArticleImageFragment frag = new ArticleImageFragment(); - frag.initialize(item.url); - - return frag; - } - break; - case TYPE_VIDEO: - if (true) { - ArticleVideoFragment frag = new ArticleVideoFragment(); - frag.initialize(item.url, item.coverUrl); - - return frag; - } - break; - } - - return null; - } - } - - /*private class ImageCheckTask extends AsyncTask, Integer, List> { - private GalleryEntry m_lastCheckedItem; - - @Override - protected List doInBackground(List... items) { - - List tmp = new ArrayList<>(items[0]); - - int position = 0; - - for (GalleryEntry item : tmp) { - - if (!isCancelled()) { - String url = item.url; - - position++; - - try { - Bitmap bmp = Glide.with(ArticleImagesPagerActivity.this) - .load(url) - .asBitmap() - .into(-1, -1) - .get(); - - if (bmp != null && bmp.getWidth() > 128 && bmp.getHeight() > 128) { - m_lastCheckedItem = item; - publishProgress(position); - } else { - m_lastCheckedItem = null; - publishProgress(position); - } - - } catch (InterruptedException e) { - e.printStackTrace(); - } catch (ExecutionException e) { - e.printStackTrace(); - } - - } - } - - return -1; - } - - @Override - protected void onProgressUpdate(Integer... progress) { - - if (!isFinishing() && m_adapter != null) { - Log.d(TAG, "progr=" + progress[0]); - - m_adapter.notifyDataSetChanged(); - - m_progress.setProgress(Integer.valueOf(progress[1])); - } else { - cancel(true); - } - } - - @Override - protected void onPostExecute(List result) { - m_progress.setVisibility(View.GONE); - - CircleIndicator indicator = (CircleIndicator) findViewById(R.id.article_images_indicator); - - if (indicator != null) { - indicator.setViewPager(m_pager); - indicator.setVisibility(View.VISIBLE); - } - - } - } */ - - @Override - public void onCreate(Bundle savedInstanceState) { - ActivityCompat.postponeEnterTransition(this); - - // we use that before parent onCreate so let's init locally - m_prefs = PreferenceManager - .getDefaultSharedPreferences(getApplicationContext()); - - setTheme(R.style.DarkTheme); - - super.onCreate(savedInstanceState); - - setContentView(R.layout.article_images_pager); - - Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); - setSupportActionBar(toolbar); - - m_progress = (ProgressBar) findViewById(R.id.article_images_progress); - - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - getSupportActionBar().hide(); - - if (savedInstanceState == null) { - m_title = getIntent().getStringExtra("title"); - //m_urls = getIntent().getStringArrayListExtra("urls"); - m_content = getIntent().getStringExtra("content"); - - String imgSrcFirst = getIntent().getStringExtra("firstSrc"); - - m_items = new ArrayList(); - - Document doc = Jsoup.parse(m_content); - Elements elems = doc.select("img,video"); - - boolean firstFound = false; - - for (Element elem : elems) { - - GalleryEntry item = new GalleryEntry(); - - if ("video".equals(elem.tagName().toLowerCase())) { - String cover = elem.attr("poster"); - - Element source = elem.select("source").first(); - String src = source.attr("src"); - - if (src.startsWith("//")) { - src = "https:" + src; - } - - if (imgSrcFirst.equals(src)) - firstFound = true; - - item.url = src; - item.coverUrl = cover; - item.type = GalleryEntryType.TYPE_VIDEO; - - } else { - String src = elem.attr("src"); - - if (src.startsWith("//")) { - src = "https:" + src; - } - - if (imgSrcFirst.equals(src)) - firstFound = true; - - item.url = src; - item.type = GalleryEntryType.TYPE_IMAGE; - } - - if (firstFound && item.url != null) { - m_items.add(item); - } - } - - } else { - m_items = (ArrayList) savedInstanceState.getSerializable("items"); - m_title = savedInstanceState.getString("title"); - m_content = savedInstanceState.getString("content"); - } - - /*if (m_items.size() > 1) { - m_progress.setProgress(0); - m_progress.setMax(m_items.size()); - m_checkedItems = new ArrayList<>(); - - ArrayList tmp = new ArrayList<>(m_items); - - m_checkedItems.add(tmp.get(0)); - tmp.remove(0); - - ImageCheckTask ict = new ImageCheckTask(); - ict.execute(tmp); - } else { - m_checkedItems = new ArrayList<>(m_items); - m_progress.setVisibility(View.GONE); - } */ - - setTitle(m_title); - - m_adapter = new ArticleImagesPagerAdapter(getSupportFragmentManager(), m_items); - - m_pager = (ViewPager) findViewById(R.id.article_images_pager); - m_pager.setAdapter(m_adapter); - m_pager.setPageTransformer(true, new DepthPageTransformer()); - - } - - @Override - public void onCreateContextMenu(ContextMenu menu, View v, - ContextMenu.ContextMenuInfo menuInfo) { - - getMenuInflater().inflate(R.menu.context_article_content_img, menu); - - super.onCreateContextMenu(menu, v, menuInfo); - } - - @Override - public void onSaveInstanceState(Bundle out) { - super.onSaveInstanceState(out); - - out.putSerializable("items", m_items); - out.putString("title", m_title); - out.putString("content", m_content); - } - - -} diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/ArticleVideoFragment.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/ArticleVideoFragment.java deleted file mode 100644 index 98eb4295..00000000 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/ArticleVideoFragment.java +++ /dev/null @@ -1,335 +0,0 @@ -package org.fox.ttrss; - -import android.app.Activity; -import android.content.res.Configuration; -import android.graphics.Rect; -import android.graphics.SurfaceTexture; -import android.media.MediaPlayer; -import android.net.Uri; -import android.os.Bundle; -import android.os.Handler; -import android.support.v4.app.ActivityCompat; -import android.support.v4.app.Fragment; -import android.support.v4.view.ViewCompat; -import android.util.Log; -import android.view.Display; -import android.view.LayoutInflater; -import android.view.MenuInflater; -import android.view.MenuItem; -import android.view.Surface; -import android.view.SurfaceHolder; -import android.view.SurfaceView; -import android.view.TextureView; -import android.view.View; -import android.view.ViewGroup; -import android.widget.FrameLayout; -import android.widget.ImageView; -import android.widget.MediaController; -import android.widget.PopupMenu; -import android.widget.ProgressBar; - -import com.bogdwellers.pinchtozoom.ImageMatrixTouchHandler; -import com.bumptech.glide.Glide; -import com.bumptech.glide.load.engine.DiskCacheStrategy; -import com.bumptech.glide.load.resource.drawable.GlideDrawable; -import com.bumptech.glide.request.RequestListener; -import com.bumptech.glide.request.target.GlideDrawableImageViewTarget; -import com.bumptech.glide.request.target.Target; - -import java.io.IOException; - -public class ArticleVideoFragment extends GalleryBaseFragment { - private final String TAG = this.getClass().getSimpleName(); - - String m_url; - String m_coverUrl; - MediaPlayer m_mediaPlayer; - private boolean m_userVisibleHint = false; - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - final View view = inflater.inflate(R.layout.fragment_article_image, container, false); - - if (savedInstanceState != null) { - m_url = savedInstanceState.getString("url"); - m_coverUrl = savedInstanceState.getString("coverUrl"); - } - - Log.d(TAG, "called for URL: " + m_url + " Cover: " + m_coverUrl); - - ImageView imgView = (ImageView) view.findViewById(R.id.flavor_image); - - ViewCompat.setTransitionName(imgView, "gallery:" + m_url); - - //registerForContextMenu(imgView); - - view.findViewById(R.id.flavor_image_overflow).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - PopupMenu popup = new PopupMenu(getContext(), v); - MenuInflater inflater = popup.getMenuInflater(); - inflater.inflate(R.menu.context_article_content_img, popup.getMenu()); - - popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { - @Override - public boolean onMenuItemClick(MenuItem item) { - return onImageMenuItemSelected(item, m_url); - } - }); - - popup.show(); - - } - }); - - final GlideDrawableImageViewTarget glideImage = new GlideDrawableImageViewTarget(imgView); - - Glide.with(this) - .load(m_coverUrl) - .dontAnimate() - .diskCacheStrategy(DiskCacheStrategy.ALL) - .skipMemoryCache(false) - .listener(new RequestListener() { - @Override - public boolean onException(Exception e, String model, Target target, boolean isFirstResource) { - ActivityCompat.startPostponedEnterTransition(m_activity); - - initializeVideoPlayer(view); - return false; - } - - @Override - public boolean onResourceReady(GlideDrawable resource, String model, Target target, boolean isFromMemoryCache, boolean isFirstResource) { - ActivityCompat.startPostponedEnterTransition(m_activity); - - initializeVideoPlayer(view); - return false; - } - }) - .into(glideImage); - - return view; - } - - @Override - public void setUserVisibleHint(boolean isVisibleToUser) { - super.setUserVisibleHint(isVisibleToUser); - m_userVisibleHint = isVisibleToUser; - - Log.d(TAG, "setUserVisibleHint: " + isVisibleToUser); - - if (getView() == null) return; - - try { - - if (isVisibleToUser) { - if (m_mediaPlayer != null && !m_mediaPlayer.isPlaying()) { - m_mediaPlayer.start(); - } - - } else { - if (m_mediaPlayer != null && m_mediaPlayer.isPlaying()) { - m_mediaPlayer.pause(); - } - } - } catch (IllegalStateException e) { - e.printStackTrace(); - } - - } - - private void initializeVideoPlayer(final View view) { - - //Log.d(TAG, "initializeVideoPlayer: " + m_activity + " " + view); - - final MediaController m_mediaController = new MediaController(m_activity); - final TextureView textureView = (TextureView) view.findViewById(R.id.flavor_video); - - textureView.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - try { - if (!m_mediaController.isShowing()) - m_mediaController.show(5000); - else - m_mediaController.hide(); - } catch (Exception e) { - e.printStackTrace(); - } - } - }); - - m_mediaController.setAnchorView(textureView); - - textureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() { - @Override - public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { - Surface s = new Surface(surface); - - m_mediaPlayer = new MediaPlayer(); - - m_mediaController.setMediaPlayer(new MediaController.MediaPlayerControl() { - @Override - public void start() { - m_mediaPlayer.start(); - } - - @Override - public void pause() { - m_mediaPlayer.pause(); - } - - @Override - public int getDuration() { - return m_mediaPlayer.getDuration(); - } - - @Override - public int getCurrentPosition() { - return m_mediaPlayer.getCurrentPosition(); - } - - @Override - public void seekTo(int pos) { - m_mediaPlayer.seekTo(pos); - } - - @Override - public boolean isPlaying() { - return m_mediaPlayer.isPlaying(); - } - - @Override - public int getBufferPercentage() { - return 0; - } - - @Override - public boolean canPause() { - return true; - } - - @Override - public boolean canSeekBackward() { - return true; - } - - @Override - public boolean canSeekForward() { - return true; - } - - @Override - public int getAudioSessionId() { - return 0; - } - }); - - m_mediaPlayer.setSurface(s); - - try { - m_mediaPlayer.setDataSource(m_url); - } catch (IOException e) { - view.findViewById(R.id.flavor_image_error).setVisibility(View.VISIBLE); - e.printStackTrace(); - } - - m_mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { - @Override - public void onPrepared(MediaPlayer mp) { - getView().findViewById(R.id.flavor_image).setVisibility(View.GONE); - getView().findViewById(R.id.flavor_image_progress).setVisibility(View.GONE); - - resizeSurface(textureView); - mp.setLooping(true); - - if (m_userVisibleHint) { - mp.start(); - } - } - }); - - m_mediaPlayer.prepareAsync(); - } - - @Override - public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { - - } - - @Override - public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { - try { - m_mediaPlayer.release(); - } catch (Exception e) { - e.printStackTrace(); - } - return false; - } - - @Override - public void onSurfaceTextureUpdated(SurfaceTexture surface) { - - } - }); - - } - - public void initialize(String url, String coverUrl) { - m_url = url; - m_coverUrl = coverUrl; - } - - /*@Override - public boolean onContextItemSelected(MenuItem item) { - int position = m_pager.getCurrentItem(); - String url = m_checkedUrls.get(position); - - if (!onImageMenuItemSelected(item, url)) - return super.onContextItemSelected(item); - else - return true; - }*/ - - @Override - public void onSaveInstanceState (Bundle out) { - super.onSaveInstanceState(out); - - out.setClassLoader(getClass().getClassLoader()); - out.putString("url", m_url); - out.putString("coverUrl", m_coverUrl); - } - - protected void resizeSurface(View surfaceView) { - // get the dimensions of the video (only valid when surfaceView is set) - float videoWidth = m_mediaPlayer.getVideoWidth(); - float videoHeight = m_mediaPlayer.getVideoHeight(); - - Rect rectangle = new Rect(); - m_activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(rectangle); - - int actionBarHeight = m_activity.isPortrait() ? m_activity.getSupportActionBar().getHeight() : 0; - - Display display = m_activity.getWindowManager().getDefaultDisplay(); - float containerWidth = display.getWidth(); - float containerHeight = display.getHeight() - rectangle.top - actionBarHeight; - - // set dimensions to surfaceView's layout params (maintaining aspect ratio) - android.view.ViewGroup.LayoutParams lp = surfaceView.getLayoutParams(); - lp.width = (int) containerWidth; - lp.height = (int) ((videoHeight / videoWidth) * containerWidth); - if(lp.height > containerHeight) { - lp.width = (int) ((videoWidth / videoHeight) * containerHeight); - lp.height = (int) containerHeight; - } - surfaceView.setLayoutParams(lp); - } - - @Override - public void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - - resizeSurface(getView().findViewById(R.id.flavor_video)); - } - -} diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/GalleryActivity.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/GalleryActivity.java new file mode 100644 index 00000000..e83e27db --- /dev/null +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/GalleryActivity.java @@ -0,0 +1,288 @@ +package org.fox.ttrss; + +import android.os.Bundle; +import android.preference.PreferenceManager; +import android.support.v4.app.ActivityCompat; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentManager; +import android.support.v4.app.FragmentStatePagerAdapter; +import android.support.v4.view.ViewPager; +import android.support.v7.widget.Toolbar; +import android.view.ContextMenu; +import android.view.View; +import android.widget.ProgressBar; + +import com.ToxicBakery.viewpager.transforms.DepthPageTransformer; + +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.nodes.Element; +import org.jsoup.select.Elements; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +public class GalleryActivity extends CommonActivity { + private final String TAG = this.getClass().getSimpleName(); + + private ArrayList m_items; + //private ArrayList m_checkedItems; + private String m_title; + private ArticleImagesPagerAdapter m_adapter; + public String m_content; + private ProgressBar m_progress; + private ViewPager m_pager; + + private enum GalleryEntryType { TYPE_IMAGE, TYPE_VIDEO }; + + private class GalleryEntry implements Serializable { + String url; + GalleryEntryType type; + String coverUrl; + } + + private class ArticleImagesPagerAdapter extends FragmentStatePagerAdapter { + private List m_items; + + public ArticleImagesPagerAdapter(FragmentManager fm, List items) { + super(fm); + m_items = items; + } + + @Override + public int getCount() { + return m_items.size(); + } + + @Override + public Fragment getItem(int position) { + + //Log.d(TAG, "getItem: " + position + " " + m_urls.get(position)); + + GalleryEntry item = m_items.get(position); + + switch (item.type) { + case TYPE_IMAGE: + if (true) { + GalleryImageFragment frag = new GalleryImageFragment(); + frag.initialize(item.url); + + return frag; + } + break; + case TYPE_VIDEO: + if (true) { + GalleryVideoFragment frag = new GalleryVideoFragment(); + frag.initialize(item.url, item.coverUrl); + + return frag; + } + break; + } + + return null; + } + } + + /*private class ImageCheckTask extends AsyncTask, Integer, List> { + private GalleryEntry m_lastCheckedItem; + + @Override + protected List doInBackground(List... items) { + + List tmp = new ArrayList<>(items[0]); + + int position = 0; + + for (GalleryEntry item : tmp) { + + if (!isCancelled()) { + String url = item.url; + + position++; + + try { + Bitmap bmp = Glide.with(zzzzticleImagesPagerActivity.this) + .load(url) + .asBitmap() + .into(-1, -1) + .get(); + + if (bmp != null && bmp.getWidth() > 128 && bmp.getHeight() > 128) { + m_lastCheckedItem = item; + publishProgress(position); + } else { + m_lastCheckedItem = null; + publishProgress(position); + } + + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (ExecutionException e) { + e.printStackTrace(); + } + + } + } + + return -1; + } + + @Override + protected void onProgressUpdate(Integer... progress) { + + if (!isFinishing() && m_adapter != null) { + Log.d(TAG, "progr=" + progress[0]); + + m_adapter.notifyDataSetChanged(); + + m_progress.setProgress(Integer.valueOf(progress[1])); + } else { + cancel(true); + } + } + + @Override + protected void onPostExecute(List result) { + m_progress.setVisibility(View.GONE); + + CircleIndicator indicator = (CircleIndicator) findViewById(R.id.article_images_indicator); + + if (indicator != null) { + indicator.setViewPager(m_pager); + indicator.setVisibility(View.VISIBLE); + } + + } + } */ + + @Override + public void onCreate(Bundle savedInstanceState) { + ActivityCompat.postponeEnterTransition(this); + + // we use that before parent onCreate so let's init locally + m_prefs = PreferenceManager + .getDefaultSharedPreferences(getApplicationContext()); + + setTheme(R.style.DarkTheme); + + super.onCreate(savedInstanceState); + + setContentView(R.layout.activity_gallery); + + Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + + m_progress = (ProgressBar) findViewById(R.id.article_images_progress); + + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportActionBar().hide(); + + if (savedInstanceState == null) { + m_title = getIntent().getStringExtra("title"); + //m_urls = getIntent().getStringArrayListExtra("urls"); + m_content = getIntent().getStringExtra("content"); + + String imgSrcFirst = getIntent().getStringExtra("firstSrc"); + + m_items = new ArrayList(); + + Document doc = Jsoup.parse(m_content); + Elements elems = doc.select("img,video"); + + boolean firstFound = false; + + for (Element elem : elems) { + + GalleryEntry item = new GalleryEntry(); + + if ("video".equals(elem.tagName().toLowerCase())) { + String cover = elem.attr("poster"); + + Element source = elem.select("source").first(); + String src = source.attr("src"); + + if (src.startsWith("//")) { + src = "https:" + src; + } + + if (imgSrcFirst.equals(src)) + firstFound = true; + + item.url = src; + item.coverUrl = cover; + item.type = GalleryEntryType.TYPE_VIDEO; + + } else { + String src = elem.attr("src"); + + if (src.startsWith("//")) { + src = "https:" + src; + } + + if (imgSrcFirst.equals(src)) + firstFound = true; + + item.url = src; + item.type = GalleryEntryType.TYPE_IMAGE; + } + + if (firstFound && item.url != null) { + m_items.add(item); + } + } + + } else { + m_items = (ArrayList) savedInstanceState.getSerializable("items"); + m_title = savedInstanceState.getString("title"); + m_content = savedInstanceState.getString("content"); + } + + /*if (m_items.size() > 1) { + m_progress.setProgress(0); + m_progress.setMax(m_items.size()); + m_checkedItems = new ArrayList<>(); + + ArrayList tmp = new ArrayList<>(m_items); + + m_checkedItems.add(tmp.get(0)); + tmp.remove(0); + + ImageCheckTask ict = new ImageCheckTask(); + ict.execute(tmp); + } else { + m_checkedItems = new ArrayList<>(m_items); + m_progress.setVisibility(View.GONE); + } */ + + setTitle(m_title); + + m_adapter = new ArticleImagesPagerAdapter(getSupportFragmentManager(), m_items); + + m_pager = (ViewPager) findViewById(R.id.article_images_pager); + m_pager.setAdapter(m_adapter); + m_pager.setPageTransformer(true, new DepthPageTransformer()); + + } + + @Override + public void onCreateContextMenu(ContextMenu menu, View v, + ContextMenu.ContextMenuInfo menuInfo) { + + getMenuInflater().inflate(R.menu.context_article_content_img, menu); + + super.onCreateContextMenu(menu, v, menuInfo); + } + + @Override + public void onSaveInstanceState(Bundle out) { + super.onSaveInstanceState(out); + + out.putSerializable("items", m_items); + out.putString("title", m_title); + out.putString("content", m_content); + } + + +} diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/GalleryBaseFragment.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/GalleryBaseFragment.java index 4b5e40d5..9dc65311 100644 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/GalleryBaseFragment.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/GalleryBaseFragment.java @@ -9,7 +9,7 @@ import android.view.MenuItem; public class GalleryBaseFragment extends Fragment { private final String TAG = this.getClass().getSimpleName(); - protected ArticleImagesPagerActivity m_activity; + protected GalleryActivity m_activity; @Override public void onCreate(Bundle savedInstanceState) { @@ -56,7 +56,7 @@ public class GalleryBaseFragment extends Fragment { super.onAttach(activity); //m_prefs = PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext()); - m_activity = (ArticleImagesPagerActivity) activity; + m_activity = (GalleryActivity) activity; } diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/GalleryImageFragment.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/GalleryImageFragment.java new file mode 100644 index 00000000..ca7dfbb3 --- /dev/null +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/GalleryImageFragment.java @@ -0,0 +1,128 @@ +package org.fox.ttrss; + +import android.os.Bundle; +import android.support.v4.app.ActivityCompat; +import android.support.v4.view.ViewCompat; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.PopupMenu; +import android.widget.ProgressBar; + +import com.bogdwellers.pinchtozoom.ImageMatrixTouchHandler; +import com.bumptech.glide.Glide; +import com.bumptech.glide.load.engine.DiskCacheStrategy; +import com.bumptech.glide.load.resource.drawable.GlideDrawable; +import com.bumptech.glide.request.RequestListener; +import com.bumptech.glide.request.target.GlideDrawableImageViewTarget; +import com.bumptech.glide.request.target.Target; + +public class GalleryImageFragment extends GalleryBaseFragment { + private final String TAG = this.getClass().getSimpleName(); + + String m_url; + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_gallery_entry, container, false); + + if (savedInstanceState != null) { + m_url = savedInstanceState.getString("url"); + } + + Log.d(TAG, "called for URL: " + m_url); + + ImageView imgView = (ImageView) view.findViewById(R.id.flavor_image); + + ImageMatrixTouchHandler touchHandler = new ImageMatrixTouchHandler(view.getContext()); + + imgView.setOnTouchListener(touchHandler); + + // shared element transitions stop GIFs from playing + if (m_url.toLowerCase().indexOf(".gif") == -1) { + ViewCompat.setTransitionName(imgView, "gallery:" + m_url); + } + + //registerForContextMenu(imgView); + + view.findViewById(R.id.flavor_image_overflow).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + PopupMenu popup = new PopupMenu(getContext(), v); + MenuInflater inflater = popup.getMenuInflater(); + inflater.inflate(R.menu.context_article_content_img, popup.getMenu()); + + popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem item) { + return onImageMenuItemSelected(item, m_url); + } + }); + + popup.show(); + + } + }); + + final ProgressBar progressBar = (ProgressBar) view.findViewById(R.id.flavor_image_progress); + final View errorMessage = view.findViewById(R.id.flavor_image_error); + + final GlideDrawableImageViewTarget glideImage = new GlideDrawableImageViewTarget(imgView); + + Glide.with(this) + .load(m_url) + .dontAnimate() + .diskCacheStrategy(DiskCacheStrategy.ALL) + .skipMemoryCache(false) + .listener(new RequestListener() { + @Override + public boolean onException(Exception e, String model, Target target, boolean isFirstResource) { + progressBar.setVisibility(View.GONE); + errorMessage.setVisibility(View.VISIBLE); + + ActivityCompat.startPostponedEnterTransition(m_activity); + return false; + } + + @Override + public boolean onResourceReady(GlideDrawable resource, String model, Target target, boolean isFromMemoryCache, boolean isFirstResource) { + progressBar.setVisibility(View.GONE); + errorMessage.setVisibility(View.GONE); + + ActivityCompat.startPostponedEnterTransition(m_activity); + return false; + } + }) + .into(glideImage); + + return view; + } + + public void initialize(String url) { + m_url = url; + } + + /*@Override + public boolean onContextItemSelected(MenuItem item) { + int position = m_pager.getCurrentItem(); + String url = m_checkedUrls.get(position); + + if (!onImageMenuItemSelected(item, url)) + return super.onContextItemSelected(item); + else + return true; + }*/ + + @Override + public void onSaveInstanceState (Bundle out) { + super.onSaveInstanceState(out); + + out.setClassLoader(getClass().getClassLoader()); + out.putString("url", m_url); + } + +} diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/GalleryVideoFragment.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/GalleryVideoFragment.java new file mode 100644 index 00000000..aba56e39 --- /dev/null +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/GalleryVideoFragment.java @@ -0,0 +1,326 @@ +package org.fox.ttrss; + +import android.content.res.Configuration; +import android.graphics.Rect; +import android.graphics.SurfaceTexture; +import android.media.MediaPlayer; +import android.os.Bundle; +import android.support.v4.app.ActivityCompat; +import android.support.v4.view.ViewCompat; +import android.util.Log; +import android.view.Display; +import android.view.LayoutInflater; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.Surface; +import android.view.TextureView; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.MediaController; +import android.widget.PopupMenu; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.load.engine.DiskCacheStrategy; +import com.bumptech.glide.load.resource.drawable.GlideDrawable; +import com.bumptech.glide.request.RequestListener; +import com.bumptech.glide.request.target.GlideDrawableImageViewTarget; +import com.bumptech.glide.request.target.Target; + +import java.io.IOException; + +public class GalleryVideoFragment extends GalleryBaseFragment { + private final String TAG = this.getClass().getSimpleName(); + + String m_url; + String m_coverUrl; + MediaPlayer m_mediaPlayer; + private boolean m_userVisibleHint = false; + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + final View view = inflater.inflate(R.layout.fragment_gallery_entry, container, false); + + if (savedInstanceState != null) { + m_url = savedInstanceState.getString("url"); + m_coverUrl = savedInstanceState.getString("coverUrl"); + } + + Log.d(TAG, "called for URL: " + m_url + " Cover: " + m_coverUrl); + + ImageView imgView = (ImageView) view.findViewById(R.id.flavor_image); + + ViewCompat.setTransitionName(imgView, "gallery:" + m_url); + + //registerForContextMenu(imgView); + + view.findViewById(R.id.flavor_image_overflow).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + PopupMenu popup = new PopupMenu(getContext(), v); + MenuInflater inflater = popup.getMenuInflater(); + inflater.inflate(R.menu.context_article_content_img, popup.getMenu()); + + popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem item) { + return onImageMenuItemSelected(item, m_url); + } + }); + + popup.show(); + + } + }); + + final GlideDrawableImageViewTarget glideImage = new GlideDrawableImageViewTarget(imgView); + + Glide.with(this) + .load(m_coverUrl) + .dontAnimate() + .diskCacheStrategy(DiskCacheStrategy.ALL) + .skipMemoryCache(false) + .listener(new RequestListener() { + @Override + public boolean onException(Exception e, String model, Target target, boolean isFirstResource) { + ActivityCompat.startPostponedEnterTransition(m_activity); + + initializeVideoPlayer(view); + return false; + } + + @Override + public boolean onResourceReady(GlideDrawable resource, String model, Target target, boolean isFromMemoryCache, boolean isFirstResource) { + ActivityCompat.startPostponedEnterTransition(m_activity); + + initializeVideoPlayer(view); + return false; + } + }) + .into(glideImage); + + return view; + } + + @Override + public void setUserVisibleHint(boolean isVisibleToUser) { + super.setUserVisibleHint(isVisibleToUser); + m_userVisibleHint = isVisibleToUser; + + Log.d(TAG, "setUserVisibleHint: " + isVisibleToUser); + + if (getView() == null) return; + + try { + + if (isVisibleToUser) { + if (m_mediaPlayer != null && !m_mediaPlayer.isPlaying()) { + m_mediaPlayer.start(); + } + + } else { + if (m_mediaPlayer != null && m_mediaPlayer.isPlaying()) { + m_mediaPlayer.pause(); + } + } + } catch (IllegalStateException e) { + e.printStackTrace(); + } + + } + + private void initializeVideoPlayer(final View view) { + + //Log.d(TAG, "initializeVideoPlayer: " + m_activity + " " + view); + + final MediaController m_mediaController = new MediaController(m_activity); + final TextureView textureView = (TextureView) view.findViewById(R.id.flavor_video); + + textureView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + try { + if (!m_mediaController.isShowing()) + m_mediaController.show(5000); + else + m_mediaController.hide(); + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + + m_mediaController.setAnchorView(textureView); + + textureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() { + @Override + public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { + Surface s = new Surface(surface); + + m_mediaPlayer = new MediaPlayer(); + + m_mediaController.setMediaPlayer(new MediaController.MediaPlayerControl() { + @Override + public void start() { + m_mediaPlayer.start(); + } + + @Override + public void pause() { + m_mediaPlayer.pause(); + } + + @Override + public int getDuration() { + return m_mediaPlayer.getDuration(); + } + + @Override + public int getCurrentPosition() { + return m_mediaPlayer.getCurrentPosition(); + } + + @Override + public void seekTo(int pos) { + m_mediaPlayer.seekTo(pos); + } + + @Override + public boolean isPlaying() { + return m_mediaPlayer.isPlaying(); + } + + @Override + public int getBufferPercentage() { + return 0; + } + + @Override + public boolean canPause() { + return true; + } + + @Override + public boolean canSeekBackward() { + return true; + } + + @Override + public boolean canSeekForward() { + return true; + } + + @Override + public int getAudioSessionId() { + return 0; + } + }); + + m_mediaPlayer.setSurface(s); + + try { + m_mediaPlayer.setDataSource(m_url); + } catch (IOException e) { + view.findViewById(R.id.flavor_image_error).setVisibility(View.VISIBLE); + e.printStackTrace(); + } + + m_mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { + @Override + public void onPrepared(MediaPlayer mp) { + getView().findViewById(R.id.flavor_image).setVisibility(View.GONE); + getView().findViewById(R.id.flavor_image_progress).setVisibility(View.GONE); + + resizeSurface(textureView); + mp.setLooping(true); + + if (m_userVisibleHint) { + mp.start(); + } + } + }); + + m_mediaPlayer.prepareAsync(); + } + + @Override + public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { + + } + + @Override + public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { + try { + m_mediaPlayer.release(); + } catch (Exception e) { + e.printStackTrace(); + } + return false; + } + + @Override + public void onSurfaceTextureUpdated(SurfaceTexture surface) { + + } + }); + + } + + public void initialize(String url, String coverUrl) { + m_url = url; + m_coverUrl = coverUrl; + } + + /*@Override + public boolean onContextItemSelected(MenuItem item) { + int position = m_pager.getCurrentItem(); + String url = m_checkedUrls.get(position); + + if (!onImageMenuItemSelected(item, url)) + return super.onContextItemSelected(item); + else + return true; + }*/ + + @Override + public void onSaveInstanceState (Bundle out) { + super.onSaveInstanceState(out); + + out.setClassLoader(getClass().getClassLoader()); + out.putString("url", m_url); + out.putString("coverUrl", m_coverUrl); + } + + protected void resizeSurface(View surfaceView) { + // get the dimensions of the video (only valid when surfaceView is set) + float videoWidth = m_mediaPlayer.getVideoWidth(); + float videoHeight = m_mediaPlayer.getVideoHeight(); + + Rect rectangle = new Rect(); + m_activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(rectangle); + + int actionBarHeight = m_activity.isPortrait() ? m_activity.getSupportActionBar().getHeight() : 0; + + Display display = m_activity.getWindowManager().getDefaultDisplay(); + float containerWidth = display.getWidth(); + float containerHeight = display.getHeight() - rectangle.top - actionBarHeight; + + // set dimensions to surfaceView's layout params (maintaining aspect ratio) + android.view.ViewGroup.LayoutParams lp = surfaceView.getLayoutParams(); + lp.width = (int) containerWidth; + lp.height = (int) ((videoHeight / videoWidth) * containerWidth); + if(lp.height > containerHeight) { + lp.width = (int) ((videoWidth / videoHeight) * containerHeight); + lp.height = (int) containerHeight; + } + surfaceView.setLayoutParams(lp); + } + + @Override + public void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + + resizeSurface(getView().findViewById(R.id.flavor_video)); + } + +} diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/HeadlinesFragment.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/HeadlinesFragment.java index 9ca7870d..eb9295c5 100755 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/HeadlinesFragment.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/HeadlinesFragment.java @@ -42,7 +42,6 @@ import android.view.LayoutInflater; import android.view.MenuInflater; import android.view.MenuItem; import android.view.Surface; -import android.view.SurfaceHolder; import android.view.TextureView; import android.view.View; import android.view.View.OnClickListener; @@ -76,8 +75,6 @@ import org.fox.ttrss.types.Feed; import org.fox.ttrss.util.HeaderViewRecyclerAdapter; import org.fox.ttrss.util.HeadlinesRequest; -import java.io.IOException; -import java.io.InterruptedIOException; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; @@ -1503,7 +1500,7 @@ public class HeadlinesFragment extends Fragment { } else { - Intent intent = new Intent(m_activity, ArticleImagesPagerActivity.class); + Intent intent = new Intent(m_activity, GalleryActivity.class); intent.putExtra("firstSrc", article.flavorStreamUri != null ? article.flavorStreamUri : article.flavorImageUri); intent.putExtra("title", article.title); diff --git a/org.fox.ttrss/src/main/res/layout/activity_gallery.xml b/org.fox.ttrss/src/main/res/layout/activity_gallery.xml new file mode 100644 index 00000000..de99eedb --- /dev/null +++ b/org.fox.ttrss/src/main/res/layout/activity_gallery.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + diff --git a/org.fox.ttrss/src/main/res/layout/article_images_pager.xml b/org.fox.ttrss/src/main/res/layout/article_images_pager.xml deleted file mode 100755 index de99eedb..00000000 --- a/org.fox.ttrss/src/main/res/layout/article_images_pager.xml +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - - - - - diff --git a/org.fox.ttrss/src/main/res/layout/fragment_article_image.xml b/org.fox.ttrss/src/main/res/layout/fragment_article_image.xml deleted file mode 100644 index e5fe47f4..00000000 --- a/org.fox.ttrss/src/main/res/layout/fragment_article_image.xml +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/org.fox.ttrss/src/main/res/layout/fragment_gallery_entry.xml b/org.fox.ttrss/src/main/res/layout/fragment_gallery_entry.xml new file mode 100644 index 00000000..e5fe47f4 --- /dev/null +++ b/org.fox.ttrss/src/main/res/layout/fragment_gallery_entry.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + \ No newline at end of file -- cgit v1.2.3