Skip to content

Commit

Permalink
Merge branch 'central-dev' into central-master
Browse files Browse the repository at this point in the history
  • Loading branch information
RobbWatershed committed May 15, 2019
2 parents 67abb23 + f14c815 commit 699f5d3
Show file tree
Hide file tree
Showing 26 changed files with 300 additions and 93 deletions.
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ android {
// or Perfect Viewer implements Content URI
//noinspection ExpiringTargetSdkVersion
targetSdkVersion 23
versionCode 103
versionName '1.7.3'
versionCode 105
versionName '1.7.5'

def fkToken = '\"' + (System.getenv("FK_TOKEN")?: "")+'\"'
def includeObjectBoxBrowser = System.getenv("INCLUDE_OBJECTBOX_BROWSER")?:"false"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent;
Expand All @@ -18,6 +17,7 @@
import android.support.design.widget.Snackbar;
import android.support.v4.app.FragmentActivity;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.SearchView;
Expand Down Expand Up @@ -59,7 +59,7 @@
import me.devsaki.hentoid.events.DownloadEvent;
import me.devsaki.hentoid.events.ImportEvent;
import me.devsaki.hentoid.fragments.AboutMikanDialogFragment;
import me.devsaki.hentoid.fragments.SearchBookIdDialogFragment;
import me.devsaki.hentoid.fragments.downloads.SearchBookIdDialogFragment;
import me.devsaki.hentoid.listener.ContentListener;
import me.devsaki.hentoid.listener.ContentClickListener.ItemSelectListener;
import me.devsaki.hentoid.services.ContentQueueManager;
Expand Down Expand Up @@ -288,7 +288,7 @@ public void onResume() {

int currentViewer = Preferences.getContentReadAction();
if (Preferences.Constant.PREF_READ_CONTENT_HENTOID_VIEWER != currentViewer) {
if (!Preferences.hasViewerChoiceBeenDisplayed()) showViewerChoiceDialog(currentViewer);
if (!Preferences.hasViewerChoiceBeenDisplayed()) showViewerChoiceDialog();
} else {
Preferences.setViewerChoiceDisplayed(true);
}
Expand Down Expand Up @@ -1176,23 +1176,17 @@ private void onContentRemoved(int i) {
updateTitle();
}

private void showViewerChoiceDialog(int currentViewer) {
int resourcePosition = 0;
if (0 == currentViewer) resourcePosition = 1;
else if (1 == currentViewer) resourcePosition = 2;
String currentViewerStr = requireContext().getResources().getStringArray(R.array.pref_read_content_entries)[resourcePosition];

String message = requireContext().getString(R.string.downloads_suggest_image_viewer).replace("@currentOption", currentViewerStr);
android.support.v7.app.AlertDialog.Builder builder = new android.support.v7.app.AlertDialog.Builder(requireContext());
builder.setTitle(R.string.downloads_suggest_image_viewer_title)
.setMessage(message)
.setPositiveButton(R.string.yes,
private void showViewerChoiceDialog() {
new AlertDialog.Builder(requireContext(), R.style.Theme_AppCompat_Dialog_Alert)
.setTitle(R.string.downloads_suggest_image_viewer_title)
.setMessage(R.string.downloads_suggest_image_viewer)
.setPositiveButton(R.string.try_it,
(dialog, which) -> {
Preferences.setViewerChoiceDisplayed(true);
Preferences.setContentReadAction(Preferences.Constant.PREF_READ_CONTENT_HENTOID_VIEWER);
})
.setNegativeButton(R.string.no,
(dialog, which) -> Preferences.setViewerChoiceDisplayed(true))
.create().show();
.show();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
import me.devsaki.hentoid.abstracts.BaseFragment.BackInterface;
import me.devsaki.hentoid.abstracts.DownloadsFragment;
import me.devsaki.hentoid.abstracts.DrawerActivity;
import me.devsaki.hentoid.fragments.EndlessFragment;
import me.devsaki.hentoid.fragments.PagerFragment;
import me.devsaki.hentoid.fragments.downloads.EndlessFragment;
import me.devsaki.hentoid.fragments.downloads.PagerFragment;
import me.devsaki.hentoid.util.Helper;
import me.devsaki.hentoid.util.Preferences;
import timber.log.Timber;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,12 @@ private void resultHandler(int resultCode, String result) {
.setAction(android.R.string.ok, v -> openAppSettings())
.show();
break;
case ConstsImport.RESULT_CANCELED:
case ConstsImport.EXISTING_LIBRARY_FOUND:
Snackbar.make(pager, R.string.import_canceled, LENGTH_LONG).show();
break;
default:
throw new InvalidParameterException("Not implemented");
// Other cases should fail silently
}
HentoidApp.setBeginImport(false);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
import me.devsaki.hentoid.abstracts.BaseFragment;
import me.devsaki.hentoid.abstracts.BaseFragment.BackInterface;
import me.devsaki.hentoid.abstracts.DownloadsFragment;
import me.devsaki.hentoid.fragments.EndlessFragment;
import me.devsaki.hentoid.fragments.PagerFragment;
import me.devsaki.hentoid.fragments.downloads.EndlessFragment;
import me.devsaki.hentoid.fragments.downloads.PagerFragment;
import me.devsaki.hentoid.util.Helper;
import me.devsaki.hentoid.util.Preferences;
import timber.log.Timber;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,26 @@

import java.util.Collections;
import java.util.List;
import java.util.concurrent.Executor;

import me.devsaki.hentoid.R;
import me.devsaki.hentoid.util.ImageLoaderThreadExecutor;
import me.devsaki.hentoid.util.Preferences;
import timber.log.Timber;


public final class ImageRecyclerAdapter extends RecyclerView.Adapter<ImageRecyclerAdapter.ImageViewHolder> {

// TODO : SubsamplingScaleImageView does _not_ support animated GIFs -> use pl.droidsonroids.gif:android-gif-drawable when serving a GIF ?

private static final Executor executor = new ImageLoaderThreadExecutor();


private View.OnTouchListener itemTouchListener;

private List<String> imageUris;


@Override
public int getItemCount() {
return imageUris.size();
Expand All @@ -48,6 +55,13 @@ public ImageViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
@Override
public void onBindViewHolder(@NonNull ImageViewHolder viewHolder, int pos) {
viewHolder.setImageUri(imageUris.get(pos));

int layoutStyle = (Preferences.Constant.PREF_VIEWER_ORIENTATION_VERTICAL == Preferences.getViewerOrientation()) ? ViewGroup.LayoutParams.WRAP_CONTENT : ViewGroup.LayoutParams.MATCH_PARENT;

ViewGroup.LayoutParams layoutParams = viewHolder.imgView.getLayoutParams();
layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
layoutParams.height = layoutStyle;
viewHolder.imgView.setLayoutParams(layoutParams);
}

final class ImageViewHolder extends RecyclerView.ViewHolder {
Expand All @@ -57,12 +71,14 @@ final class ImageViewHolder extends RecyclerView.ViewHolder {
private ImageViewHolder(@NonNull View itemView) {
super(itemView);
imgView = (SubsamplingScaleImageView) itemView;
imgView.setExecutor(executor);
imgView.setOnTouchListener(itemTouchListener);
}

void setImageUri(String uri) {
imgView.recycle();
imgView.setMinimumScaleType(getScaleType());
Timber.i(">>>>IMG %s", uri);
imgView.setImage(ImageSource.uri(uri));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import me.devsaki.hentoid.database.domains.Content;
import me.devsaki.hentoid.enums.StatusContent;
import me.devsaki.hentoid.events.DownloadEvent;
import me.devsaki.hentoid.fragments.downloads.ErrorStatsDialogFragment;
import me.devsaki.hentoid.services.ContentQueueManager;
import me.devsaki.hentoid.ui.BlinkAnimation;
import me.devsaki.hentoid.util.Helper;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package me.devsaki.hentoid.fragments;
package me.devsaki.hentoid.fragments.downloads;

import android.view.View;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package me.devsaki.hentoid.fragments;
package me.devsaki.hentoid.fragments.downloads;

import android.os.Bundle;
import android.support.annotation.NonNull;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package me.devsaki.hentoid.fragments;
package me.devsaki.hentoid.fragments.downloads;

import android.support.v7.widget.RecyclerView;
import android.view.View;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package me.devsaki.hentoid.fragments;
package me.devsaki.hentoid.fragments.downloads;

import android.content.Intent;
import android.os.Bundle;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import android.content.SharedPreferences;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
Expand All @@ -18,7 +19,6 @@
import android.widget.TextView;

import java.util.List;
import java.util.Objects;

import me.devsaki.hentoid.R;
import me.devsaki.hentoid.adapters.ImageRecyclerAdapter;
Expand All @@ -45,6 +45,8 @@ public class ImagePagerFragment extends Fragment implements GoToPageDialogFragme
private ImageRecyclerAdapter adapter;
private SeekBar seekBar;
private TextView pageNumber;
private TextView pageCurrentNumber;
private TextView pageMaxNumber;
private RecyclerView recyclerView;
private PageSnapWidget pageSnapWidget;
private ImageViewerViewModel viewModel;
Expand All @@ -65,6 +67,7 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c

onBrowseModeChange();
onUpdateFlingFactor();
onUpdatePageNumDisplay();

return view;
}
Expand All @@ -85,17 +88,17 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean(KEY_HUD_VISIBLE, controlsOverlay.getVisibility() == View.VISIBLE);
outState.putInt(KEY_HUD_VISIBLE, controlsOverlay.getVisibility());
}

@Override
public void onViewStateRestored(@Nullable Bundle savedInstanceState) {
super.onViewStateRestored(savedInstanceState);
boolean hudVisible = false; // Default state at startup
int hudVisibility = View.INVISIBLE; // Default state at startup
if (savedInstanceState != null) {
hudVisible = savedInstanceState.getBoolean(KEY_HUD_VISIBLE, false);
hudVisibility = savedInstanceState.getInt(KEY_HUD_VISIBLE, View.INVISIBLE);
}
controlsOverlay.setVisibility(hudVisible ? View.VISIBLE : View.INVISIBLE);
controlsOverlay.setVisibility(hudVisibility);
}

@Override
Expand All @@ -114,15 +117,14 @@ private void initPager(View rootView) {
.setOnVolumeUpKeyListener(this::nextPage);

recyclerView = requireViewById(rootView, R.id.image_viewer_recycler);
recyclerView.setHasFixedSize(true);
recyclerView.setAdapter(adapter);
recyclerView.setHasFixedSize(true);
recyclerView.addOnScrollListener(new ScrollPositionListener(this::onCurrentPositionChange));
recyclerView.setOnKeyListener(volumeKeyListener);
recyclerView.setOnKeyListener(volumeKeyListener.getListener());

llm = new PrefetchLinearLayoutManager(getContext());
llm.setItemPrefetchEnabled(true);
llm.setPreloadItemCount(2);
llm.setOrientation(LinearLayoutManager.HORIZONTAL);
recyclerView.setLayoutManager(llm);

pageSnapWidget = new PageSnapWidget(recyclerView)
Expand All @@ -148,8 +150,10 @@ private void initControlsOverlay(View rootView) {
View discordButton = requireViewById(rootView, R.id.viewer_discord_text);
discordButton.setOnClickListener(v -> Helper.openUrl(requireContext(), Consts.URL_DISCORD));
// Page number button
pageCurrentNumber = requireViewById(rootView, R.id.viewer_currentpage_text);
pageCurrentNumber.setOnClickListener(v -> GoToPageDialogFragment.show(this));
pageMaxNumber = requireViewById(rootView, R.id.viewer_maxpage_text);
pageNumber = requireViewById(rootView, R.id.viewer_pagenumber_text);
pageNumber.setOnClickListener(v -> GoToPageDialogFragment.show(this));
// Slider
seekBar = requireViewById(rootView, R.id.viewer_seekbar);
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
Expand Down Expand Up @@ -193,23 +197,25 @@ private void onImagesChanged(List<String> images) {

// Scroll listener
private void onCurrentPositionChange(int position) {
if (Preferences.Constant.PREF_VIEWER_DIRECTION_LTR == Preferences.getViewerDirection())
viewModel.setCurrentPosition(position);
else
viewModel.setCurrentPosition(maxPosition - position);
viewModel.setCurrentPosition(position);
seekBar.setProgress(viewModel.getCurrentPosition());
updatePageDisplay();
}

private void updatePageDisplay() {
String pageDisplayText = format("%s / %s", viewModel.getCurrentPosition() + 1, maxPosition + 1);
pageNumber.setText(pageDisplayText);
String pageNum = viewModel.getCurrentPosition() + 1 + "";
String maxPage = maxPosition + 1 + "";

pageCurrentNumber.setText(pageNum);
pageMaxNumber.setText(maxPage);
pageNumber.setText(format("%s / %s", pageNum, maxPage));
}

public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
switch (key) {
case Preferences.Key.PREF_VIEWER_BROWSE_MODE:
onBrowseModeChange();
onUpdateImageDisplay();
break;
case Preferences.Key.PREF_VIEWER_KEEP_SCREEN_ON:
onUpdatePrefsScreenOn();
Expand All @@ -220,6 +226,9 @@ public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
case Preferences.Key.PREF_VIEWER_FLING_FACTOR:
onUpdateFlingFactor();
break;
case Preferences.Key.PREF_VIEWER_DISPLAY_PAGENUM:
onUpdatePageNumDisplay();
break;
default:
// Other changes aren't handled here
}
Expand All @@ -240,6 +249,10 @@ private void onUpdateImageDisplay() {
adapter.notifyDataSetChanged(); // NB : will re-run onBindViewHolder for all displayed pictures
}

private void onUpdatePageNumDisplay() {
pageNumber.setVisibility(Preferences.isViewerDisplayPageNum() ? View.VISIBLE : View.GONE);
}

@Override
public void onBrowseModeChange() {
int currentLayoutDirection;
Expand Down Expand Up @@ -342,7 +355,11 @@ private void setSystemBarsVisible(boolean visible) {
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN;
}
Objects.requireNonNull(getView()).setSystemUiVisibility(uiOptions);

// Defensive programming here because crash reports show that getView() sometimes is null
// (just don't ask me why...)
View v = getView();
if (v != null) v.setSystemUiVisibility(uiOptions);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat
theSwitch.setChecked(Preferences.isViewerKeepScreenOn());
theSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> Preferences.setViewerKeepScreenOn(isChecked));

theSwitch = requireViewById(view, R.id.viewer_prefs_display_pagenum_action);
theSwitch.setChecked(Preferences.isViewerDisplayPageNum());
theSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> Preferences.setViewerDisplayPageNum(isChecked));

RadioGroup theRadio = requireViewById(view, R.id.viewer_prefs_display_mode_group);
switch (Preferences.getViewerResizeMode()) {
case (Preferences.Constant.PREF_VIEWER_DISPLAY_FIT):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package me.devsaki.hentoid.util;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
Inspired by {@link android.os.AsyncTask}'s THREAD_POOL_EXECUTOR,
but with a {@link ThreadPoolExecutor.DiscardPolicy} (drop tasks that cannot be processed)
instead of the default {@link ThreadPoolExecutor.AbortPolicy} (throw an exception)
*/
public class ImageLoaderThreadExecutor extends ThreadPoolExecutor {

private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
// We want at least 2 threads and at most 4 threads in the core pool,
// preferring to have 1 less than the CPU count to avoid saturating
// the CPU with background work
private static final int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 4));
private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
private static final int KEEP_ALIVE_SECONDS = 30;

public ImageLoaderThreadExecutor() {
super(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_SECONDS, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(128), new ThreadPoolExecutor.DiscardPolicy());
this.allowCoreThreadTimeOut(true);
}
}
Loading

0 comments on commit 699f5d3

Please sign in to comment.