-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpopup.tsx
155 lines (135 loc) · 4.46 KB
/
popup.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
import { useEffect, useState } from "react"
import { Storage } from "@plasmohq/storage"
import "./style.css"
import SavePopup from "./save"
const storage = new Storage()
interface BlinkoConfig {
blinkoInstance: string
blinkoToken: string
}
function ConfigPopup({ onConfigured }: { onConfigured: () => void }) {
const [config, setConfig] = useState<BlinkoConfig>({
blinkoInstance: "",
blinkoToken: ""
})
const [apiInput, setApiInput] = useState("")
const [error, setError] = useState("")
const [isLoading, setIsLoading] = useState(false)
const parseApiInput = (input: string): BlinkoConfig | null => {
try {
const instanceMatch = input.match(/https:\/\/[^\/]+/)
const tokenMatch = input.match(/Bearer\s+([^\s']+)/)
if (!instanceMatch || !tokenMatch) {
throw new Error("Invalid API format")
}
return {
blinkoInstance: instanceMatch[0],
blinkoToken: tokenMatch[1]
}
} catch (e) {
return null
}
}
const validateConfig = async (config: BlinkoConfig): Promise<boolean> => {
try {
const response = await fetch(`${config.blinkoInstance}/api/v1/note/list`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${config.blinkoToken}`
},
body: JSON.stringify({
page: 1,
size: 1,
orderBy: "desc",
type: -1,
isArchived: false,
isRecycle: false,
searchText: ""
})
})
return response.ok
} catch (e) {
return false
}
}
const handleSave = async () => {
setError("")
setIsLoading(true)
const parsedConfig = parseApiInput(apiInput)
if (!parsedConfig) {
setError("无法解析API格式,请检查输入")
setIsLoading(false)
return
}
const isValid = await validateConfig(parsedConfig)
if (!isValid) {
setError("接口地址或者token错误,请检查")
setIsLoading(false)
return
}
await storage.set("blinkoConfig", JSON.stringify(parsedConfig))
setConfig(parsedConfig)
onConfigured()
setIsLoading(false)
}
const handleClose = () => {
window.close()
}
return (
<div className="w-[600px] min-h-[400px] bg-white p-8">
<div className="flex justify-between items-center mb-8">
<h1 className="text-2xl font-bold text-gray-800">save to blinko</h1>
<button
onClick={handleClose}
className="text-gray-500 hover:text-gray-700">
<svg xmlns="http://www.w3.org/2000/svg" className="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
</div>
<div className="space-y-6">
<div>
<h2 className="text-xl font-medium text-gray-800 mb-4">
config the blinko open api
</h2>
<div className="bg-gray-50 rounded-lg p-4">
<textarea
className="w-full h-32 bg-transparent resize-none focus:outline-none text-gray-600 font-mono text-sm"
value={apiInput}
onChange={(e) => setApiInput(e.target.value)}
placeholder="//blinko api document:https://blinko.jiahongw.com/api-doc curl -X 'POST' 'https://blinko.jiahongw.com/api/v1/note/upsert' \ -H 'Content-Type: application/json' \ -H 'Authorization: Bearer secret' \ -d '{ "content": "🎉Hello,Blinko! --send from api ", "type":0 }'"
/>
</div>
</div>
{error && (
<div className="bg-red-50 text-red-600 p-3 rounded-lg text-sm">
{error}
</div>
)}
<button
onClick={handleSave}
disabled={isLoading}
className="w-full bg-yellow-100 hover:bg-yellow-200 text-gray-800 font-medium py-2 px-4 rounded-lg transition-colors">
{isLoading ? "验证中..." : "save"}
</button>
</div>
</div>
)
}
function IndexPopup() {
const [isConfigured, setIsConfigured] = useState(false)
useEffect(() => {
checkConfig()
}, [])
const checkConfig = async () => {
const savedConfig = await storage.get("blinkoConfig")
setIsConfigured(!!savedConfig)
}
return isConfigured ? (
<SavePopup />
) : (
<ConfigPopup onConfigured={() => setIsConfigured(true)} />
)
}
export default IndexPopup