New settings screen stabilization
* Fixed crashes, caused by using the incorrect Android Context * Default keys are properly set the very first time Settings screen is opened * Dictionary loading status is now displayed on the Settings screen * Dictionary loading time is now displayed after operation is completed
This commit is contained in:
parent
b550d5d5dd
commit
a6fa129984
14 changed files with 171 additions and 89 deletions
|
|
@ -1,5 +1,6 @@
|
|||
package io.github.sspanak.tt9.db;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.sqlite.SQLiteConstraintException;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
|
|
@ -43,18 +44,23 @@ public class DictionaryDb {
|
|||
};
|
||||
|
||||
|
||||
private static synchronized void createInstance() {
|
||||
dbInstance = Room.databaseBuilder(TraditionalT9.getMainContext(), T9RoomDb.class, "t9dict.db")
|
||||
public static synchronized void init(Context context) {
|
||||
if (dbInstance == null) {
|
||||
context = context == null ? TraditionalT9.getMainContext() : context;
|
||||
dbInstance = Room.databaseBuilder(context, T9RoomDb.class, "t9dict.db")
|
||||
.addCallback(TRIGGER_CALLBACK)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static synchronized void init() {
|
||||
init(null);
|
||||
}
|
||||
|
||||
|
||||
private static T9RoomDb getInstance() {
|
||||
if (dbInstance == null) {
|
||||
createInstance();
|
||||
}
|
||||
|
||||
init();
|
||||
return dbInstance;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,8 +26,10 @@ public class DictionaryLoader {
|
|||
private final SettingsStore settings;
|
||||
|
||||
private final Pattern containsPunctuation = Pattern.compile("\\p{Punct}(?<!-)");
|
||||
private Handler statusHandler = null;
|
||||
private Thread loadThread;
|
||||
|
||||
private long importStartTime = 0;
|
||||
private int currentFile = 0;
|
||||
private long lastProgressUpdate = 0;
|
||||
|
||||
|
|
@ -49,7 +51,17 @@ public class DictionaryLoader {
|
|||
}
|
||||
|
||||
|
||||
public void load(Handler handler, ArrayList<Language> languages) throws DictionaryImportAlreadyRunningException {
|
||||
public void setStatusHandler(Handler handler) {
|
||||
statusHandler = handler;
|
||||
}
|
||||
|
||||
|
||||
private long getImportTime() {
|
||||
return System.currentTimeMillis() - importStartTime;
|
||||
}
|
||||
|
||||
|
||||
public void load(ArrayList<Language> languages) throws DictionaryImportAlreadyRunningException {
|
||||
if (isRunning()) {
|
||||
throw new DictionaryImportAlreadyRunningException();
|
||||
}
|
||||
|
|
@ -58,12 +70,13 @@ public class DictionaryLoader {
|
|||
@Override
|
||||
public void run() {
|
||||
currentFile = 0;
|
||||
importStartTime = System.currentTimeMillis();
|
||||
// SQLite does not support parallel queries, so let's import them one by one
|
||||
for (Language lang : languages) {
|
||||
if (isInterrupted()) {
|
||||
break;
|
||||
}
|
||||
importAll(handler, lang);
|
||||
importAll(lang);
|
||||
currentFile++;
|
||||
}
|
||||
}
|
||||
|
|
@ -83,12 +96,12 @@ public class DictionaryLoader {
|
|||
}
|
||||
|
||||
|
||||
private void importAll(Handler handler, Language language) {
|
||||
private void importAll(Language language) {
|
||||
final String logTag = "tt9.DictionaryLoader.importAll";
|
||||
|
||||
if (language == null) {
|
||||
Logger.e(logTag, "Failed loading a dictionary for NULL language.");
|
||||
sendError(handler, InvalidLanguageException.class.getSimpleName(), -1);
|
||||
sendError(InvalidLanguageException.class.getSimpleName(), -1);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -102,7 +115,7 @@ public class DictionaryLoader {
|
|||
|
||||
try {
|
||||
start = System.currentTimeMillis();
|
||||
importWords(handler, language);
|
||||
importWords(language);
|
||||
Logger.i(
|
||||
logTag,
|
||||
"Dictionary: '" + language.getDictionaryFile() + "'" +
|
||||
|
|
@ -117,7 +130,7 @@ public class DictionaryLoader {
|
|||
);
|
||||
} catch (DictionaryImportException e) {
|
||||
stop();
|
||||
sendImportError(handler, DictionaryImportException.class.getSimpleName(), language.getId(), e.line, e.word);
|
||||
sendImportError(DictionaryImportException.class.getSimpleName(), language.getId(), e.line, e.word);
|
||||
|
||||
Logger.e(
|
||||
logTag,
|
||||
|
|
@ -129,7 +142,7 @@ public class DictionaryLoader {
|
|||
);
|
||||
} catch (Exception e) {
|
||||
stop();
|
||||
sendError(handler, e.getClass().getSimpleName(), language.getId());
|
||||
sendError(e.getClass().getSimpleName(), language.getId());
|
||||
|
||||
Logger.e(
|
||||
logTag,
|
||||
|
|
@ -168,12 +181,12 @@ public class DictionaryLoader {
|
|||
}
|
||||
|
||||
|
||||
private void importWords(Handler handler, Language language) throws Exception {
|
||||
importWords(handler, language, language.getDictionaryFile());
|
||||
private void importWords(Language language) throws Exception {
|
||||
importWords(language, language.getDictionaryFile());
|
||||
}
|
||||
|
||||
|
||||
private void importWords(Handler handler, Language language, String dictionaryFile) throws Exception {
|
||||
private void importWords(Language language, String dictionaryFile) throws Exception {
|
||||
long totalWords = countWords(dictionaryFile);
|
||||
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(assets.open(dictionaryFile), StandardCharsets.UTF_8));
|
||||
|
|
@ -181,17 +194,21 @@ public class DictionaryLoader {
|
|||
ArrayList<Word> dbWords = new ArrayList<>();
|
||||
long line = 0;
|
||||
|
||||
sendProgressMessage(handler, language, 0, 0);
|
||||
sendProgressMessage(language, 0, 0);
|
||||
|
||||
for (String word; (word = br.readLine()) != null; line++) {
|
||||
if (loadThread.isInterrupted()) {
|
||||
br.close();
|
||||
sendProgressMessage(handler, language, -1, 0);
|
||||
sendProgressMessage(language, -1, 0);
|
||||
throw new DictionaryImportAbortedException();
|
||||
}
|
||||
|
||||
validateWord(language, word, line);
|
||||
try {
|
||||
dbWords.add(stringToWord(language, word));
|
||||
} catch (InvalidLanguageCharactersException e) {
|
||||
throw new DictionaryImportException(dictionaryFile, word, line);
|
||||
}
|
||||
|
||||
if (line % settings.getDictionaryImportWordChunkSize() == 0) {
|
||||
DictionaryDb.insertWordsSync(dbWords);
|
||||
|
|
@ -200,12 +217,12 @@ public class DictionaryLoader {
|
|||
|
||||
if (totalWords > 0) {
|
||||
int progress = (int) Math.floor(100.0 * line / totalWords);
|
||||
sendProgressMessage(handler, language, progress, settings.getDictionaryImportProgressUpdateInterval());
|
||||
sendProgressMessage(language, progress, settings.getDictionaryImportProgressUpdateInterval());
|
||||
}
|
||||
}
|
||||
|
||||
br.close();
|
||||
sendProgressMessage(handler, language, 100, 0);
|
||||
sendProgressMessage(language, 100, 0);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -242,7 +259,14 @@ public class DictionaryLoader {
|
|||
}
|
||||
|
||||
|
||||
private void sendProgressMessage(Handler handler, Language language, int progress, int progressUpdateInterval) {
|
||||
private void sendProgressMessage(Language language, int progress, int progressUpdateInterval) {
|
||||
if (statusHandler == null) {
|
||||
Logger.w(
|
||||
"tt9/DictionaryLoader.sendProgressMessage",
|
||||
"Cannot send progress without a status Handler. Ignoring message.");
|
||||
return;
|
||||
}
|
||||
|
||||
long now = System.currentTimeMillis();
|
||||
if (now - lastProgressUpdate < progressUpdateInterval) {
|
||||
return;
|
||||
|
|
@ -252,32 +276,43 @@ public class DictionaryLoader {
|
|||
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putInt("languageId", language.getId());
|
||||
bundle.putLong("time", getImportTime());
|
||||
bundle.putInt("progress", progress);
|
||||
bundle.putInt("currentFile", currentFile);
|
||||
Message msg = new Message();
|
||||
msg.setData(bundle);
|
||||
handler.sendMessage(msg);
|
||||
statusHandler.sendMessage(msg);
|
||||
}
|
||||
|
||||
|
||||
private void sendError(Handler handler, String message, int langId) {
|
||||
private void sendError(String message, int langId) {
|
||||
if (statusHandler == null) {
|
||||
Logger.w("tt9/DictionaryLoader.sendError", "Cannot send an error without a status Handler. Ignoring message.");
|
||||
return;
|
||||
}
|
||||
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString("error", message);
|
||||
bundle.putInt("languageId", langId);
|
||||
Message msg = new Message();
|
||||
msg.setData(bundle);
|
||||
handler.sendMessage(msg);
|
||||
statusHandler.sendMessage(msg);
|
||||
}
|
||||
|
||||
|
||||
private void sendImportError(Handler handler, String message, int langId, long fileLine, String word) {
|
||||
private void sendImportError(String message, int langId, long fileLine, String word) {
|
||||
if (statusHandler == null) {
|
||||
Logger.w("tt9/DictionaryLoader.sendError", "Cannot send an import error without a status Handler. Ignoring message.");
|
||||
return;
|
||||
}
|
||||
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString("error", message);
|
||||
bundle.putLong("fileLine", fileLine);
|
||||
bundle.putLong("fileLine", fileLine + 1);
|
||||
bundle.putInt("languageId", langId);
|
||||
bundle.putString("word", word);
|
||||
Message msg = new Message();
|
||||
msg.setData(bundle);
|
||||
handler.sendMessage(msg);
|
||||
statusHandler.sendMessage(msg);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,7 +48,10 @@ public class InputModeValidator {
|
|||
return inputMode;
|
||||
}
|
||||
|
||||
InputMode newMode = InputMode.getInstance(allowedModes.size() > 0 ? allowedModes.get(0) : InputMode.MODE_123);
|
||||
InputMode newMode = InputMode.getInstance(
|
||||
settings,
|
||||
allowedModes.size() > 0 ? allowedModes.get(0) : InputMode.MODE_123
|
||||
);
|
||||
settings.saveInputMode(newMode);
|
||||
|
||||
if (newMode.getId() != inputMode.getId()) {
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
|
||||
import io.github.sspanak.tt9.Logger;
|
||||
import io.github.sspanak.tt9.db.DictionaryDb;
|
||||
import io.github.sspanak.tt9.ime.modes.InputMode;
|
||||
import io.github.sspanak.tt9.languages.Language;
|
||||
import io.github.sspanak.tt9.languages.LanguageCollection;
|
||||
|
|
@ -43,7 +44,7 @@ public class TraditionalT9 extends KeyPadHandler {
|
|||
private void loadSettings() {
|
||||
mLanguage = LanguageCollection.getLanguage(settings.getInputLanguage());
|
||||
mEnabledLanguages = settings.getEnabledLanguageIds();
|
||||
mInputMode = InputMode.getInstance(settings.getInputMode());
|
||||
mInputMode = InputMode.getInstance(settings, settings.getInputMode());
|
||||
mInputMode.setTextCase(settings.getTextCase());
|
||||
}
|
||||
|
||||
|
|
@ -64,12 +65,14 @@ public class TraditionalT9 extends KeyPadHandler {
|
|||
protected void onInit() {
|
||||
self = this;
|
||||
|
||||
DictionaryDb.init(this);
|
||||
|
||||
if (softKeyHandler == null) {
|
||||
softKeyHandler = new SoftKeyHandler(this);
|
||||
}
|
||||
|
||||
if (mSuggestionView == null) {
|
||||
mSuggestionView = new SuggestionsView(softKeyHandler.getView());
|
||||
mSuggestionView = new SuggestionsView(settings, softKeyHandler.getView());
|
||||
}
|
||||
|
||||
loadSettings();
|
||||
|
|
@ -446,7 +449,7 @@ public class TraditionalT9 extends KeyPadHandler {
|
|||
private void nextInputMode() {
|
||||
if (mEditing == EDITING_STRICT_NUMERIC || mEditing == EDITING_DIALER) {
|
||||
clearSuggestions();
|
||||
mInputMode = InputMode.getInstance(InputMode.MODE_123);
|
||||
mInputMode = InputMode.getInstance(settings, InputMode.MODE_123);
|
||||
}
|
||||
// when typing a word or viewing scrolling the suggestions, only change the case
|
||||
else if (!isSuggestionViewHidden()) {
|
||||
|
|
@ -459,7 +462,7 @@ public class TraditionalT9 extends KeyPadHandler {
|
|||
mInputMode.setTextCase(InputMode.CASE_UPPER);
|
||||
} else {
|
||||
int modeIndex = (allowedInputModes.indexOf(mInputMode.getId()) + 1) % allowedInputModes.size();
|
||||
mInputMode = InputMode.getInstance(allowedInputModes.get(modeIndex));
|
||||
mInputMode = InputMode.getInstance(settings, allowedInputModes.get(modeIndex));
|
||||
|
||||
mInputMode.defaultTextCase();
|
||||
}
|
||||
|
|
@ -509,11 +512,11 @@ public class TraditionalT9 extends KeyPadHandler {
|
|||
|
||||
int lastInputModeId = settings.getInputMode();
|
||||
if (allowedInputModes.contains(lastInputModeId)) {
|
||||
mInputMode = InputMode.getInstance(lastInputModeId);
|
||||
mInputMode = InputMode.getInstance(settings, lastInputModeId);
|
||||
} else if (allowedInputModes.contains(InputMode.MODE_ABC)) {
|
||||
mInputMode = InputMode.getInstance(InputMode.MODE_ABC);
|
||||
mInputMode = InputMode.getInstance(settings, InputMode.MODE_ABC);
|
||||
} else {
|
||||
mInputMode = InputMode.getInstance(allowedInputModes.get(0));
|
||||
mInputMode = InputMode.getInstance(settings, allowedInputModes.get(0));
|
||||
}
|
||||
|
||||
if (InputFieldHelper.isDialerField(inputField)) {
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import java.util.ArrayList;
|
|||
|
||||
import io.github.sspanak.tt9.Logger;
|
||||
import io.github.sspanak.tt9.languages.Language;
|
||||
import io.github.sspanak.tt9.preferences.SettingsStore;
|
||||
|
||||
abstract public class InputMode {
|
||||
// typing mode
|
||||
|
|
@ -26,10 +27,10 @@ abstract public class InputMode {
|
|||
protected String word = null;
|
||||
|
||||
|
||||
public static InputMode getInstance(int mode) {
|
||||
public static InputMode getInstance(SettingsStore settings, int mode) {
|
||||
switch (mode) {
|
||||
case MODE_PREDICTIVE:
|
||||
return new ModePredictive();
|
||||
return new ModePredictive(settings);
|
||||
case MODE_ABC:
|
||||
return new ModeABC();
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ import io.github.sspanak.tt9.languages.Punctuation;
|
|||
import io.github.sspanak.tt9.preferences.SettingsStore;
|
||||
|
||||
public class ModePredictive extends InputMode {
|
||||
private final SettingsStore settings;
|
||||
|
||||
public int getId() { return MODE_PREDICTIVE; }
|
||||
|
||||
private boolean isEmoji = false;
|
||||
|
|
@ -32,7 +34,8 @@ public class ModePredictive extends InputMode {
|
|||
private final Pattern endOfSentence = Pattern.compile("(?<!\\.)[.?!]\\s*$");
|
||||
|
||||
|
||||
ModePredictive() {
|
||||
ModePredictive(SettingsStore settings) {
|
||||
this.settings = settings;
|
||||
allowedTextCases.add(CASE_LOWER);
|
||||
allowedTextCases.add(CASE_CAPITALIZE);
|
||||
allowedTextCases.add(CASE_UPPER);
|
||||
|
|
@ -194,8 +197,8 @@ public class ModePredictive extends InputMode {
|
|||
language,
|
||||
digitSequence,
|
||||
stem,
|
||||
SettingsStore.getInstance().getSuggestionsMin(),
|
||||
SettingsStore.getInstance().getSuggestionsMax()
|
||||
settings.getSuggestionsMin(),
|
||||
settings.getSuggestionsMax()
|
||||
);
|
||||
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -22,19 +22,25 @@ public class ItemLoadDictionary extends ItemClickable {
|
|||
public static final String NAME = "dictionary_load";
|
||||
|
||||
private final Context context;
|
||||
private final SettingsStore settings;
|
||||
private final DictionaryLoader loader;
|
||||
private final DictionaryLoadingBar progressBar;
|
||||
|
||||
|
||||
ItemLoadDictionary(Preference item, Context context, DictionaryLoader loader, DictionaryLoadingBar progressBar) {
|
||||
ItemLoadDictionary(Preference item, Context context, SettingsStore settings, DictionaryLoader loader, DictionaryLoadingBar progressBar) {
|
||||
super(item);
|
||||
|
||||
this.context = context;
|
||||
this.loader = loader;
|
||||
this.progressBar = progressBar;
|
||||
this.settings = settings;
|
||||
|
||||
loader.setStatusHandler(onDictionaryLoading);
|
||||
|
||||
if (!progressBar.isCompleted() && !progressBar.isFailed()) {
|
||||
changeToCancelButton();
|
||||
} else {
|
||||
changeToLoadButton();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -43,6 +49,7 @@ public class ItemLoadDictionary extends ItemClickable {
|
|||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
progressBar.show(msg.getData());
|
||||
item.setSummary(progressBar.getTitle() + " " + progressBar.getMessage());
|
||||
|
||||
if (progressBar.isCompleted()) {
|
||||
changeToLoadButton();
|
||||
|
|
@ -57,11 +64,11 @@ public class ItemLoadDictionary extends ItemClickable {
|
|||
|
||||
@Override
|
||||
protected boolean onClick(Preference p) {
|
||||
ArrayList<Language> languages = LanguageCollection.getAll(SettingsStore.getInstance().getEnabledLanguageIds());
|
||||
ArrayList<Language> languages = LanguageCollection.getAll(settings.getEnabledLanguageIds());
|
||||
progressBar.setFileCount(languages.size());
|
||||
|
||||
try {
|
||||
loader.load(onDictionaryLoading, languages);
|
||||
loader.load(languages);
|
||||
changeToCancelButton();
|
||||
} catch (DictionaryImportAlreadyRunningException e) {
|
||||
loader.stop();
|
||||
|
|
@ -79,5 +86,6 @@ public class ItemLoadDictionary extends ItemClickable {
|
|||
|
||||
public void changeToLoadButton() {
|
||||
item.setTitle(context.getString(R.string.dictionary_load_title));
|
||||
item.setSummary(progressBar.isFailed() ? progressBar.getMessage() : "");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ public class ItemResetKeys extends ItemClickable {
|
|||
private final SettingsStore settings;
|
||||
|
||||
|
||||
ItemResetKeys(Preference item, Context context, SectionKeymap dropdowns, SettingsStore settings) {
|
||||
ItemResetKeys(Preference item, Context context, SettingsStore settings, SectionKeymap dropdowns) {
|
||||
super(item);
|
||||
this.context = context;
|
||||
this.dropdowns = dropdowns;
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import androidx.appcompat.app.AppCompatActivity;
|
|||
import androidx.appcompat.app.AppCompatDelegate;
|
||||
|
||||
import io.github.sspanak.tt9.R;
|
||||
import io.github.sspanak.tt9.db.DictionaryDb;
|
||||
import io.github.sspanak.tt9.db.DictionaryLoader;
|
||||
import io.github.sspanak.tt9.ui.DictionaryLoadingBar;
|
||||
|
||||
|
|
@ -17,7 +18,9 @@ public class PreferencesActivity extends AppCompatActivity {
|
|||
super.onCreate(savedInstanceState);
|
||||
|
||||
settings = new SettingsStore(this);
|
||||
DictionaryDb.init(this);
|
||||
|
||||
validateFunctionKeys();
|
||||
applyTheme();
|
||||
buildScreen();
|
||||
}
|
||||
|
|
@ -39,6 +42,13 @@ public class PreferencesActivity extends AppCompatActivity {
|
|||
}
|
||||
|
||||
|
||||
private void validateFunctionKeys() {
|
||||
if (!settings.areFunctionKeysSet()) {
|
||||
settings.setDefaultKeys();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DictionaryLoadingBar getDictionaryProgressBar() {
|
||||
return DictionaryLoadingBar.getInstance(this);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ public class PreferencesFragment extends PreferenceFragmentCompat {
|
|||
ItemLoadDictionary loadItem = new ItemLoadDictionary(
|
||||
findPreference(ItemLoadDictionary.NAME),
|
||||
activity,
|
||||
activity.settings,
|
||||
activity.getDictionaryLoader(),
|
||||
activity.getDictionaryProgressBar()
|
||||
);
|
||||
|
|
@ -94,7 +95,7 @@ public class PreferencesFragment extends PreferenceFragmentCompat {
|
|||
SectionKeymap section = new SectionKeymap(Arrays.asList(dropDowns), activity, activity.settings);
|
||||
section.populate().activate();
|
||||
|
||||
(new ItemResetKeys(findPreference(ItemResetKeys.NAME), activity, section, activity.settings))
|
||||
(new ItemResetKeys(findPreference(ItemResetKeys.NAME), activity, activity.settings, section))
|
||||
.enableClickHandler();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,13 +13,11 @@ import java.util.HashSet;
|
|||
import java.util.Set;
|
||||
|
||||
import io.github.sspanak.tt9.Logger;
|
||||
import io.github.sspanak.tt9.ime.TraditionalT9;
|
||||
import io.github.sspanak.tt9.ime.modes.InputMode;
|
||||
import io.github.sspanak.tt9.languages.LanguageCollection;
|
||||
|
||||
|
||||
public class SettingsStore {
|
||||
private static SettingsStore self;
|
||||
|
||||
private final SharedPreferences prefs;
|
||||
private final SharedPreferences.Editor prefsEditor;
|
||||
|
|
@ -31,15 +29,6 @@ public class SettingsStore {
|
|||
}
|
||||
|
||||
|
||||
public static SettingsStore getInstance() {
|
||||
if (self == null) {
|
||||
self = new SettingsStore(TraditionalT9.getMainContext());
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
/************* validators *************/
|
||||
|
||||
private boolean doesLanguageExist(int langId) {
|
||||
|
|
|
|||
|
|
@ -23,12 +23,15 @@ public class AddWordAct extends AppCompatActivity {
|
|||
|
||||
private View main;
|
||||
private int lang;
|
||||
private SettingsStore settings;
|
||||
private String word;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedData) {
|
||||
settings = new SettingsStore(this);
|
||||
|
||||
AppCompatDelegate.setDefaultNightMode(
|
||||
SettingsStore.getInstance().getDarkTheme() ? AppCompatDelegate.MODE_NIGHT_YES : AppCompatDelegate.MODE_NIGHT_NO
|
||||
settings.getDarkTheme() ? AppCompatDelegate.MODE_NIGHT_YES : AppCompatDelegate.MODE_NIGHT_NO
|
||||
);
|
||||
|
||||
super.onCreate(savedData);
|
||||
|
|
@ -53,7 +56,7 @@ public class AddWordAct extends AppCompatActivity {
|
|||
switch (msg.what) {
|
||||
case 0:
|
||||
Logger.d("onAddedWord", "Added word: '" + word + "'...");
|
||||
SettingsStore.getInstance().saveLastWord(word);
|
||||
settings.saveLastWord(word);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import androidx.core.app.NotificationCompat;
|
|||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
|
||||
import io.github.sspanak.tt9.R;
|
||||
import io.github.sspanak.tt9.db.DictionaryImportException;
|
||||
|
|
@ -30,9 +31,11 @@ public class DictionaryLoadingBar {
|
|||
private final NotificationCompat.Builder notificationBuilder;
|
||||
private final Resources resources;
|
||||
|
||||
private boolean hasFailed = false;
|
||||
private int maxProgress = 0;
|
||||
private int progress = 0;
|
||||
private boolean hasFailed = false;
|
||||
private String title = "";
|
||||
private String message = "";
|
||||
|
||||
|
||||
public static DictionaryLoadingBar getInstance(Context context) {
|
||||
|
|
@ -52,7 +55,7 @@ public class DictionaryLoadingBar {
|
|||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
manager.createNotificationChannel(new NotificationChannel(
|
||||
NOTIFICATION_CHANNEL_ID,
|
||||
"Dictionary Loading Channel",
|
||||
"Dictionary Status",
|
||||
NotificationManager.IMPORTANCE_LOW
|
||||
));
|
||||
notificationBuilder = new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID);
|
||||
|
|
@ -83,6 +86,16 @@ public class DictionaryLoadingBar {
|
|||
}
|
||||
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
|
||||
public void show(Bundle data) {
|
||||
String error = data.getString("error", null);
|
||||
|
||||
|
|
@ -97,6 +110,7 @@ public class DictionaryLoadingBar {
|
|||
} else {
|
||||
hasFailed = false;
|
||||
showProgress(
|
||||
data.getLong("time", 0),
|
||||
data.getInt("currentFile", 0),
|
||||
data.getInt("progress", 0),
|
||||
data.getInt("languageId", -1)
|
||||
|
|
@ -116,32 +130,31 @@ public class DictionaryLoadingBar {
|
|||
}
|
||||
|
||||
|
||||
private void showProgress(int currentFile, int currentFileProgress, int languageId) {
|
||||
progress = 100 * currentFile + currentFileProgress;
|
||||
|
||||
private void showProgress(long time, int currentFile, int currentFileProgress, int languageId) {
|
||||
if (currentFileProgress < 0) {
|
||||
hide();
|
||||
} else if (progress >= maxProgress) {
|
||||
renderProgress(
|
||||
generateTitle(-1),
|
||||
resources.getString(R.string.completed),
|
||||
0,
|
||||
0
|
||||
);
|
||||
} else {
|
||||
renderProgress(
|
||||
generateTitle(languageId),
|
||||
currentFileProgress + "%",
|
||||
progress,
|
||||
maxProgress
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
progress = 100 * currentFile + currentFileProgress;
|
||||
|
||||
if (progress >= maxProgress) {
|
||||
progress = maxProgress = 0;
|
||||
title = generateTitle(-1);
|
||||
|
||||
String timeFormat = time > 60000 ? " (%1.0fs)" : " (%1.1fs)";
|
||||
message = resources.getString(R.string.completed) + String.format(Locale.ENGLISH, timeFormat, time / 1000.0);
|
||||
} else {
|
||||
title = generateTitle(languageId);
|
||||
message = currentFileProgress + "%";
|
||||
}
|
||||
|
||||
renderProgress();
|
||||
}
|
||||
|
||||
|
||||
private void showError(String errorType, int langId, long line, String word) {
|
||||
Language lang = LanguageCollection.getLanguage(langId);
|
||||
String message;
|
||||
|
||||
if (lang == null || errorType.equals(InvalidLanguageException.class.getSimpleName())) {
|
||||
message = resources.getString(R.string.add_word_invalid_language);
|
||||
|
|
@ -156,16 +169,20 @@ public class DictionaryLoadingBar {
|
|||
message = resources.getString(R.string.dictionary_load_error, languageName, errorType);
|
||||
}
|
||||
|
||||
renderError(generateTitle(-1), message);
|
||||
title = generateTitle(-1);
|
||||
progress = maxProgress = 0;
|
||||
|
||||
renderError();
|
||||
}
|
||||
|
||||
|
||||
private void hide() {
|
||||
progress = maxProgress = 0;
|
||||
manager.cancel(NOTIFICATION_ID);
|
||||
}
|
||||
|
||||
|
||||
private void renderError(String title, String message) {
|
||||
private void renderError() {
|
||||
NotificationCompat.BigTextStyle bigMessage = new NotificationCompat.BigTextStyle();
|
||||
bigMessage.setBigContentTitle(title);
|
||||
bigMessage.bigText(message);
|
||||
|
|
@ -174,16 +191,16 @@ public class DictionaryLoadingBar {
|
|||
.setSmallIcon(android.R.drawable.stat_notify_error)
|
||||
.setStyle(bigMessage)
|
||||
.setOngoing(false)
|
||||
.setProgress(0, 0, false);
|
||||
.setProgress(maxProgress, progress, false);
|
||||
|
||||
manager.notify(NOTIFICATION_ID, notificationBuilder.build());
|
||||
}
|
||||
|
||||
|
||||
private void renderProgress(String title, String message, int progress, int maxProgress) {
|
||||
private void renderProgress() {
|
||||
notificationBuilder
|
||||
.setSmallIcon(progress < maxProgress ? android.R.drawable.stat_notify_sync : R.drawable.ic_done)
|
||||
.setOngoing(progress < maxProgress)
|
||||
.setSmallIcon(isCompleted() ? R.drawable.ic_done : android.R.drawable.stat_notify_sync)
|
||||
.setOngoing(!isCompleted())
|
||||
.setProgress(maxProgress, progress, false)
|
||||
.setContentTitle(title)
|
||||
.setContentText(message);
|
||||
|
|
|
|||
|
|
@ -22,12 +22,15 @@ public class SuggestionsView {
|
|||
protected int selectedIndex = 0;
|
||||
|
||||
private final RecyclerView mView;
|
||||
private final SettingsStore settings;
|
||||
private SuggestionsAdapter mSuggestionsAdapter;
|
||||
|
||||
|
||||
public SuggestionsView(View mainView) {
|
||||
public SuggestionsView(SettingsStore settings, View mainView) {
|
||||
super();
|
||||
|
||||
this.settings = settings;
|
||||
|
||||
mView = mainView.findViewById(R.id.main_suggestions_list);
|
||||
mView.setLayoutManager(new LinearLayoutManager(mainView.getContext(), RecyclerView.HORIZONTAL,false));
|
||||
|
||||
|
|
@ -40,8 +43,8 @@ public class SuggestionsView {
|
|||
private void configureAnimation() {
|
||||
DefaultItemAnimator animator = new DefaultItemAnimator();
|
||||
|
||||
int translateDuration = SettingsStore.getInstance().getSuggestionTranslateAnimationDuration();
|
||||
int selectDuration = SettingsStore.getInstance().getSuggestionSelectAnimationDuration();
|
||||
int translateDuration = settings.getSuggestionTranslateAnimationDuration();
|
||||
int selectDuration = settings.getSuggestionSelectAnimationDuration();
|
||||
|
||||
animator.setMoveDuration(selectDuration);
|
||||
animator.setChangeDuration(translateDuration);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue