Skip to content

feat(anki): 添加 Anki Connect 集成 - #1241

Open
XbuLee wants to merge 10 commits into
tisfeng:devfrom
XbuLee:feat/anki-field-mapping-local
Open

feat(anki): 添加 Anki Connect 集成 #1241
XbuLee wants to merge 10 commits into
tisfeng:devfrom
XbuLee:feat/anki-field-mapping-local

Conversation

@XbuLee

@XbuLee XbuLee commented Jul 9, 2026

Copy link
Copy Markdown

Related issue: #773
Supersedes #1227

Easydict 目前缺少将词典查询结果直接加入 Anki 的入口,用户需要在查词和制卡之间手动复制内容。这个功能面向词典类结果,避免把普通句子翻译默认纳入制卡流程。

新增 Anki Connect 配置、结果卡片底部按钮以及添加成功或失败的 toast 和日志。配置项支持端点、牌组、笔记类型,并可以通过 AnkiConnect 自动读取模板字段,减少手动填错。

在此基础上,设置页支持更灵活的字段映射。用户可以把每个 Anki 字段配置为 Easydict 变量模板,例如 {Word}、{Phonetic}、{Definition}、{Translation}、{DictionaryText}、{DictionaryHTML} 等,而不是只能选择固定的正反面字段。

同时新增字段预览入口。用户可以输入一个单词,选择词典服务后预览 Easydict 各变量的实际值,以及最终会写入 Anki 各字段的渲染结果,从而在真正添加卡片前确认字段是否匹配。

本次也补强了词典结果序列化逻辑:保留 simpleWords、音标、翻译文本等可见内容,并在 Apple Dictionary / MDict 多词典结果中优先使用完整渲染 HTML,避免创建卡片时丢失页面中可见的词典 section。

此修改让用户可以从词典结果直接创建 Anki 卡片,并在添加成功或失败时获得明确反馈。它也为后续扩展更细的字段映射、例句卡片或 TTS 附件支持保留了清晰入口。
image

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d2901c2627

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread Easydict/Swift/View/SettingView/Tabs/TabView/AdvancedTabAnkiSection.swift Outdated
Comment thread Easydict/Swift/View/SettingView/Tabs/TabView/tab-view-overview.md Outdated
@XbuLee XbuLee changed the title feat(anki): add field template mapping preview feat(anki): 添加 Anki Connect 集成 Jul 9, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0efb02f4f2

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@tisfeng

tisfeng commented Aug 8, 2026

Copy link
Copy Markdown
Owner

感谢 PR,请解决一下冲突,稍后我们会 review

@Issues-translate-bot

Copy link
Copy Markdown

Bot detected this issue is not in English and translated it automatically.


Thanks for the PR, please resolve the conflict and we will review it later

@tisfeng

tisfeng commented Aug 16, 2026

Copy link
Copy Markdown
Owner

请继续推进 PR

@Issues-translate-bot

Copy link
Copy Markdown

Bot detected this issue is not in English and translated it automatically.


Please keep pushing the PR

XbuLee added 6 commits August 18, 2026 12:15
Easydict 目前缺少将词典查询结果直接加入 Anki 的入口,用户需要在查词和制卡之间手动复制内容。这个功能面向词典类结果,避免把普通句子翻译默认纳入制卡流程。

新增 Anki Connect 配置、字段自动读取、结果卡片底部按钮以及添加成功或失败的 toast 和日志。配置项支持端点、牌组、笔记类型、正反面字段,并通过 AnkiConnect 读取模板字段以减少手动填错。

此修改让用户可以从词典结果直接创建 Anki 卡片,并在添加成功或失败时获得明确反馈。它也为后续扩展更细的字段映射或例句卡片支持保留了清晰入口。

----------------------------------------------------------------------

feat(anki): add Anki Connect integration

