use of com.ichi2.anki.DeckPicker in project AnkiChinaAndroid by ankichinateam.
the class SettingFragment method onCreateView.
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
Timber.i("on create view in setting fragment");
if (mRoot == null) {
final SharedPreferences preferences = getPreferences();
mRoot = inflater.inflate(R.layout.fragment_setting, container, false);
rl_login = mRoot.findViewById(R.id.rl_login);
mLl_defaultLink = mRoot.findViewById(R.id.ll_default_link);
mRl_user_name = mRoot.findViewById(R.id.tv_user_name);
mTv_logout = mRoot.findViewById(R.id.tv_quit);
mIv_entrance = mRoot.findViewById(R.id.iv_entrance);
mRl_cloud_space = mRoot.findViewById(R.id.tv_cloud_space);
mLl_switch_server = mRoot.findViewById(R.id.ll_switch_server);
mTv_server_name = mRoot.findViewById(R.id.server_name);
mTv_switch_server = mRoot.findViewById(R.id.tv_switch_server);
rl_login.setOnClickListener(v -> ((DeckPicker) getAnkiActivity()).loginToSyncServer());
mRoot.findViewById(R.id.rl_personal_setting).setOnClickListener(v -> {
Timber.i("Navigating to settings");
mOldColPath = CollectionHelper.getCurrentAnkiDroidDirectory(getAnkiActivity());
// Remember the theme we started with so we can restart the Activity if it changes
mOldTheme = Themes.getCurrentTheme(getContext());
getAnkiActivity().startActivityForResultWithAnimation(new Intent(getAnkiActivity(), Preferences.class), REQUEST_PREFERENCES_UPDATE, ActivityTransitionAnimation.FADE);
});
// mRoot.findViewById(R.id.rl_sync_set).setOnClickListener(v -> {
// Timber.i("AnkiDroid directory inaccessible");
// Intent i = Preferences.getPreferenceSubscreenIntent(getAnkiActivity(), "com.ichi2.anki.prefs.general");
// getAnkiActivity().startActivityWithAnimation(i, ActivityTransitionAnimation.FADE);
// });
mNightModeSwitch = mRoot.findViewById(R.id.switch_dark_mode);
mNightModeSwitch.setChecked(preferences.getBoolean(NIGHT_MODE_PREFERENCE, false));
mNightModeSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
applyNightMode(isChecked);
});
mAutoSyncSwitch = mRoot.findViewById(R.id.switch_auto_sync);
mAutoSyncSwitch.setChecked(preferences.getBoolean("automaticSyncMode", true));
mAutoSyncSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
preferences.edit().putBoolean("automaticSyncMode", isChecked).apply();
});
mRoot.findViewById(R.id.rl_dark_mode).setOnClickListener(v -> {
Timber.i("Toggling Night Mode");
mNightModeSwitch.performClick();
});
mRoot.findViewById(R.id.vip_power).setOnClickListener(this);
mRoot.findViewById(R.id.rl_anki_course).setOnClickListener(this);
mRoot.findViewById(R.id.rl_team).setOnClickListener(this);
mRoot.findViewById(R.id.rl_version).setOnClickListener(this);
mRoot.findViewById(R.id.rl_feedback).setOnClickListener(this);
mRoot.findViewById(R.id.user_protocol).setOnClickListener(this);
mRoot.findViewById(R.id.user_private).setOnClickListener(this);
mRoot.findViewById(R.id.rl_market_like).setOnClickListener(this);
mLl_switch_server.setOnClickListener(this);
mVipText = mRoot.findViewById(R.id.vip_text);
mVipPower = mRoot.findViewById(R.id.vip_power);
mVipText.setText(mVip ? getVipString(mVipDay) : getNotVipString());
mVipPower.setText(mVip ? "查看权益" : "立即开通");
OKHttpUtil.get(Consts.ANKI_CHINA_BASE + Consts.API_VERSION + "configs/1", "", "", new OKHttpUtil.MyCallBack() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, String token, Object arg1, Response response) throws IOException {
if (response.isSuccessful()) {
Timber.i("initMoreDrawerMenuItem successfully!:%s", response.body());
try {
final JSONObject object = new JSONObject(response.body().string());
final JSONArray items = object.getJSONArray("data");
Timber.i("initMoreDrawerMenuItem %d ", items.length());
List<DynamicItem> dynamicItems = new ArrayList<>();
for (int i = 0; i < items.length(); i++) {
JSONObject jsonObject = items.getJSONObject(i);
String title = jsonObject.optString("title");
String image = jsonObject.optString("image_url");
String link = jsonObject.optString("target_url");
Drawable drawable = null;
try {
drawable = Drawable.createFromStream(new URL(image).openStream(), title + ".jpg");
} catch (Exception e) {
e.printStackTrace();
}
dynamicItems.add(new DynamicItem(title, link, drawable));
Timber.i("load drawable result %s,%s ,%s ", title, image, link);
}
getAnkiActivity().runOnUiThread(() -> {
mLl_defaultLink.removeAllViews();
for (int i = 0; i < dynamicItems.size(); i++) {
int finalI = i;
int[] attrs = new int[] { R.attr.settingItemBackgroundTop, R.attr.settingItemBackground, R.attr.settingItemBackgroundBottom, R.attr.settingItemBackgroundRound };
TypedArray ta = getAnkiActivity().obtainStyledAttributes(attrs);
Drawable background;
background = ta.getDrawable(dynamicItems.size() == 1 ? 3 : finalI == 0 ? 0 : finalI == dynamicItems.size() - 1 ? 2 : 1);
DynamicItem dynamicItem = dynamicItems.get(finalI);
SettingItem item = new SettingItem(getContext(), dynamicItem.title, dynamicItem.drawable);
item.findViewById(R.id.rl_root).setBackground(background);
item.setOnClickListener(v -> {
WebViewActivity.openUrlInApp(getAnkiActivity(), dynamicItem.link, "", -1);
});
mLl_defaultLink.addView(item);
}
});
} catch (Exception e) {
e.printStackTrace();
}
} else {
Timber.e("initMoreDrawerMenuItem failed, error code %d", response.code());
}
}
});
}
return mRoot;
}
use of com.ichi2.anki.DeckPicker in project AnkiChinaAndroid by ankichinateam.
the class StudyOptionsFragment method onMenuItemClick.
@SuppressWarnings("deprecation")
@Override
public boolean onMenuItemClick(MenuItem item) {
switch(item.getItemId()) {
case R.id.action_browser:
{
Timber.i("DeckPicker:: Old browser button pressed");
getAnkiActivity().openOldCardBrowser();
return true;
}
case R.id.action_undo:
Timber.i("StudyOptionsFragment:: Undo button pressed");
CollectionTask.launchCollectionTask(UNDO, undoListener);
return true;
case R.id.action_deck_options:
Timber.i("StudyOptionsFragment:: Deck options button pressed");
if (getCol().getDecks().isDyn(getCol().getDecks().selected())) {
openFilteredDeckOptions();
} else {
Intent i = new Intent(getActivity(), DeckOptions.class);
getActivity().startActivityForResult(i, DECK_OPTIONS);
ActivityTransitionAnimation.slide(getActivity(), ActivityTransitionAnimation.FADE);
}
return true;
case R.id.action_setting:
Timber.i("StudyOptionsFragment:: Deck setting button pressed");
Intent i = new Intent(getActivity(), StudySettingActivity.class);
getActivity().startActivityForResult(i, DECK_OPTIONS);
ActivityTransitionAnimation.slide(getActivity(), ActivityTransitionAnimation.FADE);
return true;
case R.id.action_custom_study:
Timber.i("StudyOptionsFragment:: custom study button pressed");
showCustomStudyContextMenu();
return true;
case R.id.action_unbury:
Timber.i("StudyOptionsFragment:: unbury button pressed");
getCol().getSched().unburyCardsForDeck();
refreshInterfaceAndDecklist(true);
item.setVisible(false);
return true;
case R.id.action_rebuild:
Timber.i("StudyOptionsFragment:: rebuild cram deck button pressed");
mProgressDialog = StyledProgressDialog.show(getActivity(), "", getResources().getString(R.string.rebuild_filtered_deck), true);
CollectionTask.launchCollectionTask(REBUILD_CRAM, getCollectionTaskListener(true));
return true;
case R.id.action_empty:
Timber.i("StudyOptionsFragment:: empty cram deck button pressed");
mProgressDialog = StyledProgressDialog.show(getActivity(), "", getResources().getString(R.string.empty_filtered_deck), false);
CollectionTask.launchCollectionTask(EMPTY_CRAM, getCollectionTaskListener(true));
return true;
case R.id.action_rename:
((AnkiActivity) getActivity()).renameDeckDialog(getCol().getDecks().selected());
return true;
case R.id.action_delete:
getAnkiActivity().mContextMenuDid = getCol().getDecks().selected();
((AnkiActivity) getActivity()).confirmDeckDeletion(getCol().getDecks().selected());
return true;
case R.id.action_export:
((AnkiActivity) getActivity()).exportDeck(getCol().getDecks().selected());
return true;
case R.id.action_add_card:
addNote();
return true;
case R.id.create_deck:
getAnkiActivity().mContextMenuDid = getCol().getDecks().selected();
((AnkiActivity) getActivity()).createSubdeckDialog();
return true;
case // 停止/恢复
R.id.action_suspend:
mDeckIsStopped = deckIsStopped();
if (mDeckIsStopped) {
customDialog = new CustomStyleDialog.Builder(getAnkiActivity()).setTitle("恢复学习").setMessage("恢复学习后将每天新卡数和复习数值调整成默认值,请确认是否开始学习").setPositiveButton("确定", (dialog, which) -> {
resumeDeckStudy();
dialog.dismiss();
}).setNegativeButton("取消", (dialog, which) -> dialog.dismiss()).create();
} else {
customDialog = new CustomStyleDialog.Builder(getAnkiActivity()).setTitle("停止学习").setMessage("暂停学习将会自动把每天新卡数和复习数调整为零,适用于有事暂停一两周不学习,若该记忆库学习的时长不超过2个月,又暂停了30天未学习,建议重设进度,重新开始学习").setPositiveButton("确定", (dialog, which) -> {
stopDeckStudy();
dialog.dismiss();
}).setNegativeButton("取消", (dialog, which) -> dialog.dismiss()).create();
}
customDialog.show();
return true;
case // 重设学习进度
R.id.action_reset_card_progress:
customDialog = new CustomStyleDialog.Builder(getAnkiActivity()).setTitle("重设学习进度").setMessage("重设学习进度后,该记忆库的所有卡片学习记录都会被清除,请谨慎操作").setPositiveButton("确定", (dialog, which) -> {
CollectionTask.launchCollectionTask(RESET_DECK, new ResetCardHandler(StudyOptionsFragment.this), new TaskData(new Object[] { "deck:\"" + getCol().getDecks().current().getString("name") + "\" " }));
dialog.dismiss();
}).setNegativeButton("取消", (dialog, which) -> dialog.dismiss()).create();
customDialog.show();
return true;
default:
return false;
}
}
use of com.ichi2.anki.DeckPicker in project AnkiChinaAndroid by ankichinateam.
the class DeckPicker method showStartupScreensAndDialogs.
public void showStartupScreensAndDialogs(SharedPreferences preferences, int skip) {
if (!BackupManager.enoughDiscSpace(CollectionHelper.getCurrentAnkiDroidDirectory(this))) {
Timber.i("Not enough space to do backup");
showDialogFragment(DeckPickerNoSpaceLeftDialog.newInstance());
} else if (preferences.getBoolean("noSpaceLeft", false)) {
Timber.i("No space left");
showDialogFragment(DeckPickerBackupNoSpaceLeftDialog.newInstance());
preferences.edit().remove("noSpaceLeft").apply();
} else if ("".equals(preferences.getString("lastVersion", ""))) {
Timber.i("Fresh install");
preferences.edit().putString("lastVersion", VersionUtils.getPkgVersionName()).apply();
onFinishedStartup();
} else if (skip < 2 && !preferences.getString("lastVersion", "").equals(VersionUtils.getPkgVersionName())) {
Timber.i("AnkiDroid is being updated and a collection already exists.");
// The user might appreciate us now, see if they will help us get better?
if (!preferences.contains(UsageAnalytics.ANALYTICS_OPTIN_KEY)) {
showDialogFragment(DeckPickerAnalyticsOptInDialog.newInstance());
}
// For upgrades, we check if we are upgrading
// to a version that contains additions to the database integrity check routine that we would
// like to run on all collections. A missing version number is assumed to be a fresh
// installation of AnkiDroid and we don't run the check.
long current = VersionUtils.getPkgVersionCode();
Timber.i("Current AnkiDroid version: %s", current);
long previous;
if (preferences.contains(UPGRADE_VERSION_KEY)) {
// Upgrading currently installed app
previous = getPreviousVersion(preferences, current);
} else {
// Fresh install
previous = current;
}
preferences.edit().putLong(UPGRADE_VERSION_KEY, current).apply();
// It is rebuilt on the next sync or media check
if (previous < 20300200) {
Timber.i("Deleting media database");
File mediaDb = new File(CollectionHelper.getCurrentAnkiDroidDirectory(this), "collection.media.ad.db2");
if (mediaDb.exists()) {
mediaDb.delete();
}
}
// Recommend the user to do a full-sync if they're upgrading from before 2.3.1beta8
if (previous < 20301208) {
Timber.i("Recommend the user to do a full-sync");
mRecommendFullSync = true;
}
// Fix "font-family" definition in templates created by AnkiDroid before 2.6alhpa23
if (previous < 20600123) {
Timber.i("Fixing font-family definition in templates");
try {
Models models = getCol().getModels();
for (Model m : models.all()) {
String css = m.getString("css");
if (css.contains("font-familiy")) {
m.put("css", css.replace("font-familiy", "font-family"));
models.save(m);
}
}
models.flush();
} catch (JSONException e) {
Timber.e(e, "Failed to upgrade css definitions.");
}
}
// Check if preference upgrade or database check required, otherwise go to new feature screen
int upgradePrefsVersion = AnkiDroidApp.CHECK_PREFERENCES_AT_VERSION;
int upgradeDbVersion = AnkiDroidApp.CHECK_DB_AT_VERSION;
// Specifying a checkpoint in the future is not supported, please don't do it!
if (current < upgradePrefsVersion) {
Timber.e("Checkpoint in future produced.");
UIUtils.showSimpleSnackbar(this, "Invalid value for CHECK_PREFERENCES_AT_VERSION", false);
onFinishedStartup();
return;
}
if (current < upgradeDbVersion) {
Timber.e("Invalid value for CHECK_DB_AT_VERSION");
UIUtils.showSimpleSnackbar(this, "Invalid value for CHECK_DB_AT_VERSION", false);
onFinishedStartup();
return;
}
// Skip full DB check if the basic check is OK
// TODO: remove this variable if we really want to do the full db check on every user
boolean skipDbCheck = false;
// noinspection ConstantConditions
if ((!skipDbCheck && previous < upgradeDbVersion) || previous < upgradePrefsVersion) {
if (previous < upgradePrefsVersion) {
Timber.i("showStartupScreensAndDialogs() running upgradePreferences()");
upgradePreferences(previous);
}
// noinspection ConstantConditions
if (!skipDbCheck && previous < upgradeDbVersion) {
Timber.i("showStartupScreensAndDialogs() running integrityCheck()");
// #5852 - since we may have a warning about disk space, we don't want to force a check database
// and show a warning before the user knows what is happening.
new MaterialDialog.Builder(this).title(R.string.integrity_check_startup_title).content(R.string.integrity_check_startup_content).positiveText(R.string.integrity_check_positive).negativeText(R.string.close).onPositive((materialDialog, dialogAction) -> integrityCheck()).onNeutral((materialDialog, dialogAction) -> this.restartActivity()).onNegative((materialDialog, dialogAction) -> this.restartActivity()).canceledOnTouchOutside(false).cancelable(false).build().show();
} else if (previous < upgradePrefsVersion) {
Timber.i("Updated preferences with no integrity check - restarting activity");
// If integrityCheck() doesn't occur, but we did update preferences we should restart DeckPicker to
// proceed
this.restartActivity();
}
} else {
// If no changes are required we go to the new features activity
// There the "lastVersion" is set, so that this code is not reached again
// if (VersionUtils.isReleaseVersion()) {
// Timber.i("Displaying new features");
// Intent infoIntent = new Intent(this, Info.class);
// infoIntent.putExtra(Info.TYPE_EXTRA, Info.TYPE_NEW_VERSION);
//
// if (skip != 0) {
// startActivityForResultWithAnimation(infoIntent, SHOW_INFO_NEW_VERSION,
// ActivityTransitionAnimation.LEFT);
// } else {
// startActivityForResultWithoutAnimation(infoIntent, SHOW_INFO_NEW_VERSION);
// }
// } else {
Timber.i("Dev Build - not showing 'new features'");
// Don't show new features dialog for development builds
preferences.edit().putString("lastVersion", VersionUtils.getPkgVersionName()).apply();
String ver = getResources().getString(R.string.updated_version, VersionUtils.getPkgVersionName());
UIUtils.showSnackbar(this, ver, true, -1, null, findViewById(R.id.root_layout), null);
showStartupScreensAndDialogs(preferences, 2);
// }
}
} else {
// this is the main call when there is nothing special required
Timber.i("No startup screens required");
onFinishedStartup();
}
}
use of com.ichi2.anki.DeckPicker in project AnkiChinaAndroid by ankichinateam.
the class AbstractFlashcardViewer method restoreCollectionPreferences.
protected void restoreCollectionPreferences() {
// These are preferences we pull out of the collection instead of SharedPreferences
try {
mShowNextReviewTime = getCol().getConf().getBoolean("estTimes");
// Dynamic don't have review options; attempt to get deck-specific auto-advance options
// but be prepared to go with all default if it's a dynamic deck
JSONObject revOptions = new JSONObject();
long selectedDid = getCol().getDecks().selected();
if (!getCol().getDecks().isDyn(selectedDid)) {
revOptions = getCol().getDecks().confForDid(selectedDid).getJSONObject("rev");
}
mOptUseGeneralTimerSettings = revOptions.optBoolean("useGeneralTimeoutSettings", true);
mOptUseTimer = revOptions.optBoolean("timeoutAnswer", false);
mOptWaitAnswerSecond = revOptions.optInt("timeoutAnswerSeconds", 20);
mOptWaitQuestionSecond = revOptions.optInt("timeoutQuestionSeconds", 60);
} catch (JSONException e) {
Timber.e(e, "Unable to restoreCollectionPreferences");
throw new RuntimeException(e);
} catch (NullPointerException npe) {
// NPE on collection only happens if the Collection is broken, follow AnkiActivity example
Intent deckPicker = new Intent(this, DeckPicker.class);
// don't currently do anything with this
deckPicker.putExtra("collectionLoadError", true);
deckPicker.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivityWithAnimation(deckPicker, ActivityTransitionAnimation.LEFT);
}
}
use of com.ichi2.anki.DeckPicker in project AnkiChinaAndroid by ankichinateam.
the class DeckPickerNoSpaceLeftDialog method onCreateDialog.
@Override
public MaterialDialog onCreateDialog(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Resources res = getResources();
return new MaterialDialog.Builder(getActivity()).title(res.getString(R.string.sd_card_full_title)).content(res.getString(R.string.backup_deck_no_space_left)).cancelable(true).positiveText(res.getString(R.string.dialog_ok)).onPositive((dialog, which) -> ((DeckPicker) getActivity()).startLoadingCollection()).cancelListener(dialog -> ((DeckPicker) getActivity()).startLoadingCollection()).show();
}
Aggregations