Search in sources :

Example 1 with CARD

use of com.ichi2.anki.CardBrowser.Column.CARD in project AnkiChinaAndroid by ankichinateam.

the class AbstractFlashcardViewer method readCardText.

private void readCardText(final Card card, final SoundSide cardSide) {
    final String cardSideContent;
    if (!cardContentIsEmpty() && ((sDisplayAnswer && mFinalLoadAnswer.isEmpty()) || (!sDisplayAnswer && mFinalLoadQuestion.isEmpty()))) {
        mainHandler.postDelayed(() -> {
            showProgressBar();
            Toast.makeText(AbstractFlashcardViewer.this, "卡牌加载中,网络不佳", Toast.LENGTH_SHORT).show();
        }, 3000);
        nNeedSpeakFinalRenderContent = true;
        if (!fetchingRenderContent) {
            fetchWebViewRenderContent(mCardWebView);
        }
        return;
    }
    mainHandler.removeCallbacksAndMessages(null);
    hideProgressBar();
    // 在这里获取最后的内容
    cardSideContent = cardSide == SoundSide.QUESTION ? mFinalLoadQuestion : mFinalLoadAnswer;
    Timber.i("finally i wanna say:%s,showing answer:%s", cardSideContent, sDisplayAnswer);
    // 如果不是设置了离线模式且当前没网时,且非强制离线模式,则默认使用在线模式
    if (AnkiDroidApp.getSharedPrefs(this).getBoolean(KEY_SELECT_ONLINE_SPEAK_ENGINE, false) && !mOfflineSpeakingForOnce) {
        // 使用在线语音引擎
        File target = new File(FileUtil.createTmpDir(this), card.getId() + "-" + cardSide + ".wav");
        Timber.i("target audio :%s", target.getAbsolutePath());
        if (target.exists()) {
            Timber.i("target audio is exists,play it now");
            mSoundPlayer.playSound(target.getAbsolutePath(), mp -> mOnlineSpeaking = false);
            mOnlineSpeaking = true;
            speakingHandler.postDelayed(speakingRunnable, 300);
            return;
        }
        if (!isNetworkAvailable(AbstractFlashcardViewer.this)) {
            CustomStyleDialog customStyleDialog = new CustomStyleDialog.Builder(AbstractFlashcardViewer.this).setCustomLayout(R.layout.dialog_common_custom_next).setTitle("在线朗读需联网!").centerTitle().setMessage("没有网络时可以点下方按钮切换成本地引擎").setPositiveButton("切换本地引擎", (dialog, which) -> {
                dialog.dismiss();
                AnkiDroidApp.getSharedPrefs(this).edit().putBoolean(KEY_SELECT_ONLINE_SPEAK_ENGINE, false).apply();
            }).create();
            customStyleDialog.show();
            return;
        }
        getAccount().getToken(this, new MyAccount.TokenCallback() {

            @Override
            public void onSuccess(String token) {
                mCacheToken = token;
                // if (mFreeOnlineEngineCount != -10086) {
                // if (mFreeOnlineEngineCount > 0) {
                // String voice=ReadText.getAzureLanguage(card.getDid(), card.getOrd(), cardSide);
                // if (voice.isEmpty()) {
                // //选择语言
                // CustomStyleDialog d = new CustomStyleDialog.Builder(AbstractFlashcardViewer.this)
                // .setCustomLayout(R.layout.dialog_common_custom_next)
                // .setTitle("首次朗读,请设置语言")
                // .centerTitle()
                // .setMessage("设置语言后,朗读效果更优,还可以选择是否自动朗读。")
                // .setPositiveButton("前往设置", (dialog, which) -> {
                // dialog.dismiss();
                // SpeakSettingActivity.OpenSpeakSetting(card.getId(), card.getDid(), AbstractFlashcardViewer.this);
                // })  .create();
                // d.show();
                // return;
                // }
                List<Pair<String, String>> texts = splitAry(cardSideContent, 59, String.valueOf(card.getId()), cardSide);
                Map<String, String> params = new HashMap<>();
                params.put(SpeechSynthesizer.PARAM_SPEED, String.valueOf(ReadText.getSpeechRate(mCurrentCard.getDid(), mCurrentCard.getOrd()) * 5));
                synthesizer.setParams(params);
                int result = synthesizer.batchSpeak(texts);
                checkResult(result, "speak");
            // 
            // } else {
            // CustomStyleDialog customStyleDialog = new CustomStyleDialog.Builder(AbstractFlashcardViewer.this)
            // .setCustomLayout(R.layout.dialog_common_custom_next)
            // .setTitle("在线朗读次数已用完")
            // .centerTitle()
            // .setMessage("请前往充值在线朗读次数,学霸用户可以切换离线引擎,不限朗读次数")
            // .setPositiveButton("前往充值", (dialog, which) -> {
            // dialog.dismiss();
            // WebViewActivity.openUrlInApp(AbstractFlashcardViewer.this, String.format(mBuyOnlineEngineUrl, token, BuildConfig.VERSION_NAME), token, REFRESH_VOICE_INFO);
            // }).setNegativeButton("使用离线引擎", (dialog, which) -> {
            // dialog.dismiss();
            // AnkiDroidApp.getSharedPrefs(AbstractFlashcardViewer.this).edit().putBoolean(KEY_SELECT_ONLINE_SPEAK_ENGINE, false).apply();
            // })
            // 
            // .create();
            // 
            // customStyleDialog.show();
            // }
            // } else {
            // updateOnlineVoiceInfo(token);
            // }
            }

            @Override
            public void onFail(String message) {
                Timber.e("need login while using online speak engine ");
                Toast.makeText(AbstractFlashcardViewer.this, "当前未使用Anki记忆卡账号登录,无法使用在线语音引擎", Toast.LENGTH_SHORT).show();
                Intent myAccount = new Intent(AbstractFlashcardViewer.this, MyAccount.class);
                myAccount.putExtra("notLoggedIn", true);
                startActivityForResultWithAnimation(myAccount, REFRESH_VOICE_INFO, ActivityTransitionAnimation.FADE);
            }
        });
        speakingHandler.postDelayed(speakingRunnable, 300);
        return;
    }
    mOfflineSpeakingForOnce = false;
    String clozeReplacement = this.getString(R.string.reviewer_tts_cloze_spoken_replacement);
    ReadText.readCardSide(cardSide, cardSideContent, card.getId(), getDeckIdForCard(card), card.getOrd(), clozeReplacement, true);
    speakingHandler.postDelayed(speakingRunnable, 300);
}
Also used : JavascriptInterface(android.webkit.JavascriptInterface) UI_PLAY_END(com.ichi2.bd.MainHandlerConstant.UI_PLAY_END) Version(com.github.zafarkhaja.semver.Version) Bundle(android.os.Bundle) TagsDialog(com.ichi2.anki.dialogs.TagsDialog) JsResult(android.webkit.JsResult) NonNull(androidx.annotation.NonNull) Uri(android.net.Uri) FrameLayout(android.widget.FrameLayout) ImageView(android.widget.ImageView) AbstractSched(com.ichi2.libanki.sched.AbstractSched) RangeSeekBar(com.jaygoo.widget.RangeSeekBar) RenderProcessGoneDetail(android.webkit.RenderProcessGoneDetail) HitTestResult(android.webkit.WebView.HitTestResult) ActionBar(androidx.appcompat.app.ActionBar) FileSaveListener(com.ichi2.bd.FileSaveListener) Decks(com.ichi2.libanki.Decks) Matcher(java.util.regex.Matcher) Handler(android.os.Handler) DeckConfig(com.ichi2.libanki.DeckConfig) Map(java.util.Map) JSONException(com.ichi2.utils.JSONException) THEME_NIGHT_BLACK(com.ichi2.themes.Themes.THEME_NIGHT_BLACK) OnRangeChangedListener(com.jaygoo.widget.OnRangeChangedListener) ContextCompat(androidx.core.content.ContextCompat) TargetApi(android.annotation.TargetApi) Log(android.util.Log) ReadWriteLock(java.util.concurrent.locks.ReadWriteLock) ConnectivityManager(android.net.ConnectivityManager) HtmlUtils(com.ichi2.utils.HtmlUtils) CoordinatorLayout(androidx.coordinatorlayout.widget.CoordinatorLayout) TtsMode(com.baidu.tts.client.TtsMode) IntentFilter(android.content.IntentFilter) CardMarker(com.ichi2.anki.reviewer.CardMarker) Set(java.util.Set) JSONObject(com.ichi2.utils.JSONObject) BE_VIP(com.ichi2.anki.DeckPicker.BE_VIP) IdRes(androidx.annotation.IdRes) StringRes(androidx.annotation.StringRes) Nullable(androidx.annotation.Nullable) Message(android.os.Message) Consts(com.ichi2.libanki.Consts) OKHttpUtil(com.ichi2.utils.OKHttpUtil) CompatHelper(com.ichi2.compat.CompatHelper) WebViewDebugging(com.ichi2.utils.WebViewDebugging) DiffEngine(com.ichi2.utils.DiffEngine) TypedAnswer(com.ichi2.anki.cardviewer.TypedAnswer) WebResourceResponse(android.webkit.WebResourceResponse) Dialog(android.app.Dialog) SystemClock(android.os.SystemClock) SdCardReceiver(com.ichi2.anki.receiver.SdCardReceiver) ReentrantReadWriteLock(java.util.concurrent.locks.ReentrantReadWriteLock) CardAppearance.calculateDynamicFontSize(com.ichi2.anki.cardviewer.CardAppearance.calculateDynamicFontSize) ViewAnimation(com.ichi2.anim.ViewAnimation) ArrayList(java.util.ArrayList) REFRESH_VOICE_INFO(com.ichi2.anki.DeckPicker.REFRESH_VOICE_INFO) WebResourceRequest(android.webkit.WebResourceRequest) Toast(android.widget.Toast) Menu(android.view.Menu) Connection(com.ichi2.async.Connection) Response(okhttp3.Response) Call(okhttp3.Call) CardAppearance(com.ichi2.anki.cardviewer.CardAppearance) WebChromeClient(android.webkit.WebChromeClient) LinkedHashSet(java.util.LinkedHashSet) PRINT(com.ichi2.bd.MainHandlerConstant.PRINT) CheckResult(androidx.annotation.CheckResult) MissingImageHandler(com.ichi2.anki.cardviewer.MissingImageHandler) FileOutputStream(java.io.FileOutputStream) TextUtils(android.text.TextUtils) IOException(java.io.IOException) SoundSide(com.ichi2.libanki.Sound.SoundSide) File(java.io.File) Gravity(android.view.Gravity) Lock(java.util.concurrent.locks.Lock) SharedPreferences(android.content.SharedPreferences) TypedValue(android.util.TypedValue) FileUtil(com.ichi2.utils.FileUtil) Configuration(android.content.res.Configuration) ActivityTransitionAnimation(com.ichi2.anim.ActivityTransitionAnimation) EditText(android.widget.EditText) SpeechSynthesizerListener(com.baidu.tts.client.SpeechSynthesizerListener) ImageButton(android.widget.ImageButton) REQUEST_CODE_SPEAK_SETTING(com.ichi2.anki.SpeakSettingActivity.REQUEST_CODE_SPEAK_SETTING) LinearLayout(android.widget.LinearLayout) URLDecoder(java.net.URLDecoder) HtmlColors(com.ichi2.themes.HtmlColors) GestureDetectorCompat(androidx.core.view.GestureDetectorCompat) WindowManager(android.view.WindowManager) NonBlockSyntherizer(com.ichi2.bd.NonBlockSyntherizer) FormBody(okhttp3.FormBody) ByteArrayInputStream(java.io.ByteArrayInputStream) ViewerCommand(com.ichi2.anki.cardviewer.ViewerCommand) Gson(com.google.gson.Gson) Locale(java.util.Locale) WebViewClient(android.webkit.WebViewClient) View(android.view.View) Button(android.widget.Button) TaskData(com.ichi2.async.TaskData) WebView(android.webkit.WebView) InitConfig(com.ichi2.bd.InitConfig) Auth(com.ichi2.bd.Auth) SimpleOnGestureListener(android.view.GestureDetector.SimpleOnGestureListener) SynthesizerTool(com.baidu.tts.client.SynthesizerTool) BroadcastReceiver(android.content.BroadcastReceiver) ViewGroup(android.view.ViewGroup) Timber(timber.log.Timber) IOfflineResourceConst(com.ichi2.bd.IOfflineResourceConst) MySyntherizer(com.ichi2.bd.MySyntherizer) List(java.util.List) TextView(android.widget.TextView) ActivityNotFoundException(android.content.ActivityNotFoundException) SpeechSynthesizer(com.baidu.tts.client.SpeechSynthesizer) KEY_SELECT_ONLINE_SPEAK_ENGINE(com.ichi2.libanki.Consts.KEY_SELECT_ONLINE_SPEAK_ENGINE) Toolbar(androidx.appcompat.widget.Toolbar) RelativeLayout(android.widget.RelativeLayout) THEME_NIGHT_DARK(com.ichi2.themes.Themes.THEME_NIGHT_DARK) OfflineResource(com.ichi2.bd.OfflineResource) AudioView(com.ichi2.anki.multimediacard.AudioView) Pattern(java.util.regex.Pattern) MaterialDialog(com.afollestad.materialdialogs.MaterialDialog) Window(android.view.Window) EditorInfo(android.view.inputmethod.EditorInfo) Snackbar(com.google.android.material.snackbar.Snackbar) UnsupportedEncodingException(java.io.UnsupportedEncodingException) KEY_SHOW_TTS_ICON(com.ichi2.libanki.Consts.KEY_SHOW_TTS_ICON) Note(com.ichi2.libanki.Note) Context(android.content.Context) TaskListener(com.ichi2.async.TaskListener) UI_CHANGE_SYNTHES_TEXT_SELECTION(com.ichi2.bd.MainHandlerConstant.UI_CHANGE_SYNTHES_TEXT_SELECTION) KeyEvent(android.view.KeyEvent) Pair(android.util.Pair) Intent(android.content.Intent) ReviewerCustomFonts(com.ichi2.anki.reviewer.ReviewerCustomFonts) HashMap(java.util.HashMap) REFRESH_LOGIN_STATE_AND_TURN_TO_VIP_HTML(com.ichi2.anki.DeckPicker.REFRESH_LOGIN_STATE_AND_TURN_TO_VIP_HTML) Collection(com.ichi2.libanki.Collection) TypedArray(android.content.res.TypedArray) MenuItem(android.view.MenuItem) InputMethodManager(android.view.inputmethod.InputMethodManager) RequestBody(okhttp3.RequestBody) TASK_TYPE(com.ichi2.async.CollectionTask.TASK_TYPE) HashSet(java.util.HashSet) ConnectivityManagerCompat(androidx.core.net.ConnectivityManagerCompat) SuppressLint(android.annotation.SuppressLint) JSONArray(com.ichi2.utils.JSONArray) MotionEvent(android.view.MotionEvent) Build(android.os.Build) WeakReference(java.lang.ref.WeakReference) LinkedList(java.util.LinkedList) Sound(com.ichi2.libanki.Sound) Utils(com.ichi2.libanki.Utils) LoggerProxy(com.baidu.tts.chainofresponsibility.logger.LoggerProxy) Consumer(com.ichi2.utils.FunctionalInterfaces.Consumer) Function(com.ichi2.utils.FunctionalInterfaces.Function) UI_CHANGE_INPUT_TEXT_SELECTION(com.ichi2.bd.MainHandlerConstant.UI_CHANGE_INPUT_TEXT_SELECTION) FlagDef(com.ichi2.anki.reviewer.CardMarker.FlagDef) LayoutInflater(android.view.LayoutInflater) ReviewerUi(com.ichi2.anki.reviewer.ReviewerUi) CollectionTask(com.ichi2.async.CollectionTask) Chronometer(android.widget.Chronometer) Themes(com.ichi2.themes.Themes) Template(com.ichi2.libanki.template.Template) Color(android.graphics.Color) WebResourceError(android.webkit.WebResourceError) UI_PLAY_START(com.ichi2.bd.MainHandlerConstant.UI_PLAY_START) AdaptionUtil(com.ichi2.utils.AdaptionUtil) Card(com.ichi2.libanki.Card) Activity(android.app.Activity) VisibleForTesting(androidx.annotation.VisibleForTesting) CustomStyleDialog(com.ichi2.ui.CustomStyleDialog) Resources(android.content.res.Resources) OnClickListener(android.view.View.OnClickListener) CustomStyleDialog(com.ichi2.ui.CustomStyleDialog) ArrayList(java.util.ArrayList) List(java.util.List) LinkedList(java.util.LinkedList) Intent(android.content.Intent) File(java.io.File) Map(java.util.Map) HashMap(java.util.HashMap)

