use of com.ichi2.anim.ActivityTransitionAnimation.Direction.START in project AnkiChinaAndroid by ankichinateam.
the class NoteEditor method setMMButtonListener.
private void setMMButtonListener(ImageButton mediaButton, final int index) {
mediaButton.setOnClickListener(v -> {
Timber.i("NoteEditor:: Multimedia button pressed for field %d", index);
if (mEditorNote.items()[index][1].length() > 0) {
final Collection col = CollectionHelper.getInstance().getCol(NoteEditor.this);
// If the field already exists then we start the field editor, which figures out the type
// automatically
IMultimediaEditableNote mNote = getCurrentMultimediaEditableNote(col);
startMultimediaFieldEditor(index, mNote);
} else {
// Otherwise we make a popup menu allowing the user to choose between audio/image/text field
// TODO: Update the icons for dark material theme, then can set 3rd argument to true
PopupMenuWithIcons popup = new PopupMenuWithIcons(NoteEditor.this, v, false);
MenuInflater inflater = popup.getMenuInflater();
inflater.inflate(R.menu.popupmenu_multimedia_options, popup.getMenu());
popup.setOnMenuItemClickListener(item -> {
int itemId = item.getItemId();
if (itemId == R.id.menu_multimedia_audio) {
Timber.i("NoteEditor:: Record audio button pressed");
startMultimediaFieldEditorForField(index, new AudioRecordingField());
return true;
} else if (itemId == R.id.menu_multimedia_audio_clip) {
Timber.i("NoteEditor:: Add audio clip button pressed");
startMultimediaFieldEditorForField(index, new AudioClipField());
return true;
} else if (itemId == R.id.menu_multimedia_photo) {
Timber.i("NoteEditor:: Add image button pressed");
startMultimediaFieldEditorForField(index, new ImageField());
return true;
} else if (itemId == R.id.menu_multimedia_text) {
Timber.i("NoteEditor:: Advanced editor button pressed");
startAdvancedTextEditor(index);
return true;
} else if (itemId == R.id.menu_multimedia_clear_field) {
Timber.i("NoteEditor:: Clear field button pressed");
clearField(index);
}
return false;
});
if (AdaptionUtil.isRestrictedLearningDevice()) {
popup.getMenu().findItem(R.id.menu_multimedia_photo).setVisible(false);
popup.getMenu().findItem(R.id.menu_multimedia_text).setVisible(false);
}
popup.show();
}
});
}
use of com.ichi2.anim.ActivityTransitionAnimation.Direction.START in project AnkiChinaAndroid by ankichinateam.
the class AnkiDroidApp method onCreate.
/**
* On application creation.
*/
@Override
public void onCreate() {
super.onCreate();
registerActivityLifecycleCallbacks(activityLifecycleCallbacks);
if (sInstance != null) {
Timber.i("onCreate() called multiple times");
// 5887 - fix crash.
if (sInstance.getResources() == null) {
Timber.w("Skipping re-initialisation - no resources. Maybe uninstalling app?");
return;
}
}
sInstance = this;
// Get preferences
SharedPreferences preferences = getSharedPrefs(this);
Consts.LOGIN_SERVER = preferences.getInt(Consts.KEY_ANKI_ACCOUNT_SERVER, 0);
// Setup logging and crash reporting
acraCoreConfigBuilder = new CoreConfigurationBuilder(this);
if (BuildConfig.DEBUG) {
// Enable verbose error logging and do method tracing to put the Class name as log tag
Timber.plant(new DebugTree());
setDebugACRAConfig(preferences);
} else {
Timber.plant(new ProductionCrashReportingTree());
setProductionACRAConfig(preferences);
}
Timber.tag(TAG);
Timber.d("Startup - Application Start");
// Analytics falls back to a sensible default if this is not set.
if (ACRA.isACRASenderServiceProcess() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
try {
WebViewDebugging.setDataDirectorySuffix("acra");
} catch (Exception e) {
Timber.w(e, "Failed to set WebView data directory");
}
}
// analytics after ACRA, they both install UncaughtExceptionHandlers but Analytics chains while ACRA does not
UsageAnalytics.initialize(this);
if (BuildConfig.DEBUG) {
UsageAnalytics.setDryRun(true);
}
// Stop after analytics and logging are initialised.
if (ACRA.isACRASenderServiceProcess()) {
Timber.d("Skipping AnkiDroidApp.onCreate from ACRA sender process");
return;
}
if (AdaptionUtil.isUserATestClient()) {
UIUtils.showThemedToast(this.getApplicationContext(), getString(R.string.user_is_a_robot), false);
}
CardBrowserContextMenu.ensureConsistentStateWithSharedPreferences(this);
AnkiCardContextMenu.ensureConsistentStateWithSharedPreferences(this);
NotificationChannels.setup(getApplicationContext());
// Configure WebView to allow file scheme pages to access cookies.
CookieManager.setAcceptFileSchemeCookies(true);
// Prepare Cookies to be synchronized between RAM and permanent storage.
CompatHelper.getCompat().prepareWebViewCookies(this.getApplicationContext());
// Set good default values for swipe detection
final ViewConfiguration vc = ViewConfiguration.get(this);
DEFAULT_SWIPE_MIN_DISTANCE = vc.getScaledPagingTouchSlop();
DEFAULT_SWIPE_THRESHOLD_VELOCITY = vc.getScaledMinimumFlingVelocity();
// Forget the last deck that was used in the CardBrowser
CardBrowser.clearLastDeckId();
// Create the AnkiDroid directory if missing. Send exception report if inaccessible.
if (Permissions.hasStorageAccessPermission(this)) {
try {
String dir = CollectionHelper.getCurrentAnkiDroidDirectory(this);
CollectionHelper.initializeAnkiDroidDirectory(dir);
} catch (StorageAccessException e) {
Timber.e(e, "Could not initialize AnkiDroid directory");
String defaultDir = CollectionHelper.getDefaultAnkiDroidDirectory();
if (isSdCardMounted() && CollectionHelper.getCurrentAnkiDroidDirectory(this).equals(defaultDir)) {
// Don't send report if the user is using a custom directory as SD cards trip up here a lot
sendExceptionReport(e, "AnkiDroidApp.onCreate");
}
}
}
Timber.i("AnkiDroidApp: Starting Services");
new BootService().onReceive(this, new Intent(this, BootService.class));
// Register BroadcastReceiver NotificationService
NotificationService ns = new NotificationService();
LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);
lbm.registerReceiver(ns, new IntentFilter(NotificationService.INTENT_ACTION));
}
use of com.ichi2.anim.ActivityTransitionAnimation.Direction.START in project AnkiChinaAndroid by ankichinateam.
the class IntentHandler method handleFileImport.
private void handleFileImport(Intent intent, Intent reloadIntent, String action) {
Timber.i("Handling file import");
ImportResult importResult = ImportUtils.handleFileImport(this, intent);
// Start DeckPicker if we correctly processed ACTION_VIEW
if (importResult.isSuccess()) {
Timber.d("onCreate() import successful");
reloadIntent.setAction(action);
// reloadIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(reloadIntent);
AnkiActivity.finishActivityWithFade(this);
} else {
Timber.i("File import failed");
// Don't import the file if it didn't load properly or doesn't have apkg extension
ImportUtils.showImportUnsuccessfulDialog(this, importResult.getHumanReadableMessage(), true);
}
}
use of com.ichi2.anim.ActivityTransitionAnimation.Direction.START in project AnkiChinaAndroid by ankichinateam.
the class StudyOptionsFragment method getCollectionTaskListener.
/**
* Returns a listener that rebuilds the interface after execute.
*
* @param refreshDecklist If true, the listener notifies the parent activity to update its deck list
* to reflect the latest values.
*/
private TaskListener getCollectionTaskListener(final boolean refreshDecklist) {
return new TaskListener() {
@Override
public void onPreExecute() {
}
@Override
public void onPostExecute(TaskData result) {
dismissProgressDialog();
if (result != null) {
// Get the return values back from the AsyncTask
Object[] obj = result.getObjArray();
int newCards = (Integer) obj[0];
int lrnCards = (Integer) obj[1];
int revCards = (Integer) obj[1] + (Integer) obj[2];
int totalNew = (Integer) obj[3];
int totalCards = (Integer) obj[4];
Timber.i("start refresh list data:" + newCards + "," + lrnCards + "," + revCards + "," + totalNew + "," + totalCards);
// Don't do anything if the fragment is no longer attached to it's Activity or col has been closed
if (getActivity() == null) {
Timber.e("StudyOptionsFragment.mRefreshFragmentListener :: can't refresh");
return;
}
// #5506 If we have no view, short circuit all UI logic
if (mStudyOptionsView == null) {
tryOpenCramDeckOptions();
return;
}
// Reinitialize controls incase changed to filtered deck
initAllContentViews(mStudyOptionsView);
// Set the deck name
String fullName;
Deck deck = getCol().getDecks().current();
// Main deck name
fullName = deck.getString("name");
String[] name = Decks.path(fullName);
StringBuilder nameBuilder = new StringBuilder();
if (name.length > 0) {
nameBuilder.append(name[name.length - 1]);
}
// if (name.length > 1) {
// nameBuilder.append("\n").append(name[1]);
// }
// if (name.length > 3) {
// nameBuilder.append("...");
// }
// if (name.length > 2) {
// nameBuilder.append("\n").append(name[name.length - 1]);
// }
// mTextDeckName.setText(nameBuilder.toString());
mDeckListAdapter.mTextDeckName = nameBuilder.toString();
if (tryOpenCramDeckOptions()) {
return;
}
// Switch between the empty view, the ordinary view, and the "congratulations" view
boolean isDynamic = deck.optInt("dyn", 0) != 0;
if (totalCards == 0 && !isDynamic) {
mCurrentContentView = CONTENT_EMPTY;
mDeckListAdapter.mDeckInfoLayoutVisible = View.VISIBLE;
mDeckListAdapter.mTextCongratsMessageVisible = View.VISIBLE;
// mDeckListAdapter.mTextCongratsMessage=getString(R.string.studyoptions_empty);
mDeckListAdapter.mButtonStartEnable = false;
mDeckListAdapter.mTextButtonStart = getString(R.string.studyoptions_start);
} else if (newCards + lrnCards + revCards == 0) {
mCurrentContentView = CONTENT_CONGRATS;
if (!isDynamic) {
mDeckListAdapter.mDeckInfoLayoutVisible = View.GONE;
mDeckListAdapter.mButtonStartEnable = true;
mDeckListAdapter.mTextButtonStart = getString(R.string.add_today_study_amount);
} else {
mDeckListAdapter.mButtonStartEnable = true;
mDeckListAdapter.mTextButtonStart = getString(R.string.add_today_study_amount);
}
mDeckListAdapter.mTextCongratsMessageVisible = View.VISIBLE;
// mDeckListAdapter.mTextCongratsMessage=getCol().getSched().finishedMsg(getActivity()).toString();
// mTextCongratsMessage.setText(getCol().getSched().finishedMsg(getActivity()));
} else {
mCurrentContentView = CONTENT_STUDY_OPTIONS;
mDeckListAdapter.mDeckInfoLayoutVisible = View.VISIBLE;
mDeckListAdapter.mTextCongratsMessageVisible = View.GONE;
mDeckListAdapter.mButtonStartEnable = true;
mDeckListAdapter.mTextButtonStart = getString(R.string.studyoptions_start);
}
mDeckListAdapter.setButtonStartClickListener(mButtonClickListener);
mDeckListAdapter.setSelfStudyClickListener(mSelfStudyListener);
// Set deck description
String desc;
if (isDynamic) {
desc = getResources().getString(R.string.dyn_deck_desc);
} else {
desc = "";
// desc = getCol().getDecks().getActualDescription();
}
if (desc.length() > 0) {
mDeckListAdapter.mTextDeckDescription = desc;
mDeckListAdapter.mTextDeckDescriptionVisible = View.VISIBLE;
// mTextDeckDescription.setText(formatDescription(desc));
// mTextDeckDescription.setVisibility(View.VISIBLE);
} else {
mDeckListAdapter.mTextDeckDescriptionVisible = View.GONE;
}
// Set new/learn/review card counts
mDeckListAdapter.mTextTodayNew = String.valueOf(newCards);
mDeckListAdapter.mTextTodayRev = String.valueOf(revCards);
// Set the total number of new cards in deck
if (totalNew < NEW_CARD_COUNT_TRUNCATE_THRESHOLD) {
// if it hasn't been truncated by libanki then just set it usually
// mTextNewTotal.setText(String.valueOf(totalNew));
} else {
// mTextNewTotal.setText(">1000");
if (mFullNewCountThread != null) {
// a thread was previously made -- interrupt it
mFullNewCountThread.interrupt();
}
// mFullNewCountThread = new Thread(() -> {
// Collection collection = getCol();
// TODO: refactor code to not rewrite this query, add to Sched.totalNewForCurrentDeck()
// String query = "SELECT count(*) FROM cards WHERE did IN " +
// Utils.ids2str(collection.getDecks().active()) +
// " AND queue = " + Consts.QUEUE_TYPE_NEW;
// final int fullNewCount = collection.getDb().queryScalar(query);
// if (fullNewCount > 0) {
// Runnable setNewTotalText = new Runnable() {
// @Override
// public void run() {
// mTextNewTotal.setText(String.valueOf(fullNewCount));
// }
// };
// if (!Thread.currentThread().isInterrupted()) {
// mTextNewTotal.post(setNewTotalText);
// }
// }
// });
// mFullNewCountThread.start();
}
// Set total number of cards
// mTextTotal.setText(String.valueOf(totalCards));
double[] data = calculateStat(getCol(), getCol().getDecks().current().optLong("id"));
mNewCardsNum = (int) data[2];
mRevCardsNum = revCards;
mShouldConfigBeforeStudy = mNewCardsNum == totalCards && mShouldConfigBeforeStudy;
int hardNum = getLapses(getCol(), getCol().getDecks().current().optLong("id"));
mDeckListAdapter.mTextCountHandled = String.format(Locale.CHINA, "%d", (int) data[0]);
mDeckListAdapter.mTextCountLearning = String.format(Locale.CHINA, "%d", (int) data[1]);
mDeckListAdapter.mTextCountNew = String.format(Locale.CHINA, "%d", (int) data[2]);
mDeckListAdapter.mTextCountHard = String.format(Locale.CHINA, "%d", hardNum);
mDeckListAdapter.mTextTotal = String.format(Locale.CHINA, "共%d张卡牌", totalCards);
double percent = 0;
if (data[2] == 0) {
// 新卡已学完,显示已掌握
percent = (data[0] + data[1] + data[2] <= 0) ? 0 : (data[0] / (data[0] + data[1] + data[2]) * 100);
mDeckListAdapter.mTextHandledNum = String.format(Locale.CHINA, "%.0f/%.0f", data[0], (data[0] + data[1] + data[2]));
// holder.handled_percent.setText((String.format(Locale.CHINA, "已掌握 %.1f", percent)) + "%");
} else {
percent = (data[0] + data[1] + data[2] <= 0) ? 0 : ((data[0] + data[1]) / (data[0] + data[1] + data[2]) * 100);
mDeckListAdapter.mTextHandledNum = String.format(Locale.CHINA, "%.0f/%.0f", data[0] + data[1], data[0] + data[1] + data[2]);
// holder.handled_percent.setText((String.format(Locale.CHINA, "已学 %.1f", percent)) + "%");
}
// double percent = (data[0] + data[1] + data[2] <= 0) ? 0 : (data[0] / (data[0] + data[1] + data[2]) * 100);
// mStudyProgress.setMax(100*100);
mDeckListAdapter.mStudyProgress = (int) (percent * 100);
mDeckListAdapter.mTextHandledPercent = (String.format(Locale.CHINA, data[2] == 0 ? "已掌握 %.1f" : "已学 %.1f", percent)) + "%";
// Set estimated time remaining
int eta = (newCards + revCards) * 10 / 60;
if ((newCards + revCards) % 60 != 0) {
eta++;
}
if (eta != -1) {
mDeckListAdapter.mTextETA = "" + eta;
} else {
mDeckListAdapter.mTextETA = "-";
}
mDeckListAdapter.notifyDataSetChangedAll();
// Rebuild the options menu
configureToolbar();
}
updateDeckList();
// If in fragmented mode, refresh the deck list
if (mFragmented && refreshDecklist) {
mListener.onRequireDeckListUpdate();
}
}
};
}
use of com.ichi2.anim.ActivityTransitionAnimation.Direction.START in project AnkiChinaAndroid by ankichinateam.
the class UIUtils method saveCollectionInBackground.
public static void saveCollectionInBackground(boolean syncIgnoresDatabaseModification) {
if (CollectionHelper.getInstance().colIsOpen()) {
TaskListener listener = new TaskListener() {
@Override
public void onPreExecute() {
Timber.d("saveCollectionInBackground: start");
}
@Override
public void onPostExecute(TaskData result) {
Timber.d("saveCollectionInBackground: finished");
}
};
CollectionTask.launchCollectionTask(SAVE_COLLECTION, listener, new TaskData(syncIgnoresDatabaseModification));
}
}
Aggregations