@windrun-huaiin/third-ui 26.0.0 → 27.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ai/ai-prompt-textarea.d.ts +72 -0
- package/dist/ai/ai-prompt-textarea.js +114 -0
- package/dist/ai/ai-prompt-textarea.mjs +112 -0
- package/dist/ai/index.d.ts +1 -0
- package/dist/ai/index.js +2 -0
- package/dist/ai/index.mjs +1 -0
- package/dist/clerk/clerk-provider-client.js +0 -1
- package/dist/clerk/clerk-provider-client.mjs +0 -1
- package/dist/clerk/fingerprint/fingerprint-client.js +0 -4
- package/dist/clerk/fingerprint/fingerprint-client.mjs +0 -4
- package/dist/clerk/fingerprint/use-fingerprint.js +0 -6
- package/dist/clerk/fingerprint/use-fingerprint.mjs +0 -6
- package/dist/clerk/signin-with-fingerprint-client.js +0 -9
- package/dist/clerk/signin-with-fingerprint-client.mjs +0 -9
- package/dist/clerk/signup-button-with-fingerprint-client.js +0 -16
- package/dist/clerk/signup-button-with-fingerprint-client.mjs +0 -16
- package/dist/clerk/signup-with-fingerprint-client.js +0 -9
- package/dist/clerk/signup-with-fingerprint-client.mjs +0 -9
- package/dist/fuma/base/custom-header.js +10 -8
- package/dist/fuma/base/custom-header.mjs +10 -8
- package/dist/fuma/base/custom-home-layout.d.ts +1 -0
- package/dist/fuma/base/index.d.ts +1 -0
- package/dist/fuma/base/index.js +4 -0
- package/dist/fuma/base/index.mjs +1 -0
- package/dist/fuma/base/nav-config.d.ts +10 -0
- package/dist/fuma/base/nav-config.js +32 -0
- package/dist/fuma/base/nav-config.mjs +28 -0
- package/dist/fuma/base/site-layout.d.ts +4 -0
- package/dist/fuma/base/site-layout.js +2 -2
- package/dist/fuma/base/site-layout.mjs +2 -2
- package/dist/fuma/fuma-page-genarator.d.ts +1 -1
- package/dist/fuma/fuma-page-genarator.js +60 -5
- package/dist/fuma/fuma-page-genarator.mjs +60 -5
- package/dist/fuma/llm-copy-handler.js +0 -9
- package/dist/fuma/llm-copy-handler.mjs +0 -9
- package/dist/fuma/mdx/index.d.ts +0 -1
- package/dist/fuma/mdx/index.js +0 -2
- package/dist/fuma/mdx/index.mjs +0 -1
- package/dist/fuma/mdx/suno-embed.js +3 -1
- package/dist/fuma/mdx/suno-embed.mjs +3 -1
- package/dist/fuma/mdx/toc-base.js +0 -1
- package/dist/fuma/mdx/toc-base.mjs +0 -1
- package/dist/fuma/server/features/widgets.js +5 -1
- package/dist/fuma/server/features/widgets.mjs +5 -1
- package/dist/lib/site-docs-helper.d.ts +51 -0
- package/dist/lib/site-docs-helper.js +68 -0
- package/dist/lib/site-docs-helper.mjs +66 -0
- package/dist/main/alert-dialog/index.js +14 -0
- package/dist/main/alert-dialog/index.mjs +5 -0
- package/dist/main/buttons/gradient-button.d.ts +20 -0
- package/dist/main/buttons/gradient-button.js +88 -0
- package/dist/main/buttons/gradient-button.mjs +86 -0
- package/dist/main/buttons/index.d.ts +3 -0
- package/dist/main/buttons/index.js +12 -0
- package/dist/main/buttons/index.mjs +4 -0
- package/dist/main/buttons/x-button.d.ts +39 -0
- package/dist/main/buttons/x-button.js +92 -0
- package/dist/main/buttons/x-button.mjs +90 -0
- package/dist/main/buttons/x-toggle-button.d.ts +32 -0
- package/dist/main/buttons/x-toggle-button.js +95 -0
- package/dist/main/buttons/x-toggle-button.mjs +74 -0
- package/dist/main/credit/credit-overview-client.js +3 -2
- package/dist/main/credit/credit-overview-client.mjs +3 -2
- package/dist/main/credit/index.d.ts +4 -0
- package/dist/main/credit/index.js +10 -0
- package/dist/main/credit/index.mjs +3 -0
- package/dist/main/credit/server.d.ts +2 -0
- package/dist/main/credit/server.js +7 -0
- package/dist/main/credit/server.mjs +1 -0
- package/dist/main/cta.js +4 -2
- package/dist/main/cta.mjs +4 -2
- package/dist/main/hero/index.d.ts +2 -0
- package/dist/main/hero/index.js +10 -0
- package/dist/main/hero/index.mjs +3 -0
- package/dist/main/home/server.d.ts +7 -0
- package/dist/main/home/server.js +19 -0
- package/dist/main/home/server.mjs +7 -0
- package/dist/main/index.d.ts +0 -15
- package/dist/main/index.js +0 -43
- package/dist/main/index.mjs +0 -21
- package/dist/main/loading/index.d.ts +1 -0
- package/dist/main/loading/index.js +9 -0
- package/dist/main/loading/index.mjs +2 -0
- package/dist/main/loading-frame/index.d.ts +1 -0
- package/dist/main/loading-frame/index.js +9 -0
- package/dist/main/loading-frame/index.mjs +2 -0
- package/dist/main/money-price/index.d.ts +4 -0
- package/dist/main/money-price/index.js +15 -0
- package/dist/main/money-price/index.mjs +4 -0
- package/dist/main/money-price/money-price-button.d.ts +1 -1
- package/dist/main/money-price/money-price-button.js +10 -7
- package/dist/main/money-price/money-price-button.mjs +10 -7
- package/dist/main/money-price/money-price-interactive.js +9 -8
- package/dist/main/money-price/money-price-interactive.mjs +9 -8
- package/dist/main/money-price/money-price-types.d.ts +1 -0
- package/dist/main/money-price/server.d.ts +5 -0
- package/dist/main/money-price/server.js +18 -0
- package/dist/main/money-price/server.mjs +4 -0
- package/package.json +54 -4
- package/src/ai/index.ts +1 -0
- package/src/clerk/clerk-provider-client.tsx +1 -3
- package/src/clerk/fingerprint/fingerprint-client.ts +0 -4
- package/src/clerk/fingerprint/use-fingerprint.ts +0 -6
- package/src/clerk/signin-with-fingerprint-client.tsx +0 -10
- package/src/clerk/signup-button-with-fingerprint-client.tsx +0 -17
- package/src/clerk/signup-with-fingerprint-client.tsx +0 -10
- package/src/fuma/base/custom-header.tsx +12 -8
- package/src/fuma/base/custom-home-layout.tsx +7 -4
- package/src/fuma/base/index.ts +1 -0
- package/src/fuma/base/nav-config.ts +81 -0
- package/src/fuma/base/site-layout.tsx +6 -0
- package/src/fuma/fuma-banner-suit.tsx +1 -1
- package/src/fuma/fuma-page-genarator.tsx +60 -7
- package/src/fuma/llm-copy-handler.ts +0 -11
- package/src/fuma/mdx/index.ts +0 -1
- package/src/fuma/mdx/suno-embed.tsx +1 -1
- package/src/fuma/mdx/toc-base.tsx +0 -1
- package/src/fuma/mdx/toc-footer-wrapper.tsx +2 -2
- package/src/fuma/server/features/widgets.tsx +1 -1
- package/src/lib/server.ts +1 -1
- package/src/{fuma/mdx → main/buttons}/gradient-button.tsx +10 -21
- package/src/main/buttons/index.ts +5 -0
- package/src/main/{x-button.tsx → buttons/x-button.tsx} +28 -42
- package/src/main/credit/credit-overview-client.tsx +1 -1
- package/src/main/credit/index.ts +11 -0
- package/src/main/credit/server.ts +7 -0
- package/src/main/cta.tsx +1 -1
- package/src/main/hero/index.ts +4 -0
- package/src/main/home/server.ts +7 -0
- package/src/main/index.ts +1 -20
- package/src/main/language-detector.tsx +0 -1
- package/src/main/loading/index.ts +3 -0
- package/src/main/loading-frame/index.ts +3 -0
- package/src/main/money-price/index.ts +18 -0
- package/src/main/money-price/money-price-button.tsx +12 -6
- package/src/main/money-price/money-price-interactive.tsx +17 -10
- package/src/main/money-price/money-price-types.ts +1 -0
- package/src/main/money-price/server.ts +22 -0
- package/dist/fuma/mdx/features.d.ts +0 -8
- package/dist/fuma/mdx/features.js +0 -92
- package/dist/fuma/mdx/features.mjs +0 -85
- package/dist/fuma/mdx/image-grid.d.ts +0 -6
- package/dist/fuma/mdx/image-grid.js +0 -17
- package/dist/fuma/mdx/image-grid.mjs +0 -15
- package/dist/fuma/mdx/image-zoom.d.ts +0 -22
- package/dist/fuma/mdx/image-zoom.js +0 -39
- package/dist/fuma/mdx/image-zoom.mjs +0 -37
- package/dist/fuma/mdx/markdown-component-map.d.ts +0 -3
- package/dist/fuma/mdx/markdown-component-map.js +0 -79
- package/dist/fuma/mdx/markdown-component-map.mjs +0 -77
- package/dist/fuma/mdx/math.d.ts +0 -17
- package/dist/fuma/mdx/math.js +0 -60
- package/dist/fuma/mdx/math.mjs +0 -57
- package/dist/fuma/mdx/mermaid.d.ts +0 -13
- package/dist/fuma/mdx/mermaid.js +0 -360
- package/dist/fuma/mdx/mermaid.mjs +0 -358
- package/dist/fuma/mdx/site-mdx-components.d.ts +0 -13
- package/dist/fuma/mdx/site-mdx-components.js +0 -19
- package/dist/fuma/mdx/site-mdx-components.mjs +0 -17
- package/dist/fuma/mdx/site-mdx-presets.d.ts +0 -13
- package/dist/fuma/mdx/site-mdx-presets.js +0 -49
- package/dist/fuma/mdx/site-mdx-presets.mjs +0 -45
- package/dist/fuma/server/optional-features.d.ts +0 -6
- package/dist/fuma/server/optional-features.js +0 -17
- package/dist/fuma/server/optional-features.mjs +0 -6
- package/dist/fuma/server/site-mdx-components.d.ts +0 -13
- package/dist/fuma/server/site-mdx-components.js +0 -18
- package/dist/fuma/server/site-mdx-components.mjs +0 -16
- package/dist/fuma/server/site-mdx-presets.d.ts +0 -195
- package/dist/fuma/server/site-mdx-presets.js +0 -55
- package/dist/fuma/server/site-mdx-presets.mjs +0 -52
- /package/src/{main → ai}/ai-prompt-textarea.tsx +0 -0
- /package/src/main/{x-toggle-button.tsx → buttons/x-toggle-button.tsx} +0 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
interface AIPromptTextareaProps {
|
|
2
|
+
/**
|
|
3
|
+
* Textarea value reference
|
|
4
|
+
*/
|
|
5
|
+
value: string;
|
|
6
|
+
/**
|
|
7
|
+
* Textarea value change handler
|
|
8
|
+
*/
|
|
9
|
+
onChange: (value: string) => void;
|
|
10
|
+
/**
|
|
11
|
+
* Word limit value reference
|
|
12
|
+
*/
|
|
13
|
+
isWordLimit: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Word limit value change handler
|
|
16
|
+
*/
|
|
17
|
+
onWordLimitChange: (isLimit: boolean) => void;
|
|
18
|
+
/**
|
|
19
|
+
* Placeholder
|
|
20
|
+
*/
|
|
21
|
+
placeholder?: string;
|
|
22
|
+
/**
|
|
23
|
+
* Disabled switch condition, default is false
|
|
24
|
+
*/
|
|
25
|
+
disabled?: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Maximum words
|
|
28
|
+
*/
|
|
29
|
+
maxWords?: number;
|
|
30
|
+
/**
|
|
31
|
+
* Word count unit title
|
|
32
|
+
*/
|
|
33
|
+
wordUnitTitle?: string;
|
|
34
|
+
/**
|
|
35
|
+
* Minimum height, px
|
|
36
|
+
*/
|
|
37
|
+
minHeight?: number;
|
|
38
|
+
/**
|
|
39
|
+
* Maximum height, px
|
|
40
|
+
*/
|
|
41
|
+
maxHeight?: number;
|
|
42
|
+
/**
|
|
43
|
+
* Word count switch, default is true
|
|
44
|
+
*/
|
|
45
|
+
showWordCount?: boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Auto scroll switch, default is true
|
|
48
|
+
*/
|
|
49
|
+
autoScroll?: boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Extra scroll space, px
|
|
52
|
+
*/
|
|
53
|
+
extraScrollSpace?: number;
|
|
54
|
+
/**
|
|
55
|
+
* Custome tailwindcss style
|
|
56
|
+
*/
|
|
57
|
+
className?: string;
|
|
58
|
+
/**
|
|
59
|
+
* Title text, if not provided, no title will be rendered
|
|
60
|
+
*/
|
|
61
|
+
title?: string;
|
|
62
|
+
/**
|
|
63
|
+
* Description text
|
|
64
|
+
*/
|
|
65
|
+
description?: string;
|
|
66
|
+
/**
|
|
67
|
+
* Embed title inside textarea, default is false
|
|
68
|
+
*/
|
|
69
|
+
embed?: boolean;
|
|
70
|
+
}
|
|
71
|
+
export declare function AIPromptTextarea({ value, onChange, placeholder, disabled, maxWords, wordUnitTitle, minHeight, maxHeight, className, showWordCount, autoScroll, extraScrollSpace, isWordLimit, onWordLimitChange, title, description, embed }: AIPromptTextareaProps): import("react/jsx-runtime").JSX.Element;
|
|
72
|
+
export {};
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
5
|
+
var React = require('react');
|
|
6
|
+
var utils = require('@windrun-huaiin/lib/utils');
|
|
7
|
+
|
|
8
|
+
function AIPromptTextarea({ value, onChange, placeholder = "Enter your prompt...", disabled = false, maxWords = 400, wordUnitTitle = "words", minHeight = 150, maxHeight = 300, className = "", showWordCount = true, autoScroll = true, extraScrollSpace = 100, isWordLimit, onWordLimitChange, title, description, embed = false }) {
|
|
9
|
+
const textareaRef = React.useRef(null);
|
|
10
|
+
// count words
|
|
11
|
+
const wordArray = value.trim().split(/\s+/).filter(Boolean);
|
|
12
|
+
const wordCount = wordArray.length;
|
|
13
|
+
// auto adjust textarea height
|
|
14
|
+
const adjustTextareaHeight = () => {
|
|
15
|
+
if (textareaRef.current) {
|
|
16
|
+
const textarea = textareaRef.current;
|
|
17
|
+
const oldHeight = textarea.style.height;
|
|
18
|
+
// reset height
|
|
19
|
+
textarea.style.height = 'auto';
|
|
20
|
+
// calculate content height
|
|
21
|
+
const contentHeight = textarea.scrollHeight;
|
|
22
|
+
// auto adjust height between min and max height
|
|
23
|
+
let newHeight = Math.max(contentHeight, minHeight);
|
|
24
|
+
newHeight = Math.min(newHeight, maxHeight);
|
|
25
|
+
textarea.style.height = `${newHeight}px`;
|
|
26
|
+
// if content height is greater than max height, show scrollbar
|
|
27
|
+
if (contentHeight > maxHeight) {
|
|
28
|
+
textarea.style.overflowY = 'auto';
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
textarea.style.overflowY = 'hidden';
|
|
32
|
+
}
|
|
33
|
+
// if height increased and auto scroll is enabled, scroll to appropriate position
|
|
34
|
+
if (autoScroll && (newHeight > parseInt(oldHeight) || !oldHeight)) {
|
|
35
|
+
setTimeout(() => {
|
|
36
|
+
const rect = textarea.getBoundingClientRect();
|
|
37
|
+
window.scrollTo({
|
|
38
|
+
top: window.pageYOffset + rect.bottom + extraScrollSpace - window.innerHeight,
|
|
39
|
+
behavior: 'smooth'
|
|
40
|
+
});
|
|
41
|
+
}, 0);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
// when value changes, adjust height
|
|
46
|
+
React.useEffect(() => {
|
|
47
|
+
const timer = setTimeout(() => {
|
|
48
|
+
adjustTextareaHeight();
|
|
49
|
+
}, 0);
|
|
50
|
+
return () => clearTimeout(timer);
|
|
51
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
52
|
+
}, [value, minHeight, maxHeight, autoScroll, extraScrollSpace]);
|
|
53
|
+
// handle input, limit max words
|
|
54
|
+
const handleInputChange = (e) => {
|
|
55
|
+
const inputValue = e.target.value;
|
|
56
|
+
const words = inputValue.trim().split(/\s+/).filter(Boolean);
|
|
57
|
+
// if already reached max words, and this input will exceed limit, do not update
|
|
58
|
+
if (wordCount >= maxWords && words.length > maxWords) {
|
|
59
|
+
onWordLimitChange(true);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
if (words.length > maxWords) {
|
|
63
|
+
onChange(words.slice(0, maxWords).join(' '));
|
|
64
|
+
onWordLimitChange(true);
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
onChange(inputValue);
|
|
68
|
+
onWordLimitChange(false);
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
// when paste, also check word count
|
|
72
|
+
const handlePaste = (e) => {
|
|
73
|
+
const paste = e.clipboardData.getData('text');
|
|
74
|
+
const currentWords = value.trim().split(/\s+/).filter(Boolean);
|
|
75
|
+
const pasteWords = paste.trim().split(/\s+/).filter(Boolean);
|
|
76
|
+
if (currentWords.length >= maxWords) {
|
|
77
|
+
e.preventDefault();
|
|
78
|
+
onWordLimitChange(true);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
// only allow paste remaining words
|
|
82
|
+
const allowed = maxWords - currentWords.length;
|
|
83
|
+
if (pasteWords.length > allowed) {
|
|
84
|
+
e.preventDefault();
|
|
85
|
+
const newWords = currentWords.concat(pasteWords.slice(0, allowed));
|
|
86
|
+
onChange(newWords.join(' '));
|
|
87
|
+
onWordLimitChange(true);
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
// 渲染标题组件
|
|
91
|
+
const renderTitle = () => {
|
|
92
|
+
if (!(title === null || title === void 0 ? void 0 : title.trim()))
|
|
93
|
+
return null;
|
|
94
|
+
return (jsxRuntime.jsxs("div", { className: "space-y-1", children: [title && jsxRuntime.jsx("span", { className: "text-xl font-semibold text-foreground", children: title }), (description === null || description === void 0 ? void 0 : description.trim()) && jsxRuntime.jsx("span", { className: "text-sm text-gray-400 ml-2", children: description })] }));
|
|
95
|
+
};
|
|
96
|
+
// 渲染textarea组件
|
|
97
|
+
const renderTextarea = (isEmbedded = false) => (jsxRuntime.jsx("textarea", { ref: textareaRef, value: value, onChange: handleInputChange, onPaste: handlePaste, placeholder: placeholder, disabled: disabled, className: utils.cn('w-full p-4 bg-transparent transition-colors text-foreground placeholder-muted-foreground placeholder:text-base disabled:bg-muted disabled:cursor-not-allowed resize-none', isEmbedded
|
|
98
|
+
? 'border-0 hover:border-2 hover:border-purple-500 focus:outline-none focus:border-2 focus:border-purple-500'
|
|
99
|
+
: 'border-2 border-border rounded-lg hover:border-purple-500 focus:outline-none focus:border-purple-500', className), style: { minHeight: `${minHeight}px` } }));
|
|
100
|
+
// 渲染单词计数
|
|
101
|
+
const renderWordCount = () => {
|
|
102
|
+
if (!showWordCount)
|
|
103
|
+
return null;
|
|
104
|
+
return (jsxRuntime.jsx("div", { className: "flex justify-end", children: jsxRuntime.jsxs("span", { className: `text-sm ${wordCount >= maxWords ? 'text-red-500' : wordCount > maxWords * 0.75 ? 'text-orange-500' : 'text-muted-foreground'} ${isWordLimit ? 'animate-bounce' : ''}`, onAnimationEnd: () => onWordLimitChange(false), children: [wordCount, "/", maxWords, " ", wordUnitTitle] }) }));
|
|
105
|
+
};
|
|
106
|
+
// 如果有标题且需要嵌入,则渲染内部标题布局
|
|
107
|
+
if (embed && (title)) {
|
|
108
|
+
return (jsxRuntime.jsxs("div", { className: "space-y-2", children: [jsxRuntime.jsxs("div", { className: "border-2 border-border rounded-lg bg-transparent", children: [jsxRuntime.jsx("div", { className: "p-4 pb-2", children: renderTitle() }), jsxRuntime.jsx("hr", { className: "border-t border-border" }), jsxRuntime.jsx("div", { className: "p-1", children: renderTextarea(true) })] }), renderWordCount()] }));
|
|
109
|
+
}
|
|
110
|
+
// 默认布局:外部标题或无标题
|
|
111
|
+
return (jsxRuntime.jsxs("div", { className: "space-y-2", children: [renderTitle(), renderTextarea(), renderWordCount()] }));
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
exports.AIPromptTextarea = AIPromptTextarea;
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
|
+
import { useRef, useEffect } from 'react';
|
|
4
|
+
import { cn } from '@windrun-huaiin/lib/utils';
|
|
5
|
+
|
|
6
|
+
function AIPromptTextarea({ value, onChange, placeholder = "Enter your prompt...", disabled = false, maxWords = 400, wordUnitTitle = "words", minHeight = 150, maxHeight = 300, className = "", showWordCount = true, autoScroll = true, extraScrollSpace = 100, isWordLimit, onWordLimitChange, title, description, embed = false }) {
|
|
7
|
+
const textareaRef = useRef(null);
|
|
8
|
+
// count words
|
|
9
|
+
const wordArray = value.trim().split(/\s+/).filter(Boolean);
|
|
10
|
+
const wordCount = wordArray.length;
|
|
11
|
+
// auto adjust textarea height
|
|
12
|
+
const adjustTextareaHeight = () => {
|
|
13
|
+
if (textareaRef.current) {
|
|
14
|
+
const textarea = textareaRef.current;
|
|
15
|
+
const oldHeight = textarea.style.height;
|
|
16
|
+
// reset height
|
|
17
|
+
textarea.style.height = 'auto';
|
|
18
|
+
// calculate content height
|
|
19
|
+
const contentHeight = textarea.scrollHeight;
|
|
20
|
+
// auto adjust height between min and max height
|
|
21
|
+
let newHeight = Math.max(contentHeight, minHeight);
|
|
22
|
+
newHeight = Math.min(newHeight, maxHeight);
|
|
23
|
+
textarea.style.height = `${newHeight}px`;
|
|
24
|
+
// if content height is greater than max height, show scrollbar
|
|
25
|
+
if (contentHeight > maxHeight) {
|
|
26
|
+
textarea.style.overflowY = 'auto';
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
textarea.style.overflowY = 'hidden';
|
|
30
|
+
}
|
|
31
|
+
// if height increased and auto scroll is enabled, scroll to appropriate position
|
|
32
|
+
if (autoScroll && (newHeight > parseInt(oldHeight) || !oldHeight)) {
|
|
33
|
+
setTimeout(() => {
|
|
34
|
+
const rect = textarea.getBoundingClientRect();
|
|
35
|
+
window.scrollTo({
|
|
36
|
+
top: window.pageYOffset + rect.bottom + extraScrollSpace - window.innerHeight,
|
|
37
|
+
behavior: 'smooth'
|
|
38
|
+
});
|
|
39
|
+
}, 0);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
// when value changes, adjust height
|
|
44
|
+
useEffect(() => {
|
|
45
|
+
const timer = setTimeout(() => {
|
|
46
|
+
adjustTextareaHeight();
|
|
47
|
+
}, 0);
|
|
48
|
+
return () => clearTimeout(timer);
|
|
49
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
50
|
+
}, [value, minHeight, maxHeight, autoScroll, extraScrollSpace]);
|
|
51
|
+
// handle input, limit max words
|
|
52
|
+
const handleInputChange = (e) => {
|
|
53
|
+
const inputValue = e.target.value;
|
|
54
|
+
const words = inputValue.trim().split(/\s+/).filter(Boolean);
|
|
55
|
+
// if already reached max words, and this input will exceed limit, do not update
|
|
56
|
+
if (wordCount >= maxWords && words.length > maxWords) {
|
|
57
|
+
onWordLimitChange(true);
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
if (words.length > maxWords) {
|
|
61
|
+
onChange(words.slice(0, maxWords).join(' '));
|
|
62
|
+
onWordLimitChange(true);
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
onChange(inputValue);
|
|
66
|
+
onWordLimitChange(false);
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
// when paste, also check word count
|
|
70
|
+
const handlePaste = (e) => {
|
|
71
|
+
const paste = e.clipboardData.getData('text');
|
|
72
|
+
const currentWords = value.trim().split(/\s+/).filter(Boolean);
|
|
73
|
+
const pasteWords = paste.trim().split(/\s+/).filter(Boolean);
|
|
74
|
+
if (currentWords.length >= maxWords) {
|
|
75
|
+
e.preventDefault();
|
|
76
|
+
onWordLimitChange(true);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
// only allow paste remaining words
|
|
80
|
+
const allowed = maxWords - currentWords.length;
|
|
81
|
+
if (pasteWords.length > allowed) {
|
|
82
|
+
e.preventDefault();
|
|
83
|
+
const newWords = currentWords.concat(pasteWords.slice(0, allowed));
|
|
84
|
+
onChange(newWords.join(' '));
|
|
85
|
+
onWordLimitChange(true);
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
// 渲染标题组件
|
|
89
|
+
const renderTitle = () => {
|
|
90
|
+
if (!(title === null || title === void 0 ? void 0 : title.trim()))
|
|
91
|
+
return null;
|
|
92
|
+
return (jsxs("div", { className: "space-y-1", children: [title && jsx("span", { className: "text-xl font-semibold text-foreground", children: title }), (description === null || description === void 0 ? void 0 : description.trim()) && jsx("span", { className: "text-sm text-gray-400 ml-2", children: description })] }));
|
|
93
|
+
};
|
|
94
|
+
// 渲染textarea组件
|
|
95
|
+
const renderTextarea = (isEmbedded = false) => (jsx("textarea", { ref: textareaRef, value: value, onChange: handleInputChange, onPaste: handlePaste, placeholder: placeholder, disabled: disabled, className: cn('w-full p-4 bg-transparent transition-colors text-foreground placeholder-muted-foreground placeholder:text-base disabled:bg-muted disabled:cursor-not-allowed resize-none', isEmbedded
|
|
96
|
+
? 'border-0 hover:border-2 hover:border-purple-500 focus:outline-none focus:border-2 focus:border-purple-500'
|
|
97
|
+
: 'border-2 border-border rounded-lg hover:border-purple-500 focus:outline-none focus:border-purple-500', className), style: { minHeight: `${minHeight}px` } }));
|
|
98
|
+
// 渲染单词计数
|
|
99
|
+
const renderWordCount = () => {
|
|
100
|
+
if (!showWordCount)
|
|
101
|
+
return null;
|
|
102
|
+
return (jsx("div", { className: "flex justify-end", children: jsxs("span", { className: `text-sm ${wordCount >= maxWords ? 'text-red-500' : wordCount > maxWords * 0.75 ? 'text-orange-500' : 'text-muted-foreground'} ${isWordLimit ? 'animate-bounce' : ''}`, onAnimationEnd: () => onWordLimitChange(false), children: [wordCount, "/", maxWords, " ", wordUnitTitle] }) }));
|
|
103
|
+
};
|
|
104
|
+
// 如果有标题且需要嵌入,则渲染内部标题布局
|
|
105
|
+
if (embed && (title)) {
|
|
106
|
+
return (jsxs("div", { className: "space-y-2", children: [jsxs("div", { className: "border-2 border-border rounded-lg bg-transparent", children: [jsx("div", { className: "p-4 pb-2", children: renderTitle() }), jsx("hr", { className: "border-t border-border" }), jsx("div", { className: "p-1", children: renderTextarea(true) })] }), renderWordCount()] }));
|
|
107
|
+
}
|
|
108
|
+
// 默认布局:外部标题或无标题
|
|
109
|
+
return (jsxs("div", { className: "space-y-2", children: [renderTitle(), renderTextarea(), renderWordCount()] }));
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export { AIPromptTextarea };
|
package/dist/ai/index.d.ts
CHANGED
package/dist/ai/index.js
CHANGED
|
@@ -11,6 +11,7 @@ var aiMessageContent = require('./ai-message-content.js');
|
|
|
11
11
|
var aiMessageMeta = require('./ai-message-meta.js');
|
|
12
12
|
var aiMessageActions = require('./ai-message-actions.js');
|
|
13
13
|
var aiStatusIndicator = require('./ai-status-indicator.js');
|
|
14
|
+
var aiPromptTextarea = require('./ai-prompt-textarea.js');
|
|
14
15
|
|
|
15
16
|
|
|
16
17
|
|
|
@@ -31,3 +32,4 @@ exports.AIMessageContent = aiMessageContent.AIMessageContent;
|
|
|
31
32
|
exports.AIMessageMeta = aiMessageMeta.AIMessageMeta;
|
|
32
33
|
exports.AIMessageActions = aiMessageActions.AIMessageActions;
|
|
33
34
|
exports.AIStatusIndicator = aiStatusIndicator.AIStatusIndicator;
|
|
35
|
+
exports.AIPromptTextarea = aiPromptTextarea.AIPromptTextarea;
|
package/dist/ai/index.mjs
CHANGED
|
@@ -9,3 +9,4 @@ export { AIMessageContent } from './ai-message-content.mjs';
|
|
|
9
9
|
export { AIMessageMeta } from './ai-message-meta.mjs';
|
|
10
10
|
export { AIMessageActions } from './ai-message-actions.mjs';
|
|
11
11
|
export { AIStatusIndicator } from './ai-status-indicator.mjs';
|
|
12
|
+
export { AIPromptTextarea } from './ai-prompt-textarea.mjs';
|
|
@@ -37,7 +37,6 @@ function ClerkProviderClient({ children, locale, localePrefixAsNeeded = true, de
|
|
|
37
37
|
if (waitlistWithLocale) {
|
|
38
38
|
clerkProviderProps.waitlistUrl = waitlistWithLocale;
|
|
39
39
|
}
|
|
40
|
-
// console.log('ClerkProviderClient props:', clerkProviderProps);
|
|
41
40
|
return (jsxRuntime.jsx(nextjs.ClerkProvider, Object.assign({}, clerkProviderProps, { children: children })));
|
|
42
41
|
}
|
|
43
42
|
|
|
@@ -35,7 +35,6 @@ function ClerkProviderClient({ children, locale, localePrefixAsNeeded = true, de
|
|
|
35
35
|
if (waitlistWithLocale) {
|
|
36
36
|
clerkProviderProps.waitlistUrl = waitlistWithLocale;
|
|
37
37
|
}
|
|
38
|
-
// console.log('ClerkProviderClient props:', clerkProviderProps);
|
|
39
38
|
return (jsx(ClerkProvider, Object.assign({}, clerkProviderProps, { children: children })));
|
|
40
39
|
}
|
|
41
40
|
|
|
@@ -163,7 +163,6 @@ function generateFingerprintId() {
|
|
|
163
163
|
// 检查现有 ID
|
|
164
164
|
const existingId = checkStoredFingerprintId();
|
|
165
165
|
if (existingId) {
|
|
166
|
-
console.log('Using existing fingerprint ID:', existingId);
|
|
167
166
|
return existingId;
|
|
168
167
|
}
|
|
169
168
|
try {
|
|
@@ -174,7 +173,6 @@ function generateFingerprintId() {
|
|
|
174
173
|
// 存储到 localStorage 和 cookie
|
|
175
174
|
setLocalStorageValue(fingerprintShared.FINGERPRINT_STORAGE_KEY, fingerprintId);
|
|
176
175
|
setCookie(fingerprintShared.FINGERPRINT_COOKIE_NAME, fingerprintId, 365);
|
|
177
|
-
console.log('Generated new fingerprint ID:', fingerprintId);
|
|
178
176
|
return fingerprintId;
|
|
179
177
|
}
|
|
180
178
|
catch (error) {
|
|
@@ -183,7 +181,6 @@ function generateFingerprintId() {
|
|
|
183
181
|
const fallbackId = `fp_fallback_${Date.now()}_${Math.random().toString(36).slice(2, 11)}`;
|
|
184
182
|
setLocalStorageValue(fingerprintShared.FINGERPRINT_STORAGE_KEY, fallbackId);
|
|
185
183
|
setCookie(fingerprintShared.FINGERPRINT_COOKIE_NAME, fallbackId, 365);
|
|
186
|
-
console.log('Generated fallback fingerprint ID:', fallbackId);
|
|
187
184
|
return fallbackId;
|
|
188
185
|
}
|
|
189
186
|
});
|
|
@@ -225,7 +222,6 @@ function getOrGenerateFingerprintId() {
|
|
|
225
222
|
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
226
223
|
const existingId = checkStoredFingerprintId();
|
|
227
224
|
if (existingId) {
|
|
228
|
-
console.log('Retrieved existing fingerprint ID:', existingId);
|
|
229
225
|
return existingId;
|
|
230
226
|
}
|
|
231
227
|
return yield generateFingerprintId();
|
|
@@ -161,7 +161,6 @@ function generateFingerprintId() {
|
|
|
161
161
|
// 检查现有 ID
|
|
162
162
|
const existingId = checkStoredFingerprintId();
|
|
163
163
|
if (existingId) {
|
|
164
|
-
console.log('Using existing fingerprint ID:', existingId);
|
|
165
164
|
return existingId;
|
|
166
165
|
}
|
|
167
166
|
try {
|
|
@@ -172,7 +171,6 @@ function generateFingerprintId() {
|
|
|
172
171
|
// 存储到 localStorage 和 cookie
|
|
173
172
|
setLocalStorageValue(FINGERPRINT_STORAGE_KEY, fingerprintId);
|
|
174
173
|
setCookie(FINGERPRINT_COOKIE_NAME, fingerprintId, 365);
|
|
175
|
-
console.log('Generated new fingerprint ID:', fingerprintId);
|
|
176
174
|
return fingerprintId;
|
|
177
175
|
}
|
|
178
176
|
catch (error) {
|
|
@@ -181,7 +179,6 @@ function generateFingerprintId() {
|
|
|
181
179
|
const fallbackId = `fp_fallback_${Date.now()}_${Math.random().toString(36).slice(2, 11)}`;
|
|
182
180
|
setLocalStorageValue(FINGERPRINT_STORAGE_KEY, fallbackId);
|
|
183
181
|
setCookie(FINGERPRINT_COOKIE_NAME, fallbackId, 365);
|
|
184
|
-
console.log('Generated fallback fingerprint ID:', fallbackId);
|
|
185
182
|
return fallbackId;
|
|
186
183
|
}
|
|
187
184
|
});
|
|
@@ -223,7 +220,6 @@ function getOrGenerateFingerprintId() {
|
|
|
223
220
|
return __awaiter(this, void 0, void 0, function* () {
|
|
224
221
|
const existingId = checkStoredFingerprintId();
|
|
225
222
|
if (existingId) {
|
|
226
|
-
console.log('Retrieved existing fingerprint ID:', existingId);
|
|
227
223
|
return existingId;
|
|
228
224
|
}
|
|
229
225
|
return yield generateFingerprintId();
|
|
@@ -46,7 +46,6 @@ function useFingerprint(config) {
|
|
|
46
46
|
// Capture first-touch as early as possible before any in-site navigation can overwrite context.
|
|
47
47
|
fingerprintClient.getOrCreateFirstTouchData();
|
|
48
48
|
const currentFingerprintId = yield fingerprintClient.getOrGenerateFingerprintId();
|
|
49
|
-
console.log('Initialized fingerprintId:', currentFingerprintId);
|
|
50
49
|
setFingerprintIdState(currentFingerprintId);
|
|
51
50
|
return currentFingerprintId;
|
|
52
51
|
}
|
|
@@ -67,11 +66,9 @@ function useFingerprint(config) {
|
|
|
67
66
|
return;
|
|
68
67
|
}
|
|
69
68
|
if (isInitializingAnonymousUserRef.current) {
|
|
70
|
-
console.log('Skipping anonymous user initialization because a request is already in flight:', fingerprintId);
|
|
71
69
|
return;
|
|
72
70
|
}
|
|
73
71
|
if (requestedAnonymousFingerprintRef.current === fingerprintId && isInitialized) {
|
|
74
|
-
console.log('Skipping anonymous user initialization because fingerprint is already initialized:', fingerprintId);
|
|
75
72
|
return;
|
|
76
73
|
}
|
|
77
74
|
try {
|
|
@@ -79,7 +76,6 @@ function useFingerprint(config) {
|
|
|
79
76
|
requestedAnonymousFingerprintRef.current = fingerprintId;
|
|
80
77
|
setIsLoading(true);
|
|
81
78
|
setError(null);
|
|
82
|
-
console.log('Initializing anonymous user with fingerprintId:', fingerprintId);
|
|
83
79
|
const fingerprintHeaders = yield fingerprintClient.createFingerprintHeaders();
|
|
84
80
|
const response = yield fetch(config.apiEndpoint, {
|
|
85
81
|
method: 'POST',
|
|
@@ -91,10 +87,8 @@ function useFingerprint(config) {
|
|
|
91
87
|
throw new Error(errorData.error || 'Failed to initialize anonymous user');
|
|
92
88
|
}
|
|
93
89
|
const data = yield response.json();
|
|
94
|
-
console.log('API response in initializeAnonymousUser:', data);
|
|
95
90
|
if (data.success) {
|
|
96
91
|
const updatedXUser = data.xUser || { userId: '', fingerprintId, clerkUserId: '', email: '', status: '', createdAt: '' };
|
|
97
|
-
console.log('Setting xUser:', updatedXUser);
|
|
98
92
|
setXUser(updatedXUser);
|
|
99
93
|
setXCredit(data.xCredit || null);
|
|
100
94
|
setXSubscription(data.xSubscription || null);
|
|
@@ -44,7 +44,6 @@ function useFingerprint(config) {
|
|
|
44
44
|
// Capture first-touch as early as possible before any in-site navigation can overwrite context.
|
|
45
45
|
getOrCreateFirstTouchData();
|
|
46
46
|
const currentFingerprintId = yield getOrGenerateFingerprintId();
|
|
47
|
-
console.log('Initialized fingerprintId:', currentFingerprintId);
|
|
48
47
|
setFingerprintIdState(currentFingerprintId);
|
|
49
48
|
return currentFingerprintId;
|
|
50
49
|
}
|
|
@@ -65,11 +64,9 @@ function useFingerprint(config) {
|
|
|
65
64
|
return;
|
|
66
65
|
}
|
|
67
66
|
if (isInitializingAnonymousUserRef.current) {
|
|
68
|
-
console.log('Skipping anonymous user initialization because a request is already in flight:', fingerprintId);
|
|
69
67
|
return;
|
|
70
68
|
}
|
|
71
69
|
if (requestedAnonymousFingerprintRef.current === fingerprintId && isInitialized) {
|
|
72
|
-
console.log('Skipping anonymous user initialization because fingerprint is already initialized:', fingerprintId);
|
|
73
70
|
return;
|
|
74
71
|
}
|
|
75
72
|
try {
|
|
@@ -77,7 +74,6 @@ function useFingerprint(config) {
|
|
|
77
74
|
requestedAnonymousFingerprintRef.current = fingerprintId;
|
|
78
75
|
setIsLoading(true);
|
|
79
76
|
setError(null);
|
|
80
|
-
console.log('Initializing anonymous user with fingerprintId:', fingerprintId);
|
|
81
77
|
const fingerprintHeaders = yield createFingerprintHeaders();
|
|
82
78
|
const response = yield fetch(config.apiEndpoint, {
|
|
83
79
|
method: 'POST',
|
|
@@ -89,10 +85,8 @@ function useFingerprint(config) {
|
|
|
89
85
|
throw new Error(errorData.error || 'Failed to initialize anonymous user');
|
|
90
86
|
}
|
|
91
87
|
const data = yield response.json();
|
|
92
|
-
console.log('API response in initializeAnonymousUser:', data);
|
|
93
88
|
if (data.success) {
|
|
94
89
|
const updatedXUser = data.xUser || { userId: '', fingerprintId, clerkUserId: '', email: '', status: '', createdAt: '' };
|
|
95
|
-
console.log('Setting xUser:', updatedXUser);
|
|
96
90
|
setXUser(updatedXUser);
|
|
97
91
|
setXCredit(data.xCredit || null);
|
|
98
92
|
setXSubscription(data.xSubscription || null);
|
|
@@ -27,15 +27,6 @@ function SignInWithFingerprint() {
|
|
|
27
27
|
initializeAnonymousUser();
|
|
28
28
|
}
|
|
29
29
|
}, [fingerprintId, isInitialized, initializeAnonymousUser]);
|
|
30
|
-
// 调试日志和处理登录逻辑
|
|
31
|
-
React.useEffect(() => {
|
|
32
|
-
console.log('SignInWithFingerprint on [redirect] DEBUG:', {
|
|
33
|
-
fingerprintProvider: fingerprintContext ? 'Available' : 'Not found',
|
|
34
|
-
fingerprintId: fingerprintId || 'Not generated',
|
|
35
|
-
xUser: xUser ? 'Initialized' : 'Not initialized',
|
|
36
|
-
clerkMetadata: unsafeMetadata
|
|
37
|
-
});
|
|
38
|
-
}, [xUser, fingerprintId, fingerprintContext, unsafeMetadata]);
|
|
39
30
|
return jsxRuntime.jsx(nextjs.SignIn, { unsafeMetadata: unsafeMetadata });
|
|
40
31
|
}
|
|
41
32
|
|
|
@@ -25,15 +25,6 @@ function SignInWithFingerprint() {
|
|
|
25
25
|
initializeAnonymousUser();
|
|
26
26
|
}
|
|
27
27
|
}, [fingerprintId, isInitialized, initializeAnonymousUser]);
|
|
28
|
-
// 调试日志和处理登录逻辑
|
|
29
|
-
useEffect(() => {
|
|
30
|
-
console.log('SignInWithFingerprint on [redirect] DEBUG:', {
|
|
31
|
-
fingerprintProvider: fingerprintContext ? 'Available' : 'Not found',
|
|
32
|
-
fingerprintId: fingerprintId || 'Not generated',
|
|
33
|
-
xUser: xUser ? 'Initialized' : 'Not initialized',
|
|
34
|
-
clerkMetadata: unsafeMetadata
|
|
35
|
-
});
|
|
36
|
-
}, [xUser, fingerprintId, fingerprintContext, unsafeMetadata]);
|
|
37
28
|
return jsx(SignIn, { unsafeMetadata: unsafeMetadata });
|
|
38
29
|
}
|
|
39
30
|
|
|
@@ -28,27 +28,11 @@ function SignUpButtonWithFingerprint({ mode, signUp, }) {
|
|
|
28
28
|
initializeAnonymousUser();
|
|
29
29
|
}
|
|
30
30
|
}, [fingerprintId, isInitialized, initializeAnonymousUser]);
|
|
31
|
-
// 调试日志和处理注册逻辑
|
|
32
|
-
React.useEffect(() => {
|
|
33
|
-
console.log('SignUpWithFingerprint on [modal] DEBUG:', {
|
|
34
|
-
fingerprintProvider: fingerprintContext ? 'Available' : 'Not found',
|
|
35
|
-
fingerprintId: fingerprintId || 'Not generated',
|
|
36
|
-
xUser: xUser ? 'Initialized' : 'Not initialized',
|
|
37
|
-
clerkMetadata: unsafeMetadata
|
|
38
|
-
});
|
|
39
|
-
}, [xUser, fingerprintId, fingerprintContext, unsafeMetadata]);
|
|
40
31
|
const { openSignUp } = nextjs.useClerk();
|
|
41
32
|
const handleClick = () => {
|
|
42
33
|
openSignUp({
|
|
43
34
|
unsafeMetadata,
|
|
44
35
|
});
|
|
45
|
-
// 记录日志
|
|
46
|
-
console.log('SignUpButton on [modal] clicked', {
|
|
47
|
-
timestamp: new Date().toISOString(),
|
|
48
|
-
mode,
|
|
49
|
-
userId,
|
|
50
|
-
fingerprintId
|
|
51
|
-
});
|
|
52
36
|
};
|
|
53
37
|
return (jsxRuntime.jsx("button", { className: "w-16 sm:w-20 h-8 sm:h-9 px-1.5 sm:px-2 border border-gray-300 rounded-full hover:bg-gray-100 dark:border-gray-600 dark:hover:bg-gray-800 text-center text-xs sm:text-sm whitespace-nowrap", onClick: handleClick, children: signUp }));
|
|
54
38
|
}
|
|
@@ -26,27 +26,11 @@ function SignUpButtonWithFingerprint({ mode, signUp, }) {
|
|
|
26
26
|
initializeAnonymousUser();
|
|
27
27
|
}
|
|
28
28
|
}, [fingerprintId, isInitialized, initializeAnonymousUser]);
|
|
29
|
-
// 调试日志和处理注册逻辑
|
|
30
|
-
useEffect(() => {
|
|
31
|
-
console.log('SignUpWithFingerprint on [modal] DEBUG:', {
|
|
32
|
-
fingerprintProvider: fingerprintContext ? 'Available' : 'Not found',
|
|
33
|
-
fingerprintId: fingerprintId || 'Not generated',
|
|
34
|
-
xUser: xUser ? 'Initialized' : 'Not initialized',
|
|
35
|
-
clerkMetadata: unsafeMetadata
|
|
36
|
-
});
|
|
37
|
-
}, [xUser, fingerprintId, fingerprintContext, unsafeMetadata]);
|
|
38
29
|
const { openSignUp } = useClerk();
|
|
39
30
|
const handleClick = () => {
|
|
40
31
|
openSignUp({
|
|
41
32
|
unsafeMetadata,
|
|
42
33
|
});
|
|
43
|
-
// 记录日志
|
|
44
|
-
console.log('SignUpButton on [modal] clicked', {
|
|
45
|
-
timestamp: new Date().toISOString(),
|
|
46
|
-
mode,
|
|
47
|
-
userId,
|
|
48
|
-
fingerprintId
|
|
49
|
-
});
|
|
50
34
|
};
|
|
51
35
|
return (jsx("button", { className: "w-16 sm:w-20 h-8 sm:h-9 px-1.5 sm:px-2 border border-gray-300 rounded-full hover:bg-gray-100 dark:border-gray-600 dark:hover:bg-gray-800 text-center text-xs sm:text-sm whitespace-nowrap", onClick: handleClick, children: signUp }));
|
|
52
36
|
}
|
|
@@ -27,15 +27,6 @@ function SignUpWithFingerprint() {
|
|
|
27
27
|
initializeAnonymousUser();
|
|
28
28
|
}
|
|
29
29
|
}, [fingerprintId, isInitialized, initializeAnonymousUser]);
|
|
30
|
-
// 调试日志和处理注册逻辑
|
|
31
|
-
React.useEffect(() => {
|
|
32
|
-
console.log('SignUpWithFingerprint on [redirect] DEBUG:', {
|
|
33
|
-
fingerprintProvider: fingerprintContext ? 'Available' : 'Not found',
|
|
34
|
-
fingerprintId: fingerprintId || 'Not generated',
|
|
35
|
-
xUser: xUser ? 'Initialized' : 'Not initialized',
|
|
36
|
-
clerkMetadata: unsafeMetadata
|
|
37
|
-
});
|
|
38
|
-
}, [xUser, fingerprintId, fingerprintContext, unsafeMetadata]);
|
|
39
30
|
return jsxRuntime.jsx(nextjs.SignUp, { unsafeMetadata: unsafeMetadata });
|
|
40
31
|
}
|
|
41
32
|
|
|
@@ -25,15 +25,6 @@ function SignUpWithFingerprint() {
|
|
|
25
25
|
initializeAnonymousUser();
|
|
26
26
|
}
|
|
27
27
|
}, [fingerprintId, isInitialized, initializeAnonymousUser]);
|
|
28
|
-
// 调试日志和处理注册逻辑
|
|
29
|
-
useEffect(() => {
|
|
30
|
-
console.log('SignUpWithFingerprint on [redirect] DEBUG:', {
|
|
31
|
-
fingerprintProvider: fingerprintContext ? 'Available' : 'Not found',
|
|
32
|
-
fingerprintId: fingerprintId || 'Not generated',
|
|
33
|
-
xUser: xUser ? 'Initialized' : 'Not initialized',
|
|
34
|
-
clerkMetadata: unsafeMetadata
|
|
35
|
-
});
|
|
36
|
-
}, [xUser, fingerprintId, fingerprintContext, unsafeMetadata]);
|
|
37
28
|
return jsx(SignUp, { unsafeMetadata: unsafeMetadata });
|
|
38
29
|
}
|
|
39
30
|
|