From 36007cde60aae83e9eaff76910a36eef8bb35f1d Mon Sep 17 00:00:00 2001 From: AWAiS Date: Tue, 31 Jul 2018 19:23:43 +0500 Subject: [PATCH] huge update + REMOVED ADS!! + changed theme colors + fixed rotation problems + fixed filter action button shadow + fixed swipe to refresh layout not refreshing + added threads to perform tasks on background thread + added word dialog box search fixes + added rxjava as nonet fix + more bug fixes! --- .idea/caches/build_file_checksums.ser | Bin 537 -> 537 bytes app/build.gradle | 31 +- app/src/main/AndroidManifest.xml | 4 +- .../backworddictionary/DictionaryAdapter.java | 17 +- .../DictionaryFragment.java | 184 ++++++----- .../java/awais/backworddictionary/Main.java | 295 ++++++++++-------- .../asyncs/SearchAsync.java | 33 +- .../backworddictionary/asyncs/WordsAsync.java | 35 +-- .../custom/AdvancedDialog.java | 8 +- .../backworddictionary/custom/HuaweiFix.java | 6 +- .../backworddictionary/custom/MenuCaller.java | 8 +- .../backworddictionary/custom/WordDialog.java | 84 +++-- .../customweb/WebViewActivity.java | 4 +- .../interfaces/FilterCheck.java | 1 + .../interfaces/FragmentCallback.java | 1 + .../interfaces/MainCheck.java | 10 + app/src/main/res/drawable/dialog_back.9.png | Bin 527 -> 555 bytes app/src/main/res/drawable/no_internet.9.png | Bin 23930 -> 44564 bytes app/src/main/res/layout/activity_main.xml | 28 +- app/src/main/res/layout/advanced_dialog.xml | 4 +- app/src/main/res/layout/dictionary_view.xml | 25 +- app/src/main/res/layout/settings_dialog.xml | 2 +- app/src/main/res/layout/word_dialog.xml | 10 +- app/src/main/res/menu/menu_search.xml | 13 + app/src/main/res/menu/menu_word.xml | 1 - app/src/main/res/values/colors.xml | 24 +- app/src/main/res/values/strings.xml | 12 +- app/src/main/res/values/styles.xml | 4 + build.gradle | 3 +- 29 files changed, 451 insertions(+), 396 deletions(-) create mode 100644 app/src/main/java/awais/backworddictionary/interfaces/MainCheck.java create mode 100644 app/src/main/res/menu/menu_search.xml diff --git a/.idea/caches/build_file_checksums.ser b/.idea/caches/build_file_checksums.ser index d15034d714af1dbeaf602c9fc7a0f95685122287..b65cb37fb4e2f35c6043d411a52378d476bb52a8 100644 GIT binary patch delta 56 zcmV-80LTBC1epYom;~^#9RiV@cM!;tTWHeybC`V+XFmPlT7r`!0Ywl-_NI}M@o43I OtMQRaCBY4ocmbi|#u}Ue delta 56 zcmV-80LTBC1epYom;}Gv+^dnCcMxjhZ=G#M9A+#v*u8U*itLjk0Ywl$PQ#+QOt;J9 O5c5O)y&-IqcmbjFa2nhI diff --git a/app/build.gradle b/app/build.gradle index 01d13d4..a2d91ca 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,18 +1,17 @@ apply plugin: 'com.android.application' -apply plugin: 'com.google.firebase.firebase-perf' apply plugin: 'io.fabric' android { compileSdkVersion 28 - buildToolsVersion '28.0.1' defaultConfig { - vectorDrawables.useSupportLibrary = true applicationId "awais.backworddictionary" minSdkVersion 16 targetSdkVersion 28 - versionCode 73 - versionName "7.3" + versionCode 80 + versionName "8.0" + + vectorDrawables.useSupportLibrary = true multiDexEnabled true } @@ -25,20 +24,20 @@ android { dependencies { implementation 'com.android.support:multidex:1.0.3' implementation 'com.android.support.constraint:constraint-layout:1.1.2' - implementation 'com.android.support:support-dynamic-animation:28.0.0-alpha3' - implementation 'com.android.support:appcompat-v7:28.0.0-alpha3' - implementation 'com.android.support:support-v4:28.0.0-alpha3' - implementation 'com.android.support:design:28.0.0-alpha3' - implementation 'com.android.support:recyclerview-v7:28.0.0-alpha3' - implementation 'com.android.support:cardview-v7:28.0.0-alpha3' + implementation 'com.android.support:support-dynamic-animation:28.0.0-beta01' + implementation 'com.android.support:appcompat-v7:28.0.0-beta01' + implementation 'com.android.support:support-v4:28.0.0-beta01' + implementation 'com.android.support:design:28.0.0-beta01' + implementation 'com.android.support:recyclerview-v7:28.0.0-beta01' + implementation 'com.android.support:cardview-v7:28.0.0-beta01' implementation 'com.google.firebase:firebase-core:16.0.1' - implementation 'com.google.firebase:firebase-ads:15.0.1' - implementation 'com.google.firebase:firebase-appindexing:16.0.1' - implementation 'com.google.firebase:firebase-perf:16.0.0' - implementation 'com.crashlytics.sdk.android:crashlytics:2.9.4' + implementation 'com.google.firebase:firebase-crash:16.0.1' + implementation('com.crashlytics.sdk.android:crashlytics:2.9.4@aar') { transitive = true } + implementation 'io.reactivex.rxjava2:rxandroid:2.0.2' + implementation 'io.reactivex.rxjava2:rxjava:2.1.9' - implementation 'com.android.support:customtabs:28.0.0-alpha3' + implementation 'com.android.support:customtabs:28.0.0-beta01' implementation 'com.squareup.okhttp3:okhttp:3.10.0' implementation 'com.google.code.gson:gson:2.8.0' implementation 'com.keiferstone:nonet:2.0.4' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 3125e27..649860e 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -4,8 +4,6 @@ - - + android:configChanges="keyboardHidden|orientation|screenSize" > diff --git a/app/src/main/java/awais/backworddictionary/DictionaryAdapter.java b/app/src/main/java/awais/backworddictionary/DictionaryAdapter.java index 55a90c1..dbbe747 100644 --- a/app/src/main/java/awais/backworddictionary/DictionaryAdapter.java +++ b/app/src/main/java/awais/backworddictionary/DictionaryAdapter.java @@ -31,13 +31,14 @@ import awais.backworddictionary.custom.WordItem; import awais.backworddictionary.customweb.CustomTabActivityHelper; +import static awais.backworddictionary.Main.tts; + public class DictionaryAdapter extends RecyclerView.Adapter implements Filterable { private final Context mContext; private final List wordList; private List filterList; private WordItem currentWord; - private final TextToSpeech tts; @Override public Filter getFilter() { @@ -46,9 +47,10 @@ public Filter getFilter() { protected FilterResults performFiltering(CharSequence charSequence) { FilterResults results = new FilterResults(); results.values = wordList; - if (charSequence.toString().isEmpty()) return results; + if (String.valueOf(charSequence).isEmpty() || String.valueOf(charSequence) == null) + return results; - boolean showWords = Main.sharedPreferences.getBoolean("filterWord", false); + boolean showWords = Main.sharedPreferences.getBoolean("filterWord", true); boolean showDefs = Main.sharedPreferences.getBoolean("filterDefinition", false); boolean contains = Main.sharedPreferences.getBoolean("filterContain", true); @@ -118,11 +120,10 @@ class DictHolder extends RecyclerView.ViewHolder { } } - DictionaryAdapter(Context mContext, List wordList, TextToSpeech tts) { + DictionaryAdapter(Context mContext, List wordList) { this.mContext = mContext; this.wordList = wordList; this.filterList = wordList; - this.tts = tts; } @Override @@ -160,14 +161,14 @@ public void onBindViewHolder(@NonNull DictHolder holder, int position) { tagsBuilder.append("\nsyllables: ").append(wordItem.getNumSyllables()); else tagsBuilder.append("syllables: ").append(wordItem.getNumSyllables()); - holder.subtext.setText(tagsBuilder.toString().replaceAll(",\nsyllables", "\nsyllables")); + holder.subtext.setText(String.valueOf(tagsBuilder).replaceAll(",\nsyllables", "\nsyllables")); holder.overflow.setOnClickListener(view -> showPopupMenu(holder.overflow)); holder.cardView.setOnLongClickListener(view -> { showPopupMenu(holder.overflow); return true; }); holder.cardView.setOnClickListener(view -> - new WordDialog((Activity) mContext, wordItem, tts).show()); + new WordDialog((Activity) mContext, wordItem).show()); } private void showPopupMenu(View view) { @@ -217,7 +218,7 @@ public boolean onMenuItemClick(MenuItem menuItem) { return true; case R.id.action_wiki: String wordRawWiki = currentWord.getWord().replace(" ", "_").replace("\\s", "_"); - try {wordRawWiki = new URL(wordRawWiki).toString();} catch (Exception ignored) {} + try {wordRawWiki = String.valueOf(new URL(wordRawWiki));} catch (Exception ignored) {} Intent intent1 = new Intent(); intent1.setAction(Intent.ACTION_VIEW); diff --git a/app/src/main/java/awais/backworddictionary/DictionaryFragment.java b/app/src/main/java/awais/backworddictionary/DictionaryFragment.java index 9cb2ca5..5d0851a 100644 --- a/app/src/main/java/awais/backworddictionary/DictionaryFragment.java +++ b/app/src/main/java/awais/backworddictionary/DictionaryFragment.java @@ -3,10 +3,8 @@ import android.animation.Animator; import android.app.Activity; import android.content.Context; -import android.graphics.Color; import android.os.Build; import android.os.Bundle; -import android.speech.tts.TextToSpeech; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.design.widget.FloatingActionButton; @@ -14,11 +12,12 @@ import android.support.v4.app.Fragment; 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.text.Editable; import android.text.TextUtils; import android.text.TextWatcher; -import android.util.Log; +import android.util.TypedValue; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -27,17 +26,9 @@ import android.widget.EditText; import android.widget.FrameLayout; import android.widget.ImageView; -import android.widget.RelativeLayout; - -import com.google.android.gms.ads.AdListener; -import com.google.android.gms.ads.AdRequest; -import com.google.android.gms.ads.AdView; -import com.google.firebase.perf.metrics.AddTrace; import java.util.ArrayList; import java.util.List; -import java.util.Locale; -import java.util.concurrent.atomic.AtomicReference; import awais.backworddictionary.asyncs.WordsAsync; import awais.backworddictionary.custom.WordItem; @@ -47,83 +38,76 @@ public class DictionaryFragment extends Fragment implements FragmentCallback, FilterCheck { private List wordList; private RecyclerView recyclerView; - private TextToSpeech tts; private Activity activity; + private InputMethodManager imm; private EditText filterSearchEditor; private ImageView filterSearchButton; private FrameLayout filterView; private FloatingActionButton fab; + private SwipeRefreshLayout swipeRefreshLayout; private final boolean[] filterCheck = {true, true, true}; public DictionaryAdapter adapter; public String title; - private FilterCheck filterChecker; - private static FragmentCallback mainCallback; - private static final AtomicReference refreshLayout = new AtomicReference<>(); - private ViewGroup.MarginLayoutParams tabParams; + private static ViewGroup.MarginLayoutParams tabParams; private static int initialMargin = -1; - - public DictionaryFragment createNew(FragmentCallback callback, SwipeRefreshLayout refreshLayout) { - DictionaryFragment.mainCallback = callback; - DictionaryFragment.refreshLayout.set(refreshLayout); - return new DictionaryFragment(); - } - - @Override @AddTrace(name = "onCreateDictFragmentTrace") - public void onCreate(Bundle bundle) { - super.onCreate(bundle); - tts = new TextToSpeech(activity, initStatus -> { - if (initStatus == TextToSpeech.SUCCESS) { - if (tts.isLanguageAvailable(Locale.US) == TextToSpeech.LANG_AVAILABLE) - tts.setLanguage(Locale.US); - else if (tts.isLanguageAvailable(Locale.CANADA) == TextToSpeech.LANG_AVAILABLE) - tts.setLanguage(Locale.CANADA); - else if (tts.isLanguageAvailable(Locale.UK) == TextToSpeech.LANG_AVAILABLE) - tts.setLanguage(Locale.UK); - else if (tts.isLanguageAvailable(Locale.ENGLISH) == TextToSpeech.LANG_AVAILABLE) - tts.setLanguage(Locale.ENGLISH); - } - }); - } + private static int startOffset=-120, endOffset, topPadding; @Override public void onDestroy() { super.onDestroy(); - try {tts.stop();} catch (Exception ignore){} - try {tts.shutdown();} catch (Exception ignore){} + try {Main.tts.stop();} catch (Exception ignored){} + try {Main.tts.shutdown();} catch (Exception ignored){} } - @Nullable - @Override + @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,@Nullable Bundle savedInstanceState) { final View magicRootView = inflater.inflate(R.layout.dictionary_view, container, false); - AdView adView = magicRootView.findViewById(R.id.adView); - adView.loadAd(new AdRequest.Builder().addTestDevice(AdRequest.DEVICE_ID_EMULATOR).build()); - adView.setAdListener(new AdListener() { - public void onAdFailedToLoad(int var1) { adView.setVisibility(View.GONE); } - public void onAdLoaded() { adView.setVisibility(View.VISIBLE); } - }); + if (getActivity() != null) activity = getActivity(); + else activity = (Activity) getContext(); + + if (activity != null) + imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE); wordList = new ArrayList<>(); - adapter = new DictionaryAdapter(getContext(), wordList, tts); + adapter = new DictionaryAdapter(getContext(), wordList); adapter.setHasStableIds(true); + swipeRefreshLayout = magicRootView.findViewById(R.id.swipe_container); + swipeRefreshLayout.setColorSchemeResources(R.color.progress1, R.color.progress2, + R.color.progress3, R.color.progress4); + swipeRefreshLayout.setOnRefreshListener(() -> { + swipeRefreshLayout.setRefreshing(true); + if (getActivity() != null) { + Main activity = (Main) getActivity(); + if (activity.mSearchView != null && activity.mSearchView.isSearchOpen()) + activity.mSearchView.close(true); + if (!activity.getTitle().equals(getResources().getString(R.string.app_name))) + activity.onSearch(String.valueOf(activity.getTitle())); + else swipeRefreshLayout.setRefreshing(false); + } + }); + + startOffset = swipeRefreshLayout.getProgressViewStartOffset(); + endOffset = (int) getEndOffset(); + recyclerView = magicRootView.findViewById(R.id.recycler_view); recyclerView.setHasFixedSize(true); recyclerView.setAdapter(adapter); - filterChecker = this; + topPadding = recyclerView.getPaddingTop(); filterView = magicRootView.findViewById(R.id.filterView); ImageView filterBackButton = magicRootView.findViewById(R.id.filterBack); - filterBackButton.setOnClickListener(view -> filterChecker.isOpen(false, fab, 0)); + filterBackButton.setOnClickListener(view -> isOpen(false, fab, 0)); filterSearchEditor = magicRootView.findViewById(R.id.swipeSearch); filterSearchButton = magicRootView.findViewById(R.id.filterSettings); filterSearchButton.setTag("filter"); - filterSearchEditor.setOnClickListener(view -> openKeyboard()); + filterSearchEditor.setOnClickListener(view -> toggleKeyboard(true)); + filterSearchEditor.setOnFocusChangeListener((view, b) -> toggleKeyboard(b)); filterSearchEditor.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence cs, int i, int i1, int i2) {} @Override public void onTextChanged(CharSequence cs, int i, int i1, int i2) { @@ -142,9 +126,9 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c filterSearchButton.setOnClickListener(view -> { if (filterSearchButton.getTag() != null && !TextUtils.isEmpty((CharSequence) filterSearchButton.getTag()) && filterSearchButton.getTag().equals("filter")) { - filterCheck[0] = Main.sharedPreferences.getBoolean("filterWord", false); + filterCheck[0] = Main.sharedPreferences.getBoolean("filterWord", true); filterCheck[1] = Main.sharedPreferences.getBoolean("filterDefinition", false); - filterCheck[2] = Main.sharedPreferences.getBoolean("filterContain", true); + filterCheck[2] = Main.sharedPreferences.getBoolean("filterContain", false); AlertDialog.Builder builder = new AlertDialog.Builder(activity); builder.setTitle("Select The Difficulty Level"); @@ -174,45 +158,56 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c return magicRootView; } - private void openKeyboard() { - try { - InputMethodManager inputMethodManager = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE); - if (inputMethodManager != null) - inputMethodManager.showSoftInput(filterSearchEditor, 1); - } catch (Exception e) { Log.e("AWAISKING_APP", "", e); } + private void toggleKeyboard(boolean show) { + if (imm != null) { + if (show) imm.showSoftInput(filterSearchEditor, 1); + else imm.hideSoftInputFromWindow(filterSearchEditor.getWindowToken(), 1); + } } public void startWords(CharSequence method, String word) { if (filterView != null && filterSearchEditor != null) filterSearchEditor.setText(""); if (word == null || word.isEmpty() || TextUtils.isEmpty(word)) return; - new WordsAsync(activity,this, word, String.valueOf(method), - refreshLayout.get(), recyclerView).execute(); + new WordsAsync(this, word, String.valueOf(method)).execute(); } - @Override @AddTrace(name = "onAttachTrace") + @Override public void onAttach(Context context) { super.onAttach(context); if (getActivity() != null) activity = getActivity(); else activity = (Activity) context; } - @Override @AddTrace(name = "onActivityCreatedTrace") + @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); activity = getActivity(); } - @Override @AddTrace(name = "doneFragmentTrace") + @Override public void done(ArrayList items, final String word) { - wordList = items; - adapter = new DictionaryAdapter(activity, wordList, tts); + wordList = items != null ? items : new ArrayList<>(); + adapter = new DictionaryAdapter(activity, wordList); adapter.notifyDataSetChanged(); recyclerView.setAdapter(adapter); title = word; activity.setTitle(title); - if (mainCallback != null) mainCallback.done(items, word); + recyclerView.setClickable(true); + recyclerView.setEnabled(true); + recyclerView.setFocusable(true); + recyclerView.setLayoutFrozen(false); + swipeRefreshLayout.post(() -> swipeRefreshLayout.setRefreshing(false)); + } + + @Override + public void wordStarted() { + swipeRefreshLayout.post(() -> swipeRefreshLayout.setRefreshing(true)); + recyclerView.setClickable(false); + recyclerView.setEnabled(false); + recyclerView.setFocusable(false); + recyclerView.setLayoutFrozen(true); } public boolean isFilterOpen() { @@ -223,45 +218,62 @@ public void hideFilter() { if (fab != null) isOpen(false, fab, 0); } - @Override @AddTrace(name = "isOpenTrace") + @Override public void isOpen(boolean opened, FloatingActionButton fab, int method) { this.fab = fab; TabLayout tabLayout = ((View)fab.getParent().getParent()).findViewById(R.id.tabs); if (tabParams == null && tabLayout != null) { tabParams = (ViewGroup.MarginLayoutParams) tabLayout.getLayoutParams(); - if (initialMargin == -1) initialMargin = tabParams.rightMargin; - if (Build.VERSION.SDK_INT >= 17) - initialMargin = initialMargin < 0 ? tabParams.getMarginEnd() : initialMargin; + if (initialMargin == -1) { + initialMargin = tabParams.rightMargin; + if (Build.VERSION.SDK_INT >= 17) + initialMargin = initialMargin < 0 ? tabParams.getMarginEnd() : initialMargin; + } } if (opened) { if (method == 0 && filterView != null) { filterView.setVisibility(View.VISIBLE); - ((View)fab.getParent()).setVisibility(View.GONE); - } - if (method == 30 && filterView != null) { + if (filterSearchEditor != null) filterSearchEditor.requestFocus(); +// ((View)fab.getParent()).setVisibility(View.GONE); + } else if (method == 30 && filterView != null) { filterView.setVisibility(View.GONE); - ((View)fab.getParent()).setVisibility(View.VISIBLE); +// ((View)fab.getParent()).setVisibility(View.VISIBLE); +// } else if (method == 1) { +// ((View)fab.getParent()).setVisibility(View.GONE); } if (tabParams != null) { tabParams.setMargins(0, 0, 0, 0); if (Build.VERSION.SDK_INT >= 17) tabParams.setMarginEnd(0); } + if (recyclerView != null) { + if (method == 0) + recyclerView.setPadding(0, initialMargin, 0, recyclerView.getPaddingBottom()); + if (recyclerView.getLayoutManager() != null && + ((LinearLayoutManager)recyclerView.getLayoutManager()).findFirstVisibleItemPosition() <= 5) + recyclerView.smoothScrollToPosition(0); + swipeRefreshLayout.setProgressViewOffset(false, startOffset, endOffset); + } hideFAB(); } else { if (method == 0 && filterView != null) { filterView.setVisibility(View.GONE); - ((View)fab.getParent()).setVisibility(View.VISIBLE); - } - if (method == 30 && filterView != null) { +// ((View)fab.getParent()).setVisibility(View.VISIBLE); + } else if (method == 30 && filterView != null) { filterView.setVisibility(View.VISIBLE); - ((View)fab.getParent()).setVisibility(View.GONE); +// ((View)fab.getParent()).setVisibility(View.GONE); +// } else if (method == 1) { +// ((View)fab.getParent()).setVisibility(View.VISIBLE); } if (tabParams != null) { tabParams.setMargins(0, 0, initialMargin, 0); if (Build.VERSION.SDK_INT >= 17) tabParams.setMarginEnd(initialMargin); } + if (recyclerView != null) { + recyclerView.setPadding(0, topPadding, 0, recyclerView.getPaddingBottom()); + swipeRefreshLayout.setProgressViewOffset(false, startOffset, (int) (endOffset-(endOffset*0.7))); + } showFAB(); } } @@ -275,6 +287,7 @@ private void hideFAB() { .setListener(new Animator.AnimatorListener() { @Override public void onAnimationEnd(Animator animation) { fab.hide(); + ((View)fab.getParent()).setVisibility(View.GONE); } @Override public void onAnimationStart(Animator animation) {} @Override public void onAnimationCancel(Animator animation) {} @@ -290,10 +303,19 @@ private void showFAB() { .setListener(new Animator.AnimatorListener() { @Override public void onAnimationEnd(Animator animation) { fab.show(); + ((View)fab.getParent()).setVisibility(View.VISIBLE); } @Override public void onAnimationStart(Animator animation) {} @Override public void onAnimationCancel(Animator animation) {} @Override public void onAnimationRepeat(Animator animation) {} }); } + + private float getEndOffset() { + TypedValue tv = new TypedValue(); + if (getActivity() != null && + getActivity().getTheme().resolveAttribute(R.attr.actionBarSize, tv, true)) + return TypedValue.complexToDimensionPixelSize(tv.data, getResources().getDisplayMetrics()); + return swipeRefreshLayout != null ? swipeRefreshLayout.getProgressViewEndOffset() : 250.0f; + } } diff --git a/app/src/main/java/awais/backworddictionary/Main.java b/app/src/main/java/awais/backworddictionary/Main.java index 20c5dcf..a42c5d0 100644 --- a/app/src/main/java/awais/backworddictionary/Main.java +++ b/app/src/main/java/awais/backworddictionary/Main.java @@ -8,15 +8,16 @@ import android.os.Bundle; import android.os.Handler; import android.provider.Settings; -import android.support.design.widget.AppBarLayout; +import android.speech.tts.TextToSpeech; +import android.support.annotation.Nullable; import android.support.design.widget.FloatingActionButton; import android.support.design.widget.Snackbar; +import android.support.design.widget.SnackbarContentLayout; import android.support.design.widget.TabLayout; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentPagerAdapter; import android.support.v4.content.ContextCompat; import android.support.v4.view.ViewPager; -import android.support.v4.widget.SwipeRefreshLayout; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.TooltipCompat; import android.text.TextUtils; @@ -24,43 +25,157 @@ import android.view.Menu; import android.view.MenuItem; import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; import android.widget.ImageView; import com.crashlytics.android.Crashlytics; -import com.google.android.gms.ads.MobileAds; -import com.google.firebase.perf.metrics.AddTrace; import com.keiferstone.nonet.ConnectionStatus; import com.keiferstone.nonet.NoNet; import com.lapism.searchview.SearchAdapter; +import com.lapism.searchview.SearchItem; import com.lapism.searchview.SearchView; import java.util.ArrayList; import java.util.List; +import java.util.Locale; import awais.backworddictionary.asyncs.SearchAsync; import awais.backworddictionary.custom.AdvancedDialog; import awais.backworddictionary.custom.MenuCaller; import awais.backworddictionary.custom.SettingsDialog; -import awais.backworddictionary.interfaces.FragmentCallback; +import awais.backworddictionary.custom.WordItem; import awais.backworddictionary.interfaces.FragmentLoader; +import awais.backworddictionary.interfaces.MainCheck; import io.fabric.sdk.android.Fabric; -public class Main extends AppCompatActivity implements AppBarLayout.OnOffsetChangedListener, - FragmentLoader { +public class Main extends AppCompatActivity implements FragmentLoader, MainCheck { + public static TextToSpeech tts; + private TabLayout tabLayout; public ViewPager viewPager; public DictionariesAdapter adapter; - private SearchView mSearchView; - public static SearchAdapter searchAdapter; + public SearchView mSearchView; + private SearchAdapter searchAdapter; private FloatingActionButton fabFilter; private MenuCaller menuCaller; private ImageView noInternet; - private AppBarLayout appBarLayout; - private SwipeRefreshLayout swipeRefreshLayout; - private String[] tabs = {"Reverse", "Sounds Like", "Spelled Like", "Synonyms", "Antonyms", - "Triggers", "Part of", "Comprises", "Rhymes", "Homophones"}; + private Snackbar snackbar; + public static String[] boolsArray; + private static final String[] tabs = {"Reverse", "Sounds Like", "Spelled Like", "Synonyms", "Antonyms", + "Triggers", "Is Part of", "Comprises of", "Rhymes", "Homophones"}; public static SharedPreferences sharedPreferences; + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + Fabric.with(this, new Crashlytics()); + setContentView(R.layout.activity_main); + + tabLayout = findViewById(R.id.tabs); + viewPager = findViewById(R.id.viewpager); + noInternet = findViewById(R.id.noInternet); + fabFilter = findViewById(R.id.filterButton); + + snackbar = Snackbar.make(viewPager, R.string.no_connection, -2); + SnackbarContentLayout contentLayout = (SnackbarContentLayout) ((ViewGroup)snackbar.getView()).getChildAt(0); + Button actionButton = contentLayout.findViewById(R.id.snackbar_action); + actionButton.setVisibility(View.VISIBLE); + actionButton.setText(R.string.settings); + actionButton.setOnClickListener(v -> startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS))); + + menuCaller = new MenuCaller(this); + sharedPreferences = getSharedPreferences("settings", MODE_PRIVATE); + setSupportActionBar(findViewById(R.id.toolbar)); + + TooltipCompat.setTooltipText(fabFilter, "Filter"); + fabFilter.setOnClickListener(view -> + adapter.getItem(viewPager.getCurrentItem()).isOpen(true, fabFilter, 0)); + + handleData(); + + setupNoNet(); + } + + @Override + protected void onPostCreate(@Nullable Bundle savedInstanceState) { + super.onPostCreate(savedInstanceState); + + setSearchView(); + myThread loadFragments = new myThread(1); + myThread setupTTS = new myThread(2); + + loadFragments.start(); + setupTTS.start(); + } + + private class myThread extends Thread { + private final int method; + myThread(int method) { this.method = method; } + @Override public void run() { + switch (method) { + case 1: loadFragments(true); break; + case 2: + tts = new TextToSpeech(Main.this, initStatus -> { + if (initStatus == TextToSpeech.SUCCESS) { + if (tts.isLanguageAvailable(Locale.US) == TextToSpeech.LANG_AVAILABLE) + tts.setLanguage(Locale.US); + else if (tts.isLanguageAvailable(Locale.CANADA) == TextToSpeech.LANG_AVAILABLE) + tts.setLanguage(Locale.CANADA); + else if (tts.isLanguageAvailable(Locale.UK) == TextToSpeech.LANG_AVAILABLE) + tts.setLanguage(Locale.UK); + else if (tts.isLanguageAvailable(Locale.ENGLISH) == TextToSpeech.LANG_AVAILABLE) + tts.setLanguage(Locale.ENGLISH); + } + }); + break; + } + } + } + + private void setupNoNet() { + NoNet.monitor(this).configure(NoNet.configure().endpoint("http://api.datamuse.com/words") + .connectedPollFrequency(1).disconnectedPollFrequency(1).build()).callback(connectionStatus -> { + Log.d("AWAISKING_APP", "--> " + adapter.getItem(viewPager.getCurrentItem())); + if (connectionStatus != ConnectionStatus.CONNECTED) { + if (adapter != null && adapter.getCount() > 0 && ( + adapter.getItem(viewPager.getCurrentItem()).adapter != null + && adapter.getItem(viewPager.getCurrentItem()).adapter.getItemCount() < 1 + || adapter.getItem(viewPager.getCurrentItem()).adapter == null + )) { + if (noInternet != null) noInternet.setVisibility(View.VISIBLE); + if (viewPager != null) + viewPager.setBackgroundColor(getResources().getColor(R.color.noInternet)); + if (getSupportActionBar() != null) + getSupportActionBar().setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color.noInternetBar))); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) + getWindow().setStatusBarColor(getResources().getColor(R.color.noInternetStatusBar)); + if (findViewById(R.id.tabs) != null) + findViewById(R.id.tabs).setBackgroundColor(getResources().getColor(R.color.noInternetBar)); + if (fabFilter != null) { + fabFilter.setBackgroundTintList(ColorStateList.valueOf(getResources().getColor(R.color.noInternetAccent))); + if (fabFilter.getParent() != null && fabFilter.getParent() instanceof View) + ((View) fabFilter.getParent()).setBackgroundColor(getResources().getColor(R.color.noInternetBar)); + } + } + } else { + if (noInternet != null) noInternet.setVisibility(View.GONE); + if (viewPager != null) viewPager.setBackground(null); + if (getSupportActionBar() != null) + getSupportActionBar().setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color.colorPrimary))); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) + getWindow().setStatusBarColor(getResources().getColor(R.color.colorPrimaryDark)); + if (findViewById(R.id.tabs) != null) + findViewById(R.id.tabs).setBackgroundColor(getResources().getColor(R.color.colorPrimary)); + if (fabFilter != null) { + fabFilter.setBackgroundTintList(ColorStateList.valueOf(getResources().getColor(R.color.colorAccent))); + if (fabFilter.getParent() != null && fabFilter.getParent() instanceof View) + ((View) fabFilter.getParent()).setBackgroundColor(getResources().getColor(R.color.colorPrimary)); + } + } + }).snackbar(snackbar); + } + @Override public void loadFragments(boolean main) { if (!main) { @@ -69,25 +184,21 @@ public void loadFragments(boolean main) { return; } String bools = Main.sharedPreferences.getString("tabs", "[true, true, true, true, false, false, false, false, false, false]"); - TabLayout tabLayout = findViewById(R.id.tabs); if (tabLayout != null) try { tabLayout.clearOnTabSelectedListeners(); } catch (Exception ignored) {} adapter = new DictionariesAdapter(getSupportFragmentManager()); - FragmentCallback fragmentCallback = (items, word) -> swipeRefreshLayout.setRefreshing(false); - bools = bools.substring(1, bools.length()-1); - String[] boolsArray = bools.split(", "); - for (int i=0; i - adapter.getItem(viewPager.getCurrentItem()).isOpen(true, fabFilter, 0)); - - handleData(); - - swipeRefreshLayout.setOnRefreshListener(() -> { - swipeRefreshLayout.setRefreshing(true); - if (mSearchView != null) mSearchView.close(true); - if (!getTitle().equals(getResources().getString(R.string.app_name))) - onSearch(getTitle()); - else swipeRefreshLayout.setRefreshing(false); - }); + public int getItemPosition(String item) { + return adapter.mFragmentTitleList.indexOf(item); } private void handleData() { @@ -206,7 +280,7 @@ public void run() { } } - @Override @AddTrace(name = "onNewIntentTrace") + @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); setIntent(intent); @@ -238,10 +312,6 @@ public boolean onCreateOptionsMenu(Menu menu) { return true; } - private void onSearch(CharSequence text) { - onSearch(text.toString()); - } - public void onSearch(String word) { try { if (adapter != null && viewPager != null) { @@ -255,11 +325,25 @@ public void onSearch(String word) { } @Override - public void onOffsetChanged(AppBarLayout appBarLayout, int i) { - if (!swipeRefreshLayout.isRefreshing()) swipeRefreshLayout.setEnabled(i == 0); + public void beforeSearch() { + if (searchAdapter != null) searchAdapter.setSuggestionsList(new ArrayList<>()); + if (mSearchView != null) mSearchView.showProgress(); + } + + @Override + public void afterSearch(ArrayList result) { + if (mSearchView != null && mSearchView.isShowingProgress()) mSearchView.hideProgress(); + if (result != null && !result.isEmpty() && mSearchView != null + && mSearchView != null && searchAdapter != null) { + ArrayList suggestionsList = new ArrayList<>(); + for (WordItem item : result) suggestionsList.add(new SearchItem(item.getWord())); + searchAdapter.setData(suggestionsList); + searchAdapter.setSuggestionsList(suggestionsList); + searchAdapter.notifyDataSetChanged(); + mSearchView.showSuggestions(); + } } - @AddTrace(name = "DictionaryAdapterTrace") public class DictionariesAdapter extends FragmentPagerAdapter { private final List mFragmentList = new ArrayList<>(); private final List mFragmentTitleList = new ArrayList<>(); @@ -312,8 +396,11 @@ private void setSearchView() { searchAdapter = new SearchAdapter(this); searchAdapter.setHasStableIds(true); - searchAdapter.addOnItemClickListener((view, position) -> - onSearch(searchAdapter.getSuggestionsList().get(position).get_text())); + searchAdapter.addOnItemClickListener((view, position) -> { + if (searchAdapter.getSuggestionsList() != null + && searchAdapter.getSuggestionsList().get(position) != null) + onSearch(String.valueOf(searchAdapter.getSuggestionsList().get(position).get_text())); + }); mSearchView.setAdapter(searchAdapter); mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { @@ -323,7 +410,7 @@ private void setSearchView() { final Runnable textWatch = () -> { if (System.currentTimeMillis() > (last_text_edit + 200L)) { if (text != null && !text.isEmpty() && !TextUtils.isEmpty(text) && !text.equals("")) - new SearchAsync(mSearchView).execute(text); + new SearchAsync(Main.this).execute(text); } }; @@ -347,70 +434,18 @@ public boolean onQueryTextChange(String newText) { }); mSearchView.setOnOpenCloseListener(new SearchView.OnOpenCloseListener() { - @Override - public boolean onClose() { - if (!adapter.getItem(viewPager.getCurrentItem()).isFilterOpen()) + @Override public boolean onClose() { + if (adapter != null && adapter.getItem(viewPager.getCurrentItem()) != null && + !adapter.getItem(viewPager.getCurrentItem()).isFilterOpen()) adapter.getItem(viewPager.getCurrentItem()).isOpen(false, fabFilter, 1); return false; } - @Override - public boolean onOpen() { + @Override public boolean onOpen() { adapter.getItem(viewPager.getCurrentItem()).isOpen(true, fabFilter, 1); return false; } }); } } - - private void setupNoNet() { - NoNet.monitor(this).configure(NoNet.configure().endpoint("http://api.datamuse.com/words") - .build()).poll().callback(connectionStatus -> { - if (connectionStatus != ConnectionStatus.CONNECTED) { - if (adapter != null && adapter.getCount() > 0 && adapter.getItem(viewPager.getCurrentItem()).adapter != null - && adapter.getItem(viewPager.getCurrentItem()).adapter.getItemCount() < 1) { - if (noInternet != null) noInternet.setVisibility(View.VISIBLE); - if (viewPager != null) viewPager.setBackgroundColor(getResources().getColor(R.color.noInternet)); - if (getSupportActionBar() != null) - getSupportActionBar().setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color.noInternetBar))); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) - getWindow().setStatusBarColor(getResources().getColor(R.color.noInternetStatusBar)); - if(findViewById(R.id.tabs) != null) - findViewById(R.id.tabs).setBackgroundColor(getResources().getColor(R.color.noInternetBar)); - if (fabFilter != null) { - fabFilter.setBackgroundTintList(ColorStateList.valueOf(getResources().getColor(R.color.noInternetAccent))); - if (fabFilter.getParent() != null && fabFilter.getParent() instanceof View) - ((View) fabFilter.getParent()).setBackgroundColor(getResources().getColor(R.color.noInternetBar)); - } - } - } else { - if (noInternet != null) noInternet.setVisibility(View.GONE); - if (viewPager != null) viewPager.setBackground(null); - if (getSupportActionBar() != null) - getSupportActionBar().setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color.colorPrimary))); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) - getWindow().setStatusBarColor(getResources().getColor(R.color.colorPrimaryDark)); - if(findViewById(R.id.tabs) != null) - findViewById(R.id.tabs).setBackgroundColor(getResources().getColor(R.color.colorPrimary)); - if (fabFilter != null) { - fabFilter.setBackgroundTintList(ColorStateList.valueOf(getResources().getColor(R.color.colorAccent))); - if (fabFilter.getParent() != null && fabFilter.getParent() instanceof View) - ((View) fabFilter.getParent()).setBackgroundColor(getResources().getColor(R.color.colorPrimary)); - } - } - }).snackbar(Snackbar.make(viewPager, "Not connected to internet.", -2) - .setAction("Settings", view -> startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS)))); - } - - @Override - protected void onResume() { - super.onResume(); - appBarLayout.addOnOffsetChangedListener(this); - } - - @Override - protected void onPause() { - super.onPause(); - appBarLayout.removeOnOffsetChangedListener(this); - } } \ No newline at end of file diff --git a/app/src/main/java/awais/backworddictionary/asyncs/SearchAsync.java b/app/src/main/java/awais/backworddictionary/asyncs/SearchAsync.java index df9c7a0..40a6ee1 100644 --- a/app/src/main/java/awais/backworddictionary/asyncs/SearchAsync.java +++ b/app/src/main/java/awais/backworddictionary/asyncs/SearchAsync.java @@ -5,39 +5,31 @@ import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; -import com.lapism.searchview.SearchItem; -import com.lapism.searchview.SearchView; import java.net.URLEncoder; import java.util.ArrayList; import java.util.List; -import java.util.concurrent.atomic.AtomicReference; import awais.backworddictionary.custom.WordItem; +import awais.backworddictionary.interfaces.MainCheck; import okhttp3.Call; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; -import static awais.backworddictionary.Main.searchAdapter; - public class SearchAsync extends AsyncTask> { private static OkHttpClient client = new OkHttpClient(); - private final AtomicReference mSearchView = new AtomicReference<>(); - private ArrayList suggestionsList; private static Call call; + private final MainCheck mainCheck; - public SearchAsync(SearchView mSearchView) { - this.mSearchView.set(mSearchView); - this.suggestionsList = new ArrayList<>(); - searchAdapter.setSuggestionsList(suggestionsList); + public SearchAsync(MainCheck mainCheck) { + this.mainCheck = mainCheck; } @Override protected void onPreExecute() { super.onPreExecute(); - if (mSearchView != null && mSearchView.get() != null) - mSearchView.get().showProgress(); + mainCheck.beforeSearch(); } @Override @@ -85,19 +77,6 @@ protected ArrayList doInBackground(String... params) { @Override protected void onPostExecute(ArrayList result) { super.onPostExecute(result); - if (!isCancelled()) { - if (mSearchView != null && mSearchView.get() != null) - if (mSearchView.get().isShowingProgress()) mSearchView.get().hideProgress(); - if (!result.isEmpty() && mSearchView != null && mSearchView.get() != null - && searchAdapter != null) { - if (suggestionsList != null) suggestionsList.clear(); - else suggestionsList = new ArrayList<>(); - for (WordItem item : result) suggestionsList.add(new SearchItem(item.getWord())); - searchAdapter.setData(suggestionsList); - searchAdapter.setSuggestionsList(suggestionsList); - searchAdapter.notifyDataSetChanged(); - mSearchView.get().showSuggestions(); - } - } + mainCheck.afterSearch(result); } } diff --git a/app/src/main/java/awais/backworddictionary/asyncs/WordsAsync.java b/app/src/main/java/awais/backworddictionary/asyncs/WordsAsync.java index 607bff8..93d2efe 100644 --- a/app/src/main/java/awais/backworddictionary/asyncs/WordsAsync.java +++ b/app/src/main/java/awais/backworddictionary/asyncs/WordsAsync.java @@ -1,9 +1,6 @@ package awais.backworddictionary.asyncs; -import android.app.Activity; import android.os.AsyncTask; -import android.support.v4.widget.SwipeRefreshLayout; -import android.support.v7.widget.RecyclerView; import android.util.Log; import com.google.gson.Gson; @@ -12,7 +9,6 @@ import java.net.URLEncoder; import java.util.ArrayList; import java.util.List; -import java.util.concurrent.atomic.AtomicReference; import awais.backworddictionary.Main; import awais.backworddictionary.custom.WordItem; @@ -29,17 +25,10 @@ public class WordsAsync extends AsyncTask> { private final Request.Builder builder = new Request.Builder(); private Response response = null; - private final AtomicReference refreshLayout = new AtomicReference<>(); - private final AtomicReference recyclerView = new AtomicReference<>(); - private final AtomicReference activity = new AtomicReference<>(); private final FragmentCallback fragmentCallback; - public WordsAsync(Activity activity, FragmentCallback fragmentCallback, String word, String method, - SwipeRefreshLayout refreshLayout, RecyclerView recyclerView) { - this.activity.set(activity); + public WordsAsync(FragmentCallback fragmentCallback, String word, String method) { this.fragmentCallback = fragmentCallback; - this.refreshLayout.set(refreshLayout); - this.recyclerView.set(recyclerView); this.word = word; switch (method) { case "Reverse": this.method = "ml"; break; @@ -48,8 +37,8 @@ public WordsAsync(Activity activity, FragmentCallback fragmentCallback, String w case "Synonyms": this.method = "rel_syn"; break; case "Antonyms": this.method = "rel_ant"; break; case "Triggers": this.method = "rel_trg"; break; - case "Part of": this.method = "rel_par"; break; - case "Comprises": this.method = "rel_com"; break; + case "Is Part of": this.method = "rel_par"; break; + case "Comprises of": this.method = "rel_com"; break; case "Homophones": this.method = "rel_hom"; break; case "Rhymes": this.method = "rel_rhy"; break; default: this.method = "ml"; @@ -59,13 +48,7 @@ public WordsAsync(Activity activity, FragmentCallback fragmentCallback, String w @Override protected void onPreExecute() { super.onPreExecute(); - activity.get().runOnUiThread(() -> { - refreshLayout.get().setRefreshing(true); - recyclerView.get().setClickable(false); - recyclerView.get().setEnabled(false); - recyclerView.get().setFocusable(false); - recyclerView.get().setLayoutFrozen(true); - }); + if (fragmentCallback != null) fragmentCallback.wordStarted(); } @Override @@ -104,14 +87,8 @@ protected ArrayList doInBackground(String... params) { @Override protected void onPostExecute(ArrayList wordItems) { - if (wordItems != null) if (fragmentCallback != null) fragmentCallback.done(wordItems, word); - activity.get().runOnUiThread(() -> { - refreshLayout.get().setRefreshing(false); - recyclerView.get().setClickable(true); - recyclerView.get().setEnabled(true); - recyclerView.get().setFocusable(true); - recyclerView.get().setLayoutFrozen(false); - }); + if (fragmentCallback != null) + fragmentCallback.done(wordItems, word); super.onPostExecute(wordItems); } } \ No newline at end of file diff --git a/app/src/main/java/awais/backworddictionary/custom/AdvancedDialog.java b/app/src/main/java/awais/backworddictionary/custom/AdvancedDialog.java index 05d2d21..30d1d63 100644 --- a/app/src/main/java/awais/backworddictionary/custom/AdvancedDialog.java +++ b/app/src/main/java/awais/backworddictionary/custom/AdvancedDialog.java @@ -18,9 +18,9 @@ import awais.backworddictionary.interfaces.FragmentLoader; public class AdvancedDialog extends Dialog implements CompoundButton.OnCheckedChangeListener { - private FragmentLoader fragmentLoader; + private final FragmentLoader fragmentLoader; private List checkBoxes; - private boolean enabledChecks[] = {true, true, true, true, false, false, false, false, false, false}; + private final boolean[] enabledChecks = {true, true, true, true, false, false, false, false, false, false}; private String bools; public AdvancedDialog(Activity act) { @@ -79,9 +79,7 @@ protected void onCreate(Bundle savedInstanceState) { fragmentLoader.loadFragments(false); dismiss(); }); - (findViewById(R.id.btnCancel)).setOnClickListener(view -> { - dismiss(); - }); + (findViewById(R.id.btnCancel)).setOnClickListener(view -> dismiss()); } @Override diff --git a/app/src/main/java/awais/backworddictionary/custom/HuaweiFix.java b/app/src/main/java/awais/backworddictionary/custom/HuaweiFix.java index d0d4f12..68b4ff1 100644 --- a/app/src/main/java/awais/backworddictionary/custom/HuaweiFix.java +++ b/app/src/main/java/awais/backworddictionary/custom/HuaweiFix.java @@ -68,11 +68,11 @@ private void huaweiProtectedApps() { } catch (Exception ignored) { } } - @SuppressWarnings("JavaReflectionMemberAccess") private String getUserSerial() { - @SuppressLint("WrongConstant") Object userManager = context.getSystemService("user"); - if (userManager == null) return ""; try { + @SuppressLint("WrongConstant") Object userManager = context.getSystemService("user"); + if (userManager == null) return ""; + //noinspection JavaReflectionMemberAccess Method myUserHandleMethod = android.os.Process.class.getMethod("myUserHandle", (Class[]) null); Object myUserHandle = myUserHandleMethod.invoke(android.os.Process.class, (Object[]) null); Method getSerialNumberForUser = userManager.getClass().getMethod("getSerialNumberForUser", myUserHandle.getClass()); diff --git a/app/src/main/java/awais/backworddictionary/custom/MenuCaller.java b/app/src/main/java/awais/backworddictionary/custom/MenuCaller.java index 1247faa..051fc2a 100644 --- a/app/src/main/java/awais/backworddictionary/custom/MenuCaller.java +++ b/app/src/main/java/awais/backworddictionary/custom/MenuCaller.java @@ -96,9 +96,9 @@ public void onClick(View view) { helpBuilder.append("find antonyms of give word\n\n", new BulletSpan(26, 0xFF212121)); helpBuilder.append("Triggers:\n", new RelativeSizeSpan(1.1f), new StyleSpan(Typeface.BOLD), new ForegroundColorSpan(0xFF212121)); helpBuilder.append("find words which suit the given word or are associated with the word in paragraph or text\n\n", new BulletSpan(26, 0xFF212121)); - helpBuilder.append("Part of:\n", new RelativeSizeSpan(1.1f), new StyleSpan(Typeface.BOLD), new ForegroundColorSpan(0xFF212121)); + helpBuilder.append("Is part of:\n", new RelativeSizeSpan(1.1f), new StyleSpan(Typeface.BOLD), new ForegroundColorSpan(0xFF212121)); helpBuilder.append("find words which are part of or are meronyms of given word\n\n", new BulletSpan(26, 0xFF212121)); - helpBuilder.append("Comprises:\n", new RelativeSizeSpan(1.1f), new StyleSpan(Typeface.BOLD), new ForegroundColorSpan(0xFF212121)); + helpBuilder.append("Comprises of:\n", new RelativeSizeSpan(1.1f), new StyleSpan(Typeface.BOLD), new ForegroundColorSpan(0xFF212121)); helpBuilder.append("find words which is/are part(s) or component(s) of given word\n\n", new BulletSpan(26, 0xFF212121)); helpBuilder.append("Rhymes:\n", new RelativeSizeSpan(1.1f), new StyleSpan(Typeface.BOLD), new ForegroundColorSpan(0xFF212121)); helpBuilder.append("find words which perfectly rhyme with given word\n\n", new BulletSpan(26, 0xFF212121)); @@ -127,8 +127,8 @@ public void onClick(View view) { licensesBuilder.append("OkHttp3 [Apache License 2.0]\n", new BulletSpan(26, 0xFF212121)); licensesBuilder.append("GSON [Apache License 2.0]\n", new BulletSpan(26, 0xFF212121)); licensesBuilder.append("SearchView [Apache License 2.0]\n", new BulletSpan(26, 0xFF212121)); - licensesBuilder.append("Chrome Custom Tabs [Apache License 2.0]\n", new BulletSpan(26, 0xFF212121)); licensesBuilder.append("NoNet [Apache License 2.0]\n\n", new BulletSpan(26, 0xFF212121)); + licensesBuilder.append("Chrome Custom Tabs [Apache License 2.0]\n", new BulletSpan(26, 0xFF212121)); licensesBuilder.append("License:\n", new StyleSpan(Typeface.BOLD), new RelativeSizeSpan(1.1f), new ForegroundColorSpan(0xFF212121)); licensesBuilder.append("Apache License 2.0", new BulletSpan(26, 0xFF212121), new ClickableSpan() { @Override @@ -175,7 +175,7 @@ void append(String text, Object... styles) { } SpannableStringBuilder build() { - SpannableStringBuilder ssb = new SpannableStringBuilder(stringBuilder.toString()); + SpannableStringBuilder ssb = new SpannableStringBuilder(stringBuilder); for (SpanSection section : spanSections) section.apply(ssb); return ssb; } diff --git a/app/src/main/java/awais/backworddictionary/custom/WordDialog.java b/app/src/main/java/awais/backworddictionary/custom/WordDialog.java index f63b318..4ba6a00 100644 --- a/app/src/main/java/awais/backworddictionary/custom/WordDialog.java +++ b/app/src/main/java/awais/backworddictionary/custom/WordDialog.java @@ -13,6 +13,7 @@ import android.speech.tts.TextToSpeech; import android.support.customtabs.CustomTabsIntent; import android.support.v7.widget.DialogTitle; +import android.support.v7.widget.PopupMenu; import android.text.SpannableStringBuilder; import android.text.Spanned; import android.text.style.StyleSpan; @@ -33,16 +34,17 @@ import awais.backworddictionary.R; import awais.backworddictionary.customweb.CustomTabActivityHelper; +import static awais.backworddictionary.Main.boolsArray; +import static awais.backworddictionary.Main.tts; + public class WordDialog extends Dialog implements android.view.View.OnClickListener { private final WordItem wordItem; - private final TextToSpeech tts; private final Activity activity; - public WordDialog(Activity act, WordItem wordItem, TextToSpeech tts) { + public WordDialog(Activity act, WordItem wordItem) { super(act, R.style.Dialog); this.activity = act; this.wordItem = wordItem; - this.tts = tts; } @Override @@ -88,8 +90,8 @@ protected void onCreate(Bundle savedInstanceState) { lvDefs.setOnItemClickListener((adapterView, view, i, l) -> { SpannableStringBuilder wordItem = (SpannableStringBuilder) adapterView.getItemAtPosition(i); - if (wordItem != null && !wordItem.toString().isEmpty() && wordItem.toString().contains("\t")) { - String item = wordItem.toString().replaceAll("^(.*)\\t", ""); + if (wordItem != null && !String.valueOf(wordItem).isEmpty() && String.valueOf(wordItem).contains("\t")) { + String item = String.valueOf(wordItem).replaceAll("^(.*)\\t", ""); try { android.content.ClipboardManager clipboard = (android.content.ClipboardManager) activity.getSystemService(Context.CLIPBOARD_SERVICE); if (clipboard != null) @@ -113,16 +115,14 @@ protected void onCreate(Bundle savedInstanceState) { Button google = findViewById(R.id.btnGoogle); Button wiki = findViewById(R.id.btnWiki); Button urban = findViewById(R.id.btnUrban); - Button reverse = findViewById(R.id.btnReverse); - Button soundslike = findViewById(R.id.btnSoundsLike); + Button search = findViewById(R.id.btnSearch); copy.setOnClickListener(this); speak.setOnClickListener(this); google.setOnClickListener(this); wiki.setOnClickListener(this); urban.setOnClickListener(this); - reverse.setOnClickListener(this); - soundslike.setOnClickListener(this); + search.setOnClickListener(this); } @Override @@ -168,7 +168,7 @@ public void onClick(View v) { case R.id.btnWiki: String wordRawWiki = wordItem.getWord().replace(" ", "_").replace("\\s", "_"); - try {wordRawWiki = new URL(wordRawWiki).toString();} catch (Exception ignored) {} + try {wordRawWiki = String.valueOf(new URL(wordRawWiki));} catch (Exception ignored) {} Intent intent1 = new Intent(); intent1.setAction(Intent.ACTION_VIEW); @@ -188,27 +188,55 @@ public void onClick(View v) { Uri.parse("http://www.urbandictionary.com/define.php?term=".concat(wordItem.getWord()))); break; - case R.id.btnReverse: - if (activity.getClass() == Main.class) { - ((Main)activity).adapter.getItem(0).title = wordItem.getWord(); - ((Main)activity).viewPager.setCurrentItem(0, true); - ((Main)activity).onSearch(wordItem.getWord()); - } - break; - case R.id.btnSoundsLike: - if (activity.getClass() == Main.class) { - try { - ((Main)activity).adapter.getItem(1).title = wordItem.getWord(); - ((Main)activity).viewPager.setCurrentItem(1, true); - ((Main)activity).onSearch(wordItem.getWord()); - } catch (Exception e) { - Log.e("AWAISKING_APP", "", e); - } - } - break; + // TODO FIX +// case R.id.btnFirst: +// if (activity.getClass() == Main.class) { +// ((Main)activity).adapter.getItem(0).title = wordItem.getWord(); +// ((Main)activity).viewPager.setCurrentItem(0, true); +// ((Main)activity).onSearch(wordItem.getWord()); +// } +// break; +// +// case R.id.btnSecond: +// if (activity.getClass() == Main.class) { +// try { +// ((Main)activity).adapter.getItem(1).title = wordItem.getWord(); +// ((Main)activity).viewPager.setCurrentItem(1, true); +// ((Main)activity).onSearch(wordItem.getWord()); +// } catch (Exception e) { +// Log.e("AWAISKING_APP", "", e); +// } +// } +// break; + + case R.id.btnSearch: showPopupMenu(v); return; default: break; } dismiss(); } + + private void showPopupMenu(View view) { + PopupMenu popup = new PopupMenu(view.getContext(), view); + popup.getMenuInflater().inflate(R.menu.menu_search, popup.getMenu()); + + for (int i = 0; i < boolsArray.length; i++) + popup.getMenu().getItem(i).setVisible(Boolean.parseBoolean(boolsArray[i])); + + popup.setOnMenuItemClickListener(menuItem -> { + if (activity.getClass() == Main.class) { + try { + int index = ((Main) activity).getItemPosition((String) menuItem.getTitle()); + ((Main)activity).adapter.getItem(index).title = wordItem.getWord(); + ((Main)activity).viewPager.setCurrentItem(index, true); + ((Main)activity).onSearch(wordItem.getWord()); + } catch (Exception e) { + Log.e("AWAISKING_APP", "", e); + } + } + dismiss(); + return true; + }); + popup.show(); + } } \ No newline at end of file diff --git a/app/src/main/java/awais/backworddictionary/customweb/WebViewActivity.java b/app/src/main/java/awais/backworddictionary/customweb/WebViewActivity.java index 81f5215..cc84c06 100644 --- a/app/src/main/java/awais/backworddictionary/customweb/WebViewActivity.java +++ b/app/src/main/java/awais/backworddictionary/customweb/WebViewActivity.java @@ -1,6 +1,5 @@ package awais.backworddictionary.customweb; -import android.annotation.SuppressLint; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.MenuItem; @@ -12,7 +11,6 @@ public class WebViewActivity extends AppCompatActivity { - @SuppressLint("SetJavaScriptEnabled") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -21,7 +19,7 @@ protected void onCreate(Bundle savedInstanceState) { WebView webView = findViewById(R.id.webview); webView.setWebViewClient(new WebViewClient()); WebSettings webSettings = webView.getSettings(); - webSettings.setJavaScriptEnabled(true); + webSettings.setJavaScriptEnabled(getPackageName().startsWith("awais")); setTitle(url); if (getSupportActionBar() != null) getSupportActionBar().setDisplayHomeAsUpEnabled(true); webView.loadUrl(url); diff --git a/app/src/main/java/awais/backworddictionary/interfaces/FilterCheck.java b/app/src/main/java/awais/backworddictionary/interfaces/FilterCheck.java index 27b7510..64c2ba4 100644 --- a/app/src/main/java/awais/backworddictionary/interfaces/FilterCheck.java +++ b/app/src/main/java/awais/backworddictionary/interfaces/FilterCheck.java @@ -2,6 +2,7 @@ import android.support.design.widget.FloatingActionButton; +@SuppressWarnings("unused") public interface FilterCheck { void isOpen(boolean opened, FloatingActionButton fab, int method); } diff --git a/app/src/main/java/awais/backworddictionary/interfaces/FragmentCallback.java b/app/src/main/java/awais/backworddictionary/interfaces/FragmentCallback.java index fa30b4e..cc0c356 100644 --- a/app/src/main/java/awais/backworddictionary/interfaces/FragmentCallback.java +++ b/app/src/main/java/awais/backworddictionary/interfaces/FragmentCallback.java @@ -5,4 +5,5 @@ public interface FragmentCallback { void done(ArrayList items, String word); + void wordStarted(); } diff --git a/app/src/main/java/awais/backworddictionary/interfaces/MainCheck.java b/app/src/main/java/awais/backworddictionary/interfaces/MainCheck.java new file mode 100644 index 0000000..b8a1eed --- /dev/null +++ b/app/src/main/java/awais/backworddictionary/interfaces/MainCheck.java @@ -0,0 +1,10 @@ +package awais.backworddictionary.interfaces; + +import java.util.ArrayList; + +import awais.backworddictionary.custom.WordItem; + +public interface MainCheck { + void beforeSearch(); + void afterSearch(ArrayList result); +} diff --git a/app/src/main/res/drawable/dialog_back.9.png b/app/src/main/res/drawable/dialog_back.9.png index 7e693de7ddf9b6833e8cf63066434959d2463dfe..9c86870c82356dd367e6859889c374393672c79c 100644 GIT binary patch delta 530 zcmV+t0`2{e1giv)B!BWrL_t(|+U=TsO9DX<#t)^yASo~~3KR+hg}^`|Fi;W-5(9(6 zKp{w|@Baa=y&bHiP)^8|fwVg%AHLina3JDs zv7duNM?giyN%=~KI~5cpnqnNaSh_6en}05>i@vG zp$BXZYlM(9167qI>xt^ zSe~^w?tTY_Zi@tkx`sQ2F8Hp9wZ4rzDAW(=8ISY?eI@QI^|jAKq5C31p@HE+VE}%h znpM&{*NoFwTM6k3vrY&&J~!y@tFe32P|ylEOrZCn-I) z4~3=yuL3QXR-eY4t<8Wp;b$qa%ttw_TYJyRN6vn0pMtq^o-2K_K9A|Mwg^}nADx#X zw@An>V(vyYYhMLpZ58lsSP37US1CCyj(V;A$CTQCh+Wv^P5u@$+Xj@C#9+tLQrtQjU+ke{s8EF5|p#A5>FBtC+o37H) U!eZbW01E&B07*qoM6N<$f@1gjFaQ7m delta 501 zcmV_26S`3bvjpoXbnL8vH0W-|rhgwHlbFWB%0$-fCn4hz zGGrk{gd9icG(RDOjh>&;Ea*~xbTfQ`jn$IF$`>+x7+Pj+yac1De={9+I&_*(S+M?t z&eJu|iA|rfp!38srSO^`Q6Q+P0xFRw>PH^itQ^A>)kvUY=N^&XyR*q~*u_q48kV4F zzTm32CMOw*3V*W>Mo{AbQN)~~Oucu*ha!PZQ*u5ls+wW-!3Y4DnXiP6h-e!*f{cs} zHG``RVHsM6mZ4>68Cr&xp=IbT4bg@<72#NtPeh+r=iZMbzgL|mTGjceRh{^H)fu)8 zkby^`E2%TIs>(^Pss%}`yQI3+l}Uif^}23AF|`8uV{SbC)S7CqlAw;Fx_1UT4W3XX zzYMyDqHaqc^p$k~=uF^Cb;KHqdVGBVvZ1c!jGQ6Vhwa8@PVFqWBy^|z2nGQV40I}_ r8g!Sv&(LN;q|HFr0%-R2Z65-(Y00000NkvXXu0mjf^Cb37 diff --git a/app/src/main/res/drawable/no_internet.9.png b/app/src/main/res/drawable/no_internet.9.png index 614221111cff8d96fb2964af4b5b34077de7c169..64925e3093d517442aa6c98837277875d00da90c 100644 GIT binary patch literal 44564 zcmeFZc{r7A_dmRoGG(4B3R~uR$dn=3k~twWnKN%wW|CwhWJn3QDan{IGAm_Dl8|{U zMUgp#cU^SfkLUS5-(TEZa9Mxs-bNrm^T*GIrtMKz0N~FX`iBTvNsq#6@1r!Po zi$d*7B0LD65EUNsK>op=GjK;K>~=c(9{TEPQkE`G{N`3J7S{aU zPS6#8q~*M^=9UiD9?TZjwsy`k=((yoG_#$R3|jA`x}Z8%!TPe@IbSzxZC?!?OJ4^| zNh`FREU~n=6b#^G?P1RB?d0g}F6AwQ-WgX4o{^6Q(9AncJRD@u^2mhD`s(MI6Wfm3`5)%-V6c7^S6BLpXl#~(_V*d4mmL-NKX*Vky zsSB91zovuVWYCvAJg`y%0$yHT{9YpbE^f90LXwh_0)oN|C6gk#Wr}Ts%Ew&}d|$e|~=L%L)6>M9%KNumcnYyv?x!Li~aP z|E-giDMmAxHa`D0hOnfLkdTy!u#~9y-ZA#H{LeAq{#coNnE$^TWpCR(<5*cr*|@klnS03E zIhos93t*jXr3L==;hvWNNR^a=i=&GhEX!I}L|Wj#eY~gFj-*K`JG*SV`Sk2 zemgrWDPe1ilY-(Bl6+Ry!sdJ@MMWj~EF^8r`OL+v%mq)13Q9_d+3bL*uD-YX{}>wM zV(E$8mS00#{a+5fr~CgHTGP!AG@ZHQo;Jwp|8J-GFT?zgsm|HCgM9kzkz0`79bKkv z?fUPZ{{4lc-HuMen!CAMBR5V4{r8poM~VHTqmVv3H&@Es647R|mdJ&$wvrb3w@?4I ztbcm`>Sp)<^#FIr-_!knpTq02we$b!LhTN<)9Qa8#NEZl!^_;wTHY39;{VNE-yQYe zyZz_z(gKL~ceMNWgV_D_-_Pf7iT$7FDUB#KDUbzNm-)^a2uTb4kI()!^KN^6Z$8&=OHWnYqtORcuy}x^X{qzZEzB- zWyMaO6gep^@Sh+5XOHuC-qw!#7(2MX?ub;135)*f^q=4S*PaId>IwQ{Z_hp7{OY-T zSbGfm&ROn$3hn}UDgytwD*t}W|6GOtpCA6UrT?D?-aFi%N%o@g+vh)U{T8CV4gSEj z7meRO|AFhb5bbU72d=$n{Py_|T)%~AZ-YN@?M36a&wt?hEkt`8{DEsP8oz!11J`dM z+S}j{Tzk>@?eibFehbmw27ln%i^gxC|G@QIi1s%41J_6f8hEpM0*?j zfom@szkU7#*KZ-(+u#ped(rsq^B=f=3(?*Nf8g4S#&4hh!1Y^*_BQwf*IqP!`}_y4 z-$Jyv!5_HxqVe13KXCmPqP-3Nz_k~R-#-6=>$ec?ZSV)Ky=eUQ`43#bg=lYsKXC0u z|m8KYF_Gj^5_~O<2AEJT@DMQeN@9-N; zPrpUJ`=eV8C(wdlMmEs|f{Xah z$u)-SyhbV(HVInEj&s%-q~|QWb?OewnU&Jf@)=2wXx+#m*BvqncsyN@)2dK@O!|DF z``Xri>y6b}hVr1fT2}({gpmpuD^lF)g9LV2AXnvz^N8!4%99S7n`2dTLy`1+t@?sN zwQEJs+&$X~hlM_pIgm1ADI^FP8%eKvQlyzhIG=F~b?vc(3pnivzDy(iu#D=#%QW`IqA_6_drCkJkE46*$yH-9NA| zZChLRup!67^W(}Cx!uhfla@b@*qf7tvKdGn(K+L#Kdn=DN0X}Y=t;D|*RhavPozUy z)2X2C;ed&Yf!hjS;9MUKxv$F5t*pL(jJ^^UO4dPewO)QyDyCk37=_CuG(uC_y}Eh) zLBPk4ce-SMj)r{guFIP)ao>m*x=q02{3J(u>9l3Q3su>eRS~ub_Uk_a;+Vw>aRxsQ zH!H;otsUOp@}@iz`WuNM_lRe_q9*;8?YC{NGT?PT8`m~E%`qkc@ z88bvf-w&s0JVhZPd6S;->R}2oI`fJ3m2VE!6Dz0Q(FquOtPc7rXpSD-9TJaNGo(OvhTfYJ4*g7>|>xaxnI@1&LqoZy+)o-QG zmSMJb#<}Zmr)4Sb?LI)AU-kf*mN+Uyh%ZMY+zpek-kwM&<)Ky@ng{=zPO?_AzwKgsuF zp&=}|t=RG)XC>j@IcqTq#^h9Rv;1g!Zhq*=Xk$h== z*NvM-wh~W{_(f%wmWtlS#WmeL9)Bol=fIYT8E32Zy&W5W)o*@+n$oNNg9EQwz?$`3 zP1ULzoIO*?`^&da;7r+_EJPIXDJmwa;yFq(2m#fw6Y_b4>-*ctb#;cztrwrLG9{l9 zkHS?vfBu}t(~7KvZ$~gqN10tv9^Mh9W_5x6B^|N@-)B$F(QGbsb+B@iUzGm5x?XF( z*;B2Q`}!*{Uhg43jW16pO^-#|`zo3~w#x45AcN6s{QJt;NIrFFdQ}ZEs@id!*#W87 z6#?n52aVsb5v7HNZ+}cuYtr~{_1W6?cE7Jh!$p7h^C^*hc=d}b(&(P-1G9&PdnZ#H z3Qv%z=sGB_HTWe8Y&@OQ)|CCy+S>Z=?C_lzi-=09SfP{{^n!7TsV?9+morENik}#i ztzWxQxqb&Zy>~I{o=@_heJWR?j-OB$diu0pk)bI$&WSiY)4%~BAv$o4hy3e6P}_p_ zNFs$6w~=Nh9}$KO(bP^Su(-;7Z?(o>se>{pTG(JZsFT1{ot0j&MXETc!}V?=QH;CiOv$!aGOt3rMvqi#fSgDPFW5E`;k<3**VS)Xtw>4X0)| zG&sOB+k)Jug4=Xt3kOeEMKVwx8TOxu(&lL;m!7LUDciel)G0A} z1{8U_j)0Nbnsi$7XInTU883FEQ9x~SMf81l-Oqt1M*JHV^W$jr`1=z5`8PYN)tV&i z4(h5Hb-B=krW3^>l1aGIJ0`wK-&O{kJ4{OKm+!t>zo7`%Tetfm)d`N-*ynZPgk$wUA^w^le2{w6=Erj_!+l=km`?A{Ue(c>iBDFY`-F-+RCq zwoi;ou6Te|vh7p55QI5(EBb5v!G3`NZl%2P#)l>VpcGtMzLB6&&9*xM1FQFndi8a_ zDPiUQUQ&PhX_io&$IF*5d+4_p)8YW5<2LPHADdNY$8ZNLDN;2Ad`w}D{zLc59!$Ny zpQ?z-_8JTfBijKRj3_FJ z$I`dTkVehrudm&SMPQ85w$-nGN1{3L!pK0bB$bF!uqYaRoRg2@CN)XR67^6V~3 zxB=JFHB>4OUY0aZ+zA}1O8N`iv_Ri`?+zXAlt2ZCfE7YXtUVqW^Z3F>Zx&~w>+{(_ z_Hci0M8z?^ZLxEQA{alEu!e5;9+H?`^sf8qycR);v9g+YCfKJNC z>bm(6ml=0Y230CLEw(aU^ky#cNyT65=er}*Ph-O_Xg$smO^8Y453LWTYfe6@MaPER zF4qAUBMv_QkGGwtFAt{lm2~1ChSLoJfAXFkX$Bkm#Y=jVufA)Uch-y02h1vxDAn@? zr-?nrpR%gVP#PqVsT%9YWx}m`R`6(Lgk0vwrG1oN3`EJiCVruMn$1Ne)XrW@EB0Fp z$9>LhFu-{fnsH7m=6iUPpF!^)^ZS(W~S~!wGeEFJ5uU2VIKiRgu>!&%*XG?rG zO-H;OF6JK(N#Oo$_?C5B&Qw=Vdn3J>MEC108djr_)9BL#tw#FCNE7ip z>6Zw4zKvAPbv)rW{tzP56qdX_E)xdg1a5PqXY0~J8-K_8LZrYO^7Z`;`nR(WM;{g= z_u1dc=~>K41afiS$fV@^cqIRok5g00#l^)5TE@420e9NC#Yk9HGHH9gnN?4hh?Kivc=lYEz_GhfvF-EnZpD_Jn`+DvENX8z=8@PaJ{ z%u(3r*rV!mN!JcjR=l8QJR!g2!ysdZcnb%t0*GD!$)V8Hrd`5V)oc`0Mdp(0 z*5p*qU8%SvPse6Jg()T7SL7i+`~BE6Sjk#4o2tM)m?n~T>h$<8fe|vvyM&cWwPOnW z-tY`gIkL~BoRygN9?ls>A+qpjn!en!>qeBeDd;wi2!>ysia1@uB54Pmz1DAd&SV|j z4EBs;?kP?@q^_GZPR58+435{;vI5V+`IL^<+WYFM`!ng&^aSC^r3I8Rn^p%Dht=p! zytUrYN79=eCC2x9Y$$ZD{bu>K`e1#U3M{6I61?k$)(~1v%_?idK^<@u{?HMJ*;IoDn&C7BQh?{{U!s+cS2)3KRSVO+p5dmeV&zmOqb zqV!1cuerUFZ>b7Ad%rpJsJ$HN8^^rP`cCaIKl%7cJg>%736@4C$2=GPQgAj|;QxQ2 zyVG`?_@9M8s5Urw=aQuY4ooJ6(w1d)X$c-R@4s);wRHzN2V zHb-Zeku2;!j+gaDOtaD2COP$WilFm!ndjZXJ$2e9$rby^;)25Kt!`Al_CepsWU(igg#P}4zuT7jHC*ewTpBIy^3bn6 zr(1ln;jMF`*vs?2sNhp)?RB{vy+Mt=v7!ole(=|wPS(^v$A*p^a`pn#JpUO)lJDon zWnRoM3ctYG>8uqS)t%JTZ)i02-`KrMDNPEEZ|lBvQeGqQ^zY9038Z}l`g36~XL#4|Bg@H;@84?tw;GTr;c zjGgibj`IK&a_2wyeQ>)RLfW8+>hlAQHR3o%6vxF$=9Y{T z;F>M^RLcdfe92-BZ+_Lkbb?w7y>j9grmEt6nI^dVI7j|FJht5(b%WrEwhJM4iy6zo z;;MT)%(M#84B^ew9#Wo<)k1gg0i#RjwP;*kjo<1UlclvOOFY@_bsKIC7Az{oKRNb= zA}Of#si-PfWBMiBuWOrf`K8^ftTcZ&9|e<53uTH;b<(V``h9Qh1I8cjNU%-;IIf?n zW~+0JFn*MSVZZt@mR)YZVBWBVgn2kT&NUl+{+E3m99m`6+a?cMzgldW4sZuio8jC7*!q-?kc|w_jVcOnaE=4f#j5xa3 z;=9bQ9Q^g{NY+KPo6PFhk`RU&hAmhh4T}pRQc9y%5N*L7<%flqDTEzr*QGrb9gVg^CR85%Ah&_6;Z)$@kK>f9W4BaxyZjaZNF&~$ zPCU8WzCF-$?70@=Yvh;^!sa|~)o0JWC`wq7;?mA-uerzrFen* z@pjGnRO-8)Y)ai}oi?(No7virR`|hH^kHf21z|fgioy{G$M+3Mm=ewt&;@L*Sx=Fj z5+~Rk+g1G%fm+%mhVKx5$RQ4vqvj|6maj!H}IPds@sxU+*}=2^$Q%9?uy)Aiy1?BnyxH$&2Wn9_{1vQ z`|M8Va$AYiH`QPQNX`Ubk|eu?%AiuF%e(}#H(oyMzbK7%W4=wia}Vn~t@&I*Yqd-` zGd4v5siTT9eqvhVQ9g2|Dqt&8z$R$Dg=0u>yV(9Ma00LNbdUSi4}A7%pPCQ+y67!O z^5dr}P&zpe#vpuk%5(9~2Hz?hh$nI#rkqMIgbeA)GaTA}KrYAY?>IYH>Ni{4BplH1 zF#+DAWTKez1=S&q)8D-K+Bv-^PP0q>a?Y|t~?nZ%JdCY4soT0m@3 zM`o1if4+Avwet9Olib1M(&xA0D8^^tqGN(0dZy;Lsy$lbX26dTj{PNKx1NqDa(=vD zHCN>SeQRSD{PNTiu(WzT-S4;BfW0yWH#V63##5DRADAQK(sXf(!{(HIF}d5R-iH#l zO)qYiJgnS6?=m`^L>8ox{Q(Bxjp;0>=lFSj`{2{EUN)mbFJPD;WV_;6GaWcYDNLUv z#fIjf{FrA_V{`E>lSF+W6XPuu=2?A92F;RRfWr;aV?DPsFOZ(gJcB6t3JoqN+q8hE z=3l!lzs=RH4riY#pS%0n?y|q;WT*_FrgTnMn^EMOYnF5%xnvYuIBUzMX< zQo#4W8d`@Am%V1o(at(@CL5E5Zul6{ZwR(MqwmXf@4qMhJg|qah+K*(u}(M z?keZ*eUBWdwN+NJ_W+6OxjnKi_}9XvmmzQsZ#R={u*v6XDSmhuPb-mmFOSPme)hx_ zfwRgDz%G24SY4OxFLd6-LCD2KuX^WEp=hK=($i57sYT?XGb|C1J>E(=mySmCRC%Td)#Y5lbIem1<^IojvIhW$9~yux>$PuIOYX= z%9k<{C<}Cy?+*q^uwf9Aytuk=e`WFWhc8MlxU%m!5f%D3E9{zL80PeWmURcdT6S`E zJ+Y+9>6*&m_{UnkNPG=8H&bN_g|Y2+1L*=B8ui!2NA&{&V0nRsiI!V@EwYGfzHx2W z@1b{iNpuwb&h*L`>!*?>wpE}Tz0|>FLn~9<_A^~@)ro#pU4Lw1Ymico9FO4iYvL5J zilcUyf6gxVnlgm{Gs^g@B9iJ)X5vn@ML_3iCvxldJKO2*Iy84(( z!hnuVnX2&>qBwD!$?E!@=4bZr*tf`6cT`gO)oW(nR2i#oZH&kRi!KMgw|FGPbr030 zhjTg)(@D^1;M>o zQlw*H<$5MX=`OhU9^*MWAANBY;|^`BOy0GnrKKn*#U1NmtaEk<{L*17VS_CsL^?Xd zKnLWB^OcVLY*}Zpd#8;_7zal1L4>P3*Yh)DofNS*c26WaPq3SU(zeVnDujSkW80?X zT_n=G=yCE}H92uY#?P+_{8a00X_*}SE1u1D$Zd%tOptA2LV}fr#%_Q(^EScG+}xa) z(yra6#Am(q%K?U-{50-`GoidHER5$+7CroyUeP{P~@-cMkI(5_Q{M~~Ls!Y?xQ^d3FGk3x*_m_#x6NyhJM;+m<#W#TaDp@R%( z9d}&$iYrd7s+hAirfE;7r_5f3;x#zsG|W(uQKHO4-UdG!h#+LCt@Ymyo=VlQJ^uGX zYbN=UqOJ)|efnhcb*N_Q30RX=PA+Z6qo{WWllCjoITFDRCmM;U{iwAb<)CQ;el0V( zB{>?$8_%IW>-+umnuyvkhLL8cOH(&}!R+ljX0mlIBef>_G#W8SvUhx~0=|#!zAr!O zO}g|K&R-F0(!qULa+N^g7%*g|e+d{v0G8p?AtV0UzRaeGlhNkkuJ(Q!i_mK{$8#R1 zblh8vkf1?5Bt;WwH@sHGy^gIYRbcE^NFy$vODKb z7c;vF&6@%_)VhCTrS6h&(gKb%6?gM87v7E&qEV{+IshTrmY!`F2faH8X(uT%#5bzu^GK}cGrvKd$#)Mwb)52t^TrJF z#If}v@~k#&Xhc_N2R%=a{d5)HZ>FtVb9ecAo5eAdVA8%Fqj%D*6wIXO*$15}m?Mj3 z{`1CZO&hH7;zW1^cKcE2UjDhK@AXFt$Fe!n7+cvz9;S2bTIy5NHRa>u7Ce-anlj7p zuT3lH&J|u^p;Ao-Idnpu9`7GBS@o%|3S9d#HJ}@RMC~)tZeWLI`U#oMHys_~&xU4~ zZr;2(xH{rD7YFew_*+-q1oq<*xb8<$^~%oGoWKRcux3j$y-%7giYEX1duGEraURNN zpJY}C3&8+Afq;^$6V%j0QWVa3Bf5v`jQ1_1iJ5t6_;OpWeTJe<;2s zVHL>fPn@g6(P#)ia15wh6;G32Ge=gB0#_ADUo4svnW?4y_hG7ZX9wdLF$tTS5p(Q7 zkE=JGON9+OBOBC*>=Tuk%iz+F54lY%&oA@s+VCR*r&6SjopjTQK^AwN!Yp@s^U>WR2QYIJkG`|8HvwYv)|QqQv-xie%IT*I85vGClA_KT z>(B^a$CC|uS)4hNa8fHO!Vl4x#vC*fnOOOzSEW`m>*aN%kF#@3c^9scCyP$*^ii{+ zP&EBMH~efy5$&cVx(rqsmR2A_l)}CKs)(iK2$0jE$zqPxF_{`{j&CW%QOvHLUGG=V zD}Id2$jB(*jhe1^L_CrLcjA-_6@Tdw(?cGzs|2{jx`^uR*;;e=8`a2mMgtx^t^9O{ zhrcevtI<)Xlp49?Qjzu9#Pp>YD|72FvrctRn?~StKCYDDv9!DaAUvD-v8h1E)-p9e zyY{t9v#CVXo_(OMQv)9X1A~|4%n)}LBdKTNqpKX?G^C^v-}TI3BdyQ9>Le}T>XY!ikhgX7N8TT6@nYW#h`fV?8tN2A8O^+ zgQt{QTLzDTv(0}o#%X1z!_gm(n7>rjQPHoNnyeWqkeyifIpj@L-x8c;A->lL5W z9|(dAYCBsux3w=P5POhD7{O$o2dgqe!Rj~W9?n@;RBK*h??{Ia870&S{>o4d&XJ%? zeUM5&_$V`zwovx|-AE)(_&_W6dFQz;c-M%Q+%lP97uLV zD-`71VgY4_OlG_O{?+quvja9mVy_22_hnN_=%gb+G`_5t1;4Nm!fDO$$5)p_UR*-- z2LCX=hHikb_W~Z}N12~*6)b;TdYqorPL|BKbI+EDQ}k=M>xDxa&Nt$}QN-B%0*?dR zqOzWV8$1}2J_8i2-0KK>W+b`Cj4firUVzk+8Sqh_Qq&T=?Oi#sM2;Sby2@$MM`Rw2 zyjo^3)gxEFQ7``iS=i0`7SEGq$#0lEwQtZkFqy-8jE=)yXb2e+H}h z2oda^1p@Un?{loFJ{yrWp77z(<2PTX2;&TCuQQ|fib&ng; z3vJKKi39>lm3z-F}7&( z8%F~T*CtBDlJjvyDZ&?2_rnQ+sQ(pkZlpFKYN*oFJ*nMBobqFz<5Q8N)6?ZeTQ2QH z#(t_mEJEebsc4&8(39rCAgJbFbP%GhfP5;Ve#S4apK*09(zRoP3wz<`^Tm!4Mq>P2 zHhG$u3!(i62gt%0LFL~)oW*wCdmGAO(s=1qJJ@Y9cHO7LH!Il+Tf3~#@4V)QWhTn> z%w)U}WBP5dc47n={5tL~dPC*mam7(A=(6BQBA<9gxl_LkcJ4fnvFX7SKWRJ8TB_A3qyO6Ec#CfdUp{#hNQ8!ZM+{ zq{hI&z*ac8Ons+?PQn5_lDUWr~_&&iU!%XSCQ) zgO9%}{9LPdHcicZT+fvse5oCd%F)j!WCANN5uNy_oF;J~h7I=o25U zpfB~HevAVA3i>WQ4!G%1=#*KvS@|*PV_WU9?bbE{@_@M^uMS@*wQ)ykZmg%yTG+-( zBIxJ5%fvivfwBUs*s7a18#6+>nhWaE{K^tR({f(y_VhhT0-hvo@}}AY6ZO%GW@*^XD-Y`9!N_BY_u0I zLf|DEhhHR5mwA;}<=Qo=ac~`w{mT+(ZP_X#6cw916($V|VL*x^stY+jlk)=e8|2pZ z$xNwsv&TphVJ}{myha>ZElN+zP5(nkD)SCdyu+i5-g<&Q+KuXt+>p?TH1di3R2O#W z^r6}y*UtBM6vq?XnT1(dp`Pa$M6L(@w=zNEw+BIwX1dfZUwkvM{Ugj1B#|-xSp@}x zO+k&MBAZLAiTE+fq-~Gww90RNWqwZ~Gnk`3h4ZlEalDtRIQpDIg7G@2mnW8Fe#iNH$xQKRlT~9LSoP_^0op+8YMp2%)1+4 zQtweI_P(v-}<{{ zZII$3MzL@F=*4&30af&VUP(Jl_u-032tqs^X+Km>sUHOWS9GEtdabo~N@c6CHep~nK`t${8 z96y5uJjw++XKp7j(>(#aT$?4*C9)`*)j z$t5+=;Z9j@ZvuplX}l`wi4WDl#vCLR>;Z!t?vO>3|L!UGVPKHvkUc_1zC=IkdctJ~ zc?7hwvTE>!+}hg9JvLz>13+@=&~oA^B$}0I{G-jgHxD<{BiB28j*mM)$$%uT^=ilV zM6HZpmdwU$ku~1Kv5b6ZM5&eCuFj;0ee=<+FU@zMMYgQ_qze-JsOubj+5d_d|3;77O z$=V@AJRxgU)pz?ZGR<7XKsX6gwK$Y@vB6&z$VAQk`FHPf=)Uu2O4hgS~g&lA8lwe$s*4Q0YsN?-<%u}V~ zfj>k+vGgKCCOEgjAq)~_NGr{izbo;x){k4mnK3lRFjv3mS+mL^q&8UMXSAI=G5Ph! z16RCU{muC)rl6yqP}SI{+kSOG=I9PI_Q|&(1r~4m#EaLo^z$_+Q!8hacO(?=ybHmH z&ne|$xo}*>y=UgibS%cHXuLaED$0tg7jcZ&>c^s?8bZ+^p&Hm%ODM4lyXar#KMFN_ zdB-TD5E(F3AJ(62--1f5l*~ABE=D0To(xXJJ2^E>nDSnQ>%F#4EG-dbMMXl0PyY85 zPD%+bvJusDec^g}5un?_f~5(p%>@xGf9>nKAolF_`}>`UwVQqTk&lN*H8-&wVc9?^ z4v7o3fs5kfV7@%8HTM86$3Y=xtQ(0OQ=YD4`LTHfRR|M1{FlbUYFOu9?I=DDY+nD; z_tbLmeWymY)_dO}J5Q=sZn7srWKS`@-rNbwZMm>T3n{0YHLB}bc%ja8;fyup8F`oj zewe3qX`E`$vqz;M*GRK>MV%rj{ozc>oMl8l&#J%*L&X%azn# z-gCe{r2~i9RX*Z7qlOkP^Q@vowq>)QdmH z>2+;4e}vD^&gup^cc_Ss-t=4DT!TD=Ysun;XY^jg$W1E1%W4LNYEH}$V=d$L;n^Az z1De1<&9a7kvB+5aD0i}24)nG)<0mp z6+>V)K6!OQ!LR}_QO}d;KL>2@WcZX5qr#mqF zy$q;f1_vZPzmZ?Q{&8|r-%w#336>H|Nyd2TBExa-W~)|fyC9pg_V@%YYC0oSOf6~0 zJN&g2cj2Zt)i0(VLe&hSYij1#XEsZUi}N^mkfH+P$bry`A?MXqp4w!nIg0}RQ*pHa z#~TJv)3|+b4D{`IUS2eFT(>Gd(@Joi8OM}0X7}GrxwTVYpj5N^id(}8Gr1o4(u+Fa z_?-O}$wk~}BaVKxUz-3?Fr*3ARvHKL;kKzO;$lGk$ah|}aN6U)hp+(}6_X(3+4_DM zQSY*cbBMjZzCO1jWnl_TpqnF=!?l+q7B4d8_%3&cl5}u`|B;H@>EAx=XUW#_rbsV_ z56N8`#L^#SOCrN@|9Fxei8w4`Jhz+WpseIBO)jpjK36kCVVaH45W$d+s zW-|dgHfr-Nb!;lGxE4&Y0|=!oS_HG>9nr=!`hL^7t zgWSUOC?GyWi|U|$ z@iZVtcsqhXztKT-J(m<8Dk&fz+K=R-Hdg1-R56L4d_fST%Imp8NeowRRitRxZb1T7 zfQY4*F8LrxaM<#0Q20$YP!$Ry$G|_+sGV-jMe}HDBDlQ|B{_&z0Y(KfGOK#JsVW~t z!56J407r0^LL$$-di7>Jh(olsYTdKeG3>+Kh@)g9P|@IN8myh+lFfgot)Sb!WVUj# zKm-bsYukwFCpojF5Ox(U7t%u|L9Dvq(fx#L{L+p3ldRa@blg6?UQ?>9^&7&2=k@Bm z2csq;?p2Zlom7o?r`d7%?!9~W8eCI0hP;NKiHgC!zo1e&`dkPlD_g?a^{g{ zWsIy3Ma1#S&F5SbPr1Du2ewYz*x1ljO+VDVkWEqXh6}4QK#|(@MGdH#KFcS^2XY}d z>6ddKSVTf&(SqD&v8R0I%Ez0?dJ+Yzh(6t5^D$$PHKVAAwl!-M!LGW>ig=Z94$ERj znO(neVIvx$AmDq$+hLBafS-3@29#9Ah{6JiyG8fCH40~i7W0}x`{@89Re~hleQSnY zg%6NYRD7nZz+CC7a?$V?Y^y- z+FGEPWDskC#^(>j*WfZ0q|mz8_2o5#1ol#lI)m67>NC|!v~fF2`0{H5{Yp>jj|thR zf-*@9`e|nfuFCzqlXtf;kUIlgSAlQykq+&){G}^v04nt*Tf5#?sME2{UtT~$T=TA9 zhfo$%Kxt$j4pmtWa$BDt@Z??075=(a@c5}8ylbsV+bMiFSIMm6mWtfl{zqsoyViJri|SPol2|AgKJN& zb<_kg9$4thg4GXtdnVZO<)M#A#3f1>syz~V>Hr>nGF}#qz-I&flVP|8F?g3s(=KlA~K$wJRnXNGVh7hZj}W7n5x7_jTKpSm!(v0jkPEbu?jGTZS^zmGO>)a1!zCvyJ<0P#csF zg#%&-_6|`IE0JFC=*kx;SB$ohXJBAROTrJ1lnGY7_%4gF>ErE$1R4QI(OIGeepvc< zU9C4S`E{_is1DMN6y2x*hF@vOvVm_$@`AU8!Uh#aGhqHtH5cm@?5(Gi^&@jMjz-q}QQlevZwj3syX;nBf_2e6g;dW^62HKjSc$;M~+As~7Iy!Litd!1}bV&cVmsq=dVD5B6}H)?c-yti5N zSzGy03%$|rLsDcmc^vntr3wD(vxUlmt6Ax;x~sE8RgWW%lq#t{I5V1|H2VIVLUA}} z$49s2;UcFEjyUEUg)GefI`AoG{s&li4e1P|QLx~MFIn5^Ock+XP>MMcf|=&|d+Dyng5#m2J!r$TO+?Q)P*ET;{FMDsT0Ht= zcwRrYk}u}ATj1%Hnh&jq?n|pX$bbj#SVYK?neZw64tZmG;bx#Ufz=YLMoM6)wPuUn z?M}=`+4tJUy`aU4n>oW2a>Be*AuIx7;JW-Ht|33@Bn%R)(weGl;Wflr8~3*+HYI(p z@2x{6Nrv`l!j_92{NC~TQ4>~WG>GMjejaJ4~xeng_OYS`4kNzX+2A`!xd&C`s>>94|gf|aCEva$O z=r;K`3@9@etRcGCuB@LizC~vgE8!~#e2Bd}#H}9q>m{ywbO5Li zKSf1FlRjgQ%+zyK`26emAY@fgBf5r$@g# zhtM$-p+~?AD|-0w;Rh?>k0oO(ubKlvc}LS%oIneI_;%$^i&d+tvN9K=l+|Y(M3;Q@ zKEcQ<0)+)TBY5SUIVd!`$aGW!JNiX!R9F|uooS)5DkPNDl+WJ1dq;feph7tTllP@T zC^)=$9Z#NVM?D@u;e~lsX%nR|U-$0#%yX9fM20kE!Zb{pfq&5l6Q0=s-in&4Do>$d z{!8-LNg~M0Q%4`32mP&wf|pjxPnq#hvNZa^I~Fqch>XdqIMQ~>-0{?uoqgN z;iR@db_69sEuHjZ9K)VfyAusUxVX^^@23nVw=3$>Ll!Ors@E^GjAJE;p`?36&oppt z7-S?1Gg^2A5%68C?%S%;v6*l5I5C;}wU^m)g?#Jt%(Wsk_8=S_V_5-pEX5f8d~k4Z z>q+&`g&KdsNhm^SJO++Z4=ucsH9Yf%1M7F?+m=0Si8ZO-TJa*JL8MGamoSr)5^ug? zB`PPUrpUd)&Duf}p?5qUlYLj~$7*I1@Hq4mn10TV2vlQD+;78;j^0pB$ymC|n&AP- zfh$!t4p*+M)c2YOc#`3hJt*B>u&I|}Fm*0BdA{k7RvvAM=r)%eDq6hWBD^f~J5(a@ zd&$7JAz@+RH$GF}%9+d;*v%C{kNuj`qw8?v)ef`y*Ik;LR(N+*F?L`3X(45b{|1BM zkDgd?6f=r_X>sJomfzf_I$frB1UQq0o%>P2FZ@UiKM+I{4W_RS2dwfx===~$WGvOz z&jvw`>1bRxo~_{Fh}SlYl5;g1vkzS90^k}xAOLY%J<1qX4{47VUTu2P=7NVS-5BrC z_o?7R$^p;zBEH6xUN75Nz{XEPaxoHUilqk z!0U~t6}BqsOs1%~OkFWKIXO#-7bb=V3*zvVaq`nGR8kNXO*RB-UNc*5M& ziIca@l>_B?TfD;9e0=re1V~jEz89YGB2{%es~@LsuKekFTna_vr1tYTwf0-Dx2kkj z+!tQN4YKmKY`%!|r`%W`F|Qlx_`14!_Ge$?0~|>7+({f&ut;({o7!mf=K~Pnxdp$t z0mol?!VM)i*d&1{ zR!I8LZeyX>V5M;#wt1skF{?hHZoF!$-NxPJc70#pAx}c%QX*p;n@_hO$n7|E;98&~ zF|y?_l9adOyhA=-`f*RJVhbJF9aJz;Qn&Ew%0%E41bJK7)IQsk zoEzfcJ#*L|y%`yD439wS{3vAjvvZQb)EtdG{2mWd1T$KpN5%2N+GSVBFMH<1lB>E| z>c_PuRme14Z)QA@(Q_e5JIjJLJGlkzzH#^NL0!B^&SS%NZ(Z?vv%>8T!Lit}K1X8} zlai7Yj^7orJ*!|6kl9QkJ-efHwX_l_Y`$o*^cq`jev`2&rgfGLM?RpW6!HXMA`CSAj zbQ{~@0;KXzzfT(?SN+^Leztw^PI434t$|Q}MlImuci9lJfTtMK(Yj5WK5e+Jv=SjI zqm`9Iv+|o8t96qTF|xigG=%HV;~1mkMeS|rB^-Zr8kppq2l;Bx5w$x?O@|v`Qnsdi zrfRUSsW+!IhcNiX#vu)<0B&H-=+5|$mT1atGJs{>qQYR5)kfcibM`{=yuGcB!5iL@ zH$zg_a+y>TL<~@3I@6!?ozlO(Kj`6^x6vfgLqz@@KmAHBnd&aVhG0~bH8C~Qp*2Jm zN$#vwhEfv7gEYSDGviHl_O3z$5!<1uMeiAk9WP^GvSi92^keVX2nWkUp(DWw$K*g$neDKj!U&)*Nx~7jVaC@Y&FPln&@lP7 ztfV{x+d|@NVs=M!^S8UdF+&W)VV#PKYRO!h) zuav{lF^}rJW8{-{)4{1IfOkT@vJ%vf0H3W14o%d7KxXVQUTmubA9z4uB}EP&Qal)9 z&P+)q^R_D;~$=C%(=fwP{jb=owBB{=)B2 zzs_hPzd`Y(&$rU)4R{mptBn@xzlvtf(1vvhU}M|;tBxMJQ4)Un^Hf^E%2~?*1=@(i z<0?Qdln?cDhkV)(-0t1?3BuuD2;#6# z;T6o%d_qAX-)rIV_f2wKVj?#ftIYITGt@N&!;M?`7sYe%zghX?ApHt# zSewLWkVFaw&pS36_YTL|WF<^{7_{h;@8+%8si>4-RJY%ivao&DxWbCqKcJ#@CWqsBcH2z>l-(c(+RcD^sp1Ms#N1JzEkr5fB zp5l!E=TFJb$CWUfPGUxs)D?#ki@J8gMXLAt7%(sUawU$WBqd4OKv-4VaIB(&TEcNF z-)~CYoGH@3OfTYX>q95m$l`C7Tw1c|qmQ;qo|e}iQ~!DFD%a@k-5^P1n|24Kwwcf|M+n<&Zy7c+C-XcDA(bLgrevGSJcPe(QD4_q(p|`}^}xSI24Z_kG^yx!1k!wbuQ9TU;^x#BUQfDn;)n zwe+2|>LRJzA zlc$*7oiI!qgTKPnp1hYzrH`Tx!;X--)#79bYWy>95&wnm<(U4$3>PbgJDeZGo0Rt& zKBY=)!;`q~;&Q=*P2g2HG#von8&sztKu=+rS;^ojbv%A)2Kf4==yqZhS>s-l@`I)` zIuV~dOwBbkG%!U5ffa4mEWzXDgX42+H(BGMYgfqiC@tlc1uX-ku7KR6(N|J01R~Xf z$XcW_t~ZQ)mOMMv6&oaRuE@iYLP9r)WnnHiOMWsA{I)(TfQ!+O6@sFSTk7JTiDh%m zdgOY*u4U=)*eE1?j^!g9ITzuHt4`4xW_YsA5+L8Y$PyKlN|>!aa_l7UXsOdCcMRsJ zGc(}!!u9#2x`c|=)XJmxdv0%VGkZXXh-0>xg&4Kz*E33?Og0y;r>k-c&^ttWJJM?6 zS0WFQn`)^?j=E*$eg{$A|1uxn99t@3P*hN`=t}<)A<({Lp6l0@ikYx~Q! z+_>Z!^w;h~;G;`c9;0HT4P~&Su0>565VOOkCs|R3dB)yqOI6EDyO-Go74w7wq~2#( z9~tE>BDMBZ2sD%B1E^Po>=|HS#I^CC`>ZVtWYhth9zzQvIWdR3Dx(Npj7iC0Iw?Ip zLdUr@$%?&{gaq-2;lD?hHe9u)`UG*u59B6Bk*e_4)Y#Y_ zs8&0aSo@^X64YnNOS8Vqpq~rjpo};FT$sfM`&JF z@Rtf3udj(1|L2RxQ2AC8(@=d=&;>_Z`G_ATA_6Mc+Jf;fl4Sg$?ZRa2M2d*wLc4H- zks9u390^&`7yZO{>V6tK1^bv~qeQXK`+ z>72^8tW;g;b0P)Ewn*Llv&G(@L>Xi=W9QqB3MGd-zdQ_DlMQmu_6dRRFbqt=9GRVK zUcw&#?3vU&SPC>c!BCz-i@P|q!9P$iIi7;`kZEpwe9zHA*^xhTiLWNszrc`=D7$h#~?&x5PO-UIuBQ{y;7(NG; z4&=!|cbEtOdDO0S_~FT8&A?e`AlZ;aRM@q@FB>5Jj!rIpG!FhmoB7vY6}q#odsS^m zP=U=(pm~4&%zSgBw&BGy9P_>>YW?yUAB7j#@sDYVUjPunRIbF)eNjSO0tBG*kK+t& z%ayxtKPQBby}bQ4tN04kE)rq<^er&DM4AfuxS6W+u=JTLRlCuR_YW&rJVL4rQgkE6 zUvFt0E2fr|O*kJj-diK|XXn>_%dMfz5*TR+Hb{0nTK9mMpCjJu$_Y82-RtA_=M*Qt zo_-=}dgD;hr5*hfnx4;2-M^#vDQ8Rpcel*g#RBxDrW4@N@B(m@08f8+Y7u&_Jxm(_ z%CiR-C@~n!W4YNBFI)YyFNXwI4?pfa0%UzxNrPxfU&-~Sg=`!FG>CRzPRCO7UKO;A zSWH>_3cH$bZK^X<;j>B-aas6p+&wu+1ugfqxo~7G6!0vP;^IW_&s4p|=_}&=7x$9Q zWEH_pE$DFWGNql)NW|%r_px{1UOXo$xq0hBv&YN>_FF$~KePW75VkqV1l>#Syk#~= z3Hsv}Gs9sw%ir6)a_nD1$DYTAjc^~v*rEyAMzOOZ{s#QPkwdAKQ-5c;B3nP#KYh!R zw+g0e#q;y?Ga)cv!s);7$^En|NeJ4fIgCj?ocNNE2?9V#zhk#|wdpK9nQ8X1^gaPV zP>wCoO9vuvRR!UN%0z@obI;A@=6%*~&a#V8V3KK=6?Xak?~t_OwS3Cu1~!=FbDqCT}4 z$v{I%L#dnF3+gu;=LDdug@@M-wi%|XwLH)6OGVPSf8^p4b7c2l6FQ$A`TAsQeckv4 z1?zR@_CLb2E7(tl+Q(tc2T;8krm;C9-Zl<>IykY7Yzpe{k^_=`SEjxgfWlPd#X~?# z$YEDOZ5_cuF}#1?D(t6++`<7=V5u^;mL%KdI5KqLAPmfT%Mv#y_dX*ZTo2eU#*hAn ztk=H`Wt*;DM^s_qdJCcuU34yDtg2D^|_r)Pbko*CNpd znZ+@vCX@>|{_44$N{}40ym(SgU0rA7L6y-(9@(?-XkS(l4U!cn1rOJ2(1Gi4vGD~HwfHHJ| z+T4*1d`n6vUw#-uWEqSUS5(2t%5F<;^Jnq#eUE3VUKkhoF2XQRU}Gg&Pxv0x6)=^s z&ynI6Gx&% zSicL+BE?fuu75yQx&@tvEa7fVCVo@rsfxdKkoAf6pT z#q-BaVQ`R^8U?mh)|8)s=uu;QuD3SqRe>7D0=2T zBoce@IL)x6O^IYVK)%W*<&Asoma@|)XpSk#SB?gy85Guwh>QEYqg-j+Kg)hH3}+tx z9U0_om^l#bUiBhae!F`m3E>;Se5!|ROKI?UyliT=c7JDJGCmyu-D0Zm!%5ogX9~H! z2`~$P-M4mE5w@D^YF68+qq~P1>Av`1i|1tfCkX>U8aCc%+k~IO~6KedG+^tx~d_xl+WLHmBo`@M838Bk^c0lglTSXlz5U> zT*Kacq4I=^Hixc@hp_u=DPblQ%73A3HHW_H6;vc!so!mR%~THAhEBx6#?BvvJa* zT3N#ng@Tg3Dke4{xB9dBF%J)q#hh<#x0e*#k(0;n2DsOU`J|~iN1TQaRhq(Px;xB2 z)UP*}&(ltqGyLIQ!>XyFk+WOluqN$`A-v0B*o2O#BdFD58Ff#;Ne`{bRSdx z@P!kDFyP~54|(G@?SmU^=%}4dYT*kfe;)}}r{i*#``^W6r2n~%%s`nFaDy_bU6F7Z zFUj^A*bKM(GZCPATWL>`=BYs;-&VEZkL?>%G#em!ddzr*#|a}QyE zG#%@6khsd`i#(xtMj@~ja2sD8m5yr@iwRc&qyXTnkViA6Y5f9NhwEIX&egJO<;GT; zm#oC3rO8QgaLinWuob0}`Ir3lKlfCjEK-n}#ScwRu%56J+rNgv&h~7Y-Q3%K-IB(c zu>dm}UA=&Tv2k&MY0k*!LYW-yUsM-njk>Kx5};B>>m{9vN$&jq4_gcV)<%*Ya{vp= z!fUioO%&q;cGMHe&!N2-h}K(^C5?NR<>f;PMwc2$crz)@{>`O(nGgzx7^Qp|392{= z>?d8)4%9#n2_-sJwSTJ_u@=FLojz%USn$v!>*S7Uc^p5C@;|avJNxOnIxU>-0ezw& zjG0bo;BNHx_NvaU|MnW{3u|p~YdHgTfe*z^`I+u2K3*1(?({lKoa&kL=2%@@Yw==} zobC|qu0wi)LTO$9_x${G!RnK{N9l?>tO%#pjzfrgJ*hxMV8`Y zjO0`41VpApz{Q}@CzfnqH{w`MD|z}PoCPJcW~%M$q+Ds=Xr7etqi`M!rw9@D%L`Yt zb!-0u(FQ``RX7Yt<5MrMRL`2b!Hx}U^7$0S^ne3JC;3?=u<(KgSO{d$eF=j} zqZR3pzHL9)$sS>0VR-Q+ANm+|@wH!!Fy010##xxWGbOb=*3r?y zdMP^DQjEoIqRyi?pmA_E6uy9lnUV{+36srq4*%g?Z$5dqEg7a9%V^Xu^PK|W z7z_gh6GoIX$tl2bA4su9lPM@D^ynEFcv66vTmk^kgtegGfF-JlVt!zEiwY%29nSir zDM%m0s6ydJQ)iJRZeTyG7ns{AkV_O}>2$y|3fXIyxx;~1Jv^wzzwSZt_*4K{BoENbHLfDd2Prbuep#(gxwad5so*d%!&IgRhMt(E)xZ;#7pd@wX> z$rtd-SFs-+oRc(TEBJ>Cwe{$n>+{qNJP4l1w5Ct%)OkO8aunFRyzF;8lLpDJ8Wg$= zvk3_i)I7v006^_f8D;TB^KLEqIN8hFEKxc7pnmwmne}AztM8q=z>&cxe0l$m$@~s* zVnXfqm)lXoR84ji{zqJ@EcgwdfB`XaZ!+_-oDyyZ*1+|GkWj<3sP_46jno{~ECPdZ zCKJU`Ap#gdc&OvYA8=$SMyd1;LJ$Yx69a%3@lv((7qlJk`N-(!K!ovpzMC$8%NKU) zvCKD|3h{tKj(gCmEvJf`d89H!L&#mjM$a5$AkX3AOIQ+ZTsr$8`q5GdeUVEs@L?A+ z>1Qu)Z2!iBh!pPCrg1L~7Ode+>^542?BZE9fvnI|N`D`2wma^Bq$s?V`c5UecdO?P zg&QQoZIH0VK~-8vTSJ3I3ui~K^P=E-NoF~8ry}E*3Gewfr#t5N+;M&5RP99RK?g&NoKnsMuL z<96gL{(z^04TR9{0;l*Fbj%k|g#Xab3LVu<90jnItXb!_FzxE!V8MMCoMr%!#&f#|Kn&|a;2 zCRvLg9_TC>;wAdCu&~BcGNYxOyQETPbPxaZR~oxQJ;@Y1>TgFx`Dtk z1EJ3iD)S)UUBU9}v?c$ZFcCp>sibrRi%l7e)i3B_7kZO--U5zgF)(Zyw&)mGz(G4} z>v#t-k~$nwzj_#dO5duN(-u&k1onH0uD%;17qUn-#jAFQ_t@^CeVDBrNYcv5*P8eU zGWJ?BuW_sO-TC$TK%|Fr%mbN?k%|s~^b!LTK@_mBPqld5jf;&{$;!?)n=E%4Oa_6O z5h&;&D@2}{SVCCSb%y2_lYE>gr#nF?ToWuJI1sKn#kF}eprgF1O=sXAgdzEnW4T=c zX`Nr0`eWeivT zWA0}jL&Nige!Os*x&!#}R-~8+Gi1zO8##f-%&(!*@1beBdeALI1B*2TS zWdVHi`g(j*5DT|fg`=-3j0EVY5A%R!bzePn53PWVpA2E-Nn)ZTAEf`D+-|#obCE`5 zMFIm;ZbXaJV33LO)LJBGw#36pit>e&A952l|8`5ex#@?! zIm`7(_Q%8Jj;2rSdGwws>)((~nXHwAhW^Vza5vyHtM#qt;^O-D6aWHbqAG`a5z1vL z<0x>N&!Ta9Bz{TEO;Pb3UOIKT0vSM=0S^L4 zV2|o_Cc1rKupd5QnfhApoFmrl!d=cVu1g(|DuK1?)-u#we>0%*Z;XrLR##WKnHd>P zbF%Oec_s|21J1Q{Q0FS{r&yNaERI(ns|K2(Wo~Ys1X$l|FQ!LNPj3tM?txZoAMp!H zq0cSoaWMZySAS^f)!x?2D~0;cpsEFXSQ56f5ZJSxdKekG!ks|{HUyQ>VDi`xLI)77 z^SHjv)2mPW4u(jk2*y*Lu|akS824xn9tj*mS#ep}-S7AA-J1iu zq>y27X)*v*$yA;mYJ`DFoEr*trlABFZA4uYgGRFfh1=Yzp8n z2p46FZbz>l-vK~ zxx)X_HUOZ#l>{qEcvk%76#L~{Z#yUGBA#LUj% za_6+<)Ns>z2@agMv94~<6?pnprp21n)YLr2MFSDgoYo7sE`}wM8$vkVk@5w>-1OkzW-L**D$r=UG707gBp8oNfOOA# zbB07OfV{TiHiJv6fPkSdrvf8_xeeFecwf`eAqU~S^&pPpq1!MGe&in!eh~R!F9vCqXxHVnj^Xr>jbSTLl4L=@fs25~C)hPkOH0rz1;qp(7&jhhajo1r zizV5U4h=1`gYxwX zj5n^1lGO5^l|Mx_kfx8s_E`-tZL{PrIgH41On%7!sU|{zsU&THAYDrBQioK^5nv-05CqP0pS@W9uzz-z zmMC#^Jet?Q-o^i*dPAJTW_ZlU7wBe_UTEZhe;vbNM+bzAC51!^Xdv6O0Vm|Kv9%?% zb#*ng0bS5kQ+uX>6Qw+P`r>SA<>X!-;l&<+9d_E8 z(TaUv7%u1p3B-?%EXdZ9aII)S9S%SS`b~jPu94UPA;q+KQEWXoEH}lX%-6g{+xz{%2$fFqd)THU%BlUvxgW} zdk%D5>;CnFJR^rC<&f<^0p#NW`cAZXNCLTPAI612z)D~D6$sB0aY>8^3xLBIXlBHP zDm^S{Qi%ANzw(iZp6swl!GgmnfqRS)fk0@0y2d{s7+N8x3}FZ0(7xo0B@H7OhL|np zLObRJGsruiQi#f9##r~xUnFE3URi|3R;mmm3lqaNup%-r^;`1U|7m}y z3E6treC9Z7$AeuUm~O+#R2o`O6^+PyQ1DJaXs{?h&qOh>^#FpWVKp_x)y3Z`IP9?| z8Fb!=qSx%lCdS5kz6K5Wqvgd%c349LU0qKT2<9)5FbuJA1Kfzdkdc~-aLDREE$J@s zyuHluE;b-SNpN|0W*LJ$CyGuM@5g2Hs_u=d<{e&W@qFG;Q5*nObf>i7`TW7++KrkJ zU?!8AxJpou{;IC7hIQ`A0fH-n999SbzY%E=ffOV-E{+hoxqGtbUf#X)ngb~)9XIWx zG8J7?>2n}ve^VRy8|TW4HhT{7UgGr08KB#_)^IA<=lh-RciJWgfBeht4tikbgc@BDG(J1wIU;;^h)Txdh_TjY5TI98cj42c@_U>V<&ld2;&1Z5SqIg{I|Q zMJNW;1Mb_xYPbLdh(afA4sg~8Fm9cdT0RD#Cm|!VL!a0#{ti*ZH8gaWtC>{Fj_HtA z`I&N5apTfII_|+K`)ZH56kUJu({5D`u9#J`Xv1z&mIivBjEgojAm-G!S(D&3F}E~f z6Zb)G+5vFfi|j*fb@e1=oG9pKD{L1no1C+^z@K^R9$mNOe^*Z*3N06Th51DzK-Zok zSxY(ir^$j`vaAL`k_7y$*;zu{uiCV-YJ54_sLVwX#Ly~O>O%NX;a9`XvmiUY0CCh3 zk-@R^^d8-v{kR&jYQfRFNd4q*0r$?a$4>dJJ~kg{ca8ezEwL;xODGIwv_V)24=9vd zAru)_s1K$vx)*!0+s{Cm;;E+vA>X=wWnw1{aRGDN{W-qb?&muBI=eWhqG$FW3DBk* z=Yz*y;{;YAw*Qpg^F)dC#XA+PO`Tmj+o( z_{^I9iz2Y&c}ANNCFyxP=x*MSaZCV)@Auim$n}QId&3f>5Kvh zeAB}w1&{hEyuamIQc_YS^e&7-g6Tp9)pFt-C&l_MNcS~2*7J{`a1``X4twrrl((IS<@kWo!=lL7exj%M zSC|5iRybdM{e1?A1;{AamE98E+~0FkfHCoXD~PW=8A*`NY`_K8g4xqDFCSlZQC^-s z2`FiS*kt*zGXkmtz_3(2*(Bp_?7M7bRU(OgV~iepBX`97x&_Za>{5X&gb*zr2Xk_Mv*)(~Fd_E2@`0kwi3R^mkT46W*SP;s(=dGNvEmGoN}a8Ut*a|SZA zN(j5xU?D^!?77jM5C}z=e0R=3SIo1Zb)upC?^*fX?P_rMu$?YQ54l#2NNxxy`&v%! znaMq_49&iwcdpB(=t|f1Fsj_w0+QRExH0ENEgf#YvOu4Mh~sy7@QxKFN8ok}8k^f{ieXNW z;ZXd3A5CtB?Vt(SF#rGFWISUrDyMMsxBR#~jE5#pmyJ8y5E&>n_>RExy+wU2K?=s9rgzPRPAak#VIfSI& zTQJqlo~|qLEge~*wE}?>61+Gp{J}%mCYr#rz;I*I0d|l!AOxTbY~M$aOUOXx5u^?0 z_z`frIe5mE*0#3%=n4d%$q*StS)vAEM1~BtM2tI|pAf5`xDn)V5HjsJd3e%Ube=sa zudK3$cICu&-TeMk2x3|~)_Al8EX0Iu={T5a z7F+p^sLXrUTwgRFwFDs)w4a7W){WwVAd6J)PD^4oGqFG)T}kUe4Q0P3AAWen0Q)6b zf$fUIoui5DjzAI!PA1?W?*?Xv)x-}cQCIpdGL-!#3ae%dm~XPS zx|&m}Hd2P9i=JLyZU!uK{Jde5i>$K|63H$pKoh&HMWS@5Mynsb0%?WDdP)9wUY6kg zX|jZ<3`bdkzJqR=>Nt`~Rxwm%hNpOHceOV3da@~fKQXi$p0+qKcFo!A>OI$RLaxl9 zy;$@cqYId%&hMJnvX&h|$^vh|DrBGz-rB(c=^X+fZHO$-P_OPRC4xeEOULuF#Fe%I zWxWIHY}3($OL_}=Njq*y1S;~cKUh`Y?!=xc$WkW0^F6jOJYbe^mZ+KRSt)47Qk1roYANdw2FoC6o666S1 zKVF3A`OdLCx(qJZ=)%)TC`)nyzt4o+nhCDvQJb}HRgblZS$@A`3j(Dk58JG3PN3XZ zAnu9xkV^G}!ZB0oXPinWv zO6M}y+^X>KzTq%vuC>@@IX4*m5*LI*(`bQ04kS%1JZM(x9#M(LU{4;Hx6G%8+@=xf z)aKKz8|`~9HGXM5-Q~R==!~xYu1kl$uBSTuW=QhO9KVC;83ARM$R1=^*k?evyd$5( zi;X&eVOZ16Mse0!F){n$XK^l{dHYnX-}vzN-Z&RrebSHAE(sp-Akcz7{w4TT%iR?iH?jT~tsQBx|b7gP2pJg7hDJA0KM zrf6LZpKmACS=2e-R?4DxujTCg7-Dn6jVm+;M25~ThSNy|y-$@;J7BGCHUz#qYC7Yo zy`?nG9a&u;CE~<3QlDe}lK9{1X{H%(pis|6GbX5+6x#LGjcYXe7M)APOWks43XYrT zy<_Hcp+h!DF++Qbv~;eHdTOjM@jW48AZa*NnsxNnB7d9S%uy6heC|0h{EunxP+Hz` zQq)qCqk3;?y*M#}7B6@ImBI+p{BcX1&x;DLX69wp@*2-Wk`|E$N+eH2MdC{s<@3!E@rttIs{N}&E@>(7I^8epA{`a~6 w_Z|G7kN@uu!sS9E@0J`~RudInoW;I8Dxy8dFq?5P1GyS?Wdg2P(elp!0AcDrhX4Qo literal 23930 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 OV~94@eXVmP?Ee5)5ucI( diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index a087679..838e3bc 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -8,34 +8,32 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/AppTheme.AppBarOverlay" android:stateListAnimator="@null"> + android:layout_height="@dimen/toolbarSize" app:layout_scrollFlags="scroll|enterAlways" + app:popupTheme="@style/AppTheme.PopupOverlay" android:id="@+id/toolbar" /> + app:layout_collapseMode="pin" android:layout_gravity="bottom" + android:clipChildren="false"> + android:layout_alignParentRight="true" android:layout_alignParentEnd="true" + android:clipChildren="false"> + android:scaleType="centerInside" /> - - - + app:layout_behavior="@string/scroll_behavior"/> + android:padding="@dimen/toolbarSize" android:visibility="gone" android:layout_margin="20dp" + app:layout_behavior="@string/scroll_behavior" /> \ No newline at end of file diff --git a/app/src/main/res/layout/advanced_dialog.xml b/app/src/main/res/layout/advanced_dialog.xml index 208c2e4..c20941b 100644 --- a/app/src/main/res/layout/advanced_dialog.xml +++ b/app/src/main/res/layout/advanced_dialog.xml @@ -1,7 +1,7 @@ + + + + - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/settings_dialog.xml b/app/src/main/res/layout/settings_dialog.xml index 4e47e15..80a5281 100644 --- a/app/src/main/res/layout/settings_dialog.xml +++ b/app/src/main/res/layout/settings_dialog.xml @@ -1,7 +1,7 @@