1
0
Fork 0

Delete word screen improvements

* added the word count

	* all words are displayed when there is no search term

	* fixed incorrect padding and font size when the word list is long
This commit is contained in:
sspanak 2024-08-08 17:12:46 +03:00 committed by Dimo Karaivanov
parent 2eea62b26f
commit d8b791dd40
9 changed files with 101 additions and 34 deletions

View file

@ -112,8 +112,13 @@ public class WordStore {
} }
@NonNull public ArrayList<String> getSimilarCustom(Language language, String wordFilter) { @NonNull public ArrayList<String> getSimilarCustom(String wordFilter, int maxWords) {
return language != null && !(language instanceof NullLanguage) && checkOrNotify() ? readOps.getCustomWords(sqlite.getDb(), language, wordFilter) : new ArrayList<>(); return checkOrNotify() ? readOps.getCustomWords(sqlite.getDb(), wordFilter, maxWords) : new ArrayList<>();
}
public long countCustom() {
return checkOrNotify() ? readOps.countCustomWords(sqlite.getDb()) : 0;
} }

View file

@ -74,9 +74,16 @@ public class WordStoreAsync {
} }
public static void getCustomWords(ConsumerCompat<ArrayList<String>> dataHandler, Language language, String wordFilter) { public static void getCustomWords(ConsumerCompat<ArrayList<String>> dataHandler, String wordFilter, int maxWords) {
new Thread(() -> asyncHandler.post(() -> dataHandler.accept( new Thread(() -> asyncHandler.post(() -> dataHandler.accept(
getStore().getSimilarCustom(language, wordFilter))) getStore().getSimilarCustom(wordFilter, maxWords)))
).start();
}
public static void countCustomWords(ConsumerCompat<Long> dataHandler) {
new Thread(() -> asyncHandler.post(() -> dataHandler.accept(
getStore().countCustom()))
).start(); ).start();
} }

View file

