-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.html
207 lines (189 loc) · 12.7 KB
/
index.html
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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="css/style.min.css">
<link rel="icon" href="/icons/icon-192x192.webp">
<title>LLM Text Tool</title>
<link rel="manifest" href="/manifest.json">
<meta name="theme-color" content="#155a82">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body class="min-h-screen text-gray-900 bg-gradient-to-br from-gray-50 to-gray-100">
<div id="settings-toast"
class="fixed z-50 px-4 py-2 transition-all duration-300 transform translate-x-full rounded-lg shadow-lg opacity-0 top-4 right-4">
</div>
<div id="loadingOverlay" class="fixed inset-0 z-50 flex items-center justify-center hidden bg-black bg-opacity-70 backdrop-blur-sm">
<div class="flex flex-col items-center justify-center text-center">
<div class="w-16 h-16 mb-4 border-t-2 border-b-2 border-white rounded-full animate-spin"></div>
<p id="loadingMessage" class="text-xl font-medium text-white">Processing...</p>
</div>
</div>
<!-- SETTINGS MODAL -->
<div id="modal" class="fixed inset-0 z-50 flex items-center justify-center hidden bg-black bg-opacity-70 backdrop-blur-sm">
<div class="bg-white rounded-2xl shadow-xl py-4 px-8 max-w-md w-full m-4 max-h-[90vh] flex flex-col">
<h2 class="sticky top-0 pt-2 mb-6 text-2xl font-bold bg-white">Settings</h2>
<div class="flex-grow pr-2 space-y-6 overflow-y-auto">
<div class="mb-4">
<details open>
<summary class="mb-2 font-semibold cursor-pointer text-md hover:text-blue-600">
OpenAI API
</summary>
<div class="pl-4 space-y-4">
<div>
<label class="block mb-2 font-medium text-gray-700">OpenAI API Endpoint</label>
<input id="apiEndpoint" type="text" class="w-full p-2 transition-all border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500" placeholder="https://api.openai.com/v1/chat/completions">
</div>
<div>
<label class="block mb-2 font-medium text-gray-700">API Key</label>
<input id="apiKey" type="text" class="w-full p-2 font-mono text-sm transition-all border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500" placeholder="Your OpenAI API Key">
</div>
<div>
<label class="block mb-2 font-medium text-gray-700">Model ID</label>
<input id="modelId" type="text" class="w-full p-2 transition-all border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500" placeholder="gpt-4-mini">
<small class="block mt-2 text-gray-600">*Recommended: <i>Claude 3.5 Haiku</i>, <i>Gemini 2.0 Flash</i>, <i>Qwen2.5</i></small>
</div>
</div>
<small class="block mt-2 text-gray-500">*Check out <a href="https://nano-gpt.com" class="text-blue-600 hover:underline">nano-gpt</a> or <a href="https://ppq.ai" class="text-blue-600 hover:underline">ppq.ai</a> for privacy-respecting multi-models via OpenAI compatible API.</small>
</details>
</div>
<div class="mb-4">
<details>
<summary class="mb-2 font-semibold cursor-pointer text-md hover:text-blue-600">
Share Configuration
</summary>
<div class="pl-4 space-y-4">
<div>
<label class="block mb-2 font-medium text-gray-700">PocketJSON Endpoint</label>
<input id="pocketJsonEndpoint" type="text" class="w-full p-2 transition-all border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500" placeholder="https://pocketjson.pluja.dev">
<small class="block mt-1 text-gray-600">Default: https://pocketjson.pluja.dev</small>
</div>
<div>
<label class="block mb-2 font-medium text-gray-700">PocketJSON API Key (optional)</label>
<input id="pocketJsonApiKey" type="text" class="w-full p-2 font-mono text-sm transition-all border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500" placeholder="Your PocketJSON API Key">
<small class="block mt-1 text-gray-600">Required for permanent shares</small>
</div>
</div>
</details>
</div>
<div class="mb-6">
<details>
<summary class="mb-2 font-semibold cursor-pointer text-md hover:text-blue-600">
Language Management
</summary>
<div class="pl-4">
<div class="flex gap-3 mb-4">
<input id="newLanguage" type="text" class="flex-grow p-3 transition-all border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500" placeholder="Add new language">
<button id="addLanguage" class="px-6 text-white transition-all bg-green-500 rounded-lg hover:bg-green-600">Add</button>
</div>
<div id="languageList" class="overflow-y-auto border border-gray-200 rounded-lg max-h-40"></div>
</div>
</details>
</div>
</div>
<div class="sticky bottom-0 pt-4 bg-white">
<button id="saveConfig" class="w-full py-2 font-medium text-white transition-all bg-blue-600 rounded-lg hover:bg-blue-700">Save</button>
</div>
</div>
</div>
<!-- END SETTINGS MODAL -->
<div class="container max-w-4xl px-4 py-12 mx-auto">
<div class="p-8 bg-white shadow-lg rounded-2xl">
<div class="flex items-center justify-between mb-8">
<button id="editConfigBtn" class="flex items-center gap-2 px-4 py-2 text-white transition-all bg-blue-600 rounded-lg hover:bg-blue-700">
<span>⚙️</span>
<span class="font-medium">Settings</span>
</button>
<h1 class="text-xl font-bold text-gray-800">🤖 LLM Text Tool</h1>
</div>
<textarea id="inputText" rows="6" class="w-full p-4 mb-6 transition-all border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500" placeholder="Paste website URL or text here..."></textarea>
<div class="grid hidden grid-cols-1 gap-6 mb-6 md:grid-cols-2 languageSelectors">
<div>
<label class="block mb-2 font-medium text-gray-700">Input Language</label>
<select id="inputLanguage" class="w-full p-3 transition-all border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
<option value="auto">Auto Detect</option>
</select>
</div>
<div>
<label class="block mb-2 font-medium text-gray-700">Output Language</label>
<select id="outputLanguage" class="w-full p-3 transition-all border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"></select>
</div>
</div>
<div id="correctionOptions" class="hidden mb-6 space-y-4">
<div>
<label class="block mb-2 font-medium text-gray-700">Correction Level</label>
<select id="correctionLevel" class="w-full p-3 transition-all border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
<option value="low">Light (Minor Changes)</option>
<option value="medium">Medium (Moderate Changes)</option>
<option value="high">High (Major Changes)</option>
</select>
</div>
<div>
<label class="block mb-2 font-medium text-gray-700">Style</label>
<select id="correctionStyle" class="w-full p-3 transition-all border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
<option value="formal">Formal</option>
<option value="informal">Informal</option>
<option value="academic">Academic</option>
<option value="business">Business</option>
</select>
</div>
</div>
<div class="mb-6">
<label class="block mb-3 font-medium text-gray-700">Task</label>
<div class="grid grid-cols-1 gap-4 md:grid-cols-3">
<label class="relative group">
<input type="radio" name="task" value="translate" class="absolute opacity-0 peer">
<div class="flex items-center justify-center gap-2 p-2 transition-all duration-200 border-2 border-gray-200 cursor-pointer rounded-xl hover:border-green-200 hover:bg-green-50 peer-checked:border-green-500 peer-checked:bg-green-50 peer-checked:ring-2 peer-checked:ring-green-500">
<span class="text-lg font-medium text-green-600">✨ Translate</span>
</div>
</label>
<label class="relative group">
<input type="radio" name="task" value="summarize" class="absolute opacity-0 peer">
<div class="flex items-center justify-center gap-2 p-2 transition-all duration-200 border-2 border-gray-200 cursor-pointer rounded-xl hover:border-blue-200 hover:bg-blue-50 peer-checked:border-blue-500 peer-checked:bg-blue-50 peer-checked:ring-2 peer-checked:ring-blue-500">
<span class="text-lg font-medium text-blue-600">📝 Summarize</span>
</div>
</label>
<label class="relative group">
<input type="radio" name="task" value="correct" class="absolute opacity-0 peer">
<div class="flex items-center justify-center gap-2 p-2 transition-all duration-200 border-2 border-gray-200 cursor-pointer rounded-xl hover:border-purple-200 hover:bg-purple-50 peer-checked:border-purple-500 peer-checked:bg-purple-50 peer-checked:ring-2 peer-checked:ring-purple-500">
<span class="text-lg font-medium text-purple-600">✓ Correct</span>
</div>
</label>
</div>
</div>
<button id="processBtn" class="hidden w-full py-4 text-lg font-medium text-white transition-all bg-yellow-500 rounded-xl hover:bg-yellow-600">
Process Text
</button>
</div>
<div id="resultContainer" class="hidden mt-8">
<h2 class="mb-4 text-2xl font-bold">Result</h2>
<div class="p-8 bg-white shadow-lg rounded-2xl">
<div id="resultContent" class="mx-auto prose-sm prose sm:prose lg:prose-lg xl:prose-xl"></div>
</div>
</div>
</div>
<footer class="py-6 text-center text-gray-600">
<a class="transition-colors hover:text-gray-900" href="https://github.com/pluja/llm-language-tool">Open Source</a> project by <a class="transition-colors hover:text-gray-900" href="https://pluja.dev">pluja</a>
</footer>
<script src="js/marked.min.js"></script>
<script src="js/languageManager.js"></script>
<script src="js/config.js"></script>
<script src="js/ui.js"></script>
<script src="js/textProcessor.js"></script>
<script src="js/main.js"></script>
<script>
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/sw.js')
.then(registration => {
console.log('ServiceWorker registration successful');
})
.catch(err => {
console.log('ServiceWorker registration failed: ', err);
});
});
}
</script>
</body>
</html>