|
255 | 255 | // Open file: Ctrl+O (Windows/Linux) or Cmd+O (Mac) |
256 | 256 | if (modKey && e.key === 'o') { |
257 | 257 | e.preventDefault(); |
258 | | - if (!this.editor.value.trim()) { |
259 | | - const input = document.createElement('input'); |
260 | | - input.type = 'file'; |
261 | | - input.accept = '.txt'; |
262 | | - input.onchange = (event) => { |
263 | | - const file = event.target.files[0]; |
264 | | - if (file) { |
265 | | - const reader = new FileReader(); |
266 | | - reader.onload = () => { |
267 | | - this.editor.value = reader.result; |
268 | | - this.saveText(); |
269 | | - this.updateCount(); |
270 | | - this.updateFade(); |
271 | | - }; |
272 | | - reader.readAsText(file); |
273 | | - } |
274 | | - input.value = null; |
275 | | - }; |
276 | | - input.click(); |
277 | | - } |
| 258 | + this.openFile(); |
278 | 259 | return; |
279 | 260 | } |
280 | 261 |
|
|
305 | 286 | this.fullscreen(); |
306 | 287 | return; |
307 | 288 | } |
| 289 | + |
| 290 | + // Focus editor on any other keydown |
| 291 | + this.editor.focus(); |
308 | 292 | }); |
309 | 293 |
|
310 | 294 | // Update text area fade on scroll |
311 | 295 | this.editor.addEventListener('scroll', () => this.updateFade(), { passive: true }); |
312 | 296 |
|
313 | | - // Always focus on editor on keydown |
314 | | - window.addEventListener('keydown', () => { |
315 | | - this.editor.focus(); |
316 | | - }); |
317 | | - |
318 | 297 | window.addEventListener('resize', () => this.updateFade(), { passive: true }); |
319 | 298 |
|
320 | 299 | // Control buttons |
|
425 | 404 | return `~${days} day${days !== 1 ? 's' : ''}`; |
426 | 405 | } |
427 | 406 | } |
| 407 | + |
428 | 408 | updateCount() { |
429 | 409 | const text = this.editor.value; |
430 | 410 | const wordCount = this.getWordsCount(text); |
|
491 | 471 | } |
492 | 472 |
|
493 | 473 | // Actions |
| 474 | + openFile() { |
| 475 | + const input = document.createElement('input'); |
| 476 | + input.type = 'file'; |
| 477 | + input.accept = '.txt'; |
| 478 | + input.onchange = (event) => { |
| 479 | + const file = event.target.files[0]; |
| 480 | + if (file) { |
| 481 | + if (this.editor.value.trim() && !confirm('Are you sure you want to clear all text and load the selected file?')) { |
| 482 | + return; |
| 483 | + } |
| 484 | + const reader = new FileReader(); |
| 485 | + reader.onload = () => { |
| 486 | + this.editor.value = reader.result; |
| 487 | + this.saveText(); |
| 488 | + this.updateCount(); |
| 489 | + this.updateFade(); |
| 490 | + }; |
| 491 | + reader.readAsText(file); |
| 492 | + } |
| 493 | + }; |
| 494 | + input.click(); |
| 495 | + input.remove(); |
| 496 | + } |
| 497 | + |
494 | 498 | download() { |
495 | | - const timestamp = new Date().toISOString().slice(0, 16).replace(/[:T]/g, m => m === 'T' ? '_' : '-'); |
| 499 | + const timestamp = new Date().toISOString().slice(0, 16).replace(/[:T]/g, m => m === 'T' ? '_at_' : '-'); |
496 | 500 | const a = document.createElement('a'); |
497 | 501 | a.href = URL.createObjectURL(new Blob([this.editor.value], { type: 'text/plain' })); |
498 | | - a.download = `shiro_${timestamp}.txt`; |
| 502 | + a.download = `shiro_notes_on_${timestamp}.txt`; |
499 | 503 | a.click(); |
500 | 504 | URL.revokeObjectURL(a.href); |
501 | 505 | } |
|
0 commit comments