Easydict did not provide a direct path from dictionary lookup results to Anki cards, so users had to copy content manually between lookup and note creation. This feature targets dictionary-style results and keeps general sentence translation out of the default card flow.

Add Anki Connect settings, automatic note-field loading, a result-card toolbar button, and toast plus log feedback for add success or failure. The settings cover endpoint, deck, note type, and front/back fields, while AnkiConnect field loading helps avoid manual field-name mistakes.

This lets users create Anki cards directly from dictionary results with clear feedback when the add operation succeeds or fails. It also leaves a focused path for future field mapping or example-sentence card support.
Anki Connect 之前只能把结果写入固定的正反面字段,无法把音标、释义或词形等内容拆到独立字段。使用自定义 Anki 模板时,用户仍然需要在 Easydict 和 Anki 之间手动调整字段。

新增可持久化的 Easydict 字段映射,并在设置页提供 Anki 字段到 Easydict 内容的逐行选择。读取 Anki 模板字段后会保存字段列表,默认映射仍保持 Word 和 Full Result 两行。

这样用户可以为音标、释义、翻译、词形和相关词等内容配置单独的 Anki 字段。旧的 Front/Back 设置仍作为兜底,因此现有制卡流程可以继续使用。

----------------------------------------------------------------------

feat(anki): add field mapping settings

Anki Connect previously wrote results into fixed front and back fields, so phonetics, definitions, and word forms could not be sent to separate fields. Users with custom Anki note types still had to adjust field content manually between Easydict and Anki.

Add persistent Easydict field mappings and expose row-by-row selection from Anki fields to Easydict content in settings. Loading fields from the Anki note type now stores the field list, while the default mapping still keeps Word and Full Result rows.

This lets users map phonetics, definitions, translations, word forms, and related words into dedicated Anki fields. The old Front/Back settings remain as a fallback, so the existing card creation flow keeps working.
Anki Connect 集成已经可以从词典结果创建卡片,但字段配置仍然偏固定,用户很难确认每个 Easydict 字段最终会写入 Anki 的内容。之前的 review 也暴露了不同词典结果在序列化时容易丢失可见内容的问题。

新增基于模板的 Anki 字段映射和设置页预览,支持插入 {Word}、{Definition} 等 Easydict 变量,并把 Anki Connect 设置区域拆成独立的 SwiftUI section。模板渲染同时补齐 simpleWords、音标、翻译文本以及 Apple Dictionary 和 MDict 的完整 HTML 结果处理。

此修改让用户可以在设置中预览 Anki 字段输出,再从词典结果创建更准确的卡片。拆分后的设置代码也降低了高级设置页的体积,便于后续 review 和维护。

----------------------------------------------------------------------

feat(anki): add field template mapping preview

The Anki Connect integration could already create cards from dictionary results, but field configuration was still too fixed and users could not easily confirm what each Easydict field would send to Anki. Earlier review feedback also showed that some dictionary result shapes could lose visible content during serialization.

Add template-based Anki field mappings and a settings preview with insertable Easydict variables such as {Word} and {Definition}. Split the Anki Connect settings into a dedicated SwiftUI section, and harden template rendering for simpleWords, phonetics, translated text, and full Apple Dictionary or MDict HTML results.

This lets users preview rendered Anki field output before creating cards from dictionary results. The settings split also keeps the advanced tab smaller and easier to review and maintain.
Anki 设置页首次出现时会先写入 Front 和 Back fallback 映射。用户随后读取真实模板字段时,这些未改动的默认映射会阻止新字段自动生效,导致非 Front/Back 笔记类型仍用旧字段名提交。

在读取 Anki 字段后检测当前映射是否仍是默认 fallback 或旧的默认字段映射。如果用户没有自定义过映射,就用新读取到的字段重新生成默认映射;如果用户已经改过字段或模板,则保留现有配置。

这样首次配置非 Front/Back 模板时,读取字段后即可直接得到正确的 Anki 字段名。用户的手动映射不会被刷新操作覆盖。

