@@ -90,195 +90,206 @@ function handleRootRequest() {
90
90
<!-- 文件链接文本框 -->
91
91
<div class="form-group mb-3" style="display: none;"> <!-- 初始隐藏 -->
92
92
<textarea class="form-control" id="fileLink" readonly></textarea>
93
- </div>
94
- <!-- 上传中的提示 -->
95
- <div id="uploadingText" style="display: none; text-align: center;">文件上传中...</div>
96
- </form>
93
+ </div>
94
+ <!-- 上传中的提示 -->
95
+ <div id="uploadingText" style="display: none; text-align: center;">文件上传中...</div>
96
+ <!-- 压缩中的提示 -->
97
+ <div id="compressingText" style="display: none; text-align: center;">图片压缩中...</div>
98
+ </form>
97
99
</div>
98
100
<p style="font-size: 14px; text-align: center;">
99
101
项目开源于 GitHub - <a href="https://github.com/0-RTT/telegraph" target="_blank" rel="noopener noreferrer">0-RTT/telegraph</a>
100
102
</p>
101
103
</div>
102
104
<script>
103
- $(document).ready(function () {
104
- let originalImageURL = '';
105
-
106
- // 初始化文件上传
107
- initFileInput();
108
-
109
- // 文件上传初始化函数
110
- function initFileInput() {
111
- $("#fileInput").fileinput({
112
- theme: 'fa',
113
- language: 'zh',
114
- dropZoneEnabled: true,
115
- browseOnZoneClick: true,
116
- dropZoneTitle: "拖拽文件到这里...",
117
- dropZoneClickTitle: "",
118
- browseClass: "btn btn-light",
119
- uploadClass: "btn btn-light",
120
- removeClass: "btn btn-light",
121
- showUpload: false,
122
- layoutTemplates: {
123
- actionZoom: '',
124
- },
125
- }).on('filebatchselected', handleFileSelection)
126
- .on('fileclear', handleFileClear); // 添加移除按钮点击事件处理程序
127
- }
105
+ $(document).ready(function() {
106
+ let originalImageURL = '';
128
107
129
- // 处理文件选择事件
130
- async function handleFileSelection() {
131
- const selectedInterface = $('#interfaceSelector').val();
132
- const file = $('#fileInput')[0].files[0];
133
-
134
- // 检查文件大小是否大于5MB
135
- if (file && file.size > 5 * 1024 * 1024) {
136
- if (file.type === 'image/gif') {
137
- toastr.error('GIF 文件必须≤5MB');
138
- } else {
139
- // 对于大于5MB的非GIF图片,执行压缩处理
140
- const compressedFile = await compressImage(file);
141
- await uploadFile(compressedFile); // 上传处理后的文件
142
- }
143
- return;
144
- }
108
+ // 初始化文件上传
109
+ initFileInput();
145
110
146
- // 对于小于等于5MB的GIF和图片,直接上传
147
- if (file && (file.type === 'image/gif' || file.type.includes('image/'))) {
148
- await uploadFile(file);
149
- }
150
- }
111
+ // 文件上传初始化函数
112
+ function initFileInput() {
113
+ $("#fileInput").fileinput({
114
+ theme: 'fa',
115
+ language: 'zh',
116
+ dropZoneEnabled: true,
117
+ browseOnZoneClick: true,
118
+ dropZoneTitle: "拖拽文件到这里...",
119
+ dropZoneClickTitle: "",
120
+ browseClass: "btn btn-light",
121
+ uploadClass: "btn btn-light",
122
+ removeClass: "btn btn-light",
123
+ showUpload: false,
124
+ layoutTemplates: {
125
+ actionZoom: '',
126
+ },
127
+ }).on('filebatchselected', handleFileSelection)
128
+ .on('fileclear', handleFileClear);
129
+ }
151
130
152
- // 上传文件函数
153
- async function uploadFile(file) {
154
- try {
155
- $('#uploadingText').show();
156
- const formData = new FormData($('#uploadForm')[0]);
157
- formData.set('file', file, file.name);
158
- const uploadResponse = await fetch('/upload', { method: 'POST', body: formData });
159
- originalImageURL = await handleUploadResponse(uploadResponse);
160
- $('#fileLink').val(originalImageURL);
161
- $('.form-group').show();
162
- adjustTextareaHeight($('#fileLink')[0]);
163
- } catch (error) {
164
- console.error('上传文件时出现错误:', error);
165
- $('#fileLink').val('文件上传失败!');
166
- } finally {
167
- $('#uploadingText').hide();
168
- }
131
+ // 处理接口选择器变更事件
132
+ $('#interfaceSelector').change(function() {
133
+ const selectedInterface = $(this).val();
134
+ let acceptTypes = '';
135
+
136
+ switch (selectedInterface) {
137
+ case 'tg':
138
+ acceptTypes = 'image/gif,image/jpeg,image/png';
139
+ break;
169
140
}
141
+ $('#fileInput').attr('accept', acceptTypes);
142
+ }).trigger('change');
170
143
171
- // 处理上传响应
172
- async function handleUploadResponse(response) {
173
- if (response.ok) {
174
- const result = await response.json();
175
- return result.data;
144
+ // 处理文件选择事件
145
+ async function handleFileSelection() {
146
+ const selectedInterface = $('#interfaceSelector').val();
147
+ const file = $('#fileInput')[0].files[0];
148
+
149
+ if (file && file.size > 5 * 1024 * 1024) {
150
+ if (file.type === 'image/gif') {
151
+ toastr.error('GIF 文件必须≤5MB');
176
152
} else {
177
- return '文件上传失败!';
153
+ const compressedFile = await compressImage(file);
154
+ await uploadFile(compressedFile);
178
155
}
156
+ return;
179
157
}
180
158
181
- // 处理移除按钮点击事件
182
- function handleFileClear(event) {
183
- // 清空文本框的内容
184
- $('#fileLink').val('');
159
+ if (file && (file.type === 'image/gif' || file.type.includes('image/'))) {
160
+ await uploadFile(file);
161
+ }
162
+ }
185
163
186
- // 上传完成后调整文本框高度
164
+ // 处理上传文件函数
165
+ async function uploadFile(file) {
166
+ try {
167
+ $('#uploadingText').show();
168
+ const formData = new FormData($('#uploadForm')[0]);
169
+ formData.set('file', file, file.name);
170
+ const uploadResponse = await fetch('/upload', { method: 'POST', body: formData });
171
+ originalImageURL = await handleUploadResponse(uploadResponse);
172
+ $('#fileLink').val(originalImageURL);
173
+ $('.form-group').show();
187
174
adjustTextareaHeight($('#fileLink')[0]);
175
+ } catch (error) {
176
+ console.error('上传文件时出现错误:', error);
177
+ $('#fileLink').val('文件上传失败!');
178
+ } finally {
179
+ $('#uploadingText').hide();
180
+ }
181
+ }
188
182
189
- // 隐藏按钮和文本框
190
- hideButtonsAndTextarea();
183
+ // 处理上传响应函数
184
+ async function handleUploadResponse(response) {
185
+ if (response.ok) {
186
+ const result = await response.json();
187
+ return result.data;
188
+ } else {
189
+ return '文件上传失败!';
191
190
}
191
+ }
192
192
193
- // 根据接口选择器的值设置文件类型接受属性
194
- $('#interfaceSelector').change(function () {
195
- const selectedInterface = $(this).val();
196
- let acceptTypes = '';
197
-
198
- switch (selectedInterface) {
199
- case 'tg':
200
- acceptTypes = 'image/gif,image/jpeg,image/png';
201
- break;
202
- }
203
- $('#fileInput').attr('accept', acceptTypes);
204
- }).trigger('change');
205
-
206
- // 处理按钮点击事件
207
- $('#urlBtn, #bbcodeBtn, #markdownBtn').on('click', function () {
208
- const fileLink = originalImageURL.trim();
209
- if (fileLink !== '') {
210
- let formattedLink;
211
- switch ($(this).attr('id')) {
193
+ // 处理按钮点击事件
194
+ $('#urlBtn, #bbcodeBtn, #markdownBtn').on('click', function() {
195
+ const fileLink = originalImageURL.trim();
196
+ if (fileLink !== '') {
197
+ let formattedLink;
198
+ switch ($(this).attr('id')) {
199
+ case 'urlBtn':
200
+ formattedLink = fileLink;
201
+ break
212
202
case 'urlBtn':
213
203
formattedLink = fileLink;
214
- break
215
- case 'urlBtn':
216
- formattedLink = fileLink;
217
- break;
218
- case 'bbcodeBtn':
219
- formattedLink = '[img]' + fileLink + '[/img]';
220
- break;
221
- case 'markdownBtn':
222
- formattedLink = '';
223
- break;
224
- default:
225
- formattedLink = fileLink;
226
- }
227
- $('#fileLink').val(formattedLink);
228
- adjustTextareaHeight($('#fileLink')[0]); // 调整文本框高度
229
- copyToClipboardWithToastr(formattedLink);
230
- }
231
- });
232
-
233
- // 自动调整文本框高度函数
234
- function adjustTextareaHeight(textarea) {
235
- textarea.style.height = '1px'; // 先将高度设置为最小值
236
- textarea.style.height = (textarea.scrollHeight) + 'px'; // 根据内容重新设置高度
237
- }
238
-
239
- // 复制文本到剪贴板,并显示 toastr 提示框
240
- function copyToClipboardWithToastr(text) {
241
- const input = document.createElement('input');
242
- input.setAttribute('value', text);
243
- document.body.appendChild(input);
244
- input.select();
245
- document.execCommand('copy');
246
- document.body.removeChild(input);
247
-
248
- toastr.success('已复制到剪贴板', '', { timeOut: 300 });
249
- }
250
-
251
- // 隐藏按钮和文本框
252
- function hideButtonsAndTextarea() {
253
- $('#urlBtn, #bbcodeBtn, #markdownBtn, #fileLink').parent('.form-group').hide();
254
- }
255
-
256
- // 图片压缩函数
257
- function compressImage(file) {
258
- return new Promise((resolve) => {
259
- const quality = 0.6;
260
- const reader = new FileReader();
261
- reader.onload = ({ target: { result: src } }) => {
262
- const image = new Image();
263
- image.onload = async () => {
264
- const canvas = document.createElement('canvas');
265
- canvas.width = image.width;
266
- canvas.height = image.height;
267
- const ctx = canvas.getContext('2d');
268
- ctx.drawImage(image, 0, 0, image.width, image.height);
269
- const compressedDataURL = canvas.toDataURL('image/jpeg', quality);
270
- const blob = await fetch(compressedDataURL).then(res => res.blob());
271
- const compressedFile = new File([blob], file.name, { type: 'image/jpeg' });
272
-
273
- resolve(compressedFile);
274
- };
275
- image.src = src;
276
- };
277
- reader.readAsDataURL(file);
278
- });
204
+ break;
205
+ case 'bbcodeBtn':
206
+ formattedLink = '[img]' + fileLink + '[/img]';
207
+ break;
208
+ case 'markdownBtn':
209
+ formattedLink = '';
210
+ break;
211
+ default:
212
+ formattedLink = fileLink;
279
213
}
214
+ $('#fileLink').val(formattedLink);
215
+ adjustTextareaHeight($('#fileLink')[0]);
216
+ copyToClipboardWithToastr(formattedLink);
217
+ }
218
+ });
219
+
220
+ // 处理移除按钮点击事件
221
+ function handleFileClear(event) {
222
+ $('#fileLink').val('');
223
+ adjustTextareaHeight($('#fileLink')[0]);
224
+ hideButtonsAndTextarea();
225
+ }
226
+
227
+ // 自动调整文本框高度函数
228
+ function adjustTextareaHeight(textarea) {
229
+ textarea.style.height = '1px';
230
+ textarea.style.height = (textarea.scrollHeight) + 'px';
231
+ }
232
+
233
+ // 复制文本到剪贴板,并显示 toastr 提示框
234
+ function copyToClipboardWithToastr(text) {
235
+ const input = document.createElement('input');
236
+ input.setAttribute('value', text);
237
+ document.body.appendChild(input);
238
+ input.select();
239
+ document.execCommand('copy');
240
+ document.body.removeChild(input);
241
+ toastr.success('已复制到剪贴板', '', { timeOut: 300 });
242
+ }
243
+
244
+ // 隐藏按钮和文本框
245
+ function hideButtonsAndTextarea() {
246
+ $('#urlBtn, #bbcodeBtn, #markdownBtn, #fileLink').parent('.form-group').hide();
247
+ }
248
+
249
+ // 处理图片压缩事件
250
+ async function compressImage(file, quality = 0.6, maxResolution = 20000000) {
251
+ $('#compressingText').show();
252
+
253
+ return new Promise((resolve) => {
254
+ const image = new Image();
255
+ image.onload = () => {
256
+ const width = image.width;
257
+ const height = image.height;
258
+
259
+ const resolution = width * height;
260
+
261
+ let scale = 1;
262
+ if (resolution > maxResolution) {
263
+ scale = Math.sqrt(maxResolution / resolution);
264
+ }
265
+
266
+ const targetWidth = Math.round(width * scale);
267
+ const targetHeight = Math.round(height * scale);
268
+
269
+ const canvas = document.createElement('canvas');
270
+ const ctx = canvas.getContext('2d');
271
+
272
+ canvas.width = targetWidth;
273
+ canvas.height = targetHeight;
274
+ ctx.drawImage(image, 0, 0, targetWidth, targetHeight);
275
+
276
+ canvas.toBlob((blob) => {
277
+ const compressedFile = new File([blob], file.name, { type: 'image/jpeg' });
278
+ $('#compressingText').hide();
279
+ resolve(compressedFile);
280
+ }, 'image/jpeg', quality);
281
+ };
282
+
283
+ const reader = new FileReader();
284
+ reader.onload = (event) => {
285
+ image.src = event.target.result;
286
+ };
287
+ reader.readAsDataURL(file);
280
288
});
281
- </script>
289
+ }
290
+ });
291
+
292
+ </script>
282
293
283
294
</body>
284
295
</html>
@@ -358,4 +369,3 @@ return new Response(html, { headers: { 'Content-Type': 'text/html;charset=UTF-8'
358
369
359
370
return url ;
360
371
}
361
-
0 commit comments