Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
153b8cc
feat: support streaming update mermaid chart
zhu-xiaowei Sep 9, 2025
8571530
feat: add error handler for mermaid
zhu-xiaowei Sep 16, 2025
3d51c10
fix: code format issues
zhu-xiaowei Sep 22, 2025
93ee791
fix: support for smooth streaming mermaid rendering
zhu-xiaowei Sep 22, 2025
30b75ae
fix: the warning for injectedJavaScript, fix the height for mermaid code
zhu-xiaowei Sep 22, 2025
2c46721
fix: update status
zhu-xiaowei Sep 22, 2025
d0aa061
fix: support dark mode for mermaid
zhu-xiaowei Sep 22, 2025
7e791e5
fix: support MermaidFullScreenViewer
zhu-xiaowei Sep 23, 2025
7e8614d
fix: support landscape for MermaidFullScreenViewer
zhu-xiaowei Sep 23, 2025
79e9c3b
fix: landscape chart display padding
zhu-xiaowei Sep 24, 2025
427cf24
fix: save mermaid issue
zhu-xiaowei Sep 24, 2025
b4b01de
fix: change to align with center
zhu-xiaowei Sep 24, 2025
ed9d946
feat: fix loading for MermaidRenderer.tsx
zhu-xiaowei Oct 20, 2025
7e2716d
feat: add log and fix fist render failed issue
zhu-xiaowei Nov 3, 2025
39d1610
feat: add mermaid refresh when streaming status is completed
zhu-xiaowei Nov 3, 2025
796d811
feat: finish mermiad renderer
zhu-xiaowei Nov 4, 2025
be6468c
fix: mermaid update and fix gantt renderring error issue
zhu-xiaowei Nov 5, 2025
0b558f3
feat: optimize mac display
zhu-xiaowei Nov 5, 2025
d3c43c2
feat: fix mermaid for android
zhu-xiaowei Nov 6, 2025
2fced18
feat: fix lint issues
zhu-xiaowei Nov 7, 2025
2b91b12
fix: copy mermaid code issue
zhu-xiaowei Nov 10, 2025
32af732
feat: update readme for mermiad
zhu-xiaowei Nov 10, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 10 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,17 @@ across Android, iOS, and macOS platforms.
![](assets/promo.avif)

### What's New 🔥