@ -9,13 +9,13 @@ import androidx.annotation.NonNull;
import java.util.ArrayList; import java.util.ArrayList;
import io.github.sspanak.tt9.db.entities.NormalizationList;
import io.github.sspanak.tt9.util.Logger;
import io.github.sspanak.tt9.db.SlowQueryStats; import io.github.sspanak.tt9.db.SlowQueryStats;
import io.github.sspanak.tt9.db.entities.NormalizationList;
import io.github.sspanak.tt9.db.entities.WordList; import io.github.sspanak.tt9.db.entities.WordList;
import io.github.sspanak.tt9.db.entities.WordPositionsStringBuilder; import io.github.sspanak.tt9.db.entities.WordPositionsStringBuilder;
import io.github.sspanak.tt9.languages.EmojiLanguage; import io.github.sspanak.tt9.languages.EmojiLanguage;
import io.github.sspanak.tt9.languages.Language; import io.github.sspanak.tt9.languages.Language;
import io.github.sspanak.tt9.util.Logger;
public class ReadOps { public class ReadOps {
private final String LOG_TAG = "ReadOperations"; private final String LOG_TAG = "ReadOperations";
@ -71,18 +71,16 @@ public class ReadOps {
} }
public ArrayList<String> getCustomWords(@NonNull SQLiteDatabase db, @NonNull Language language, @NonNull String wordFilter) { public ArrayList<String> getCustomWords(@NonNull SQLiteDatabase db, @NonNull String wordFilter, int maxWords) {
ArrayList<String> words = new ArrayList<>(); ArrayList<String> words = new ArrayList<>();
String[] select = new String[]{"word"}; String[] select = new String[]{"word"};
String where = "word LIKE ? AND (langId = ? OR langId = ?)"; String where = "word LIKE ?";
String[] whereArgs = new String[] { String[] whereArgs = new String[]{wordFilter + "%"};
wordFilter + "%", String limit = maxWords > 0 ? String.valueOf(maxWords) : null;
String.valueOf(language.getId()), String orderBy = maxWords > 0 ? null : "word";
String.valueOf(new EmojiLanguage().getId())
};
try (Cursor cursor = db.query(Tables.CUSTOM_WORDS, select, where, whereArgs, null, null, "word")) { try (Cursor cursor = db.query(Tables.CUSTOM_WORDS, select, where, whereArgs, null, null, orderBy, limit)) {
while (cursor.moveToNext()) { while (cursor.moveToNext()) {
words.add(cursor.getString(0)); words.add(cursor.getString(0));
} }

View file

@ -15,12 +15,12 @@ final public class PreferencePlainText extends ScreenPreference {
public PreferencePlainText(@NonNull Context context) { super(context); } public PreferencePlainText(@NonNull Context context) { super(context); }
@Override @Override
protected int getDefaultLayout() { public int getDefaultLayout() {
return R.layout.pref_plain_text; return R.layout.pref_plain_text;
} }
@Override @Override
protected int getLargeLayout() { public int getLargeLayout() {
return R.layout.pref_plain_text_large; return R.layout.pref_plain_text_large;
} }
} }

View file

@ -8,14 +8,19 @@ import java.util.ArrayList;
import io.github.sspanak.tt9.R; import io.github.sspanak.tt9.R;
import io.github.sspanak.tt9.preferences.custom.PreferencePlainText; import io.github.sspanak.tt9.preferences.custom.PreferencePlainText;
import io.github.sspanak.tt9.preferences.settings.SettingsStore;
class DeletableWordsList { class DeletableWordsList {
static final String NAME = "delete_words_list"; static final String NAME = "delete_words_list";
private final PreferenceCategory item; private final PreferenceCategory item;
private final boolean largeFont;
private int currentWords = 0;
private long totalWords = 0;
DeletableWordsList(Preference preference) { DeletableWordsList(SettingsStore settings, Preference preference) {
item = preference instanceof PreferenceCategory ? (PreferenceCategory) preference : null; item = preference instanceof PreferenceCategory ? (PreferenceCategory) preference : null;
largeFont = settings.getSettingsFontSize() == SettingsStore.FONT_SIZE_LARGE;
} }
private void clear() { private void clear() {
@ -24,10 +29,19 @@ class DeletableWordsList {
} }
} }
void delete(PreferenceDeletableWord wordItem) {
if (item != null) {
item.removePreference(wordItem);
setTotalWords(totalWords - 1);
}
}
private void addWord(String word) { private void addWord(String word) {
if (item != null) { if (item != null) {
PreferenceDeletableWord pref = new PreferenceDeletableWord(item.getContext()); PreferenceDeletableWord pref = new PreferenceDeletableWord(item.getContext());
pref.setParent(this);
pref.setWord(word); pref.setWord(word);
pref.setLayoutResource(largeFont ? pref.getLargeLayout() : pref.getDefaultLayout());
item.addPreference(pref); item.addPreference(pref);
} }
} }
@ -40,18 +54,35 @@ class DeletableWordsList {
void addNoResult(boolean noSearchTerm) { void addNoResult(boolean noSearchTerm) {
if (item != null) { if (item != null) {
Preference pref = new PreferencePlainText(item.getContext()); PreferencePlainText pref = new PreferencePlainText(item.getContext());
pref.setSummary(noSearchTerm ? "--" : item.getContext().getString(R.string.search_results_void)); pref.setSummary(noSearchTerm ? "--" : item.getContext().getString(R.string.search_results_void));
pref.setLayoutResource(largeFont ? pref.getLargeLayout() : pref.getDefaultLayout());
item.addPreference(pref); item.addPreference(pref);
} }
} }
void setResult(@NonNull String searchTerm, ArrayList<String> words) { void setResult(@NonNull String searchTerm, ArrayList<String> words) {
clear(); clear();
if (words == null || words.isEmpty()) { if (words == null || words.isEmpty()) {
addNoResult(searchTerm.isEmpty()); addNoResult(searchTerm.isEmpty());
} else { } else {
addWords(words); addWords(words);
} }
currentWords = words == null ? 0 : words.size();
setResultCount();
}
void setTotalWords(long total) {
totalWords = total > 0 ? total : 0;
setResultCount();
}
private void setResultCount() {
if (item != null) {
String results = " (" + currentWords + "/" + totalWords + ")";
item.setTitle(item.getContext().getString(R.string.search_results) + results);
}
} }
} }

View file

@ -19,12 +19,15 @@ public class DeleteWordsScreen extends BaseScreenFragment {
} }
private void createPage() { private void createPage() {
DeletableWordsList searchResultsList = new DeletableWordsList(findPreference(DeletableWordsList.NAME)); DeletableWordsList searchResultsList = new DeletableWordsList(activity.getSettings(), findPreference(DeletableWordsList.NAME));
searchResultsList.setTotalWords(0);
searchResultsList.setResult("", null); searchResultsList.setResult("", null);
PreferenceSearchWords searchWords = findPreference(PreferenceSearchWords.NAME); PreferenceSearchWords searchWords = findPreference(PreferenceSearchWords.NAME);
if (searchWords != null) { if (searchWords != null) {
searchWords.setOnWordsHandler((words) -> searchResultsList.setResult(searchWords.getLastSearchTerm(), words)); searchWords.setOnWordsHandler((words) -> searchResultsList.setResult(searchWords.getLastSearchTerm(), words));
searchWords.setOnTotalWordsHandler(searchResultsList::setTotalWords);
searchWords.search("");
} }
resetFontSize(false); resetFontSize(false);

View file

@ -16,6 +16,7 @@ import io.github.sspanak.tt9.preferences.settings.SettingsStore;
import io.github.sspanak.tt9.ui.UI; import io.github.sspanak.tt9.ui.UI;
public class PreferenceDeletableWord extends ScreenPreference { public class PreferenceDeletableWord extends ScreenPreference {
private DeletableWordsList parent;
private String word; private String word;
@ -29,7 +30,14 @@ public class PreferenceDeletableWord extends ScreenPreference {
@Override protected int getLargeLayout() { return R.layout.pref_deletable_word_large; } @Override protected int getLargeLayout() { return R.layout.pref_deletable_word_large; }
public void setWord(String word) { void setParent(DeletableWordsList parent) {
if (parent != null) {
this.parent = parent;
}
}
void setWord(String word) {
this.word = word; this.word = word;
setTitle(word); setTitle(word);
} }
@ -62,14 +70,18 @@ public class PreferenceDeletableWord extends ScreenPreference {
} }
private void onWordDeleted() { private void deleteSelf() {
if (getParent() instanceof PreferenceCategory) { if (parent != null) {
parent.delete(this);
} else if (getParent() instanceof PreferenceCategory) {
getParent().removePreference(this); getParent().removePreference(this);
} }
Activity activity = (Activity) getContext(); UI.toastFromAsync(getContext(), getContext().getString(R.string.delete_words_deleted_x, word));
activity.runOnUiThread( }
() -> UI.toastFromAsync(getContext(), activity.getString(R.string.delete_words_deleted_x, word))
);
private void onWordDeleted() {
((Activity) getContext()).runOnUiThread(this::deleteSelf);
} }
} }

View file

@ -9,8 +9,6 @@ import androidx.annotation.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import io.github.sspanak.tt9.db.WordStoreAsync; import io.github.sspanak.tt9.db.WordStoreAsync;
import io.github.sspanak.tt9.languages.Language;
import io.github.sspanak.tt9.languages.LanguageCollection;
import io.github.sspanak.tt9.preferences.items.ItemTextInput; import io.github.sspanak.tt9.preferences.items.ItemTextInput;
import io.github.sspanak.tt9.preferences.settings.SettingsStore; import io.github.sspanak.tt9.preferences.settings.SettingsStore;
import io.github.sspanak.tt9.util.ConsumerCompat; import io.github.sspanak.tt9.util.ConsumerCompat;
@ -21,8 +19,11 @@ public class PreferenceSearchWords extends ItemTextInput {
private static final String LOG_TAG = PreferenceSearchWords.class.getSimpleName(); private static final String LOG_TAG = PreferenceSearchWords.class.getSimpleName();
private ConsumerCompat<ArrayList<String>> onWords; private ConsumerCompat<ArrayList<String>> onWords;
private ConsumerCompat<Long> onTotalWords;
private SettingsStore settings; private SettingsStore settings;
@NonNull private String lastSearchTerm = ""; @NonNull private String lastSearchTerm = "";
private long totalWords = 0;
public PreferenceSearchWords(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); } public PreferenceSearchWords(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); }
@ -39,24 +40,29 @@ public class PreferenceSearchWords extends ItemTextInput {
} }
@Override
protected void onChange(String word) {
search(word);
}
@NonNull @NonNull
public String getLastSearchTerm() { public String getLastSearchTerm() {
return lastSearchTerm; return lastSearchTerm;
} }
@Override void search(String word) {
protected void onChange(String word) {
lastSearchTerm = word == null || word.trim().isEmpty() ? "" : word.trim(); lastSearchTerm = word == null || word.trim().isEmpty() ? "" : word.trim();
if (onWords == null) { if (onWords == null) {
Logger.w(LOG_TAG, "No handler set for the word change event."); Logger.w(LOG_TAG, "No handler set for the word change event.");
} else if (lastSearchTerm.isEmpty()) { } else if (lastSearchTerm.isEmpty()) {
Logger.d(LOG_TAG, "Not searching for an empty word."); WordStoreAsync.countCustomWords(onTotalWords);
onWords.accept(null); WordStoreAsync.getCustomWords(onWords, lastSearchTerm, SettingsStore.CUSTOM_WORDS_SEARCH_RESULTS_MAX);
} else { } else {
Language currentLanguage = LanguageCollection.getLanguage(getContext(), getSettings().getInputLanguage()); WordStoreAsync.countCustomWords(onTotalWords);
WordStoreAsync.getCustomWords(onWords, currentLanguage, lastSearchTerm); WordStoreAsync.getCustomWords(onWords, lastSearchTerm, -1);
} }
} }
@ -64,4 +70,8 @@ public class PreferenceSearchWords extends ItemTextInput {
void setOnWordsHandler(ConsumerCompat<ArrayList<String>> onWords) { void setOnWordsHandler(ConsumerCompat<ArrayList<String>> onWords) {
this.onWords = onWords; this.onWords = onWords;
} }
void setOnTotalWordsHandler(ConsumerCompat<Long> onTotalWords) {
this.onTotalWords = onTotalWords;
}
} }

View file

@ -10,6 +10,7 @@ public class SettingsStore extends SettingsUI {
public final static int CLIPBOARD_PREVIEW_LENGTH = 20; public final static int CLIPBOARD_PREVIEW_LENGTH = 20;
public final static int CUSTOM_WORDS_IMPORT_MAX_LINES = 250; public final static int CUSTOM_WORDS_IMPORT_MAX_LINES = 250;
public final static int CUSTOM_WORDS_MAX = 1000; public final static int CUSTOM_WORDS_MAX = 1000;
public final static int CUSTOM_WORDS_SEARCH_RESULTS_MAX = 50;
public final static int DICTIONARY_AUTO_LOAD_COOLDOWN_TIME = 1200000; // 20 minutes in ms public final static int DICTIONARY_AUTO_LOAD_COOLDOWN_TIME = 1200000; // 20 minutes in ms
public final static int DICTIONARY_DOWNLOAD_CONNECTION_TIMEOUT = 10000; // ms public final static int DICTIONARY_DOWNLOAD_CONNECTION_TIMEOUT = 10000; // ms
public final static int DICTIONARY_DOWNLOAD_READ_TIMEOUT = 10000; // ms public final static int DICTIONARY_DOWNLOAD_READ_TIMEOUT = 10000; // ms