----------------------------------------------------------------------

fix(anki): refresh untouched default field mappings

The Anki settings view writes Front and Back fallback mappings when it first appears. When users later fetch real model fields, those untouched defaults prevented the fetched fields from taking effect, so non-Front/Back note types could still submit stale field names.

Detect whether the current mappings still match the fallback defaults or the previously generated default mappings after Anki fields are loaded. If the user has not customized them, regenerate defaults from the fetched fields; if the user has changed fields or templates, keep the existing configuration.

This lets first-time setup for non-Front/Back models pick up the correct Anki field names immediately after fetching fields. Manual user mappings remain protected from refresh overwrites.
审计本次 Anki 变更时发现词典渲染模板和 WebView 管理器里有几处无功能意义的空白或单用 helper 改动。

移除这些噪音,让最终 diff 聚焦 Anki Connect、字段映射、预览和词典内容采集本身,减少 PR 审查负担。

----------------------------------------------------------------------

chore(anki): remove unrelated rendering churn

While auditing the Anki changes, a few dictionary rendering and WebView manager edits turned out to be whitespace or a single-use helper with no behavior impact.

Remove that noise so the final diff stays focused on Anki Connect, field mapping, preview, and dictionary content collection, reducing review overhead.
@XbuLee
XbuLee force-pushed the feat/anki-field-mapping-local branch from 0efb02f to 9ae8268 Compare August 18, 2026 05:49

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9ae8268a57

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread Easydict/Swift/Feature/AnkiConnect/AnkiConnectClient.swift
Comment thread Easydict/Swift/Feature/AnkiConnect/AnkiConnectClient.swift
Comment thread Easydict/Swift/Feature/AnkiConnect/AnkiConnectClient.swift
@KurodaKayn

Copy link
Copy Markdown
Collaborator

ai review出来的problem处理就你直接点solve mark掉就行了
我们人工给的comment留给我们reviwer自己点掉

@Issues-translate-bot

Copy link
Copy Markdown

Bot detected this issue is not in English and translated it automatically.


To deal with the problems that come out of the AI review, just click solve mark and it will be done.
The comments we give manually are left for us to review and click on ourselves.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 44a2b4626f

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

let entryHTML = result.htmlStrings?.joined(separator: "\n\n")
let renderedHTML = result.htmlString

return firstNonEmpty([innerText, entryHTML, renderedHTML])

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep DictionaryText plain for MDict

When an MDict result is mapped to {DictionaryText}, innerTexts and htmlStrings are unset, so this fallback returns the complete rendered htmlString. The supposedly plain-text variable therefore becomes identical to {DictionaryHTML} and can include the document's CSS and markup in the Anki field. Populate or extract MDict plain text and use that here instead of falling back to HTML.

Useful? React with 👍 / 👎.

Comment on lines +343 to +345
let part = simpleWord.part?.trimmed ?? ""
let prefix = [word, part].filter { !$0.isEmpty }.joined(separator: " ")
return prefix.isEmpty ? means : "\(prefix): \(means)"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Avoid prefixing Youdao parts of speech twice

For Youdao simple-word entries with a part of speech, the parser sets showPartMeans = true, which already embeds simpleWord.part into meansText; this code then adds the same part to prefix. Consequently {Definition} and {FullResult} contain values such as foo n.: n. bar. Build the definition from simpleWord.means or skip the extra prefix when the part is already included.

Useful? React with 👍 / 👎.

Comment on lines +372 to +374
let lines = partLines(from: wordResult.synonyms, title: "Synonyms")
+ partLines(from: wordResult.antonyms, title: "Antonyms")
+ partLines(from: wordResult.collocation, title: "Collocation")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Localize headings embedded in Anki fields

On every non-English locale, {Related} and {FullResult} still write the English headings Synonyms, Antonyms, and Collocation into generated cards, even though the existing result UI and String Catalog already localize all three labels. Resolve the existing static catalog keys before passing these titles to partLines.

