247247//@grant GM_download
248248//@match https://x.com/*
249249//@match https://twitter.com/*
250- //@version 2025.12.02.1433
250+ //@version 2025.12.02.01
251251//@created 2025-03-11 08:11:29
252252//@modified 2025-12-02 14:33:28
253253//@require https://cdnjs.cloudflare.com/ajax/libs/jszip/3.7.1/jszip.min.js
259259 * File: twitter-media-downloader.user.js
260260 * Project: UserScripts
261261 * File Created: 2025/03/11,Tuesday 08:11:41
262- * Author: goemon2017,天音,Tiande,人民的勤务员@ChinaGodMan (china.qinwuyuan@gmail.com)
262+ * Author: goemon2017,天音,Tiande,molanp, 人民的勤务员@ChinaGodMan (china.qinwuyuan@gmail.com)
263263 * -----
264- * Last Modified: 2025/04/28,Monday 17:19:11
265- * Last Modified: 2025/04/28,Monday 17:19:11
264+ * Last Modified: 2025/12/02,Tuesday 15:48:18
265+ * Last Modified: 2025/12/02,Tuesday 15:48:18
266266 * Modified By: 人民的勤务员@ChinaGodMan (china.qinwuyuan@gmail.com)
267267 * License: MIT License
268- * Copyright © 2024 - 2025 ChinaGodMan,Inc
269- * -----
270- * Last Modified: 2025/12/02,Tuesday 14:33:28
271- * Last Modified: 2025/12/02,Tuesday 14:33:28
272- * Modified By: @molanp
273- * License: MIT License
274- * Copyright © 2025 molanp
268+ * Copyright © 2024 - 2025 ChinaGodMan & molanp,Inc
275269 */
276270
277271//! 修复代码来自:goemon2017:https://greasyfork.org/scripts/423001/discussions/296626#comment-589742
@@ -405,10 +399,10 @@ const TMD = (function () {
405399btn_down . onclick = ( ) => this . click ( btn_down , status_id , is_exist )
406400} )
407401} ,
408- selectTweetDialog :function ( originalUser , quotedUser ) {
402+ selectTweetDialog :function ( originalUser , quotedUser ) {
409403return new Promise ( ( resolve ) => {
410404// 创建遮罩层
411- const overlay = document . createElement ( 'div' ) ;
405+ const overlay = document . createElement ( 'div' )
412406overlay . style . cssText = `
413407 position: fixed;
414408 left: 0;
@@ -420,40 +414,40 @@ const TMD = (function () {
420414 display: flex;
421415 justify-content: center;
422416 align-items: center;
423- ` ;
417+ `
424418
425419// 创建对话框
426- const dialog = document . createElement ( 'div' ) ;
420+ const dialog = document . createElement ( 'div' )
427421dialog . style . cssText = `
428422 background: white;
429423 border-radius: 16px;
430424 padding: 24px;
431425 width: 400px;
432426 box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
433427 font-family: system-ui, -apple-system, sans-serif;
434- ` ;
428+ `
435429
436430// 添加标题
437- const title = document . createElement ( 'h3' ) ;
438- title . textContent = '选择要下载的媒体' ;
431+ const title = document . createElement ( 'h3' )
432+ title . textContent = ` ${ lang . choose } `
439433title . style . cssText = `
440434 margin-top: 0;
441435 margin-bottom: 20px;
442436 text-align: center;
443437 color: #0f1419;
444- ` ;
438+ `
445439
446440// 添加选项按钮容器
447- const buttonsContainer = document . createElement ( 'div' ) ;
441+ const buttonsContainer = document . createElement ( 'div' )
448442buttonsContainer . style . cssText = `
449443 display: flex;
450444 flex-direction: column;
451445 gap: 12px;
452- ` ;
446+ `
453447
454448// 原始推文按钮
455- const originalBtn = document . createElement ( 'button' ) ;
456- originalBtn . textContent = `原始推文 (by${ originalUser } )` ;
449+ const originalBtn = document . createElement ( 'button' )
450+ originalBtn . textContent = `${ lang . original } (by${ originalUser } )`
457451originalBtn . style . cssText = `
458452 background: #1DA1F2;
459453 color: white;
@@ -464,21 +458,21 @@ const TMD = (function () {
464458 font-weight: 600;
465459 cursor: pointer;
466460 transition: background 0.2s;
467- ` ;
461+ `
468462originalBtn . addEventListener ( 'mouseenter' , ( ) => {
469- originalBtn . style . background = '#1a91da' ;
470- } ) ;
463+ originalBtn . style . background = '#1a91da'
464+ } )
471465originalBtn . addEventListener ( 'mouseleave' , ( ) => {
472- originalBtn . style . background = '#1DA1F2' ;
473- } ) ;
466+ originalBtn . style . background = '#1DA1F2'
467+ } )
474468originalBtn . addEventListener ( 'click' , ( ) => {
475- resolve ( 'original' ) ;
476- document . body . removeChild ( overlay ) ;
477- } ) ;
469+ resolve ( 'original' )
470+ document . body . removeChild ( overlay )
471+ } )
478472
479473// 引用推文按钮
480- const quotedBtn = document . createElement ( 'button' ) ;
481- quotedBtn . textContent = `引用推文 (by${ quotedUser } )` ;
474+ const quotedBtn = document . createElement ( 'button' )
475+ quotedBtn . textContent = `${ lang . quote } (by${ quotedUser } )`
482476quotedBtn . style . cssText = `
483477 background: #fff;
484478 color: #1DA1F2;
@@ -489,21 +483,21 @@ const TMD = (function () {
489483 font-weight: 600;
490484 cursor: pointer;
491485 transition: all 0.2s;
492- ` ;
486+ `
493487quotedBtn . addEventListener ( 'mouseenter' , ( ) => {
494- quotedBtn . style . background = '#f0f8ff' ;
495- } ) ;
488+ quotedBtn . style . background = '#f0f8ff'
489+ } )
496490quotedBtn . addEventListener ( 'mouseleave' , ( ) => {
497- quotedBtn . style . background = '#fff' ;
498- } ) ;
491+ quotedBtn . style . background = '#fff'
492+ } )
499493quotedBtn . addEventListener ( 'click' , ( ) => {
500- resolve ( 'quoted' ) ;
501- document . body . removeChild ( overlay ) ;
502- } ) ;
494+ resolve ( 'quoted' )
495+ document . body . removeChild ( overlay )
496+ } )
503497
504498// 取消按钮
505- const cancelBtn = document . createElement ( 'button' ) ;
506- cancelBtn . textContent = '取消' ;
499+ const cancelBtn = document . createElement ( 'button' )
500+ cancelBtn . textContent = ` ${ lang . cancel } `
507501cancelBtn . style . cssText = `
508502 background: transparent;
509503 color: #657786;
@@ -512,29 +506,29 @@ const TMD = (function () {
512506 font-size: 14px;
513507 cursor: pointer;
514508 margin-top: 8px;
515- ` ;
509+ `
516510cancelBtn . addEventListener ( 'click' , ( ) => {
517- resolve ( null ) ;
518- document . body . removeChild ( overlay ) ;
519- } ) ;
511+ resolve ( null )
512+ document . body . removeChild ( overlay )
513+ } )
520514
521515// 组装对话框
522- buttonsContainer . appendChild ( originalBtn ) ;
523- buttonsContainer . appendChild ( quotedBtn ) ;
524- buttonsContainer . appendChild ( cancelBtn ) ;
525- dialog . appendChild ( title ) ;
526- dialog . appendChild ( buttonsContainer ) ;
527- overlay . appendChild ( dialog ) ;
528- document . body . appendChild ( overlay ) ;
516+ buttonsContainer . appendChild ( originalBtn )
517+ buttonsContainer . appendChild ( quotedBtn )
518+ buttonsContainer . appendChild ( cancelBtn )
519+ dialog . appendChild ( title )
520+ dialog . appendChild ( buttonsContainer )
521+ overlay . appendChild ( dialog )
522+ document . body . appendChild ( overlay )
529523
530524// 点击遮罩层外部关闭对话框
531525overlay . addEventListener ( 'click' , ( e ) => {
532526if ( e . target === overlay ) {
533- resolve ( null ) ;
534- document . body . removeChild ( overlay ) ;
527+ resolve ( null )
528+ document . body . removeChild ( overlay )
535529}
536- } ) ;
537- } ) ;
530+ } )
531+ } )
538532} ,
539533click :async function ( btn , status_id , is_exist , index ) {
540534if ( btn . classList . contains ( 'loading' ) ) return
@@ -545,7 +539,7 @@ const TMD = (function () {
545539
546540// 检查是否存在引用推文
547541let hasQuotedMedia = json . quoted_status_result ?. result ?. legacy ?. media ||
548- json . quoted_status_result ?. result ?. legacy ?. extended_entities ?. media
542+ json . quoted_status_result ?. result ?. legacy ?. extended_entities ?. media
549543
550544let tweet
551545let user
@@ -943,10 +937,10 @@ const TMD = (function () {
943937} ,
944938
945939language :{
946- en :{ download :'Download' , completed :'Download Completed' , settings :'Settings' , dialog :{ title :'Download Settings' , save :'Save' , save_history :'Remember download history' , clear_history :'(Clear)' , clear_confirm :'Clear download history?' , show_sensitive :'Always show sensitive content' , pattern :'File Name Pattern' } , enable_packaging :'Package multiple files into a ZIP' } ,
947- ja :{ download :'ダウンロード' , completed :'ダウンロード完了' , settings :'設定' , dialog :{ title :'ダウンロード設定' , save :'保存' , save_history :'ダウンロード履歴を保存する' , clear_history :'(クリア)' , clear_confirm :'ダウンロード履歴を削除する?' , show_sensitive :'センシティブな内容を常に表示する' , pattern :'ファイル名パターン' } , enable_packaging :'複数ファイルを ZIP にパッケージ化する' } ,
948- zh :{ download :'下载' , completed :'下载完成' , settings :'设置' , dialog :{ title :'下载设置' , save :'保存' , save_history :'保存下载记录' , clear_history :'(清除)' , clear_confirm :'确认要清除下载记录?' , show_sensitive :'自动显示敏感的内容' , pattern :'文件名格式' } , enable_packaging :'多文件打包成 ZIP' } ,
949- 'zh-Hant' :{ download :'下載' , completed :'下載完成' , settings :'設置' , dialog :{ title :'下載設置' , save :'保存' , save_history :'保存下載記錄' , clear_history :'(清除)' , clear_confirm :'確認要清除下載記錄?' , show_sensitive :'自動顯示敏感的内容' , pattern :'文件名規則' } , enable_packaging :'多文件打包成 ZIP' }
940+ en :{ download :'Download' , completed :'Download Completed' , settings :'Settings' , dialog :{ title :'Download Settings' , save :'Save' , save_history :'Remember download history' , clear_history :'(Clear)' , clear_confirm :'Clear download history?' , show_sensitive :'Always show sensitive content' , pattern :'File Name Pattern' } , enable_packaging :'Package multiple files into a ZIP' , original : 'Original Tweet' , quote : 'Quoted Tweet' , cancel : 'Cancel' , choose : 'Select media to download' } ,
941+ ja :{ download :'ダウンロード' , completed :'ダウンロード完了' , settings :'設定' , dialog :{ title :'ダウンロード設定' , save :'保存' , save_history :'ダウンロード履歴を保存する' , clear_history :'(クリア)' , clear_confirm :'ダウンロード履歴を削除する?' , show_sensitive :'センシティブな内容を常に表示する' , pattern :'ファイル名パターン' } , enable_packaging :'複数ファイルを ZIP にパッケージ化する' , original : '元のツイート' , quote : '引用ツイート' , cancel : 'キャンセル' , choose : 'メディアを選択' } ,
942+ zh :{ download :'下载' , completed :'下载完成' , settings :'设置' , dialog :{ title :'下载设置' , save :'保存' , save_history :'保存下载记录' , clear_history :'(清除)' , clear_confirm :'确认要清除下载记录?' , show_sensitive :'自动显示敏感的内容' , pattern :'文件名格式' } , enable_packaging :'多文件打包成 ZIP' , original : '原始推文' , quote : '引用推文' , cancel : '取消' , choose : '选择要下载的媒体' } ,
943+ 'zh-Hant' :{ download :'下載' , completed :'下載完成' , settings :'設置' , dialog :{ title :'下載設置' , save :'保存' , save_history :'保存下載記錄' , clear_history :'(清除)' , clear_confirm :'確認要清除下載記錄?' , show_sensitive :'自動顯示敏感的内容' , pattern :'文件名規則' } , enable_packaging :'多文件打包成 ZIP' , original : '原始推文' , quote : '引用推文' , cancel : '取消' , choose : '選擇要下載的媒體' }
950944} ,
951945css :`
952946.tmd-down {margin-left: 12px; order: 99;}