diff options
Diffstat (limited to 'org.fox.ttrss/src')
3 files changed, 203 insertions, 49 deletions
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 index c527730b..538e1c8f 100755 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/GalleryActivity.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/GalleryActivity.java @@ -12,22 +12,28 @@ import android.view.Window; import android.widget.PopupMenu; import android.widget.ProgressBar; +import androidx.annotation.NonNull; import androidx.appcompat.widget.Toolbar; import androidx.core.app.ActivityCompat; import androidx.core.view.WindowCompat; import androidx.core.view.WindowInsetsCompat; import androidx.core.view.WindowInsetsControllerCompat; import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentStatePagerAdapter; +import androidx.lifecycle.ViewModelProvider; import androidx.preference.PreferenceManager; +import androidx.recyclerview.widget.DiffUtil; import androidx.viewpager.widget.ViewPager; +import androidx.viewpager2.widget.ViewPager2; import com.ToxicBakery.viewpager.transforms.DepthPageTransformer; import com.bumptech.glide.Glide; import com.bumptech.glide.load.engine.DiskCacheStrategy; import org.fox.ttrss.types.GalleryEntry; +import org.fox.ttrss.util.DiffFragmentStateAdapter; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; @@ -42,32 +48,36 @@ import me.relex.circleindicator.CircleIndicator; public class GalleryActivity extends CommonActivity { private final String TAG = this.getClass().getSimpleName(); - protected ArrayList<GalleryEntry> m_items = new ArrayList<>(); protected String m_title; private ArticleImagesPagerAdapter m_adapter; public String m_content; - private ViewPager m_pager; // TODO replace with viewpager2 + private ViewPager2 m_pager; // TODO replace with viewpager2 private ProgressBar m_checkProgress; - private static class ArticleImagesPagerAdapter extends FragmentStatePagerAdapter { - private final List<GalleryEntry> m_items; + private static class GalleryEntryDiffItemCallback extends DiffUtil.ItemCallback<GalleryEntry> { - public ArticleImagesPagerAdapter(FragmentManager fm, List<GalleryEntry> items) { - super(fm); - m_items = items; + @Override + public boolean areItemsTheSame(@NonNull GalleryEntry oldItem, @NonNull GalleryEntry newItem) { + return oldItem.url.equals(newItem.url); } @Override - public int getCount() { - return m_items.size(); + public boolean areContentsTheSame(@NonNull GalleryEntry oldItem, @NonNull GalleryEntry newItem) { + return oldItem.url.equals(newItem.url) && oldItem.type.equals(newItem.type); + } + } + + private static class ArticleImagesPagerAdapter extends DiffFragmentStateAdapter<GalleryEntry> { + protected ArticleImagesPagerAdapter(FragmentActivity fragmentActivity, DiffUtil.ItemCallback<GalleryEntry> diffCallback) { + super(fragmentActivity, diffCallback); } @Override - public Fragment getItem(int position) { + public Fragment createFragment(int position) { //Log.d(TAG, "getItem: " + position + " " + m_urls.get(position)); - GalleryEntry item = m_items.get(position); + GalleryEntry item = getItem(position); switch (item.type) { case TYPE_IMAGE: { @@ -150,6 +160,7 @@ public class GalleryActivity extends CommonActivity { } } + /* boolean collectGalleryContents(String imgSrcFirst, Document doc, List<GalleryEntry> uncheckedItems ) { Elements elems = doc.select("img,video"); @@ -229,19 +240,18 @@ public class GalleryActivity extends CommonActivity { } return firstFound; - } + } */ public void onSaveInstanceState(Bundle out) { super.onSaveInstanceState(out); - out.putParcelableArrayList("m_items", m_items); out.putString("m_title", m_title); out.putString("m_content", m_content); } @Override public void onCreate(Bundle savedInstanceState) { - ActivityCompat.postponeEnterTransition(this); + // ActivityCompat.postponeEnterTransition(this); // we use that before parent onCreate so let's init locally m_prefs = PreferenceManager @@ -263,62 +273,68 @@ public class GalleryActivity extends CommonActivity { getSupportActionBar().setDisplayHomeAsUpEnabled(true); getSupportActionBar().hide(); - ArrayList<GalleryEntry> uncheckedItems = new ArrayList<>(); - if (savedInstanceState == null) { m_title = getIntent().getStringExtra("title"); m_content = getIntent().getStringExtra("content"); - String imgSrcFirst = getIntent().getStringExtra("firstSrc"); + // this should be returned first so that transition completes properly + String firstSrc = getIntent().getStringExtra("firstSrc"); - Document doc = Jsoup.parse(m_content); + // Document doc = Jsoup.parse(m_content); // if we were unable to find first image, try again for all media content so that // gallery doesn't lock up because of a pending shared transition - if (!collectGalleryContents(imgSrcFirst, doc, uncheckedItems)) + /* if (!collectGalleryContents(imgSrcFirst, doc, uncheckedItems)) if (!collectGalleryContents("", doc, uncheckedItems)) - m_items.add(new GalleryEntry(imgSrcFirst, GalleryEntry.GalleryEntryType.TYPE_IMAGE, null)); - } else { - ArrayList<GalleryEntry> list = savedInstanceState.getParcelableArrayList("m_items"); + m_items.add(new GalleryEntry(imgSrcFirst, GalleryEntry.GalleryEntryType.TYPE_IMAGE, null)); */ + + GalleryModel model = new ViewModelProvider(this).get(GalleryModel.class); + model.collectItems(m_content, firstSrc); + + model.getItems().observe(this, galleryEntries -> { + Log.d(TAG, "observed gallery entries=" + galleryEntries + " firstSrc=" + firstSrc); - m_items.clear(); - m_items.addAll(list); + m_adapter.submitList(galleryEntries, () -> { + Log.d(TAG, "selecting first src=" + firstSrc); + }); + }); + } else { + // ArrayList<GalleryEntry> list = savedInstanceState.getParcelableArrayList("m_items"); m_title = savedInstanceState.getString("m_title"); m_content = savedInstanceState.getString("m_content"); } findViewById(R.id.gallery_overflow).setOnClickListener(v -> { - PopupMenu popup = new PopupMenu(GalleryActivity.this, v); - MenuInflater inflater = popup.getMenuInflater(); - inflater.inflate(R.menu.content_gallery_entry, popup.getMenu()); + try { + GalleryEntry entry = m_adapter.getCurrentList().get(m_pager.getCurrentItem()); - final GalleryEntry entry = m_items.get(m_pager.getCurrentItem()); + PopupMenu popup = new PopupMenu(GalleryActivity.this, v); + MenuInflater inflater = popup.getMenuInflater(); + inflater.inflate(R.menu.content_gallery_entry, popup.getMenu()); - popup.getMenu().findItem(R.id.article_img_share) - .setVisible(entry.type == GalleryEntry.GalleryEntryType.TYPE_IMAGE); + popup.getMenu().findItem(R.id.article_img_share) + .setVisible(entry.type == GalleryEntry.GalleryEntryType.TYPE_IMAGE); - popup.setOnMenuItemClickListener(item -> onImageMenuItemSelected(item, entry)); + popup.setOnMenuItemClickListener(item -> onImageMenuItemSelected(item, entry)); - popup.show(); + popup.show(); + } catch (IndexOutOfBoundsException e) { + e.printStackTrace(); + } }); setTitle(m_title); - m_adapter = new ArticleImagesPagerAdapter(getSupportFragmentManager(), m_items); + m_adapter = new ArticleImagesPagerAdapter(this, new GalleryEntryDiffItemCallback()); m_pager = findViewById(R.id.gallery_pager); m_pager.setAdapter(m_adapter); - m_pager.setPageTransformer(true, new DepthPageTransformer()); - - CircleIndicator indicator = findViewById(R.id.gallery_pager_indicator); - indicator.setViewPager(m_pager); - m_adapter.registerDataSetObserver(indicator.getDataSetObserver()); m_checkProgress = findViewById(R.id.gallery_check_progress); - Log.d(TAG, "items to check:" + uncheckedItems.size()); + /* Log.d(TAG, "items to check:" + uncheckedItems.size()); MediaCheckTask mct = new MediaCheckTask() { @Override @@ -339,26 +355,25 @@ public class GalleryActivity extends CommonActivity { @Override protected void onPostExecute(List<GalleryEntry> result) { m_items.addAll(result); - m_adapter.notifyDataSetChanged(); } }; - mct.execute(uncheckedItems); - + mct.execute(uncheckedItems); */ } @Override public boolean onContextItemSelected(MenuItem item) { int position = m_pager.getCurrentItem(); - GalleryEntry entry = m_items.get(position); + try { + GalleryEntry entry = m_adapter.getCurrentList().get(position); - //String url = m_items.get(position).url; + if (onImageMenuItemSelected(item, entry)) + return true; - - - if (onImageMenuItemSelected(item, entry)) - return true; + } catch (IndexOutOfBoundsException e) { + e.printStackTrace(); + } return super.onContextItemSelected(item); } diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/GalleryModel.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/GalleryModel.java new file mode 100644 index 00000000..25117bb2 --- /dev/null +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/GalleryModel.java @@ -0,0 +1,139 @@ +package org.fox.ttrss; + +import android.app.Application; +import android.net.Uri; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.lifecycle.AndroidViewModel; +import androidx.lifecycle.LiveData; +import androidx.lifecycle.MutableLiveData; + +import org.fox.ttrss.types.GalleryEntry; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.nodes.Element; +import org.jsoup.select.Elements; + +import java.util.ArrayList; +import java.util.List; + +public class GalleryModel extends AndroidViewModel { + private final String TAG = this.getClass().getSimpleName(); + + private MutableLiveData<List<GalleryEntry>> m_items = new MutableLiveData<>(new ArrayList<>()); + + public GalleryModel(@NonNull Application application) { + super(application); + } + + public LiveData<List<GalleryEntry>> getItems() { + return m_items; + } + + public void collectItems(String articleText, String srcFirst) { + Document doc = Jsoup.parse(articleText); + + /* look for srcFirst and post an update */ + + Elements elems = doc.select("img,video"); + + for (Element elem : elems) { + GalleryEntry item = new GalleryEntry(); + + if ("video".equalsIgnoreCase(elem.tagName())) { + + + } else { + String src = elem.attr("abs:src"); + + + } + } + } + + List<GalleryEntry> collectGalleryContents(String imgSrcFirst, String articleText, List<GalleryEntry> uncheckedItems ) { + List<GalleryEntry> items = new ArrayList<>(); + + Document doc = Jsoup.parse(articleText); + + Elements elems = doc.select("img,video"); + + boolean firstFound = false; + + for (Element elem : elems) { + + GalleryEntry item = new GalleryEntry(); + + if ("video".equalsIgnoreCase(elem.tagName())) { + String cover = elem.attr("poster"); + + Element source = elem.select("source").first(); + + if (source != null) { + String src = source.attr("src"); + + if (!src.isEmpty()) { + //Log.d(TAG, "vid/src=" + src); + + if (src.startsWith("//")) { + src = "https:" + src; + } + + if (imgSrcFirst.equals(src)) + firstFound = true; + + try { + Uri checkUri = Uri.parse(src); + + if (!"data".equalsIgnoreCase(checkUri.getScheme())) { + item.url = src; + item.coverUrl = cover; + item.type = GalleryEntry.GalleryEntryType.TYPE_VIDEO; + } + + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + } else { + String src = elem.attr("src"); + + if (!src.isEmpty()) { + if (src.startsWith("//")) { + src = "https:" + src; + } + + if (imgSrcFirst.equals(src)) + firstFound = true; + + Log.d(TAG, "img/fir=" + imgSrcFirst + ";"); + Log.d(TAG, "img/src=" + src + "; ff=" + firstFound); + + try { + Uri checkUri = Uri.parse(src); + + if (!"data".equalsIgnoreCase(checkUri.getScheme())) { + item.url = src; + item.type = GalleryEntry.GalleryEntryType.TYPE_IMAGE; + } + + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + if ((firstFound || imgSrcFirst.isEmpty()) && item.url != null) { + if (m_items.isEmpty()) + m_items.add(item); + else + uncheckedItems.add(item); + } + } + + return firstFound; + } +} diff --git a/org.fox.ttrss/src/main/res/layout/activity_gallery.xml b/org.fox.ttrss/src/main/res/layout/activity_gallery.xml index b0f67761..b38f0408 100644 --- a/org.fox.ttrss/src/main/res/layout/activity_gallery.xml +++ b/org.fox.ttrss/src/main/res/layout/activity_gallery.xml @@ -5,7 +5,7 @@ android:animateLayoutChanges="true" android:layout_height="fill_parent"> - <com.bogdwellers.pinchtozoom.view.ImageViewPager + <androidx.viewpager2.widget.ViewPager2 android:id="@+id/gallery_pager" android:layout_width="fill_parent" android:layout_height="fill_parent" |