AGENTS.md reference: AGENTS.md:L25-L25

Useful? React with 👍 / 👎.

return (false, object, "\(error)")
}

return (true, object, NSLocalizedString("anki.connect.added", comment: ""))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reject responses that omit the Anki result

If the configured endpoint or an intervening proxy returns an unrelated JSON object such as {}, this path reports success because no non-null error exists. addNote then shows the localized “added” toast and permanently disables the result-card button even though no note ID was returned. Validate the Anki response envelope and require the expected result type for each action before reporting success.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 47c094514e

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +246 to +249
rendered = rendered.replacingOccurrences(
of: field.templateToken,
with: value,
options: [.caseInsensitive]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Encode plain values for Anki HTML fields

When a mapping uses a generated multiline value such as {Definition} or {FullResult}, this inserts its plain \n separators directly into an Anki field, which Anki renders as HTML; the lines therefore collapse into one paragraph, and tag-like dictionary text is interpreted as markup even though the settings preview displays it literally. HTML-escape plain token values and convert their line breaks to <br>, while preserving intentional template markup and raw {DictionaryHTML} content.

Useful? React with 👍 / 👎.

Comment on lines +384 to +385
let shouldReplaceMappings = shouldReplaceMappingsAfterFetching()
ankiConnectModelFields = fields

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Ignore stale field responses after model edits

When the user changes the Note Type while a field request is pending, the editable model field can move from—for example—Basic to Cloze, but this completion still stores the fields returned for Basic and may replace the mappings with them. Subsequent addNote requests then use field names that do not exist in the currently configured model. Capture the requested model and discard the response if it changed, or disable model editing until the request completes.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 85e55cf42f

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +264 to +266
result.translatedText,
result.copiedText,
dictionaryContentForBack(from: result),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Avoid duplicating dictionary content in FullResult

When an Apple Dictionary or MDict WebView has finished loading, fetchDictionaryHTMLTextIfNeeded stores the extracted plain text in both translatedResults and copiedText. This list then adds that text alongside dictionaryContentForBack, which returns the complete HTML for those services; uniqueText removes only the duplicate plain-text copy, leaving {FullResult} with both plain text and the same content as HTML. Cards added after WebView extraction therefore contain duplicated definitions and can become unnecessarily large; exclude the WebView-derived text for these services or use only the preferred rendered HTML.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bot automatically translated this content.


P2 Badge 避免在 FullResult 中重复字典内容

当 Apple Dictionary 或 MDict WebView 完成加载时,“fetchDictionaryHTMLTextIfNeeded”会将提取的纯文本存储在“translatedResults”和“copiedText”中。 然后,该列表将该文本添加到“dictionaryContentForBack”旁边,返回这些服务的完整 HTML; uniqueText 仅删除重复的纯文本副本,留下 {FullResult} 包含纯文本和与 HTML 相同的内容。 因此,在 WebView 提取后添加的卡片包含重复的定义,并且可能会变得不必要的大; 排除这些服务的 WebView 派生文本或仅使用首选呈现的 HTML。

有用? 用 👍 / 👎 做出反应。

Comment on lines +528 to +529
let result = try await queryAnkiPreview(text: text, serviceID: serviceID)
previewValues = AnkiTemplateRenderer.previewValues(from: result)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Discard previews for edited inputs

During a slow preview query, the word field and service picker remain editable while only the query button is disabled. The request captures the old text and service before this await, but its completion unconditionally replaces the preview, so changing either control in flight can leave the UI showing input B with results from request A. Compare a request token and the captured inputs before updating state, or disable those controls until the request finishes.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bot automatically translated this content.


P2 Badge 放弃已编辑输入的预览

在慢速预览查询期间,单词字段和服务选择器保持可编辑状态,而仅查询按钮被禁用。 该请求在此“await”之前捕获旧文本和服务,但其完成无条件地替换预览,因此更改运行中的任一控件都可以使 UI 显示输入 B 和请求 A 的结果。在更新状态之前比较请求令牌和捕获的输入,或禁用这些控件直到请求完成。

有用? 用 👍 / 👎 做出反应。

@tisfeng

tisfeng commented Sep 6, 2026

Copy link
Copy Markdown
Owner

你好,有很多 review 评论,请看一下。

@Issues-translate-bot

Copy link
Copy Markdown

Bot automatically translated this content.


Hello, there are many review comments, please take a look.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 8, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-08T14:29:45.241301Z 41d8320 New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@Issues-translate-bot

Copy link
Copy Markdown

Bot automatically translated this content.


法典审查摘要

此评论显示了针对此拉取请求的最新法典审查活动。

评论 状态 提交 审查触发器
📝 代码审查 🔄 **自 2026-09-08T14:24:25.756845Z 开始运行** 41d8320 新提交
ℹ️ 关于 GitHub 中的 Codex

您的团队已设置 Codex 来审查此存储库中的拉取请求。 当您

  • 打开拉取请求以供审核
  • 将草稿标记为就绪
  • 评论“@codex review”或“@codex security review”。

当任何审查正在进行时,Codex 会以 👀 做出反应,如果有建议则进行评论,并在所有审查结束且没有发现结果时以 👍 做出反应。

</详情>

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

@Issues-translate-bot

Copy link
Copy Markdown

Bot automatically translated this content.


要在此处使用 Codex,请创建 Codex 帐户并连接到 github

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 41d832035f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +1012 to +1014
BOOL shouldShowAnkiButton = MyConfiguration.shared.enableAnkiConnect &&
EZResultHasAnkiContent(result) &&
(result.wordResult || EZResultNeedsDictionaryHTMLHeight(result));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Show the Anki action for translation-only results

For Google sentence translations and other non-dictionary services that populate translatedText without a wordResult, this final condition is false, so the Anki button never appears even though EZResultHasAnkiContent accepts that translation and the new renderer exposes a {Translation} mapping. Remove the word-result/dictionary-only restriction or otherwise include translation-only results so users can actually add these supported values.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bot automatically translated this content.


P1 Badge 显示仅翻译结果的 Anki 操作

对于在没有“wordResult”的情况下填充“translatedText”的 Google 句子翻译和其他非词典服务,此最终条件为 false,因此即使“EZResultHasAnkiContent”接受该翻译并且新渲染器公开“{Translation}”映射,Anki 按钮也永远不会出现。 删除仅限单词结果/字典的限制或以其他方式包含仅限翻译的结果,以便用户实际上可以添加这些支持的值。

有用? 用 👍 / 👎 做出反应。

EZResultHasAnkiContent(result) &&
(result.wordResult || EZResultNeedsDictionaryHTMLHeight(result));
if (shouldShowAnkiButton) {
EZSymbolImageButton *ankiButton = [EZSymbolImageButton buttonWithSybolImageName:@"plus.rectangle.on.rectangle"];

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Use SFSafeSymbols for the Anki button

Replace the hardcoded plus.rectangle.on.rectangle identifier with the repository's typed SFSafeSymbols representation (bridged through a Swift helper if necessary); the current string bypasses compile-time symbol validation and directly violates the required symbol API convention. docs/agents/development.mdL52-L55

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bot automatically translated this content.


P1 Badge 使用 SFSafeSymbols 作为 Anki 按钮

将硬编码的 plus.rectangle.on.rectangle 标识符替换为存储库的类型化 SFSafeSymbols 表示形式(如有必要,通过 Swift 助手进行桥接); 当前字符串绕过编译时符号验证并直接违反了所需的符号 API 约定。 docs/agents/development.mdL52-L55

有用吗? 用 👍 / 👎 做出反应。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants