package monakhv.android.samlib; import android.annotation.SuppressLint; import android.app.AlarmManager; import android.app.PendingIntent; import android.content.*; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.design.widget.AppBarLayout; import android.support.design.widget.NavigationView; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentTransaction; import android.support.v4.widget.DrawerLayout; import android.support.v7.app.ActionBar; import android.support.v7.app.ActionBarDrawerToggle; import android.support.v7.widget.Toolbar; import android.text.TextUtils; import android.view.Gravity; import android.view.MenuItem; import android.view.View; import android.view.Window; import android.widget.*; import monakhv.android.samlib.search.SearchAuthorActivity; import monakhv.android.samlib.search.SearchAuthorsFragment; import monakhv.android.samlib.service.CleanNotificationData; import monakhv.samlib.service.AuthorGuiState; import monakhv.android.samlib.sortorder.AuthorSortOrder; import monakhv.samlib.db.TagController; import monakhv.samlib.db.entity.SamLibConfig; import monakhv.samlib.db.entity.Tag; import monakhv.samlib.log.Log; import monakhv.samlib.service.GuiUpdateObject; import rx.Observable; import rx.Subscription; import java.io.Serializable; import java.util.ArrayList; import java.util.Calendar; /* * Copyright 2014 Dmitry Monakhov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * 12/5/14. */ public class MainActivity extends MyBaseAbstractActivity implements NavigationView.OnNavigationItemSelectedListener, AppBarLayout.OnOffsetChangedListener, AuthorFragment.Callbacks, AuthorTagFragment.AuthorTagCallback, BookFragment.Callbacks, AdapterView.OnItemSelectedListener { private static final String DEBUG_TAG = "MainActivity"; private static final int ARCHIVE_ACTIVITY = 1; private static final int SEARCH_ACTIVITY = 2; private static final int PREFS_ACTIVITY = 3; public static final String ACTION_CLEAN = "MainActivity.ACTION_CLEAN"; private static final String SELECTED_TAG_ID = "SELECTED_TAG_ID"; private static final String PROGRESS_TIME = "PROGRESS_TIME"; private AuthorFragment authorFragment; private BookFragment bookFragment; private AuthorTagFragment tagFragment; private boolean twoPain; private boolean isTagShow = false; private int selectedTagId = SamLibConfig.TAG_AUTHOR_ALL; private TagController tagSQL; private AppBarLayout mAppBarLayout; private DrawerLayout mDrawerLayout; private ArrayAdapter<UITag> tagAdapter; private Spinner tagFilter; private Observable<GuiUpdateObject> mBus; private Subscription mAuthorSubscription; private Subscription mBookSubscription; @Override protected void onCreate(Bundle savedInstanceState) { Log.d(DEBUG_TAG, "onCreate"); getWindow().requestFeature(Window.FEATURE_ACTION_BAR_OVERLAY); super.onCreate(savedInstanceState); setContentView(R.layout.main_layout); final String action = getIntent().getAction(); if (action != null) { if (action.equalsIgnoreCase(ACTION_CLEAN)) { CleanNotificationData.start(this); } } authorFragment = (AuthorFragment) getSupportFragmentManager().findFragmentById(R.id.authorFragment); authorFragment.setHasOptionsMenu(true); final Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); final ActionBar actionBar = getSupportActionBar(); if (actionBar != null) { actionBar.setDisplayHomeAsUpEnabled(true); actionBar.setHomeButtonEnabled(true); actionBar.setDisplayShowTitleEnabled(false); } twoPain = findViewById(R.id.two_pain) != null; if (twoPain) { Log.d(DEBUG_TAG, "onCreate: two pane"); isTagShow = false; Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.listBooksFragment); if (fragment == null) { Log.d(DEBUG_TAG, "Initial construction: add BookFragment"); bookFragment = new BookFragment(); final FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); ft.add(R.id.listBooksFragment, bookFragment); ft.commit(); tagFragment = new AuthorTagFragment(); } else { if (fragment instanceof AuthorTagFragment) { Log.d(DEBUG_TAG, "Secondary construction: create BookFragment"); tagFragment = (AuthorTagFragment) fragment; bookFragment = new BookFragment(); final FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); ft.replace(R.id.listBooksFragment, bookFragment); ft.commit(); } else { Log.d(DEBUG_TAG, "Secondary construction: create AuthorTagFragment"); tagFragment = new AuthorTagFragment(); bookFragment = (BookFragment) fragment; } } bookFragment.setHasOptionsMenu(true); tagFragment.setHasOptionsMenu(true); } else { Log.i(DEBUG_TAG, "onCreate: one pane"); } tagSQL = getAuthorController().getTagController(); mAppBarLayout = (AppBarLayout) findViewById(R.id.appBarLayout); createDrawer(); //find Save fragment final SaveFragment saveFragment = (SaveFragment) getSupportFragmentManager().findFragmentByTag(SaveFragment.TAG); if (saveFragment != null) {//fragment is found mBus = saveFragment.getObjectObservable(); } else {//fragment not found we need create it and put under Fragment manager final SaveFragment fragment = new SaveFragment(); getSupportFragmentManager().beginTransaction() .add(fragment, SaveFragment.TAG) .commit(); getSupportFragmentManager().executePendingTransactions(); final SaveFragment fr1 = (SaveFragment) getSupportFragmentManager().findFragmentByTag(SaveFragment.TAG); mBus = fr1.getObjectObservable(); } } @Override protected void onDestroy() { Log.d(DEBUG_TAG, "onDestroy"); super.onDestroy(); } @SuppressLint("RtlHardcoded") @Override public void drawerToggle() { mDrawerLayout.openDrawer(Gravity.LEFT); } private void openActionBar() { if (mAppBarLayout == null) { return; } mAppBarLayout.setExpanded(true); } /** * Create MaterialDrawer */ private void createDrawer() { mDrawerLayout = (DrawerLayout) findViewById(R.id.drawerLayout); //begin magic to make Home button available final ActionBarDrawerToggle mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, 0, 0); mDrawerLayout.setDrawerListener(mDrawerToggle); mDrawerToggle.syncState(); //end magic to make Home button available final NavigationView navigationView = (NavigationView) findViewById(R.id.navigationView); navigationView.setCheckedItem(authorFragment.getSortOrder().getMenuId()); navigationView.setNavigationItemSelectedListener(this); tagFilter = (Spinner) findViewById(R.id.tagList); ArrayList<UITag> tags = UITag.getPreList(this); tagAdapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, tags); tagFilter.setAdapter(tagAdapter); tagAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); tagFilter.setOnItemSelectedListener(this); } @Override public void showTags(long author_id) { Log.d(DEBUG_TAG, "showTags: go to Tags author_id = " + author_id); final FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); ft.replace(R.id.listBooksFragment, tagFragment); ft.addToBackStack(null); ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); ft.commit(); isTagShow = true; } @Override public boolean onNavigationItemSelected(MenuItem menuItem) { //menuItem.setChecked(true); mDrawerLayout.closeDrawers(); int iSel = menuItem.getItemId(); if (iSel == R.id.dr_search) { authorFragment.searchOrAdd(); } if (iSel == R.id.dr_selected) { authorFragment.cleanSelection(); onAuthorSelected(SamLibConfig.SELECTED_BOOK_ID); restoreTagSelection(); } if (iSel == R.id.dr_data) { Log.d(DEBUG_TAG, "onItemClick: go to Archive"); Intent prefsIntent = new Intent(getApplicationContext(), ArchiveActivity.class); restoreTagSelection(); startActivityForResult(prefsIntent, MainActivity.ARCHIVE_ACTIVITY); } if (iSel == R.id.dr_setting) { Intent prefsIntent = new Intent(getApplicationContext(), SamlibPreferencesActivity.class); //prefsIntent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); restoreTagSelection(); startActivityForResult(prefsIntent, MainActivity.PREFS_ACTIVITY); } if (iSel == R.id.author_sort_name) { authorFragment.setSortOrder(AuthorSortOrder.AuthorName); } if (iSel == R.id.author_sort_upadte) { authorFragment.setSortOrder(AuthorSortOrder.DateUpdate); } return true; } /** * Restore selection of the tag into Drawer */ private void restoreTagSelection() { if (tagSQL.getById(selectedTagId) == null) { selectedTagId = SamLibConfig.TAG_AUTHOR_ALL; } //drResult.setSelection(selectedTagId + tagsShift, false); } @Override protected void onSaveInstanceState(Bundle outState) { Log.d(DEBUG_TAG, "onSaveInstanceState"); super.onSaveInstanceState(outState); outState.putInt(SELECTED_TAG_ID, selectedTagId); outState.putLong(PROGRESS_TIME, Calendar.getInstance().getTimeInMillis()); } @Override protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) { Log.d(DEBUG_TAG, "onRestoreInstanceState"); super.onRestoreInstanceState(savedInstanceState); selectedTagId = savedInstanceState.getInt(SELECTED_TAG_ID, SamLibConfig.TAG_AUTHOR_ALL); Tag tag = tagSQL.getById(selectedTagId); if (tag != null) { authorFragment.selectTag(selectedTagId, null); restoreTagSelection(); } } @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); if (intent == null) { return; } final String action = intent.getAction(); if (action != null) { if (action.equalsIgnoreCase(ACTION_CLEAN)) { CleanNotificationData.start(this); } } } @Override protected void onResume() { Log.d(DEBUG_TAG, "onResume"); super.onResume(); makeSubscription(); if (mAppBarLayout != null) { mAppBarLayout.addOnOffsetChangedListener(this); } refreshTags(); } private void makeSubscription(){ mAuthorSubscription = mBus .filter(o -> o.isResult() || o.isAuthor()) .subscribe(authorFragment.getSubscriber()); addSubscription(mAuthorSubscription); if (twoPain) { if (bookFragment == null) { Log.e(DEBUG_TAG, "Fragment is NULL for two pane layout!!"); } mBookSubscription = mBus .filter(o -> o.isBook() || o.isGroup()) .subscribe(bookFragment.getSubscriber()); addSubscription(mBookSubscription); } } private void unMakeSubscribe(){ mAuthorSubscription.unsubscribe(); if (mBookSubscription!=null && ! mBookSubscription.isUnsubscribed()){ mBookSubscription.unsubscribe(); } } @Override public AuthorGuiState getAuthorGuiState() { return authorFragment.getGuiState(); } @Override protected void onPause() { super.onPause(); Log.d(DEBUG_TAG, "onPause"); unMakeSubscribe(); if (mAppBarLayout != null) { mAppBarLayout.removeOnOffsetChangedListener(this); } //getActionBarHelper().setRefreshActionItemState(refreshStatus); } /** * Return from ArchiveActivity or SearchActivity * * @param requestCode request code * @param resultCode result code * @param data Intent data */ @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode != RESULT_OK) { Log.d(DEBUG_TAG, "Wrong result code from onActivityResult"); //authorFragment.refresh(SamLibConfig.TAG_AUTHOR_ALL, null); return; } if (requestCode == ARCHIVE_ACTIVITY) { int res = data.getIntExtra(ArchiveActivity.UPDATE_KEY, -1); if (res == ArchiveActivity.UPDATE_LIST) { Log.d(DEBUG_TAG, "Reconstruct List View"); restartApp(); } } if (requestCode == SEARCH_ACTIVITY) { Log.v(DEBUG_TAG, "Start add Author"); String url = data.getStringExtra(SearchAuthorsFragment.AUTHOR_URL); ArrayList<String> urls = new ArrayList<>(); urls.add(url); getSamlibOperation().makeAuthorAdd(urls, getAuthorGuiState()); } if (requestCode == PREFS_ACTIVITY) { restartApp(); //finish(); } } @Override public void onAuthorSelected(long id) { Log.d(DEBUG_TAG, "onAuthorSelected: go to Books"); if (twoPain) { Log.i(DEBUG_TAG, "Two fragments Layout - set author_id: " + id); bookFragment.setAuthorId(id); tagFragment.setAuthor_id(id); if (isTagShow && (id == SamLibConfig.SELECTED_BOOK_ID)) { onFinish(id); } } else { Log.i(DEBUG_TAG, "One fragment Layout - set author_id: " + id); Intent intent = new Intent(this, BooksActivity.class); intent.putExtra(BookFragment.AUTHOR_ID, id); startActivity(intent); } } @Override public void cleanBookSelection() { if (twoPain) { bookFragment.setAuthorId(0);//empty selection } } /** * Add new Author to SQL Store * * @param view View */ @SuppressWarnings("UnusedParameters") public void addAuthor(View view) { addAuthorFromText(); } private void addAuthorFromText() { final EditText editText = (EditText) findViewById(R.id.addUrlText); if (editText == null || editText.getText() ==null ) { return; } String text = editText.getText().toString(); editText.setText(""); View v = findViewById(R.id.add_author_panel); v.setVisibility(View.GONE); String url = SamLibConfig.getParsedUrl(text); if (url != null) {//add Author by URL ArrayList<String> urls = new ArrayList<>(); urls.add(url); getSamlibOperation().makeAuthorAdd(urls, getAuthorGuiState()); } else { if (TextUtils.isEmpty(text)) { return; } //Start Search activity to make search and add selected Authors to Data Base Intent prefsIntent = new Intent(getApplicationContext(), SearchAuthorActivity.class); prefsIntent.putExtra(SearchAuthorActivity.EXTRA_PATTERN, text); prefsIntent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); startActivityForResult(prefsIntent, SEARCH_ACTIVITY); } } @Override public void onBackPressed() { Log.d(DEBUG_TAG, "onBackPressed: selected tag " + authorFragment.getSelection()); if (authorFragment.getSelection() != SamLibConfig.TAG_AUTHOR_ALL) { selectedTagId = SamLibConfig.TAG_AUTHOR_ALL; tagFilter.setSelection(0);//this handle tag selection into AuthorFragment openActionBar(); } else { finish(); } } @Override public void onFinish(long id) { authorFragment.refresh(); Log.d(DEBUG_TAG, "Return to Books"); final FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); ft.replace(R.id.listBooksFragment, bookFragment); ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_CLOSE); ft.commitAllowingStateLoss(); isTagShow = false; } @Override public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) { authorFragment.setAppBarOffset(verticalOffset); } @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { UITag uitag = tagAdapter.getItem(position); if (uitag == null) { return; } selectedTagId = uitag.id; authorFragment.selectTag(uitag.id, null); } @Override public void onNothingSelected(AdapterView<?> parent) { } private static class UITag implements Serializable { int id; String title; UITag(int id, String title) { this.id = id; this.title = title; } UITag(Tag tag) { this.id = tag.getId(); this.title = tag.getName(); } @Override public String toString() { return title; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; UITag uiTag = (UITag) o; return id == uiTag.id; } @Override public int hashCode() { return id; } static ArrayList<UITag> getPreList(Context ctx) { ArrayList<UITag> tags = new ArrayList<>(); //tags.add(new UITag(SamLibConfig.TAG_AUTHOR_ALL,ctx.getString(R.string.filter_all))); tags.add(new UITag(SamLibConfig.TAG_AUTHOR_ALL, ctx.getString(R.string.app_name))); tags.add(new UITag(SamLibConfig.TAG_AUTHOR_NEW, ctx.getString(R.string.filter_new))); return tags; } } private void refreshTags() { Log.d(DEBUG_TAG, "refreshTags: making refresh tags"); tagAdapter.clear(); tagAdapter.addAll(UITag.getPreList(this)); for (Tag tag : tagSQL.getAll()) { tagAdapter.add(new UITag(tag)); } tagAdapter.notifyDataSetChanged(); } private void restartApp() { restart(100); } private void restart(int delay) { PendingIntent intent = PendingIntent.getActivity(this.getBaseContext(), 0, new Intent(getIntent()), PendingIntent.FLAG_ONE_SHOT); AlarmManager manager = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE); manager.set(AlarmManager.RTC, System.currentTimeMillis() + delay, intent); System.exit(2); } }