diff --git a/apps/mobile/src/screens/WorkspaceScreen.tsx b/apps/mobile/src/screens/WorkspaceScreen.tsx index 07744e66..d2ecbf45 100644 --- a/apps/mobile/src/screens/WorkspaceScreen.tsx +++ b/apps/mobile/src/screens/WorkspaceScreen.tsx @@ -2063,7 +2063,6 @@ const CreateMemoModal = ({ const [tagsText, setTagsText] = useState(""); const [contentMarkdown, setContentMarkdown] = useState(""); const [contentSelection, setContentSelection] = useState({ start: 0, end: 0 }); - const [insertTextOpen, setInsertTextOpen] = useState(false); const [notebookPickerOpen, setNotebookPickerOpen] = useState(false); const targetNotebookId = notebookId || fallbackNotebookId; const selectedNotebookName = notebooks.find((notebook) => notebook.id === targetNotebookId)?.name ?? "选择笔记本"; @@ -2130,69 +2129,93 @@ const CreateMemoModal = ({ }); const canSubmitCreateMemo = Boolean(targetNotebookId) && !createMutation.isPending; - const pasteClipboardText = async () => { + const insertImageLinkFromClipboard = async () => { const text = await Clipboard.getStringAsync(); - if (!text.trim()) { + const url = text.trim(); + if (!/^https?:\/\//i.test(url)) { + Alert.alert("未找到图片链接", "请先复制一个以 http:// 或 https:// 开头的图片链接。"); return; } - const next = insertPlainText(contentMarkdown, contentSelection, text); + const next = insertPlainText(contentMarkdown, contentSelection, `![图片](${url})`); setContentMarkdown(next.value); setContentSelection(next.selection); }; - const insertManualText = (text: string) => { - const next = insertPlainText(contentMarkdown, contentSelection, text); + const applyCreateEditorAction = (action: MarkdownAction) => { + const next = applyMarkdownAction(contentMarkdown, contentSelection, action); setContentMarkdown(next.value); setContentSelection(next.selection); }; return ( - !createMutation.isPending && onClose()} presentationStyle="pageSheet" visible={visible}> - - - - - - 新建笔记 - createMutation.mutate()}> - {createMutation.isPending ? : } - + !createMutation.isPending && onClose()} presentationStyle="fullScreen" visible={visible}> + + + + + + + + {createMutation.isPending ? "保存中" : "未保存"} + + createMutation.mutate()} + style={[styles.createMemoDoneButton, !canSubmitCreateMemo && styles.createMemoDoneButtonDisabled]} + > + {createMutation.isPending ? : 完成} + + - - 笔记本 - setNotebookPickerOpen(true)} style={styles.editorNotebookButton}> - - {selectedNotebookName} - - - - 标题 - - - 标签 - - - 正文 - { - const next = applyMarkdownAction(contentMarkdown, contentSelection, action); - setContentMarkdown(next.value); - setContentSelection(next.selection); - }} - onInsertText={() => setInsertTextOpen(true)} - onPasteText={() => void pasteClipboardText()} + + + + + setNotebookPickerOpen(true)} style={styles.createMemoNotebookButton}> + {selectedNotebookName} + + + + + + + } onPress={() => void insertImageLinkFromClipboard()} /> + } onPress={() => applyCreateEditorAction("bold")} /> + } onPress={() => applyCreateEditorAction("bullet")} /> + } onPress={() => applyCreateEditorAction("quote")} /> + } onPress={() => applyCreateEditorAction("horizontalRule")} /> + + setContentSelection(event.nativeEvent.selection)} - placeholder="输入正文,可用上方工具插入 Markdown 格式" + placeholder="开始记录..." placeholderTextColor="#94a3b8" selection={contentSelection} - style={styles.markdownInput} + style={styles.createMemoContentInput} textAlignVertical="top" value={contentMarkdown} /> @@ -2201,7 +2224,6 @@ const CreateMemoModal = ({ {createMutation.error instanceof Error ? createMutation.error.message : "创建失败"} ) : null} - setInsertTextOpen(false)} onInsert={insertManualText} visible={insertTextOpen} /> ); +const CreateMemoToolbarButton = ({ + accessibilityLabel, + icon, + onPress, +}: { + accessibilityLabel: string; + icon: ReactNode; + onPress: () => void; +}) => ( + [styles.createMemoToolButton, pressed && styles.createMemoToolButtonPressed]} + > + {icon} + +); + const InsertTextModal = ({ onClose, onInsert, @@ -6842,6 +6883,153 @@ const styles = StyleSheet.create({ backgroundColor: "#f8fafc", flex: 1, }, + createMemoSafeArea: { + backgroundColor: "#ffffff", + flex: 1, + }, + createMemoHeader: { + alignItems: "center", + backgroundColor: "#ffffff", + borderBottomColor: "#f1f5f9", + borderBottomWidth: 1, + flexDirection: "row", + gap: 8, + justifyContent: "space-between", + minHeight: 52, + paddingBottom: 8, + paddingHorizontal: 12, + paddingTop: 8, + }, + createMemoBackButton: { + alignItems: "center", + borderRadius: 999, + height: 38, + justifyContent: "center", + width: 38, + }, + createMemoHeaderActions: { + alignItems: "center", + flexDirection: "row", + gap: 8, + }, + createMemoStatus: { + backgroundColor: "#f1f5f9", + borderRadius: 999, + color: "#64748b", + fontSize: 12, + fontWeight: "700", + overflow: "hidden", + paddingHorizontal: 10, + paddingVertical: 6, + }, + createMemoStatusActive: { + backgroundColor: "#ecfdf5", + color: "#047857", + }, + createMemoDoneButton: { + alignItems: "center", + backgroundColor: "#020617", + borderRadius: 999, + justifyContent: "center", + minHeight: 36, + minWidth: 58, + paddingHorizontal: 12, + paddingVertical: 7, + }, + createMemoDoneButtonDisabled: { + backgroundColor: "#e2e8f0", + }, + createMemoDoneText: { + color: "#ffffff", + fontSize: 14, + fontWeight: "700", + }, + createMemoDoneTextDisabled: { + color: "#64748b", + }, + createMemoScroll: { + backgroundColor: "#ffffff", + flex: 1, + }, + createMemoMain: { + flexGrow: 1, + paddingBottom: 32, + paddingHorizontal: 12, + paddingTop: 14, + }, + createMemoTitleInput: { + color: "#0f172a", + fontSize: 28, + fontWeight: "800", + lineHeight: 34, + minHeight: 42, + padding: 0, + }, + createMemoMetaRow: { + alignItems: "center", + flexDirection: "row", + gap: 10, + minHeight: 40, + }, + createMemoNotebookButton: { + alignItems: "center", + flexDirection: "row", + flexShrink: 1, + gap: 3, + maxWidth: "46%", + minHeight: 30, + paddingRight: 5, + }, + createMemoNotebookText: { + color: "#64748b", + flexShrink: 1, + fontSize: 15, + fontWeight: "700", + }, + createMemoTagsInput: { + color: "#64748b", + flex: 1, + fontSize: 15, + lineHeight: 23, + minHeight: 36, + minWidth: 0, + padding: 0, + }, + createMemoToolbar: { + alignItems: "center", + borderBottomColor: "#f1f5f9", + borderBottomWidth: 1, + borderTopColor: "#f1f5f9", + borderTopWidth: 1, + flexDirection: "row", + gap: 4, + marginHorizontal: -12, + minHeight: 45, + paddingHorizontal: 12, + paddingVertical: 6, + }, + createMemoToolButton: { + alignItems: "center", + borderColor: "transparent", + borderRadius: 999, + borderWidth: 1, + height: 32, + justifyContent: "center", + width: 36, + }, + createMemoToolButtonPressed: { + backgroundColor: "#ecfdf5", + borderColor: "#bbf7d0", + }, + createMemoContentInput: { + color: "#020617", + flex: 1, + fontSize: 17, + lineHeight: 29, + minHeight: 420, + paddingHorizontal: 0, + paddingTop: 18, + }, richEditorSafeArea: { backgroundColor: "#ffffff", flex: 1,