Skip to content

Commit

Permalink
Dynamic groups : Minor fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
RobbWatershed committed Apr 1, 2023
1 parent bb405a0 commit 07330a3
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 86 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@
import me.devsaki.hentoid.util.LocaleHelper;
import me.devsaki.hentoid.util.Preferences;
import me.devsaki.hentoid.util.SearchHelper;
import me.devsaki.hentoid.util.ToastHelper;
import me.devsaki.hentoid.util.TooltipHelper;
import me.devsaki.hentoid.util.file.FileHelper;
import me.devsaki.hentoid.util.file.PermissionHelper;
Expand Down Expand Up @@ -423,13 +424,7 @@ private void initUI() {

// Save search
searchSaveButton = findViewById(R.id.search_save_btn);
searchSaveButton.setOnClickListener(v -> InputDialog.invokeInputDialog(
this,
R.string.group_new_name_dynamic,
"TODO",
s -> viewModel.saveSearchToDynamicGroup(getAdvSearchCriteria(), s),
null
));
searchSaveButton.setOnClickListener(v -> saveSearchAsGroup());

// Clear search
searchClearButton = findViewById(R.id.search_clear_btn);
Expand Down Expand Up @@ -504,7 +499,7 @@ private void initToolbar() {
searchMenu.setOnActionExpandListener(new MenuItem.OnActionExpandListener() {
@Override
public boolean onMenuItemActionExpand(MenuItem item) {
showSearchSubBar(true, null, !preventShowSearchHistoryNextExpand);
showSearchSubBar(true, null, null, !preventShowSearchHistoryNextExpand);
preventShowSearchHistoryNextExpand = false;
invalidateNextQueryTextChange = true;

Expand Down Expand Up @@ -551,7 +546,6 @@ public boolean onQueryTextSubmit(String s) {
setQuery(s.trim());
signalCurrentFragment(EV_SEARCH, getQuery());
actionSearchView.clearFocus();

return true;
}

Expand All @@ -562,13 +556,15 @@ public boolean onQueryTextChange(String s) {
} else if (s.isEmpty()) {
searchClearDebouncer.submit(1);
} else searchClearDebouncer.clear();

return true;
}
});
}

public void initFragmentToolbars(@NonNull final SelectExtension<?> selectExtension, @NonNull final Toolbar.OnMenuItemClickListener toolbarOnItemClicked, @NonNull final Toolbar.OnMenuItemClickListener selectionToolbarOnItemClicked) {
public void initFragmentToolbars(
@NonNull final SelectExtension<?> selectExtension,
@NonNull final Toolbar.OnMenuItemClickListener toolbarOnItemClicked,
@NonNull final Toolbar.OnMenuItemClickListener selectionToolbarOnItemClicked) {
toolbar.setOnMenuItemClickListener(toolbarOnItemClicked);
if (selectionToolbar != null) {
selectionToolbar.setOnMenuItemClickListener(selectionToolbarOnItemClicked);
Expand All @@ -587,7 +583,7 @@ public void updateSearchBarOnResults(boolean nonEmptyResults) {
} else if (nonEmptyResults) {
collapseSearchMenu();
}
showSearchSubBar(!isGroupDisplayed(), true, false);
showSearchSubBar(!isGroupDisplayed(), true, !getAdvSearchCriteria().isEmpty(), false);
} else {
collapseSearchMenu();
if (actionSearchView.getQuery().length() > 0) actionSearchView.setQuery("", false);
Expand Down Expand Up @@ -622,13 +618,13 @@ public boolean toolbarOnItemClicked(@NonNull MenuItem menuItem) {
return true;
}

private void showSearchSubBar(boolean showAdvancedSearch, Boolean showClear, boolean showSearchHistory) {
private void showSearchSubBar(boolean showAdvancedSearch, Boolean showClear, Boolean showSaveSearch, boolean showSearchHistory) {
searchSubBar.setVisibility(View.VISIBLE);
advancedSearchButton.setVisibility(showAdvancedSearch && !isGroupDisplayed() ? View.VISIBLE : View.GONE);
if (showClear != null) {
if (showClear != null)
searchClearButton.setVisibility(showClear ? View.VISIBLE : View.GONE);
searchSaveButton.setVisibility(showClear && !isGroupDisplayed() ? View.VISIBLE : View.GONE);
}
if (showSaveSearch != null)
searchSaveButton.setVisibility(showSaveSearch && !isGroupDisplayed() ? View.VISIBLE : View.GONE);

if (showSearchHistory && !searchRecords.isEmpty()) {
PowerMenu.Builder powerMenuBuilder = new PowerMenu.Builder(this).setAnimation(MenuAnimation.DROP_DOWN).setLifecycleOwner(this).setTextColor(ContextCompat.getColor(this, R.color.white_opacity_87)).setTextTypeface(Typeface.DEFAULT).setShowBackground(false).setWidth((int) getResources().getDimension(R.dimen.dialog_width)).setMenuColor(ContextCompat.getColor(this, R.color.medium_gray)).setTextSize(Helper.dimensAsDp(this, R.dimen.text_subtitle_2)).setAutoDismiss(true);
Expand Down Expand Up @@ -1103,6 +1099,22 @@ private void enableFragment(int fragmentIndex) {
}
}

private void saveSearchAsGroup() {
SearchHelper.AdvancedSearchCriteria criteria = getAdvSearchCriteria();
InputDialog.invokeInputDialog(
this,
R.string.group_new_name_dynamic,
criteria.toString(this),
s -> viewModel.newGroup(Grouping.DYNAMIC, s, SearchActivityBundle.Companion.buildSearchUri(criteria, null).toString(), this::onNewSearchGroupNameExists),
null
);
}

private void onNewSearchGroupNameExists() {
ToastHelper.toast(R.string.group_name_exists);
saveSearchAsGroup();
}

/**
* ============================== SUBCLASS
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ private void confirmEdit() {
}

private void newGroupPrompt() {
InputDialog.invokeInputDialog(requireActivity(), R.string.new_group_name, groupName -> viewModel.newGroup(Preferences.getGroupingDisplay(), groupName, this::onNewGroupNameExists));
InputDialog.invokeInputDialog(requireActivity(), R.string.new_group_name, groupName -> viewModel.newGroup(Preferences.getGroupingDisplay(), groupName, null, this::onNewGroupNameExists));
}

private void onNewGroupNameExists() {
Expand Down
57 changes: 55 additions & 2 deletions app/src/main/java/me/devsaki/hentoid/util/SearchHelper.kt
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
package me.devsaki.hentoid.util

import android.content.Context
import android.content.res.Resources
import android.text.TextUtils
import androidx.annotation.StringRes
import com.annimon.stream.Stream
import me.devsaki.hentoid.R
import me.devsaki.hentoid.database.domains.Attribute

class SearchHelper {

data class AttributeQueryResult(
val attributes: List<Attribute>,
val totalSelectedAttributes: Long
val attributes: List<Attribute>, val totalSelectedAttributes: Long
)

data class AdvancedSearchCriteria(
Expand All @@ -25,5 +30,53 @@ class SearchHelper {
fun isEmpty(): Boolean {
return (query.isEmpty() && attributes.isEmpty() && ContentHelper.Location.ANY == location && ContentHelper.Type.ANY == contentType)
}

@StringRes
private fun formatLocation(@ContentHelper.Location value: Int): Int {
return when (value) {
ContentHelper.Location.PRIMARY -> R.string.refresh_location_internal
ContentHelper.Location.PRIMARY_1 -> R.string.refresh_location_internal_1
ContentHelper.Location.PRIMARY_2 -> R.string.refresh_location_internal_2
ContentHelper.Location.EXTERNAL -> R.string.refresh_location_external
ContentHelper.Location.ANY -> R.string.search_location_entries_1
else -> R.string.search_location_entries_1
}
}

@StringRes
private fun formatContentType(@ContentHelper.Type value: Int): Int {
return when (value) {
ContentHelper.Type.FOLDER -> R.string.search_type_entries_2
ContentHelper.Type.STREAMED -> R.string.search_type_entries_3
ContentHelper.Type.ARCHIVE -> R.string.search_type_entries_4
ContentHelper.Type.PLACEHOLDER -> R.string.search_type_entries_5
ContentHelper.Type.ANY -> R.string.search_type_entries_1
else -> R.string.search_type_entries_1
}
}

private fun formatAttribute(a: Attribute, res: Resources): String {
return String.format(
"%s%s:%s",
if (a.isExcluded) "[x]" else "",
res.getString(a.type.displayName),
a.displayName
)
}

fun toString(context: Context): String {
val labelElts: MutableList<String?> = Stream.of(attributes).map { a: Attribute ->
formatAttribute(a, context.resources)
}.toList()
if (location != ContentHelper.Location.ANY) labelElts.add(
"loc:" + context.resources.getString(formatLocation(location)).lowercase()
)
if (contentType != ContentHelper.Type.ANY) labelElts.add(
"type:" + context.resources.getString(formatContentType(contentType)).lowercase()
)
var label = TextUtils.join("|", labelElts)
if (label.length > 50) label = label.substring(0, 50) + ""
return label
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,11 @@
import static me.devsaki.hentoid.util.GroupHelper.moveContentToCustomGroup;

import android.app.Application;
import android.content.res.Resources;
import android.net.Uri;
import android.os.Bundle;
import android.text.TextUtils;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.documentfile.provider.DocumentFile;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
Expand Down Expand Up @@ -271,61 +268,11 @@ public void searchContent(@NonNull String query, @NonNull SearchHelper.AdvancedS
contentSearchManager.setContentType(metadata.getContentType());
newContentSearch.setValue(true);

if (!metadata.isEmpty()) {
List<String> labelElts = Stream.of(metadata.getAttributes()).map(a -> formatAttribute(a, getApplication().getResources())).toList();
if (metadata.getLocation() != ContentHelper.Location.ANY)
labelElts.add("loc:" + getApplication().getResources().getString(formatLocation(metadata.getLocation())).toLowerCase());
if (metadata.getContentType() != ContentHelper.Type.ANY)
labelElts.add("type:" + getApplication().getResources().getString(formatContentType(metadata.getContentType())).toLowerCase());
String label = TextUtils.join("|", labelElts);
if (label.length() > 50) label = label.substring(0, 50) + "…";
dao.insertSearchRecord(SearchRecord.fromContentAdvancedSearch(searchUri, label), 10);
}
if (!metadata.isEmpty())
dao.insertSearchRecord(SearchRecord.fromContentAdvancedSearch(searchUri, metadata.toString(getApplication())), 10);
doSearchContent();
}

private @StringRes
int formatLocation(@ContentHelper.Location int value) {
switch (value) {
case ContentHelper.Location.PRIMARY:
return R.string.refresh_location_internal;
case ContentHelper.Location.PRIMARY_1:
return R.string.refresh_location_internal_1;
case ContentHelper.Location.PRIMARY_2:
return R.string.refresh_location_internal_2;
case ContentHelper.Location.EXTERNAL:
return R.string.refresh_location_external;
case ContentHelper.Location.ANY:
default:
return R.string.search_location_entries_1;
}
}

private @StringRes
int formatContentType(@ContentHelper.Type int value) {
switch (value) {
case ContentHelper.Type.FOLDER:
return R.string.search_type_entries_2;
case ContentHelper.Type.STREAMED:
return R.string.search_type_entries_3;
case ContentHelper.Type.ARCHIVE:
return R.string.search_type_entries_4;
case ContentHelper.Type.PLACEHOLDER:
return R.string.search_type_entries_5;
case ContentHelper.Type.ANY:
default:
return R.string.search_type_entries_1;
}
}

private String formatAttribute(@NonNull Attribute a, @NonNull Resources res) {
return String.format("%s%s:%s",
a.isExcluded() ? "[x]" : "",
res.getString(a.getType().getDisplayName()),
a.getDisplayName()
);
}

public void clearContent() {
if (currentSource != null) {
libraryPaged.removeSource(currentSource);
Expand Down Expand Up @@ -979,18 +926,20 @@ public List<Content> getGroupContents(@NonNull Group group) {
return dao.selectContent(Helper.getPrimitiveArrayFromList(group.getContentIds()));
}

public void newGroup(@NonNull final Grouping grouping, @NonNull final String newGroupName,
public void newGroup(@NonNull final Grouping grouping,
@NonNull final String newGroupName,
@Nullable final String searchUri,
@NonNull final Runnable onNameExists) {
// Check if the group already exists
List<Group> localGroups = getGroups().getValue();
if (null == localGroups) return;

List<Group> groupMatchingName = Stream.of(localGroups).filter(g -> g.name.equalsIgnoreCase(newGroupName)).toList();
List<Group> groupingGroups = dao.selectGroups(grouping.getId());
List<Group> groupMatchingName = Stream.of(groupingGroups).filter(g -> g.name.equalsIgnoreCase(newGroupName)).toList();
if (!groupMatchingName.isEmpty()) { // Existing group with the same name
onNameExists.run();
} else {
Group newGroup = new Group(grouping, newGroupName, -1);
if (searchUri != null && !searchUri.isEmpty()) newGroup.searchUri = searchUri;
compositeDisposable.add(
Completable.fromRunnable(() -> dao.insertGroup(new Group(grouping, newGroupName, -1)))
Completable.fromRunnable(() -> dao.insertGroup(newGroup))
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.io())
.doOnComplete(() -> {
Expand Down Expand Up @@ -1361,10 +1310,4 @@ private Content createContentFromChapter(@NonNull Content content, @NonNull Chap
public void clearSearchHistory() {
dao.deleteAllSearchRecords();
}

public void saveSearchToDynamicGroup(SearchHelper.AdvancedSearchCriteria criteria, String groupName) {
Group g = new Group(Grouping.DYNAMIC, groupName, -1);
g.searchUri = SearchActivityBundle.Companion.buildSearchUri(criteria, null).toString();
dao.insertGroup(g);
}
}

0 comments on commit 07330a3

Please sign in to comment.