Skip to content

Commit

Permalink
Merge branch 'dev' into central-master
Browse files Browse the repository at this point in the history
  • Loading branch information
RobbWatershed committed Mar 13, 2021
2 parents e6c3ac0 + 26f5de1 commit 159d2d0
Show file tree
Hide file tree
Showing 41 changed files with 540 additions and 120 deletions.
2 changes: 1 addition & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ android {
//noinspection ExpiringTargetSdkVersion
targetSdkVersion 30
versionCode 130 // is updated automatically by BitRise; only used when building locally
versionName '1.14.1'
versionName '1.14.2'

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 @@ -222,10 +222,16 @@ public class CustomSubsamplingScaleImageView extends View {
// Image orientation setting
private int orientation = ORIENTATION_0;

// Max scale allowed (prevent infinite zoom)
// Zoom cap for double-tap zoom
// (factor of default scaling)
private float doubleTapZoomCap = -1;

// Max scale allowed (factor of source resolution)
// Used to prevent infinite zoom
private float maxScale = 2F;

// Min scale allowed (prevent infinite zoom)
// Min scale allowed (factor of source resolution)
// Used to prevent infinite zoom
private float minScale = minScale();

// Density to reach before loading higher resolution tiles
Expand Down Expand Up @@ -258,8 +264,11 @@ public class CustomSubsamplingScaleImageView extends View {
private int doubleTapZoomStyle = ZOOM_FOCUS_FIXED;
private int doubleTapZoomDuration = 500;

// Current scale and scale at start of zoom
// Initial scale, according to panLimit and minimumScaleType
private float initialScale = -1;
// Current scale
private float scale;
// Scale at start of zoom (transitional)
private float scaleStart;

// Screen coordinate of top-left corner of source image (image offset relative to screen)
Expand Down Expand Up @@ -388,8 +397,8 @@ public CustomSubsamplingScaleImageView(@NonNull Context context, @Nullable Attri
screenWidth = context.getResources().getDisplayMetrics().widthPixels;
screenHeight = context.getResources().getDisplayMetrics().heightPixels;

setMinimumDpi(120);
setDoubleTapZoomDpi(120);
setMinimumDpi(160);
setDoubleTapZoomDpi(160);
setMinimumTileDpi(320);
setGestureDetector(context);
this.handler = new Handler(Looper.getMainLooper(), message -> {
Expand Down Expand Up @@ -616,6 +625,7 @@ public final void setImage(@NonNull ImageSource imageSource, @Nullable ImageSour
*/
private void reset(boolean newImage) {
debug("reset newImage=" + newImage);
initialScale = -1;
scale = 0f;
scaleStart = 0f;
vTranslate = null;
Expand Down Expand Up @@ -1162,6 +1172,11 @@ private void doubleTapZoom(PointF sCenter, PointF vFocus) {
}
}
float targetDoubleTapZoomScale = Math.min(maxScale, doubleTapZoomScale);
if (doubleTapZoomCap > -1) {
targetDoubleTapZoomScale = Math.min(targetDoubleTapZoomScale, initialScale * doubleTapZoomCap);
Timber.i(">> doubleTapZoomCap %s -> %s", initialScale, targetDoubleTapZoomScale);
}

boolean zoomIn = (scale <= targetDoubleTapZoomScale * 0.9) || scale == minScale;
float targetScale = zoomIn ? targetDoubleTapZoomScale : minScale();
if (doubleTapZoomStyle == ZOOM_FOCUS_CENTER_IMMEDIATE) {
Expand Down Expand Up @@ -1769,6 +1784,10 @@ private void fitToBounds(boolean center, @NonNull Point sSize) {
satTemp.vTranslate.set(vTranslate);
fitToBounds(center, satTemp, sSize);
scale = satTemp.scale;
if (-1 == initialScale) {
initialScale = scale;
Timber.i(">> initialScale : %s", initialScale);
}
vTranslate.set(satTemp.vTranslate);

// Recenter images if their dimensions are lower than the view's dimensions after the above call to fitToBounds
Expand Down Expand Up @@ -2117,10 +2136,11 @@ private boolean needsRotating(int sWidth, int sHeight) {
private static class SingleImage {
// private int sampleSize;
// private Bitmap bitmap;
private boolean loading;
private float scale = 1;
private int rawWidth = -1;
private int rawHeight = -1;

private boolean loading;
}

private static class Tile {
Expand Down Expand Up @@ -2747,6 +2767,7 @@ public final void setMaximumDpi(int dpi) {
setMinScale(averageDpi / dpi);
}


/**
* Returns the maximum allowed scale.
*
Expand Down Expand Up @@ -3119,6 +3140,11 @@ public final void setDoubleTapZoomDuration(int durationMs) {
this.doubleTapZoomDuration = Math.max(0, durationMs);
}

// TODO doc
public void setDoubleTapZoomCap(float cap) {
this.doubleTapZoomCap = cap;
}


/**
* Enable or disable eager loading of tiles that appear on screen during gestures or animations,
Expand Down
8 changes: 7 additions & 1 deletion app/objectbox-models/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
},
{
"id": "2:5880334030341287801",
"lastPropertyId": "24:6637631044428919138",
"lastPropertyId": "25:515620137730542700",
"name": "Content",
"properties": [
{
Expand Down Expand Up @@ -171,6 +171,12 @@
"name": "isFlaggedForDeletion",
"type": 1,
"flags": 4
},
{
"id": "25:515620137730542700",
"name": "readProgress",
"type": 7,
"flags": 4
}
],
"relations": [
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -482,8 +482,8 @@
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider.FileProvider"
android:exported="false"
android:enabled="true"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
Expand Down
7 changes: 6 additions & 1 deletion app/src/main/java/me/devsaki/hentoid/HentoidApp.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import com.google.firebase.analytics.FirebaseAnalytics;
import com.google.firebase.crashlytics.FirebaseCrashlytics;
import com.jakewharton.threetenabp.AndroidThreeTen;
import com.thin.downloadmanager.util.Log;

import org.threeten.bp.Instant;

Expand Down Expand Up @@ -138,7 +139,11 @@ public void onCreate() {
FirebaseAnalytics.getInstance(this).setUserProperty("color_theme", Integer.toString(Preferences.getColorTheme()));
FirebaseAnalytics.getInstance(this).setUserProperty("endless", Boolean.toString(Preferences.getEndlessScroll()));

FirebaseCrashlytics.getInstance().setCustomKey("Library display mode", Preferences.getEndlessScroll() ? "endless" : "paged");
try {
FirebaseCrashlytics.getInstance().setCustomKey("Library display mode", Preferences.getEndlessScroll() ? "endless" : "paged");
} catch (IllegalStateException e) { // Happens during unit tests
Log.e("fail@init Crashlytics", e);
}

// Plug the lifecycle listener to handle locking
ProcessLifecycleOwner.get().getLifecycle().addObserver(new LifeCycleListener());
Expand Down
38 changes: 26 additions & 12 deletions app/src/main/java/me/devsaki/hentoid/activities/SearchActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import android.os.Bundle;
import android.util.SparseIntArray;
import android.view.View;
import android.widget.CheckBox;
import android.widget.TextView;

import androidx.annotation.NonNull;
Expand Down Expand Up @@ -53,6 +54,7 @@ public class SearchActivity extends BaseActivity {
// ViewModel of this activity
private SearchViewModel viewModel;

private boolean excludeClicked = false;

@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
Expand All @@ -61,12 +63,13 @@ protected void onSaveInstanceState(@NonNull Bundle outState) {
SearchActivityBundle.Builder builder = new SearchActivityBundle.Builder();
builder.setUri(SearchActivityBundle.Builder.buildSearchUri(viewModel.getSelectedAttributesData().getValue()));
outState.putAll(builder.getBundle());
outState.putBoolean("exclude", excludeClicked);
}

@Override
protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);

excludeClicked = savedInstanceState.getBoolean("exclude");
Uri searchUri = new SearchActivityBundle.Parser(savedInstanceState).getUri();
if (searchUri != null) {
List<Attribute> preSelectedAttributes = SearchActivityBundle.Parser.parseSearchUri(searchUri);
Expand All @@ -84,6 +87,7 @@ protected void onCreate(Bundle savedInstanceState) {

SearchActivityBundle.Parser parser = new SearchActivityBundle.Parser(intent.getExtras());
Uri searchUri = parser.getUri();
excludeClicked = parser.getExcludeMode();
if (searchUri != null)
preSelectedAttributes = SearchActivityBundle.Parser.parseSearchUri(searchUri);
}
Expand All @@ -97,27 +101,32 @@ protected void onCreate(Bundle savedInstanceState) {

// Attribute type buttons
TextView anyTypeButton = findViewById(R.id.textCategoryAny);
anyTypeButton.setOnClickListener(v -> onAttrButtonClick(AttributeType.TAG, AttributeType.ARTIST,
anyTypeButton.setOnClickListener(v -> onAttrButtonClick(excludeClicked, AttributeType.TAG, AttributeType.ARTIST,
AttributeType.CIRCLE, AttributeType.SERIE, AttributeType.CHARACTER, AttributeType.LANGUAGE)); // Everything but source !
anyTypeButton.setEnabled(true);

tagTypeButton = findViewById(R.id.textCategoryTag);
tagTypeButton.setOnClickListener(v -> onAttrButtonClick(AttributeType.TAG));
tagTypeButton.setOnClickListener(v -> onAttrButtonClick(excludeClicked,AttributeType.TAG));


artistTypeButton = findViewById(R.id.textCategoryArtist);
artistTypeButton.setOnClickListener(v -> onAttrButtonClick(AttributeType.ARTIST, AttributeType.CIRCLE));
artistTypeButton.setOnClickListener(v -> onAttrButtonClick(excludeClicked, AttributeType.ARTIST, AttributeType.CIRCLE));

seriesTypeButton = findViewById(R.id.textCategorySeries);
seriesTypeButton.setOnClickListener(v -> onAttrButtonClick(AttributeType.SERIE));
seriesTypeButton.setOnClickListener(v -> onAttrButtonClick(excludeClicked, AttributeType.SERIE));

characterTypeButton = findViewById(R.id.textCategoryCharacter);
characterTypeButton.setOnClickListener(v -> onAttrButtonClick(AttributeType.CHARACTER));
characterTypeButton.setOnClickListener(v -> onAttrButtonClick(excludeClicked, AttributeType.CHARACTER));

languageTypeButton = findViewById(R.id.textCategoryLanguage);
languageTypeButton.setOnClickListener(v -> onAttrButtonClick(AttributeType.LANGUAGE));
languageTypeButton.setOnClickListener(v -> onAttrButtonClick(excludeClicked, AttributeType.LANGUAGE));

sourceTypeButton = findViewById(R.id.textCategorySource);
sourceTypeButton.setOnClickListener(v -> onAttrButtonClick(AttributeType.SOURCE));
sourceTypeButton.setOnClickListener(v -> onAttrButtonClick(excludeClicked, AttributeType.SOURCE));

CheckBox checkBox = (CheckBox) findViewById(R.id.checkBox);
checkBox.setChecked(excludeClicked);


searchTags = findViewById(R.id.search_tags);
LinearLayoutManager llm = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
Expand Down Expand Up @@ -159,6 +168,10 @@ private void onQueryUpdated(@NonNull final SparseIntArray attrCount) {
updateAttributeTypeButton(sourceTypeButton, attrCount, AttributeType.SOURCE);
}

public void onExcludeClick(View view){
excludeClicked = ((CheckBox) view).isChecked();
}

/**
* Update the text of a given attribute type button based on the given SparseIntArray and relevant type(s)
*
Expand All @@ -182,8 +195,8 @@ private void updateAttributeTypeButton(@NonNull final TextView button, @NonNull
*
* @param attributeTypes Attribute type(s) to select
*/
private void onAttrButtonClick(AttributeType... attributeTypes) {
SearchBottomSheetFragment.invoke(this, getSupportFragmentManager(), attributeTypes);
private void onAttrButtonClick(boolean excludeClicked, AttributeType... attributeTypes) {
SearchBottomSheetFragment.invoke(this, getSupportFragmentManager(), attributeTypes, excludeClicked);
}

/**
Expand Down Expand Up @@ -220,7 +233,7 @@ private void onSelectedAttributeClick(View button) {
* @param count Current book count matching the currently selected attributes
*/
private void onBooksCounted(int count) {
if (count > 0) {
if (count >= 0) {
searchButton.setText(getResources().getQuantityString(R.plurals.search_button, count, count));
searchButton.setVisibility(View.VISIBLE);
} else {
Expand All @@ -237,9 +250,10 @@ private void searchBooks() {
Timber.d("URI :%s", searchUri);

SearchActivityBundle.Builder builder = new SearchActivityBundle.Builder().setUri(searchUri);
builder.setExcludeMode(excludeClicked);

Intent returnIntent = new Intent();
returnIntent.putExtras(builder.getBundle());

setResult(Activity.RESULT_OK, returnIntent);
finish();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public class SearchActivityBundle {
private static final String KEY_MODE = "mode";
private static final String KEY_URI = "uri";
private static final String KEY_GROUP = "group";
private static final String EXCLUDE_MODE = "exclude";

private SearchActivityBundle() {
throw new UnsupportedOperationException();
Expand All @@ -40,6 +41,9 @@ public void setAttributeTypes(AttributeType... attributeTypes) {

bundle.putIntegerArrayList(KEY_ATTRIBUTE_TYPES, attrTypes);
}
public void setExcludeMode(boolean excludeMode){
bundle.putBoolean(EXCLUDE_MODE, excludeMode);
}

public void setMode(int mode) {
bundle.putInt(KEY_MODE, mode);
Expand Down Expand Up @@ -68,7 +72,7 @@ public static Uri buildSearchUri(List<Attribute> attributes) {
List<Attribute> attrs = entry.getValue();
if (attrs != null)
for (Attribute attr : attrs)
searchUri.appendQueryParameter(attrType.name(), attr.getId() + ";" + attr.getName());
searchUri.appendQueryParameter(attrType.name(), attr.getId() + ";" + attr.getName() + ";" + attr.isExcluded());
}

return searchUri.build();
Expand Down Expand Up @@ -96,7 +100,7 @@ public List<AttributeType> getAttributeTypes() {

return result;
}

public boolean getExcludeMode(){return bundle.getBoolean(EXCLUDE_MODE, false);}
public int getMode() {
return bundle.getInt(KEY_MODE, -1);
}
Expand Down Expand Up @@ -124,8 +128,8 @@ public static List<Attribute> parseSearchUri(Uri uri) {
if (type != null)
for (String attrStr : uri.getQueryParameters(typeStr)) {
String[] attrParams = attrStr.split(";");
if (2 == attrParams.length) {
result.add(new Attribute(type, attrParams[1]).setId(Long.parseLong(attrParams[0])));
if (3 == attrParams.length) {
result.add(new Attribute(type, attrParams[1]).setId(Long.parseLong(attrParams[0])).setExcluded(Boolean.parseBoolean(attrParams[2])));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ protected void onCreate(Bundle savedInstanceState) {
// Top toolbar
Toolbar toolbar = findViewById(R.id.toolbar);
toolbar.setOnMenuItemClickListener(this::onMenuItemSelected);
toolbar.setTitle(getStartSite().getDescription());
refreshStopMenu = toolbar.getMenu().findItem(R.id.web_menu_refresh_stop);
bookmarkMenu = toolbar.getMenu().findItem(R.id.web_menu_bookmark);

Expand Down Expand Up @@ -698,7 +699,8 @@ public void onActionClick() {
else if (ActionMode.DOWNLOAD_PLUS == actionButtonMode) processDownload(false, true);
else if (ActionMode.VIEW_QUEUE == actionButtonMode) goToQueue();
else if (ActionMode.READ == actionButtonMode && currentContent != null) {
currentContent = objectBoxDAO.selectContentBySourceAndUrl(currentContent.getSite(), currentContent.getUrl(), currentContent.getCoverImageUrl());
String searchUrl = getStartSite().hasCoverBasedPageUpdates() ? currentContent.getCoverImageUrl() : "";
currentContent = objectBoxDAO.selectContentBySourceAndUrl(currentContent.getSite(), currentContent.getUrl(), searchUrl);
if (currentContent != null && (StatusContent.DOWNLOADED == currentContent.getStatus()
|| StatusContent.ERROR == currentContent.getStatus()
|| StatusContent.MIGRATED == currentContent.getStatus()))
Expand Down Expand Up @@ -844,7 +846,8 @@ int processContent(@NonNull Content content, boolean quickDownload) {
if (content.getUrl().isEmpty()) return result;

Timber.i("Content Site, URL : %s, %s", content.getSite().getCode(), content.getUrl());
Content contentDB = objectBoxDAO.selectContentBySourceAndUrl(content.getSite(), content.getUrl(), content.getCoverImageUrl());
String searchUrl = getStartSite().hasCoverBasedPageUpdates() ? content.getCoverImageUrl() : "";
Content contentDB = objectBoxDAO.selectContentBySourceAndUrl(content.getSite(), content.getUrl(), searchUrl);

boolean isInCollection = (contentDB != null && ContentHelper.isInLibrary(contentDB.getStatus()));
boolean isInQueue = (contentDB != null && ContentHelper.isInQueue(contentDB.getStatus()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

public class ImhentaiActivity extends BaseWebActivity {

private static final String DOMAIN_FILTER = "imhentai.com";
private static final String[] GALLERY_FILTER = {"//imhentai.com/gallery/"};
private static final String DOMAIN_FILTER = "imhentai.xxx";
private static final String[] GALLERY_FILTER = {"//imhentai.xxx/gallery/"};
// private static final String[] DIRTY_ELEMENTS = {".bblocktop"}; <-- fucks up the CSS when removed

Site getStartSite() {
Expand Down
Loading

0 comments on commit 159d2d0

Please sign in to comment.