- 🚀 Support streaming rendering of Mermaid charts (From v2.6.0).
<div style="display: flex; flex-direction: 'row'; background-color: #888888;">
<img src="assets/animations/mermaid_en.avif" width=48%>
<img src="assets/animations/mermaid_save_en.avif" width=48%>
</div>
- 🚀 Support using Bedrock API Key for Amazon Bedrock models (From v2.5.0).
- 🚀 Support virtual try-on, automatically recognize clothes, pants, shoes and try them on (From v2.5.0).
- 🚀 Support shortcuts for macOS (From v2.5.0).
- Use `Shift + Enter`, `Control + Enter` or `Option + Enter` to add a line break.
- Use `⌘ + V` to add images (Screenshot), videos, or documents from your clipboard.
- Use `⌘ + N` to opening multiple Mac windows for parallel operations.
- Support adds multiple OpenAI Compatible model providers. You can now
use [Easy Model Deployer](https://github.com/aws-samples/easy-model-deployer), OpenRouter, or any OpenAI-compatible
model provider. (From v2.5.0).
- Supports dark mode on Android, iOS, and Mac (From v2.4.0).
- Support Speech to Speech By Amazon Nova Sonic on Apple Platform. (From v2.3.0).

## 📱 Quick Download

Expand Down Expand Up @@ -207,6 +206,10 @@ Congratulations 🎉 Your SwiftChat App is ready to use!
- `GPT-4.1`
- `GPT-4.1 mini`
- `GPT-4.1 nano`
- `GPT-5`
- `GPT-5 chat`
- `GPT-5 mini`
- `GPT-5 nano`

Additionally, if you have deployed and configured the [SwiftChat Server](#getting-started-with-amazon-bedrock), you
can enable the **Use Proxy** option to forward your requests.
Expand All @@ -232,7 +235,7 @@ can enable the **Use Proxy** option to forward your requests.
## Key Features

- Real-time streaming chat with AI
- Rich Markdown Support: Tables, Code Blocks, LaTeX and More
- Rich Markdown Support: Tables, Code Blocks, LaTeX, Mermaid Chart and More
- AI image generation with progress
- Multimodal support (images, videos & documents)
- Conversation history list view and management
Expand Down
16 changes: 10 additions & 6 deletions README_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,17 @@ SwiftChat 是一款快速响应的 AI 聊天应用,采用 [React Native](https

### 新功能 🔥

- 🚀 支持流式渲染 Mermaid 图表(自 v2.6.0 起)。
<div style="display: flex; flex-direction: 'row'; background-color: #888888;">
<img src="assets/animations/mermaid.avif" width=48%>
<img src="assets/animations/mermaid_save.avif" width=48%>
</div>
- 🚀 支持使用 Bedrock API Key 连接 Amazon Bedrock 模型(自 v2.5.0 起)。
- 🚀 支持虚拟试衣功能,自动识别衣服、裤子、鞋子并试穿(自 v2.5.0 起)。
- 🚀 支持 macOS 快捷键操作(自 v2.5.0 起)。
- 使用 `Shift + Enter`、`Control + Enter` 或 `Option + Enter` 添加换行。
- 使用 `⌘ + V` 从剪贴板添加图片(截图)、视频或文档。
- 使用 `⌘ + N` 打开多个 Mac 窗口进行并行操作。
- 支持添加多个 OpenAI Compatible
模型提供商。您现在可以使用 [Easy Model Deployer](https://github.com/aws-samples/easy-model-deployer)、OpenRouter 或任何
OpenAI 兼容的模型提供商(自 v2.5.0 起)。
- 支持 Android、iOS 和 Mac 上的暗黑模式(自 v2.4.0 起)。
- 在 Apple 平台上支持 Amazon Nova Sonic 语音对语音功能(自 v2.3.0 起)。

## 📱 快速下载

Expand Down Expand Up @@ -195,6 +195,10 @@ SwiftChat 是一款快速响应的 AI 聊天应用,采用 [React Native](https
- `GPT-4.1`
- `GPT-4.1 mini`
- `GPT-4.1 nano`
- `GPT-5`
- `GPT-5 chat`
- `GPT-5 mini`
- `GPT-5 nano`

此外,如果您已部署并配置了 [SwiftChat 服务器](#amazon-bedrock-入门指南),可以启用 **Use Proxy** 选项来转发您的请求。

Expand All @@ -218,7 +222,7 @@ SwiftChat 是一款快速响应的 AI 聊天应用,采用 [React Native](https
## 主要功能

- 与 AI 进行实时流式聊天
- 丰富的 Markdown 支持:表格、代码块、LaTeX
- 丰富的 Markdown 支持:表格、代码块、LaTeX, Mermaid图标等
- 带进度显示的 AI 图像生成
- 多模态支持(图像、视频和文档)
- 对话历史列表查看和管理
Expand Down
Binary file added assets/animations/mermaid.avif
Binary file not shown.
Binary file added assets/animations/mermaid_en.avif
Binary file not shown.
Binary file added assets/animations/mermaid_save.avif
Binary file not shown.
Binary file added assets/animations/mermaid_save_en.avif
Binary file not shown.
141 changes: 83 additions & 58 deletions react-native/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ PODS:
- hermes-engine (0.74.1):
- hermes-engine/Pre-built (= 0.74.1)
- hermes-engine/Pre-built (0.74.1)
- MMKV (1.3.9):
- MMKVCore (~> 1.3.9)
- MMKVCore (1.3.9)
- MMKV (2.2.3):
- MMKVCore (~> 2.2.3)
- MMKVCore (2.2.3)
- RCT-Folly (2024.01.01.00):
- boost
- DoubleConversion
Expand Down Expand Up @@ -1027,6 +1027,27 @@ PODS:
- Yoga
- react-native-safe-area-context (4.10.8):
- React-Core
- react-native-webview (13.16.0):
- DoubleConversion
- glog
- hermes-engine
- RCT-Folly (= 2024.01.01.00)
- RCTRequired
- RCTTypeSafety
- React-Codegen
- React-Core
- React-debug
- React-Fabric
- React-featureflags
- React-graphics
- React-ImageManager
- React-NativeModulesApple
- React-RCTFabric
- React-rendererdebug
- React-utils
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- Yoga
- React-nativeconfig (0.74.1)
- React-NativeModulesApple (0.74.1):
- glog
Expand Down Expand Up @@ -1374,6 +1395,7 @@ DEPENDENCIES:
- react-native-image-picker (from `../node_modules/react-native-image-picker`)
- react-native-mmkv (from `../node_modules/react-native-mmkv`)
- react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`)
- react-native-webview (from `../node_modules/react-native-webview`)
- React-nativeconfig (from `../node_modules/react-native/ReactCommon`)
- React-NativeModulesApple (from `../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios`)
- React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`)
Expand Down Expand Up @@ -1488,6 +1510,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native-mmkv"
react-native-safe-area-context:
:path: "../node_modules/react-native-safe-area-context"
react-native-webview:
:path: "../node_modules/react-native-webview"
React-nativeconfig:
:path: "../node_modules/react-native/ReactCommon"
React-NativeModulesApple:
Expand Down Expand Up @@ -1562,73 +1586,74 @@ SPEC CHECKSUMS:
fmt: 4c2741a687cc09f0634a2e2c72a838b99f1ff120
glog: c5d68082e772fa1c511173d6b30a9de2c05a69a2
hermes-engine: 16b8530de1b383cdada1476cf52d1b52f0692cbc
MMKV: 817ba1eea17421547e01e087285606eb270a8dcb
MMKVCore: af055b00e27d88cd92fad301c5fecd1ff9b26dd9
RCT-Folly: 02617c592a293bd6d418e0a88ff4ee1f88329b47
MMKV: 941e8774da0e6fdf12c6b3fcc833ca687ae5a42d
MMKVCore: 6d5cc1bacce539f4c974985dfe646fb65a5d27d2
RCT-Folly: 5dc73daec3476616d19e8a53f0156176f7b55461
RCTDeprecation: efb313d8126259e9294dc4ee0002f44a6f676aba
RCTRequired: f49ea29cece52aee20db633ae7edc4b271435562
RCTTypeSafety: a11979ff0570d230d74de9f604f7d19692157bc4
React: 88794fad7f460349dbc9df8a274d95f37a009f5d
React-callinvoker: 7a7023e34a55c89ea2aa62486bb3c1164ab0be0c
React-Codegen: af31a9323ce23988c255c9afd0ae9415ff894939
React-Core: 60075333bc22b5a793d3f62e207368b79bff2e64
React-CoreModules: 147c314d6b3b1e069c9ad64cbbbeba604854ff86
React-cxxreact: 5de27fd8bff4764acb2eac3ee66001e0e2b910e7
React-Codegen: 118828b0731a9ecf9021270b788f958f9ccb2e19
React-Core: 74cc07109071b230de904d394c2bf15b9f886bff
React-CoreModules: 8beb4863375aafeac52c49a3962b81d137577585
React-cxxreact: d0b0d575214ba236dff569e14dd4411ac82b3566
React-debug: 6397f0baf751b40511d01e984b01467d7e6d8127
React-Fabric: 6fa475e16e0a37b38d462cec32b70fd5cf886305
React-FabricImage: 7e09b3704e3fa084b4d44b5b5ef6e2e3d3334ec0
React-Fabric: 37f29709a9caefd2a9fece6f695bc88a0af77f40
React-FabricImage: 9c3f6125b2f5908a2e7d0947cfb74022c1a0b294
React-featureflags: 2eb79dd9df4095bff519379f2a4c915069e330bb
React-graphics: 82a482a3aa5d9659b74cdf2c8b57faf67eaa10fb
React-hermes: d93936b02de2fd7e67c11e92c16d4278a14d0134
React-ImageManager: ebb3c4812e2c5acba5a89728c2d77729471329ad
React-jserrorhandler: a08e0adcf1612900dde82b8bf8e93e7d2ad953b3
React-jsi: f46d09ee5079a4f3b637d30d0e59b8ea6470632c
React-jsiexecutor: e73579560957aa3ca9dc02ab90e163454279d48c
React-jsinspector: e8ba20dde269c7c1d45784b858fa1cf4383f0bbb
React-jsitracing: 233d1a798fe0ff33b8e630b8f00f62c4a8115fbc
React-logger: 7e7403a2b14c97f847d90763af76b84b152b6fce
React-Mapbuffer: 11029dcd47c5c9e057a4092ab9c2a8d10a496a33
react-native-compressor: 2ae9013718fb351264fcfcdf232eccbbf3d280a2
react-native-document-picker: c4f197741c327270453aa9840932098e0064fd52
react-native-get-random-values: 21325b2244dfa6b58878f51f9aa42821e7ba3d06
react-native-image-picker: fb0c2b3adc3eff6caa3cd6a507a34b9dcc9238dd
react-native-mmkv: 8c9a677e64a1ac89b0c6cf240feea528318b3074
react-native-safe-area-context: b7daa1a8df36095a032dff095a1ea8963cb48371
React-graphics: d0b9a0a174fb86bfed50bf4fb7c835183a546ab5
React-hermes: 06e8316213d56ab914afb9a829763123fcfacf22
React-ImageManager: 821a1182139cc986598868d0e9a00b3a021feddb
React-jserrorhandler: 1dd2a75b24dd9a318ee88fa6792e98524879af24
React-jsi: e381545475da5ea77777e7b5513031a434ced04b
React-jsiexecutor: ce91dde1a61efd519a5ff7ac0f64b61a14217072
React-jsinspector: 627ac44b1d090fc6a8039b1df723677bc7d86fe4
React-jsitracing: dd0e541a34027b3ab668ad94cf268482ad6f82fb
React-logger: 6070f362a1657bb53335eb1fc903d3f49fd79842
React-Mapbuffer: 2c95cbabc3d75a17747452381e998c35208ea3ee
react-native-compressor: 837b2774cb6e6a026862d90a783586ca317c29c3
react-native-document-picker: 451699da81cba8b40b596b8076019a4deb86f46e
react-native-get-random-values: d16467cf726c618e9c7a8c3c39c31faa2244bbba
react-native-image-picker: f1006d8935a3bc0baf8157faaa7857c76a77c8bb
react-native-mmkv: f8155c2efbe795cb0c7586d00ff484b1c9388af0
react-native-safe-area-context: b72c4611af2e86d80a59ac76279043d8f75f454c
react-native-webview: b836f1f162b87b5b8351611b5d5299f2b699360a
React-nativeconfig: b0073a590774e8b35192fead188a36d1dca23dec
React-NativeModulesApple: df46ff3e3de5b842b30b4ca8a6caae6d7c8ab09f
React-NativeModulesApple: 61b07ab32af3ea4910ba553932c0a779e853c082
React-perflogger: 3d31e0d1e8ad891e43a09ac70b7b17a79773003a
React-RCTActionSheet: c4a3a134f3434c9d7b0c1054f1a8cfed30c7a093
React-RCTAnimation: 0e5d15320eeece667fcceb6c785acf9a184e9da1
React-RCTAppDelegate: c4f6c0700b8950a8b18c2e004996eec1807d430a
React-RCTBlob: c46aaaee693d371a1c7cae2a8c8ee2aa7fbc1adb
React-RCTFabric: 0dbf28ce96c7f2843483e32a725a5b5793584ff3
React-RCTImage: a04dba5fcc823244f5822192c130ecf09623a57f
React-RCTLinking: 533bf13c745fcb2a0c14e0e49fd149586a7f0d14
React-RCTNetwork: a29e371e0d363d7b4c10ab907bc4d6ae610541e9
React-RCTSettings: 127813224780861d0d30ecda17a40d1dfebe7d73
React-RCTText: 8a823f245ecf82edb7569646e3c4d8041deb800a
React-RCTVibration: 46b5fae74e63f240f22f39de16ad6433da3b65d9
React-rendererdebug: 4653f8da6ab1d7b01af796bdf8ca47a927539e39
React-RCTAnimation: dab04683056694845eb7a9e283f4c63eec7fa633
React-RCTAppDelegate: 1785d42459138c45175b2fa18e86cd2aee829a93
React-RCTBlob: a0a8f6bfd8926bff0e2814ec3f8cd5514f2db243
React-RCTFabric: f69d856b74b6d385c4cf4bd128c330161ce18306
React-RCTImage: 51db983bcc5075fa9bf3e094e5c6c1f5b5575472
React-RCTLinking: 3430cd1023a5ac86a96ed6d4fbf7a8ed7b2e44d5
React-RCTNetwork: 52198f8a8c823639dcc8f6725ca5b360d66ea1a0
React-RCTSettings: c127440c2c538128f92fb45524e976e25cb69bd6
React-RCTText: 640b2d0bfb51d88d8a76c6a1a7ea1f94667bf231
React-RCTVibration: bd20c8156b649cd745c70db3341c409ae3b42821
React-rendererdebug: 16394ffe0d852967123b3b76a630233b90ec8e63
React-rncore: 4f1e645acb5107bd4b4cf29eff17b04a7cd422f3
React-RuntimeApple: 013b606e743efb5ee14ef03c32379b78bfe74354
React-RuntimeCore: 7205be45a25713b5418bbf2db91ddfcca0761d8b
React-RuntimeApple: 97d0a5c655467c57b88076434427ec32413e7802
React-RuntimeCore: a55443ddb73e6666b441963d8951a16ba5cfc223
React-runtimeexecutor: a278d4249921853d4a3f24e4d6e0ff30688f3c16
React-RuntimeHermes: 44c628568ce8feedc3acfbd48fc07b7f0f6d2731
React-runtimescheduler: e2152ed146b6a35c07386fc2ac4827b27e6aad12
React-utils: 3285151c9d1e3a28a9586571fc81d521678c196d
ReactCommon: f42444e384d82ab89184aed5d6f3142748b54768
RNCClipboard: 0a720adef5ec193aa0e3de24c3977222c7e52a37
RNFileViewer: ce7ca3ac370e18554d35d6355cffd7c30437c592
RNFS: 4ac0f0ea233904cb798630b3c077808c06931688
RNGestureHandler: 8dbcccada4a7e702e7dec9338c251b1cf393c960
RNReactNativeHapticFeedback: ec56a5f81c3941206fd85625fa669ffc7b4545f9
RNReanimated: f4ff116e33e0afc3d127f70efe928847c7c66355
RNScreens: 024c5cb8569dea6667b5c73e6c119beb83f686f0
RNShare: 0fad69ae2d71de9d1f7b9a43acf876886a6cb99c
RNSVG: 7ff26379b2d1871b8571e6f9bc9630de6baf9bdf
React-RuntimeHermes: 6273f0755fef304453fc3c356b25abf17e915b83
React-runtimescheduler: 87b14969bb0b10538014fb8407d472f9904bc8cd
React-utils: 67574b07bff4429fd6c4d43a7fad8254d814ee20
ReactCommon: 64c64f4ae1f2debe3fab1800e00cb8466a4477b7
RNCClipboard: 4598dae0fe33e2aa130d9d213e2007be78310266
RNFileViewer: 4b5d83358214347e4ab2d4ca8d5c1c90d869e251
RNFS: 89de7d7f4c0f6bafa05343c578f61118c8282ed8
RNGestureHandler: 77ca8899a0bd9a9d948e74174ee401bbffa5e524
RNReactNativeHapticFeedback: a6fb5b7a981683bf58af43e3fb827d4b7ed87f83
RNReanimated: fe62058b0e1ecb46e252d63d27580f36cd6d9eb2
RNScreens: df14a2a11e7afb57e6f35f8964d206271f4dae44
RNShare: 694e19d7f74ac4c04de3a8af0649e9ccc03bd8b1
RNSVG: 3421710ac15f4f2dc47e5c122f2c2e4282116830
SocketRocket: abac6f5de4d4d62d24e11868d7a2f427e0ef940d
Yoga: b9a182ab00cf25926e7f79657d08c5d23c2d03b0
Yoga: 348f8b538c3ed4423eb58a8e5730feec50bce372

PODFILE CHECKSUM: ccd372319eaeea775147eb2843bb9cf9d1b4cd7a
PODFILE CHECKSUM: eed3e49f72b6465b4551e72df9de6b83230c91ca

COCOAPODS: 1.14.3
COCOAPODS: 1.16.2
43 changes: 43 additions & 0 deletions react-native/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions react-native/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
"react-native-share": "^10.2.1",
"react-native-svg": "^15.4.0",
"react-native-toast-message": "^2.2.1",
"react-native-webview": "^13.16.0",
"react-syntax-highlighter": "^15.5.0"
},
"devDependencies": {
Expand Down
Binary file added react-native/src/assets/download.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions react-native/src/chat/ChatScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,10 @@ function ChatScreen(): React.JSX.Element {
});
}, 100);
}
// Notify Mermaid renderers to refresh after streaming completes
setTimeout(() => {
sendEventRef.current('refreshMermaid');
}, 150);
setChatStatus(ChatStatus.Init);
}
}, [chatStatus]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,8 @@ export const CustomCodeHighlighter: FunctionComponent<CodeHighlighterProps> = ({
const renderNode = useCallback(
(nodes: rendererNode[]): ReactNode => {
// Calculate margin bottom value once
const marginBottomValue = -nodes.length * (isMac ? 3 : 2.75);
const scale = rest.language === 'mermaid' ? 1.75 : isMac ? 3 : 2.75;
const marginBottomValue = -nodes.length * scale;

// Optimization for streaming content - only process new nodes
if (nodes.length >= prevNodesLength.current) {
Expand Down Expand Up @@ -200,7 +201,7 @@ export const CustomCodeHighlighter: FunctionComponent<CodeHighlighterProps> = ({
</TextInput>
);
},
[processNode]
[processNode, rest.language]
);

const renderAndroidNode = useCallback(
Expand Down
Loading