Example 2 with CARD

use of com.ichi2.anki.CardBrowser.Column.CARD in project AnkiChinaAndroid by ankichinateam.

the class AbstractFlashcardViewer method requireApiVersion.

/**
 * Supplied api version must be equal to current api version to call mark card, toggle flag functions etc.
 */
private boolean requireApiVersion(String apiVer, String apiDevContact) {
    try {
        if (TextUtils.isEmpty(apiDevContact)) {
            return false;
        }
        Version mVersionCurrent = Version.valueOf(sCurrentJsApiVersion);
        Version mVersionSupplied = Version.valueOf(apiVer);
        /*
             * if api major version equals to supplied major version then return true and also check for minor version and patch version
             * show toast for update and contact developer if need updates
             * otherwise return false
             */
        if (mVersionSupplied.equals(mVersionCurrent)) {
            return true;
        } else if (mVersionSupplied.lessThan(mVersionCurrent)) {
            UIUtils.showThemedToast(AbstractFlashcardViewer.this, getString(R.string.update_js_api_version, mCardSuppliedDeveloperContact), false);
            if (mVersionSupplied.greaterThanOrEqualTo(Version.valueOf(sMinimumJsApiVersion))) {
                return true;
            } else {
                return false;
            }
        } else {
            UIUtils.showThemedToast(AbstractFlashcardViewer.this, getString(R.string.valid_js_api_version, mCardSuppliedDeveloperContact), false);
            return false;
        }
    } catch (Exception e) {
        Timber.w(e, "requireApiVersion::exception");
    }
    return false;
}
Also used : Version(com.github.zafarkhaja.semver.Version) JSONException(com.ichi2.utils.JSONException) IOException(java.io.IOException) ActivityNotFoundException(android.content.ActivityNotFoundException) UnsupportedEncodingException(java.io.UnsupportedEncodingException)

Example 3 with CARD

use of com.ichi2.anki.CardBrowser.Column.CARD in project AnkiChinaAndroid by ankichinateam.

the class AbstractFlashcardViewer method updateCard.

private void updateCard(final String newContent) {
    Timber.d("updateCard()");
    mCacheContent = newContent;
    mUseTimerDynamicMS = 0;
    // Add CSS for font color and font size
    if (mCurrentCard == null) {
        processCardAction(cardWebView -> cardWebView.getSettings().setDefaultFontSize(calculateDynamicFontSize(newContent)));
    }
    if (sDisplayAnswer) {
        addAnswerSounds(newContent);
    } else {
        // reset sounds each time first side of card is displayed, which may happen repeatedly without ever
        // leaving the card (such as when edited)
        mSoundPlayer.resetSounds();
        mAnswerSoundsAdded = false;
        mSoundPlayer.addSounds(mBaseUrl, newContent, SoundSide.QUESTION);
        if (mUseTimer && !mAnswerSoundsAdded && getConfigForCurrentCard().optBoolean("autoplay", false)) {
            addAnswerSounds(mCurrentCard.a());
        }
    }
    String content = Sound.expandSounds(mBaseUrl, newContent);
    content = CardAppearance.fixBoldStyle(content);
    Timber.v("content card = \n %s", content);
    String style = mCardAppearance.getStyle();
    Timber.v("::style:: / %s", style);
    // CSS class for card-specific styling
    String cardClass = mCardAppearance.getCardClass(mCurrentCard.getOrd() + 1, Themes.getCurrentTheme(this));
    if (Template.textContainsMathjax(content)) {
        cardClass += " mathjax-needs-to-render";
    }
    if (isInNightMode()) {
        if (!mCardAppearance.hasUserDefinedNightMode(mCurrentCard)) {
            content = HtmlColors.invertColors(content);
        }
    }
    content = CardAppearance.convertSmpToHtmlEntity(content);
    SharedPreferences prefs = AnkiDroidApp.getSharedPrefs(this);
    String localViewSettingStr = prefs.getString(Consts.KEY_LOCAL_LAYOUT_CONFIG, "");
    boolean dark = false;
    if (AnkiDroidApp.getSharedPrefs(this).getBoolean("invertedColors", false)) {
        int theme = Integer.parseInt(prefs.getString("nightTheme", "0"));
        dark = theme == THEME_NIGHT_DARK || theme == THEME_NIGHT_BLACK;
    }
    if (mCurrentCSS.isEmpty() || mCurrentCSSModelID != mCurrentCard.model().getLong("id")) {
        mCurrentCSSModelID = mCurrentCard.model().getLong("id");
        Timber.i("find new model id css %s", mCurrentCSS);
        if (localViewSettingStr != null && !localViewSettingStr.isEmpty()) {
            try {
                JSONObject viewSetting = new JSONObject(localViewSettingStr);
                JSONObject currentModelSetting = viewSetting.getJSONObject(String.valueOf(mCurrentCSSModelID));
                if (currentModelSetting != null) {
                    mCurrentCSS = convertJson2Css(currentModelSetting, false);
                } else {
                    mCurrentCSS = "";
                }
            } catch (Exception e) {
                e.printStackTrace();
                mCurrentCSS = "";
            }
        }
    }
    Timber.i("now theme is dark:%s", dark);
    if (!dark) {
        if (!mCurrentCSS.isEmpty()) {
            Matcher bgMatcher = Pattern.compile("background-color:(.+?);").matcher(mCurrentCSS);
            Window window = getWindow();
            if (bgMatcher.find()) {
                String fld1 = bgMatcher.group(1).trim();
                if (shouldChangeToolbarBgLikeCss2()) {
                    findViewById(R.id.toolbar).setBackgroundColor(Color.parseColor(fld1));
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                        window.setStatusBarColor(Color.parseColor(fld1));
                    }
                }
                mCardWebView.setBackgroundColor(Color.parseColor(fld1));
                findViewById(R.id.bottom_area_layout).setBackgroundColor(Color.parseColor(fld1));
            } else {
                if (shouldChangeToolbarBgLikeCss2()) {
                    int[] attrs = new int[] { R.attr.reviewStatusBarColor };
                    TypedArray ta = obtainStyledAttributes(attrs);
                    findViewById(R.id.toolbar).setBackground(ta.getDrawable(0));
                    ta.recycle();
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                        window.setStatusBarColor(Themes.getColorFromAttr(this, getStatusBarColorAttr()));
                    }
                }
                mCardWebView.setBackgroundColor(Color.WHITE);
                findViewById(R.id.bottom_area_layout).setBackgroundColor(Color.TRANSPARENT);
            }
        } else {
            if (shouldChangeToolbarBgLikeCss2()) {
                int[] attrs = new int[] { R.attr.reviewStatusBarColor };
                TypedArray ta = obtainStyledAttributes(attrs);
                findViewById(R.id.toolbar).setBackground(ta.getDrawable(0));
                ta.recycle();
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                    Window window = getWindow();
                    window.setStatusBarColor(Themes.getColorFromAttr(this, getStatusBarColorAttr()));
                }
            }
            mCardWebView.setBackgroundColor(Color.WHITE);
            findViewById(R.id.bottom_area_layout).setBackgroundColor(Color.TRANSPARENT);
        }
    }
    // if (mCurrentCSS.isEmpty()) {//保存的配置文件没有,则直接找默认的css
    // mCurrentCSS = mCurrentCard.css().replace("<style>", "").replace("</style>", "");
    // }
    mCardContent = mCardTemplate.replace("::content::", content).replace("::style::", style).replace("::class::", cardClass).replace("::style2::", mCurrentCSS).replace("::class2::", sDisplayAnswer ? "ck-back" : "ck-front");
    Timber.d("base url = %s", mBaseUrl);
    Timber.v("::content:: / %s", content);
    Timber.v("::style2:: / %s", mCurrentCSS);
    if (AnkiDroidApp.getSharedPrefs(this).getBoolean("html_javascript_debugging", false)) {
        try {
            try (FileOutputStream f = new FileOutputStream(new File(CollectionHelper.getCurrentAnkiDroidDirectory(this), "card.html"))) {
                f.write(mCardContent.getBytes());
            }
        } catch (IOException e) {
            Timber.d(e, "failed to save card");
        }
    }
    fillFlashcard();
    if (!mConfigurationChanged) {
        playSoundsVIP(false);
    }
}
Also used : Window(android.view.Window) SharedPreferences(android.content.SharedPreferences) Matcher(java.util.regex.Matcher) IOException(java.io.IOException) SuppressLint(android.annotation.SuppressLint) JSONException(com.ichi2.utils.JSONException) IOException(java.io.IOException) ActivityNotFoundException(android.content.ActivityNotFoundException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) JSONObject(com.ichi2.utils.JSONObject) TypedArray(android.content.res.TypedArray) FileOutputStream(java.io.FileOutputStream) File(java.io.File)

Example 4 with CARD

use of com.ichi2.anki.CardBrowser.Column.CARD in project AnkiChinaAndroid by ankichinateam.

the class AbstractFlashcardViewer method showTagsDialog.

protected void showTagsDialog() {
    ArrayList<String> tags = new ArrayList<>(getCol().getTags().all());
    ArrayList<String> selTags = new ArrayList<>(mCurrentCard.note().getTags());
    TagsDialog.TagsDialogListener tagsDialogListener = (selectedTags, option) -> {
        if (!mCurrentCard.note().getTags().equals(selectedTags)) {
            String tagString = TextUtils.join(" ", selectedTags);
            Note note = mCurrentCard.note();
            note.setTagsFromStr(tagString);
            note.flush();
            // Reload current card to reflect tag changes
            displayCardQuestion(true);
        }
    };
    TagsDialog dialog = TagsDialog.newInstance(TagsDialog.TYPE_ADD_TAG, selTags, tags);
    dialog.setTagsDialogListener(tagsDialogListener);
    showDialogFragment(dialog);
}
Also used : JavascriptInterface(android.webkit.JavascriptInterface) UI_PLAY_END(com.ichi2.bd.MainHandlerConstant.UI_PLAY_END) Version(com.github.zafarkhaja.semver.Version) Bundle(android.os.Bundle) TagsDialog(com.ichi2.anki.dialogs.TagsDialog) JsResult(android.webkit.JsResult) NonNull(androidx.annotation.NonNull) Uri(android.net.Uri) FrameLayout(android.widget.FrameLayout) ImageView(android.widget.ImageView) AbstractSched(com.ichi2.libanki.sched.AbstractSched) RangeSeekBar(com.jaygoo.widget.RangeSeekBar) RenderProcessGoneDetail(android.webkit.RenderProcessGoneDetail) HitTestResult(android.webkit.WebView.HitTestResult) ActionBar(androidx.appcompat.app.ActionBar) FileSaveListener(com.ichi2.bd.FileSaveListener) Decks(com.ichi2.libanki.Decks) Matcher(java.util.regex.Matcher) Handler(android.os.Handler) DeckConfig(com.ichi2.libanki.DeckConfig) Map(java.util.Map) JSONException(com.ichi2.utils.JSONException) THEME_NIGHT_BLACK(com.ichi2.themes.Themes.THEME_NIGHT_BLACK) OnRangeChangedListener(com.jaygoo.widget.OnRangeChangedListener) ContextCompat(androidx.core.content.ContextCompat) TargetApi(android.annotation.TargetApi) Log(android.util.Log) ReadWriteLock(java.util.concurrent.locks.ReadWriteLock) ConnectivityManager(android.net.ConnectivityManager) HtmlUtils(com.ichi2.utils.HtmlUtils) CoordinatorLayout(androidx.coordinatorlayout.widget.CoordinatorLayout) TtsMode(com.baidu.tts.client.TtsMode) IntentFilter(android.content.IntentFilter) CardMarker(com.ichi2.anki.reviewer.CardMarker) Set(java.util.Set) JSONObject(com.ichi2.utils.JSONObject) BE_VIP(com.ichi2.anki.DeckPicker.BE_VIP) IdRes(androidx.annotation.IdRes) StringRes(androidx.annotation.StringRes) Nullable(androidx.annotation.Nullable) Message(android.os.Message) Consts(com.ichi2.libanki.Consts) OKHttpUtil(com.ichi2.utils.OKHttpUtil) CompatHelper(com.ichi2.compat.CompatHelper) WebViewDebugging(com.ichi2.utils.WebViewDebugging) DiffEngine(com.ichi2.utils.DiffEngine) TypedAnswer(com.ichi2.anki.cardviewer.TypedAnswer) WebResourceResponse(android.webkit.WebResourceResponse) Dialog(android.app.Dialog) SystemClock(android.os.SystemClock) SdCardReceiver(com.ichi2.anki.receiver.SdCardReceiver) ReentrantReadWriteLock(java.util.concurrent.locks.ReentrantReadWriteLock) CardAppearance.calculateDynamicFontSize(com.ichi2.anki.cardviewer.CardAppearance.calculateDynamicFontSize) ViewAnimation(com.ichi2.anim.ViewAnimation) ArrayList(java.util.ArrayList) REFRESH_VOICE_INFO(com.ichi2.anki.DeckPicker.REFRESH_VOICE_INFO) WebResourceRequest(android.webkit.WebResourceRequest) Toast(android.widget.Toast) Menu(android.view.Menu) Connection(com.ichi2.async.Connection) Response(okhttp3.Response) Call(okhttp3.Call) CardAppearance(com.ichi2.anki.cardviewer.CardAppearance) WebChromeClient(android.webkit.WebChromeClient) LinkedHashSet(java.util.LinkedHashSet) PRINT(com.ichi2.bd.MainHandlerConstant.PRINT) CheckResult(androidx.annotation.CheckResult) MissingImageHandler(com.ichi2.anki.cardviewer.MissingImageHandler) FileOutputStream(java.io.FileOutputStream) TextUtils(android.text.TextUtils) IOException(java.io.IOException) SoundSide(com.ichi2.libanki.Sound.SoundSide) File(java.io.File) Gravity(android.view.Gravity) Lock(java.util.concurrent.locks.Lock) SharedPreferences(android.content.SharedPreferences) TypedValue(android.util.TypedValue) FileUtil(com.ichi2.utils.FileUtil) Configuration(android.content.res.Configuration) ActivityTransitionAnimation(com.ichi2.anim.ActivityTransitionAnimation) EditText(android.widget.EditText) SpeechSynthesizerListener(com.baidu.tts.client.SpeechSynthesizerListener) ImageButton(android.widget.ImageButton) REQUEST_CODE_SPEAK_SETTING(com.ichi2.anki.SpeakSettingActivity.REQUEST_CODE_SPEAK_SETTING) LinearLayout(android.widget.LinearLayout) URLDecoder(java.net.URLDecoder) HtmlColors(com.ichi2.themes.HtmlColors) GestureDetectorCompat(androidx.core.view.GestureDetectorCompat) WindowManager(android.view.WindowManager) NonBlockSyntherizer(com.ichi2.bd.NonBlockSyntherizer) FormBody(okhttp3.FormBody) ByteArrayInputStream(java.io.ByteArrayInputStream) ViewerCommand(com.ichi2.anki.cardviewer.ViewerCommand) Gson(com.google.gson.Gson) Locale(java.util.Locale) WebViewClient(android.webkit.WebViewClient) View(android.view.View) Button(android.widget.Button) TaskData(com.ichi2.async.TaskData) WebView(android.webkit.WebView) InitConfig(com.ichi2.bd.InitConfig) Auth(com.ichi2.bd.Auth) SimpleOnGestureListener(android.view.GestureDetector.SimpleOnGestureListener) SynthesizerTool(com.baidu.tts.client.SynthesizerTool) BroadcastReceiver(android.content.BroadcastReceiver) ViewGroup(android.view.ViewGroup) Timber(timber.log.Timber) IOfflineResourceConst(com.ichi2.bd.IOfflineResourceConst) MySyntherizer(com.ichi2.bd.MySyntherizer) List(java.util.List) TextView(android.widget.TextView) ActivityNotFoundException(android.content.ActivityNotFoundException) SpeechSynthesizer(com.baidu.tts.client.SpeechSynthesizer) KEY_SELECT_ONLINE_SPEAK_ENGINE(com.ichi2.libanki.Consts.KEY_SELECT_ONLINE_SPEAK_ENGINE) Toolbar(androidx.appcompat.widget.Toolbar) RelativeLayout(android.widget.RelativeLayout) THEME_NIGHT_DARK(com.ichi2.themes.Themes.THEME_NIGHT_DARK) OfflineResource(com.ichi2.bd.OfflineResource) AudioView(com.ichi2.anki.multimediacard.AudioView) Pattern(java.util.regex.Pattern) MaterialDialog(com.afollestad.materialdialogs.MaterialDialog) Window(android.view.Window) EditorInfo(android.view.inputmethod.EditorInfo) Snackbar(com.google.android.material.snackbar.Snackbar) UnsupportedEncodingException(java.io.UnsupportedEncodingException) KEY_SHOW_TTS_ICON(com.ichi2.libanki.Consts.KEY_SHOW_TTS_ICON) Note(com.ichi2.libanki.Note) Context(android.content.Context) TaskListener(com.ichi2.async.TaskListener) UI_CHANGE_SYNTHES_TEXT_SELECTION(com.ichi2.bd.MainHandlerConstant.UI_CHANGE_SYNTHES_TEXT_SELECTION) KeyEvent(android.view.KeyEvent) Pair(android.util.Pair) Intent(android.content.Intent) ReviewerCustomFonts(com.ichi2.anki.reviewer.ReviewerCustomFonts) HashMap(java.util.HashMap) REFRESH_LOGIN_STATE_AND_TURN_TO_VIP_HTML(com.ichi2.anki.DeckPicker.REFRESH_LOGIN_STATE_AND_TURN_TO_VIP_HTML) Collection(com.ichi2.libanki.Collection) TypedArray(android.content.res.TypedArray) MenuItem(android.view.MenuItem) InputMethodManager(android.view.inputmethod.InputMethodManager) RequestBody(okhttp3.RequestBody) TASK_TYPE(com.ichi2.async.CollectionTask.TASK_TYPE) HashSet(java.util.HashSet) ConnectivityManagerCompat(androidx.core.net.ConnectivityManagerCompat) SuppressLint(android.annotation.SuppressLint) JSONArray(com.ichi2.utils.JSONArray) MotionEvent(android.view.MotionEvent) Build(android.os.Build) WeakReference(java.lang.ref.WeakReference) LinkedList(java.util.LinkedList) Sound(com.ichi2.libanki.Sound) Utils(com.ichi2.libanki.Utils) LoggerProxy(com.baidu.tts.chainofresponsibility.logger.LoggerProxy) Consumer(com.ichi2.utils.FunctionalInterfaces.Consumer) Function(com.ichi2.utils.FunctionalInterfaces.Function) UI_CHANGE_INPUT_TEXT_SELECTION(com.ichi2.bd.MainHandlerConstant.UI_CHANGE_INPUT_TEXT_SELECTION) FlagDef(com.ichi2.anki.reviewer.CardMarker.FlagDef) LayoutInflater(android.view.LayoutInflater) ReviewerUi(com.ichi2.anki.reviewer.ReviewerUi) CollectionTask(com.ichi2.async.CollectionTask) Chronometer(android.widget.Chronometer) Themes(com.ichi2.themes.Themes) Template(com.ichi2.libanki.template.Template) Color(android.graphics.Color) WebResourceError(android.webkit.WebResourceError) UI_PLAY_START(com.ichi2.bd.MainHandlerConstant.UI_PLAY_START) AdaptionUtil(com.ichi2.utils.AdaptionUtil) Card(com.ichi2.libanki.Card) Activity(android.app.Activity) VisibleForTesting(androidx.annotation.VisibleForTesting) CustomStyleDialog(com.ichi2.ui.CustomStyleDialog) Resources(android.content.res.Resources) OnClickListener(android.view.View.OnClickListener) Note(com.ichi2.libanki.Note) ArrayList(java.util.ArrayList) TagsDialog(com.ichi2.anki.dialogs.TagsDialog)

Example 5 with CARD

use of com.ichi2.anki.CardBrowser.Column.CARD in project AnkiChinaAndroid by ankichinateam.

the class AbstractFlashcardViewer method answerCard.

protected void answerCard(@Consts.BUTTON_TYPE int ease) {
    if (mInAnswer) {
        return;
    }
    mIsSelecting = false;
    hideLookupButton();
    int buttonNumber = getCol().getSched().answerButtons(mCurrentCard);
    // Detect invalid ease for current card (e.g. by using keyboard shortcut or gesture).
    if (buttonNumber < ease) {
        return;
    }
    // Set the dots appearing below the toolbar
    switch(ease) {
        case EASE_1:
            mChosenAnswer.setText("\u2022");
            mChosenAnswer.setTextColor(ContextCompat.getColor(this, R.color.material_red_500));
            break;
        case EASE_2:
            mChosenAnswer.setText("\u2022\u2022");
            mChosenAnswer.setTextColor(ContextCompat.getColor(this, buttonNumber == Consts.BUTTON_FOUR ? R.color.material_blue_grey_600 : R.color.material_green_500));
            break;
        case EASE_3:
            mChosenAnswer.setText("\u2022\u2022\u2022");
            mChosenAnswer.setTextColor(ContextCompat.getColor(this, buttonNumber == Consts.BUTTON_FOUR ? R.color.material_green_500 : R.color.material_light_blue_500));
            break;
        case EASE_4:
            mChosenAnswer.setText("\u2022\u2022\u2022\u2022");
            mChosenAnswer.setTextColor(ContextCompat.getColor(this, R.color.material_light_blue_500));
            break;
        default:
            Timber.w("Unknown easy type %s", ease);
            break;
    }
    // remove chosen answer hint after a while
    mTimerHandler.removeCallbacks(removeChosenAnswerText);
    mTimerHandler.postDelayed(removeChosenAnswerText, mShowChosenAnswerLength);
    mSoundPlayer.stopSounds();
    stopOnlineSpeaking();
    mCurrentEase = ease;
    CollectionTask.launchCollectionTask(ANSWER_CARD, mAnswerCardHandler(true), new TaskData(mCurrentCard, mCurrentEase));
}
Also used : SuppressLint(android.annotation.SuppressLint) TaskData(com.ichi2.async.TaskData)

Aggregations

Card (com.ichi2.libanki.Card)222 Test (org.junit.Test)212 Collection (com.ichi2.libanki.Collection)179 Note (com.ichi2.libanki.Note)173 RobolectricTest (com.ichi2.anki.RobolectricTest)168 JSONObject (com.ichi2.utils.JSONObject)114 JSONArray (com.ichi2.utils.JSONArray)80 DeckConfig (com.ichi2.libanki.DeckConfig)72 ArrayList (java.util.ArrayList)48 NonNull (androidx.annotation.NonNull)33 Deck (com.ichi2.libanki.Deck)32 Intent (android.content.Intent)29 JSONException (com.ichi2.utils.JSONException)27 Model (com.ichi2.libanki.Model)26 Context (android.content.Context)23 SuppressLint (android.annotation.SuppressLint)22 Cursor (android.database.Cursor)22 HashMap (java.util.HashMap)21 Matchers.containsString (org.hamcrest.Matchers.containsString)20 List (java.util.List)17