From ede669330aa8d4d5105f29a3daf8b69652f59087 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=91=E3=82=85=E3=80=82?= <54940894+HanayumiR@users.noreply.github.com> Date: Fri, 3 Oct 2025 17:22:01 +0900 Subject: [PATCH 01/23] Corrected the mistranslation --- _locales/ja/messages.json | 58 +++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/_locales/ja/messages.json b/_locales/ja/messages.json index fc4ed511..bf200b1a 100644 --- a/_locales/ja/messages.json +++ b/_locales/ja/messages.json @@ -17,8 +17,8 @@ "website": { "message": "ウェブサイト" }, "help": { "message": "ヘルプ", "description": "noun" }, "terms": { "message": "利用規約", "description": "Shortest word that you can find for Terms of service" }, - "privacy": { "message": "プライバシー", "description": "Shortest word that you can find for Privacy policy" }, - "about": { "message": "詳細" }, + "privacy": { "message": "プライバシーポリシー", "description": "Shortest word that you can find for Privacy policy" }, + "about": { "message": "もっと見る" }, "donate": { "message": "寄付" }, "home": { "message": "ホーム", "description": "This is for navbar menu. If no appropriate word, you can use something like Feed or Timeline" }, "notifications": { "message": "通知" }, @@ -39,7 +39,7 @@ "minutes": { "message": "分" }, "remove_poll": { "message": "投票を削除" }, "open_newtwitter": { "message": "新しいTwitterに切り替え" }, - "last_version": { "message": "最新版" }, + "last_version": { "message": "最新バージョン" }, "thank_you": { "message": "OldTwitterをインストールして頂きありがとうございます! 気に入っていただけると幸いです。 $AT1$Oldwitterの設定$AT2$もチェックしてみてください。", "placeholders": { @@ -54,7 +54,7 @@ "unfollow_user": { "message": "@$SCREEN_NAME$さんのフォローを解除", "example": "->Unfollow<- @CoolPerson2000", "placeholders": { "screen_name": { "content": "CoolPerson2000" } } }, "thank_you_follow": { "message": "フォローありがとうございます。" }, "loading_tweets": { "message": "ツイートを読み込み中..." }, - "retweeted": { "message": "さんがリツイート", "example": "CoolPerson2000 ->retweeted<-" }, + "retweeted": { "message": "がリツイート", "example": "CoolPerson2000 ->retweeted<-" }, "see_new_tweets": { "message": "新しいツイートを見る" }, "must2variants": { "message": "投票を行うには少なくとも2つ以上の選択肢が必要です。" }, "delete_all": { "message": "全て削除" }, @@ -121,7 +121,7 @@ "unmute": { "message": "ミュートを解除" }, "see_lists": { "message": "リストを見る" }, "stop_notifications": { "message": "通知をオフにする" }, - "receive_notifications": { "message": "通知する" }, + "receive_notifications": { "message": "通知をオンにする" }, "from_list": { "message": "リストに追加/削除" }, "share_user": { "message": "プロフィールを共有" }, "copy_profile_link": { "message": "プロフィールのリンクをコピー" }, @@ -281,14 +281,14 @@ "cancel": { "message": "取り消し" }, "youre_not_interested": { "message": "このツイートに興味がない" }, "autoplay_videos": { "message": "動画の自動再生" }, - "turn_on_retweets": { "message": "タイムライン上のリツイートを表示する" }, - "turn_off_retweets": { "message": "タイムライン上のリツイートを非表示にする" }, + "turn_on_retweets": { "message": "リツイートを表示する" }, + "turn_off_retweets": { "message": "リツイートを非表示にする" }, "you_can_reply": { "message": "ツイートに返信できます" }, "audience": { "message": "送信先" }, "who_can_reply": { "message": "返信できるアカウント" }, "people_you_follow": { "message": "フォローしているアカウント" }, "people_you_mention": { "message": "@ツイートしたアカウントのみ" }, - "new_version": { "message": "新しいバージョンに更新する" }, + "new_version": { "message": "最新アップデート バージョン" }, "display_sensitive_content": { "message": "センシティブなコンテンツを含む可能性のあるメディアを表示する" }, "is_private": { "message": "非公開にする" }, "s": { "message": "$NUMBER$秒", "description": "Short for 'second', like '1s' means 1 second", "placeholders": { "number": { "content": "1" } } }, @@ -356,7 +356,7 @@ }, "initialization": { "message": "初期化" }, "converting": { "message": "変換中" }, - "time_mode": { "message": "19時-9時の間にダークモードを有効化する" }, + "time_mode": { "message": "自動的にダークモードを切り替える" }, "show_original_images": { "message": "常に元の画質の画像を表示する" }, "hide_retweets": { "message": "リツイートを表示しない" }, "see_tweet_views": { "message": "ツイートの表示回数を表示する" }, @@ -365,11 +365,11 @@ "dont_autotranslate": { "message": "ツイートを自動で翻訳しない" }, "round_avatars": { "message": "丸いアイコン" }, "search_user_tweets": { "message": "ツイートを検索" }, - "no_tl_tweets": { "message": "あなたは誰もフォローしていないので、タイムラインにツイートはありません。アカウントをフォローするか、このページの右側と、OldTwitterの設定にある「タイムラインの種類」を「あなたへのおすすめ」に変更してください。" }, + "no_tl_tweets": { "message": "興味のあるアカウントをフォローしましょう。「いま」起きていることがここに表示されます。また、「タイムラインの種類」の「あなたへのおすすめ」もお試しください。" }, "replying_to": { "message": "返信先", "description": "Used for mention list. Use 'Mentions' if translation sounds bad in your language.", "example": "Replying to: - user1, - user2" }, "display": { "message": "ディスプレイ", "description": "Used for display settings (fonts, colors, style, etc)" }, "twitter_blue_checkmarks": { "message": "Twitter Blueの認証マークを表示する" }, - "retweet_hotkey_warn": { "message": "このツイートをリツイートしますか?確認を押すと、今後この警告はTキーを押してリツイートする際に表示されなくなります。" }, + "retweet_hotkey_warn": { "message": "このツイートをリツイートしますか?" }, "reply_btn": { "message": "返信", "description": "Used for reply button." }, "retweet_btn": { "message": "リツイート / 引用ツイート", "description": "Used for retweet menu button." }, "like_btn": { "message": "いいね / いいねを取り消し", "description": "Used for like button." }, @@ -378,21 +378,21 @@ "developer_mode": { "message": "開発者モード" }, "copy_user_id": { "message": "ユーザーIDをコピー" }, "copy_tweet_id": { "message": "ツイートIDをコピー" }, - "unfollowers": { "message": "フォローを解除されたユーザー", "description": "People that stopped following you" }, - "unfollowings": { "message": "フォローを解除したユーザー", "description": "People that you stopped following" }, - "no_unfollowers": { "message": "フォローを解除されたユーザーはいません" }, - "no_unfollowings": { "message": "フォローを解除したユーザーはいません" }, + "unfollowers": { "message": "あなたのフォローを解除したユーザー", "description": "People that stopped following you" }, + "unfollowings": { "message": "フォローを解除されたユーザー", "description": "People that you stopped following" }, + "no_unfollowers": { "message": "あなたのフォローを解除したユーザーはいません。" }, + "no_unfollowings": { "message": "フォローを解除したユーザーはいません。" }, "recent_unfollow_update": { "message": "最近更新されたフォローを解除したユーザー" }, "deleted_accounts": { "message": "アカウントを削除したユーザー" }, "open_tweet_newtwitter": { "message": "新しいTwitterのUIに切り替える" }, - "black_mode_link": { "message": "ブラックモード(OLED向け)", "note": "You can name this OLED mode too" }, + "black_mode_link": { "message": "ダークモードのカラーをブラックに変更する", "note": "You can name this OLED mode too" }, "custom_mode_link": { "message": "カスタムモード" }, "tweet_verb": { "message": "Tweet", "description": "Used for tweet verb.", "example": "->Tweet<- #itsokay" }, "do_you_want_to_tweet": { "message": "ツイートしますか? - \"$TWEET_TEXT$\"", "placeholders": { "tweet_text": { "content": "it's okay" } } }, "user_protected" : { "message": "このアカウントのツイートは非公開です。" }, "follow_to_see": { "message": "@$SCREEN_NAME$さんから承認された場合のみツイートを表示できます。承認をリクエストするには [フォローする] をクリックします。", "placeholders": { "screen_name": { "content": "dimden" } } }, - "copy_tweet_links_as": { "message": "ツイートのURLをコピーする際の形式:", "example": "->Copy links as<- vxtwitter.com" }, - "use_new_icon": { "message": "Faviconを鳥マークにする" }, + "copy_tweet_links_as": { "message": "ツイートを共有する際に使用するURL:", "example": "->Copy links as<- vxtwitter.com" }, + "use_new_icon": { "message": "ページの画像を青い鳥に切り替える" }, "update_timeline_automatically": { "message": "新着ツイートがある場合にタイムラインを自動更新する" }, "chrono_no_retweets": { "message": "新しい順(リツイートを除く)" }, "chrono_retweets": { "message": "新しい順(リツイートのみ)" }, @@ -407,14 +407,14 @@ "do_you_want_see_blocked_user": { "message": "ツイートを表示してもよろしいですか?これによって@$SCREEN_NAME$さんのブロックが解除されることはありません。", "placeholders": { "screen_name": { "content": "CoolPerson2000" } } }, "I_want_see_blocked_user": { "message": "閲覧する" }, "logout_title": { "message": "ログアウトしますか?" }, - "logout_desc_1": { "message": "OldTwitterは仕様上、Twitterにログインしている場合のみ動作します。" }, - "logout_desc_2": { "message": "他にTwitterにログインしているアカウントがない場合、ログインページに移動します。" }, + "logout_desc_1": { "message": "OldTwitterはTwitterにログインしている場合のみ利用できます。" }, + "logout_desc_2": { "message": "Twitterにログインしているアカウントがない場合はログインページに移動します。" }, "logout_button": { "message": "ログアウト" }, "disable_personalized_trends": { "message": "おすすめトレンドを無効にする" }, "show_bookmark_count": { "message": "ブックマーク数を表示する" }, "bookmarks_count": { "message": "ブックマーク", "description": "Used for bookmarks count." }, "remove_bookmark": { "message": "ブックマークを解除" }, - "hide_community_notes": { "message": "コミュニティ投稿を隠す" }, + "hide_community_notes": { "message": "コミュニティノート(BirdWatch)を表示しない" }, "disable_gif_autoplay": { "message": "GIF画像を自動再生しない" }, "hide_tweet": { "message": "ツイートを隠す" }, "unhide_tweet": { "message": "ツイートを表示する" }, @@ -456,16 +456,16 @@ "accessibility": { "message":"アクセシビリティ", "description":"Setting Text" }, "tweets_and_timeline": { "message":"ツイート・タイムライン", "description":"Setting Text" }, "dark_mode_setting": { "message": "ダークモード", "description":"Setting Text" }, - "old_twitter_look": {"message": "昔のTwitterの仕様", "description":"Setting Text" }, + "old_twitter_look": {"message": "外観設定", "description":"Setting Text" }, "content_you_see": {"message": "コンテンツ", "description":"Setting Text" }, - "use_old_style_reply": {"message": "旧式の返信を使用する" }, + "use_old_style_reply": {"message": "リプライ時に先頭にユーザーネームを配置する" }, "algov2": { "message": "あなたへのおすすめ" }, - "chrono_help": { "message": "新しい順のタイムライン(「フォロー」)は、最新のツイートやリツイートを新しい順に表示し、それ以外は何も追加しません。" }, + "chrono_help": { "message": "新しい順のタイムラインは、フォロー中のユーザーの最新のツイートやリツイートを新しい順に表示します。" }, "chrono_no_retweets_help": { "message": "最初のタイムラインと同じですが、リツイートを表示しません。" }, "chrono_retweets_help": { "message": "最初のタイムラインと同じですが、リツイートのみを表示します。" }, "chrono_social_help": { "message": "新しい順のタイムラインの中に、一部「誰かがいいねしたツイート」や「誰かがフォローしているアカウントのツイート」が追加されます。" }, "algo_help": { "message": "古いアルゴリズムのタイムラインは、Twitterがおすすめするツイートを表示します。 バージョン1はこのタイムラインの古いバージョンで、レート制限はないようですが(あるいは非常に大きい)、なぜツイートがタイムラインに追加されたのかについてのラベルはありません。" }, - "algov2_help": { "message": "アルゴリズムのタイムライン(あなたへのおすすめ)は、Twitterがおすすめするツイートを表示します。" }, + "algov2_help": { "message": "あなたへのおすすめは、Twitterがおすすめするツイートを表示します。" }, "import_settings": { "message": "設定内容をインポート" }, "export_settings": { "message": "設定内容をエクスポート" }, "import_style_settings": { "message": "スタイルをインポート" }, @@ -515,7 +515,7 @@ "unmute_user": { "message": "@$SCREEN_NAME$さんのミュートを解除", "placeholders": { "screen_name": { "content": "CoolPerson2000" } } }, "muted_user": { "message": "@$SCREEN_NAME$さんをミュートしました", "placeholders": { "screen_name": { "content": "CoolPerson2000" } } }, "unmuted_user": { "message": "@$SCREEN_NAME$さんのミュートを解除しました", "placeholders": { "screen_name": { "content": "CoolPerson2000" } } }, - "localize_digit":{ "message" : "アジアの4桁表記を使用する (日中韓のみ)", "description":"Non-CJK dont need to translate this message, just copy and paste"}, + "localize_digit":{ "message" : "数字の区切りを四桁区切りにする", "description":"Non-CJK dont need to translate this message, just copy and paste"}, "disable_retweet_hotkey": { "message": "リツイートのホットキーを無効化 (T)" }, "disable_like_hotkey": { "message": "いいねのホットキーを無効化 (L)" }, "enable_extension_compatibility": { "message": "拡張機能の互換性モードを有効にする (OldTwitterで拡張機能を動作させたい場合にのみ有効にしてください)" }, @@ -551,7 +551,7 @@ "quotes": { "message": "引用" }, "disable_find_hotkey": { "message": "検索ホットキーを無効化 (F)" }, "follow_system_settings_dark_mode": { "message": "システムの設定に従ってダークモードを切り替える" }, - "modern_ui": { "message": "2018年のTwitterデザインを使用する(丸いアイコンとボタンなどのUIが変更されます。)" }, + "modern_ui": { "message": "後期UIに切り替える" }, "show_exact_values": { "message": "リツイート数、いいね数、フォロワー数などを正確に表示する" }, "hide_timeline_types": { "message": "ホームの「タイムラインの種類」スイッチを隠す" }, "autotranslation": { "message": "自動翻訳" }, @@ -584,9 +584,9 @@ "transition_profile_banner": { "message": "プロフィールバナーに自動翻訳を使用する" }, "hide_original_languages": { "message": "自動翻訳時に翻訳前の言語を非表示にする" }, "nonexistent_user": { "message": "このアカウントは存在しません" }, - "nonexistent_user_desc": { "message": "アカウントが削除されてるか、ユーザー名が間違えてる可能性がございます。キーワードを変えて再度検索してみてください。" }, + "nonexistent_user_desc": { "message": "キーワードを変えて検索してみてください。" }, "suspended_user": { "message": "アカウントは凍結されています" }, - "suspended_user_desc": { "message": "残念ながら、このアカウントはTwitterの利用規約に違反したため、アカウントが凍結されました。" }, + "suspended_user_desc": { "message": "Twitterでは、Twitterルールに違反しているアカウントを凍結しています。" }, "custom_downloadtemplate": { "message": "ファイル名テンプレートのカスタマイズ" }, "custom_downloadtemplate_text": { "message": "メディア付きのツイートをダウンロードする際のファイル名テンプレートをカスタマイズ出来ます。" }, "save_downloadtemplate": { "message": "ファイル名テンプレートを保存する" }, From e4f71ee5517fa0324c49021777eea2b151dd4157 Mon Sep 17 00:00:00 2001 From: sayan <54yan@pm.me> Date: Sun, 15 Mar 2026 22:35:18 -0400 Subject: [PATCH 02/23] change x chat iframe URL --- layouts/header/script.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/layouts/header/script.js b/layouts/header/script.js index 870c7f2a..2fdefe22 100644 --- a/layouts/header/script.js +++ b/layouts/header/script.js @@ -1398,7 +1398,7 @@ let userDataFunction = async user => { modal = createModal(html`
- +
`, "inbox-modal", () => { From ec80bc3cec7ea6396d6d8f67ace3303c8f158078 Mon Sep 17 00:00:00 2001 From: Jaehoon You Date: Wed, 18 Mar 2026 15:55:48 +0900 Subject: [PATCH 03/23] update challenge code regex --- scripts/twchallenge.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/twchallenge.js b/scripts/twchallenge.js index a39a58e5..73fd4082 100644 --- a/scripts/twchallenge.js +++ b/scripts/twchallenge.js @@ -201,7 +201,8 @@ async function initChallenge() { ).map((svg) => svg.outerHTML); let vendorCode = homepageData.match(/vendor.(\w+).js"/)[1]; - let challengeCode = homepageData.match(/"ondemand.s":"(\w+)"/)[1]; + let challengePos = homepageData.match(/(\d+):"ondemand.s"/)[1]; + let challengeCode = homepageData.match(new RegExp(`${challengePos}:"(\\w+)"`))[1]; OLDTWITTER_CONFIG.verificationKey = verificationKey; From e2a7d3bcceb045c767dfc00a30a54370038731ef Mon Sep 17 00:00:00 2001 From: dimden Date: Wed, 18 Mar 2026 11:11:40 +0100 Subject: [PATCH 04/23] bump ver --- manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manifest.json b/manifest.json index c7c1728a..922ff22a 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "name": "Old Twitter Layout (2026)", "description": "__MSG_ext_description__", - "version": "1.9.6", + "version": "1.9.6.1", "manifest_version": 3, "homepage_url": "https://github.com/dimdenGD/OldTwitter", "background": { From 53fc364c59ee4bb4cc1da4f8cff91bc70d93ea85 Mon Sep 17 00:00:00 2001 From: Yanstory <862415702@qq.com> Date: Wed, 18 Mar 2026 18:52:47 +0800 Subject: [PATCH 05/23] Update zh_CN --- _locales/zh_CN/messages.json | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/_locales/zh_CN/messages.json b/_locales/zh_CN/messages.json index fa52c468..af0c48e3 100644 --- a/_locales/zh_CN/messages.json +++ b/_locales/zh_CN/messages.json @@ -395,6 +395,7 @@ "copy_tweet_links_as": { "message": "将推特链接以此域名复制:", "example": "->Copy links as<- vxtwitter.com" }, "use_new_icon": { "message": "标签页图标使用新版 Logo(当然,不是X)" }, "update_timeline_automatically": { "message": "在有新推文时自动更新时间线" }, + "keep_timeline_position": { "message": "更新时间线时保持当前位置" }, "chrono_no_retweets": { "message": "时间线(不含转推)" }, "chrono_retweets": { "message": "时间线(仅有转推)" }, "hide_trends": { "message": "隐藏趋势" }, @@ -461,7 +462,7 @@ "content_you_see": {"message": "您看到的内容", "description":"Setting Text"}, "use_old_style_reply": {"message": "使用旧版回复提及样式"}, "algov2": { "message": "算法时间线(“为你推荐”)" }, - "chrono_help": { "message": "经典的时间线(“正在关注”),将会在顶部显示最近的转推与推文,没有其它多余的内容。" }, + "chrono_help": { "message": "经典的时间线(“正在关注 - 最近排序”),将会在顶部显示最近的转推与推文,没有其它多余的内容。" }, "chrono_no_retweets_help": { "message": "和第一个类似,但去除了转推。" }, "chrono_retweets_help": { "message": "和第一个类似,但只保留转推。" }, "chrono_social_help": { "message": "经典时间线内偶尔插入算法时间线中的“某人喜欢”与“某人关注”。" }, @@ -652,5 +653,8 @@ "show_based_in": { "message": "显示账号所在地" }, "based_in": { "message": "位于" }, "based_in_vpn": { "message": "(VPN)" }, - "new_gallery": { "message": "个人资料页媒体页面使用新画廊(宫格)样式" } + "new_gallery": { "message": "个人资料页媒体页面使用新画廊(宫格)样式" }, + "popular_from_follows": { "message": "来自关注的热门" }, + "popular_from_follows_help": { "message": "将只会显示你所关注的人的热门推文(“正在关注 - 热门排序”)。" }, + "use_x_chat": { "message": "使用 X Chat 替代 OldTwitter 的消息界面" } } From 1976aa3738ed93b2beb65df05458e41f43bc0342 Mon Sep 17 00:00:00 2001 From: Maxokie <97196757+Maxokie@users.noreply.github.com> Date: Wed, 18 Mar 2026 20:37:11 +0100 Subject: [PATCH 06/23] Update messages.json --- _locales/fr/messages.json | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/_locales/fr/messages.json b/_locales/fr/messages.json index 7e9640cc..d9437546 100644 --- a/_locales/fr/messages.json +++ b/_locales/fr/messages.json @@ -395,6 +395,7 @@ "copy_tweet_links_as": { "message": "Copier les liens de tweets en", "example": "->Copy links as<- vxtwitter.com" }, "use_new_icon": { "message": "Utiliser le nouveau logo comme icône d'onglet" }, "update_timeline_automatically": { "message": "Mise à jour automatique de la chronologie en cas de nouveaux tweets. Cette option est expérimentale, ne l'utilisez que si vous voulez constamment être en haut de la chronologie, elle ne sera pas mise à jour automatiquement lorsque vous aurez fait défiler environ plus de 15 tweets vers le bas." }, + "keep_timeline_position": { "message": "Conserver la position de la chronologie lors de la mise à jour." }, "chrono_no_retweets": { "message": "Chronologique inversé (sans retweets)" }, "chrono_retweets": { "message": "Chronologique inversé (seulement retweets)" }, "hide_trends": { "message": "Masquer les tendances" }, @@ -647,5 +648,14 @@ "suspended_user_desc": { "message": "Le profil que vous essayez de voir est suspendu." }, "show_boring_indicators": { "message": "Afficher un indicateur sur la page des abonnés/abonnements si le dernier tweet de la personne est un retweet, une citation, inexistant ou ancien" }, "hide_original_languages":{"message": "Cacher le message original lorsqu'il est traduit" }, - "blocked": { "message": "bloqué.e" } + "blocked": { "message": "bloqué.e" }, + "use_retweeted_id": { "message": "Lorsqu'on aime ou retweete un retweet, notifier l'utilisateur qui a retweeté." }, + "show_based_in": { "message": "Afficher là où le compte est basé" }, + "based_in": { "message": "Basé à :" }, + "based_in_vpn": { "message": "(VPN)" }, + "new_gallery": { "message": "Utiliser la nouvelle galerie pour la page média du profil" }, + "popular_from_follows": { "message": "Populaire parmi vos abonnements" }, + "popular_from_follows_help": { "message": "Cela affichera uniquement les tweets récents les plus populaires venant des personnes que vous suivez." }, + "use_x_chat": { "message": "Utiliser X Chat au lieu des messages privés d'OldTwitter." } } + From e6e1e5bd8af94ecc7b168b397db20794aeb39238 Mon Sep 17 00:00:00 2001 From: Jaehoon You Date: Sat, 21 Mar 2026 08:42:27 +0900 Subject: [PATCH 07/23] fix list not shown due to validation error and target user id variable changes --- scripts/apis.js | 13 ++++++++----- scripts/helpers.js | 6 +++--- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/scripts/apis.js b/scripts/apis.js index 2307e77e..9d234a63 100644 --- a/scripts/apis.js +++ b/scripts/apis.js @@ -8578,11 +8578,14 @@ const API = { ) .then((i) => i.json()) .then((data) => { - if (data.errors && data.errors[0].code === 32) { - return reject("Not logged in"); - } - if (data.errors && data.errors[0]) { - return reject(data.errors[0].message); + if (data.errors) { + if (data.errors[0].code === 32) { + return reject("Not logged in"); + } else if (data.errors[0].code === 214) { + console.warn("Validation Failed: " + data.errors[0].message); + } else { + return reject(data.errors[0].message); + } } chrome.storage.local.set({ listData: {} }, () => {}); resolve( diff --git a/scripts/helpers.js b/scripts/helpers.js index afb5c966..6b73840e 100644 --- a/scripts/helpers.js +++ b/scripts/helpers.js @@ -3402,7 +3402,7 @@ async function appendTweet(t, timelineContainer, options = {}) { `); let lists = await API.list.getOwnerships( user.id_str, - t.user.id_str + t.user_id_str ); let container = document.getElementById("modal-lists"); for (let i in lists) { @@ -3465,7 +3465,7 @@ async function appendTweet(t, timelineContainer, options = {}) { if (l.is_member) { await API.list.removeMember( l.id_str, - t.user.id_str + t.user_id_str ); l.is_member = false; listElement.getElementsByClassName( @@ -3474,7 +3474,7 @@ async function appendTweet(t, timelineContainer, options = {}) { } else { await API.list.addMember( l.id_str, - t.user.id_str + t.user_id_str ); l.is_member = true; listElement.getElementsByClassName( From 8315beb00eeb2af901aee93e241404800c9d8b55 Mon Sep 17 00:00:00 2001 From: dimden Date: Wed, 25 Mar 2026 11:53:51 +0100 Subject: [PATCH 08/23] update apis --- scripts/apis.js | 76 ++++++++++++++++++++---------------------- scripts/injection.js | 21 ------------ scripts/twchallenge.js | 3 -- 3 files changed, 37 insertions(+), 63 deletions(-) diff --git a/scripts/apis.js b/scripts/apis.js index 9d234a63..66ca4ad6 100644 --- a/scripts/apis.js +++ b/scripts/apis.js @@ -4591,7 +4591,6 @@ const API = { possibly_sensitive: false, }, semantic_annotation_ids: [], - dark_request: false, }; if (tweet.card_uri) { variables.card_uri = tweet.card_uri; @@ -4649,7 +4648,7 @@ const API = { `/i/api/graphql/${ parsedTweet.weightedLength > 280 ? "cuvrhmg0s4pGaLWV68NNnQ/CreateNoteTweet" - : "I_J3_LvnnihD0Gjbq5pD2g/CreateTweet" + : "zkcFc6F-RKRgWN8HUkJfZg/CreateTweet" }`, { method: "POST", @@ -4657,7 +4656,7 @@ const API = { authorization: OLDTWITTER_CONFIG.public_token, "x-csrf-token": OLDTWITTER_CONFIG.csrf, "x-twitter-auth-type": "OAuth2Session", - "content-type": "application/json; charset=utf-8", + "content-type": "application/json", "x-twitter-client-language": LANGUAGE ? LANGUAGE : navigator.language @@ -4667,32 +4666,11 @@ const API = { credentials: "include", body: JSON.stringify({ variables, - features: { - c9s_tweet_anatomy_moderator_badge_enabled: true, - tweetypie_unmention_optimization_enabled: true, - responsive_web_edit_tweet_api_enabled: true, - graphql_is_translatable_rweb_tweet_is_translatable_enabled: true, - view_counts_everywhere_api_enabled: true, - longform_notetweets_consumption_enabled: true, - responsive_web_twitter_article_tweet_consumption_enabled: false, - tweet_awards_web_tipping_enabled: false, - responsive_web_home_pinned_timelines_enabled: true, - longform_notetweets_rich_text_read_enabled: true, - longform_notetweets_inline_media_enabled: true, - responsive_web_graphql_exclude_directive_enabled: true, - verified_phone_label_enabled: false, - freedom_of_speech_not_reach_fetch_enabled: true, - standardized_nudges_misinfo: true, - tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled: true, - responsive_web_media_download_video_enabled: false, - responsive_web_graphql_skip_user_profile_image_extensions_enabled: false, - responsive_web_graphql_timeline_navigation_enabled: true, - responsive_web_enhance_cards_enabled: false, - }, + features: {"premium_content_api_read_enabled":false,"communities_web_enable_tweet_community_results_fetch":true,"c9s_tweet_anatomy_moderator_badge_enabled":true,"responsive_web_grok_analyze_button_fetch_trends_enabled":false,"responsive_web_grok_analyze_post_followups_enabled":true,"responsive_web_jetfuel_frame":true,"responsive_web_grok_share_attachment_enabled":true,"responsive_web_grok_annotations_enabled":true,"responsive_web_edit_tweet_api_enabled":true,"graphql_is_translatable_rweb_tweet_is_translatable_enabled":true,"view_counts_everywhere_api_enabled":true,"longform_notetweets_consumption_enabled":true,"responsive_web_twitter_article_tweet_consumption_enabled":true,"tweet_awards_web_tipping_enabled":false,"content_disclosure_indicator_enabled":true,"content_disclosure_ai_generated_indicator_enabled":true,"responsive_web_grok_show_grok_translated_post":false,"responsive_web_grok_analysis_button_from_backend":true,"post_ctas_fetch_enabled":true,"longform_notetweets_rich_text_read_enabled":true,"longform_notetweets_inline_media_enabled":false,"profile_label_improvements_pcf_label_in_post_enabled":true,"responsive_web_profile_redirect_enabled":false,"rweb_tipjar_consumption_enabled":false,"verified_phone_label_enabled":false,"articles_preview_enabled":true,"responsive_web_grok_community_note_auto_translation_is_enabled":false,"responsive_web_graphql_skip_user_profile_image_extensions_enabled":false,"freedom_of_speech_not_reach_fetch_enabled":true,"standardized_nudges_misinfo":true,"tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled":true,"responsive_web_grok_image_annotation_enabled":true,"responsive_web_grok_imagine_annotation_enabled":true,"responsive_web_graphql_timeline_navigation_enabled":true,"responsive_web_enhance_cards_enabled":false}, queryId: parsedTweet.weightedLength > 280 ? "cuvrhmg0s4pGaLWV68NNnQ" - : "I_J3_LvnnihD0Gjbq5pD2g", + : "zkcFc6F-RKRgWN8HUkJfZg", }), } ) @@ -4763,7 +4741,12 @@ const API = { authorization: OLDTWITTER_CONFIG.public_token, "x-csrf-token": OLDTWITTER_CONFIG.csrf, "x-twitter-auth-type": "OAuth2Session", - "content-type": "application/json; charset=utf-8", + "content-type": "application/json", + "x-twitter-client-language": LANGUAGE + ? LANGUAGE + : navigator.language + ? navigator.language + : "en", }, credentials: "include", body: JSON.stringify({ @@ -4791,7 +4774,12 @@ const API = { authorization: OLDTWITTER_CONFIG.public_token, "x-csrf-token": OLDTWITTER_CONFIG.csrf, "x-twitter-auth-type": "OAuth2Session", - "content-type": "application/json; charset=utf-8", + "content-type": "application/json", + "x-twitter-client-language": LANGUAGE + ? LANGUAGE + : navigator.language + ? navigator.language + : "en", }, credentials: "include", body: JSON.stringify({ @@ -4813,7 +4801,7 @@ const API = { }, retweet: (id) => { return new Promise((resolve, reject) => { - fetch(`/i/api/graphql/ojPdsZsimiJrUGLR1sjUtA/CreateRetweet`, { + fetch(`/i/api/graphql/mbRO74GrOvSfRcJnlMapnQ/CreateRetweet`, { method: "POST", headers: { authorization: @@ -4829,8 +4817,8 @@ const API = { }, credentials: "include", body: JSON.stringify({ - variables: { tweet_id: id, dark_request: false }, - queryId: "ojPdsZsimiJrUGLR1sjUtA", + variables: { tweet_id: id }, + queryId: "mbRO74GrOvSfRcJnlMapnQ", }), }) .then((i) => i.json()) @@ -4848,18 +4836,23 @@ const API = { }, unretweet: (id) => { return new Promise((resolve, reject) => { - fetch(`/i/api/graphql/iQtK4dl5hBmXewYZuEOKVw/DeleteRetweet`, { + fetch(`/i/api/graphql/ZyZigVsNiFO6v1dEks1eWg/DeleteRetweet`, { method: "POST", headers: { authorization: OLDTWITTER_CONFIG.public_token, "x-csrf-token": OLDTWITTER_CONFIG.csrf, "x-twitter-auth-type": "OAuth2Session", - "content-type": "application/json; charset=utf-8", + "content-type": "application/json", + "x-twitter-client-language": LANGUAGE + ? LANGUAGE + : navigator.language + ? navigator.language + : "en", }, credentials: "include", body: JSON.stringify({ - variables: { source_tweet_id: id, dark_request: false }, - queryId: "iQtK4dl5hBmXewYZuEOKVw", + variables: { source_tweet_id: id }, + queryId: "ZyZigVsNiFO6v1dEks1eWg", }), }) .then((i) => i.json()) @@ -4877,18 +4870,23 @@ const API = { }, delete: (id) => { return new Promise((resolve, reject) => { - fetch(`/i/api/graphql/VaenaVgh5q5ih7kvyVjgtg/DeleteTweet`, { + fetch(`/i/api/graphql/nxpZCY2K-I6QoFHAHeojFQ/DeleteTweet`, { method: "POST", headers: { authorization: OLDTWITTER_CONFIG.public_token, "x-csrf-token": OLDTWITTER_CONFIG.csrf, "x-twitter-auth-type": "OAuth2Session", - "content-type": "application/json; charset=utf-8", + "content-type": "application/json", + "x-twitter-client-language": LANGUAGE + ? LANGUAGE + : navigator.language + ? navigator.language + : "en", }, credentials: "include", body: JSON.stringify({ - variables: { tweet_id: id, dark_request: false }, - queryId: "VaenaVgh5q5ih7kvyVjgtg", + variables: { tweet_id: id }, + queryId: "nxpZCY2K-I6QoFHAHeojFQ", }), }) .then((i) => i.json()) diff --git a/scripts/injection.js b/scripts/injection.js index 23b5d593..fae6a3ca 100644 --- a/scripts/injection.js +++ b/scripts/injection.js @@ -705,27 +705,6 @@ let page = LOC_EN = LOC_EN_DATA; LOC_EN.extension_id = { message: chrome.runtime.id }; - try { - let cryptoKey = await readCryptoKey(); - console.log("Crypto key", cryptoKey); - if (cryptoKey) { - OLDTWITTER_CONFIG.deviceId = cryptoKey.deviceId; - } else { - OLDTWITTER_CONFIG.deviceId = localStorage.getItem("device_id"); - if (!OLDTWITTER_CONFIG.deviceId) { - OLDTWITTER_CONFIG.deviceId = uuidV4(); - localStorage.setItem("device_id", OLDTWITTER_CONFIG.deviceId); - } - } - } catch (e) { - console.error("Error reading crypto key", e); - OLDTWITTER_CONFIG.deviceId = localStorage.getItem("device_id"); - if (!OLDTWITTER_CONFIG.deviceId) { - OLDTWITTER_CONFIG.deviceId = uuidV4(); - localStorage.setItem("device_id", OLDTWITTER_CONFIG.deviceId); - } - } - LOC_EN.twitter_site_verification = { message: OLDTWITTER_CONFIG.verificationKey, }; diff --git a/scripts/twchallenge.js b/scripts/twchallenge.js index 73fd4082..a180fb2d 100644 --- a/scripts/twchallenge.js +++ b/scripts/twchallenge.js @@ -141,9 +141,6 @@ fetch = async function (url, options) { if (!options.headers["x-twitter-active-user"]) { options.headers["x-twitter-active-user"] = "yes"; } - if (!options.headers["X-Client-UUID"]) { - options.headers["X-Client-UUID"] = OLDTWITTER_CONFIG.deviceId; - } if (!url.startsWith("http:") && !url.startsWith("https:")) { let host = location.hostname; if (!["x.com", "twitter.com"].includes(host)) host = "x.com"; From df2ca69dc063a649d756b54b6ec903daf67e3b38 Mon Sep 17 00:00:00 2001 From: dimden Date: Sat, 28 Mar 2026 08:38:50 +0100 Subject: [PATCH 09/23] bump version --- manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manifest.json b/manifest.json index 922ff22a..38e35ee3 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "name": "Old Twitter Layout (2026)", "description": "__MSG_ext_description__", - "version": "1.9.6.1", + "version": "1.9.6.2", "manifest_version": 3, "homepage_url": "https://github.com/dimdenGD/OldTwitter", "background": { From 6a956453c6416093096ffb8e8a200623be9702e6 Mon Sep 17 00:00:00 2001 From: jakeayy Date: Thu, 9 Apr 2026 11:15:18 +0200 Subject: [PATCH 10/23] Add missing keys in Polish language --- README.md | 2 +- _locales/pl/messages.json | 86 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 86 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 175bdfe8..7d4b35e0 100644 --- a/README.md +++ b/README.md @@ -180,7 +180,7 @@ Turkish - [KayrabCebll](https://steamcommunity.com/id/KayrabCebll), [YordemEren] Italian - [krek](https://twitter.com/CactusInc420), [Francesco](https://twitter.com/FrancescoRosi27) Arabic - [Yours Truly,](https://twitter.com/schrotheneko) Thai - [0.21%BloodAlcohol](https://github.com/Silberweich) -Polish - lele, [nomi](https://twitter.com/youmaynomi) +Polish - lele, [nomi](https://twitter.com/youmaynomi), [jakeayy](https://twitter.com/jakeayy_) Vietnamese - [btmxh](https://github.com/btmxh) Traditional Chinese - [Oliver Tzeng(曾嘉禾)](https://github.com/olivertzeng), [cirx1e](https://github.com/cirx1e) Simplified Chinese - [am1006](https://github.com/am1006), [CarimoWuling](https://twitter.com/carimowuling) diff --git a/_locales/pl/messages.json b/_locales/pl/messages.json index 6c6682a6..ba2b0ad2 100644 --- a/_locales/pl/messages.json +++ b/_locales/pl/messages.json @@ -628,5 +628,89 @@ "accepted_conversation": { "message": "Zaakceptowano konwersację" }, "anniversary_tweet": { "message": "Pamiętasz, od kiedy korzystasz z Twittera? Ja tak!\n#MojeTwitteroweUrodziny" }, "you_shared_tweet": { "message": "Udostępniłeś(-aś) tweet" }, - "user_shared_tweet": { "message": "$NAME$ udostępnił(-a) tweet", "placeholders": { "name": { "content": "Display Name" } } } + "user_shared_tweet": { "message": "$NAME$ udostępnił(-a) tweet", "placeholders": { "name": { "content": "Display Name" } } }, + "always_show_link_color": { + "message": "Zawsze pokazuj własny kolor linków zamiast po najechaniu kursorem." + }, + "keep_timeline_position": { + "message": "Utrzymaj pozycje osi czasu po aktualizacji." + }, + "transition_profile_banner": { + "message": "Użyj przejścia na banerze profilu." + }, + "custom_downloadtemplate": { + "message": "Własny szablon pobrania" + }, + "custom_downloadtemplate_text": { + "message": "Pozwala na dostosowanie nazw plików podczas pobierania media tweeta." + }, + "save_downloadtemplate": { + "message": "Zapisz szablon pobrania" + }, + "custom_downloadtemplate_hintName1": { + "message": "{user_name}: Nazwa użytkownika." + }, + "custom_downloadtemplate_hintName2": { + "message": "{user_screen_name}: Nazwa konta użytkownika. (Przykład: @dril)" + }, + "custom_downloadtemplate_hintTime": { + "message": "{timestamp}: Data i czas publikacji tweeta." + }, + "custom_downloadtemplate_hintExtension": { + "message": "{extension}: Rozszerzenie pobranego pliku z tweeta." + }, + "custom_downloadtemplate_hintID": { + "message": "{id}: ID tweeta." + }, + "custom_downloadtemplate_hintIndex": { + "message": "{index}: Indeks dla każdego pliku do pobrania. (dla postów z wieloma media)" + }, + "custom_downloadtemplate_hintFilename": { + "message": "{filename}: Oryginalna nazwa pliku z pbs.twimg.com." + }, + "nonexistent_user": { + "message": "To konto nie istnieje" + }, + "nonexistent_user_desc": { + "message": "Spróbuj poszukać innego." + }, + "suspended_user": { + "message": "Konto zawieszone" + }, + "suspended_user_desc": { + "message": "Profil który próbujesz zobaczyć został zawieszony." + }, + "show_boring_indicators": { + "message": "Pokaż wskaźnik na stronie obserwujących/obserwowanych jak ostatni tweet osoby jest retweetem/cytatem/nie isnitejący/stary" + }, + "hide_original_languages": { + "message": "Ukryj oryginalne języki gdy przetłumaczone" + }, + "blocked": { + "message": "Zablokowano" + }, + "use_retweeted_id": { + "message": "Gdy lubisz lub retweetujesz retweet, powiadom osobę retweetowaną." + }, + "show_based_in": { + "message": "Pokaż gdzie znajduje się konto" + }, + "based_in": { + "message": "Znajduje się w:" + }, + "based_in_vpn": { + "message": "(VPN)" + }, + "new_gallery": { + "message": "Używaj nowej galerii dla strony media na profilu" + }, + "popular_from_follows": { + "message": "Popularne od obserwowanych" + }, + "popular_from_follows_help": { + "message": "To pokaże najpopularniejsze ostatnie tweety tylko od osób które obserwujesz." + }, + "use_x_chat": { + "message": "Użyj Czatu X zamiast DM-ów OldTwitter." + } } From 8c5dc500e5de5170099beab764be34070229ce44 Mon Sep 17 00:00:00 2001 From: jakeayy Date: Thu, 9 Apr 2026 14:14:22 +0200 Subject: [PATCH 11/23] add external fallback to font URLs fixes #1167 --- layouts/header/style.css | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/layouts/header/style.css b/layouts/header/style.css index 1f4cac69..75616275 100644 --- a/layouts/header/style.css +++ b/layouts/header/style.css @@ -44,15 +44,15 @@ @font-face { font-family: 'RosettaIcons'; - src: url(chrome-extension://__MSG_@@extension_id__/fonts/rosetta.woff); + src: url(chrome-extension://__MSG_@@extension_id__/fonts/rosetta.woff), url(https://dimden.dev/fonts/rosetta.woff); } @font-face { font-family: "edgeicons"; - src: url(chrome-extension://__MSG_@@extension_id__/fonts/edge-icons-Regular.woff); + src: url(chrome-extension://__MSG_@@extension_id__/fonts/edge-icons-Regular.woff), url(https://dimden.dev/fonts/edge-icons-Regular.woff); } @font-face { font-family: 'JustBird'; - src: url(chrome-extension://__MSG_@@extension_id__/fonts/JustBird.woff2); + src: url(chrome-extension://__MSG_@@extension_id__/fonts/JustBird.woff2), url(https://dimden.dev/fonts/JustBird.woff2); unicode-range: U+EA00; } h1, h2, h3, h4, h5, h6 { From f4930a57100f7d4ff4f2b6a697bfd2374e3637ab Mon Sep 17 00:00:00 2001 From: dimden Date: Thu, 9 Apr 2026 14:19:13 +0200 Subject: [PATCH 12/23] bump ver --- manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manifest.json b/manifest.json index 38e35ee3..dac0bb3a 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "name": "Old Twitter Layout (2026)", "description": "__MSG_ext_description__", - "version": "1.9.6.2", + "version": "1.9.6.3", "manifest_version": 3, "homepage_url": "https://github.com/dimdenGD/OldTwitter", "background": { From f017e4bc411c11122b8fff37c51c290f4bdfa45f Mon Sep 17 00:00:00 2001 From: Xnuk Shuman Date: Tue, 14 Apr 2026 00:17:56 +0900 Subject: [PATCH 13/23] Add ko translation --- _locales/ko/messages.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/_locales/ko/messages.json b/_locales/ko/messages.json index eb9101a8..8397cf61 100644 --- a/_locales/ko/messages.json +++ b/_locales/ko/messages.json @@ -1328,6 +1328,9 @@ "update_timeline_automatically": { "message": "타임라인의 새 트윗을 자동으로 갱신합니다." }, + "keep_timeline_position": { + "message": "업데이트 시 타임라인 위치를 유지합니다." + }, "chrono_no_retweets": { "message": "최신순 타임라인 (리트윗 없음)" }, @@ -2231,5 +2234,14 @@ }, "new_gallery": { "message": "프로필 미디어 페이지에 새 갤러리를 사용합니다" + }, + "popular_from_follows": { + "message": "팔로우 중인 계정의 인기 트윗" + }, + "popular_from_follows_help": { + "message": "팔로우 중인 계정의 최근 인기 트윗만 보여줍니다." + }, + "use_x_chat": { + "message": "OldTwitter DM 대신 X Chat를 사용합니다." } } \ No newline at end of file From 42e917370c6dadefb56eb3e7ffb9316b29d71beb Mon Sep 17 00:00:00 2001 From: myuu <46139605+myuubunny@users.noreply.github.com> Date: Mon, 13 Apr 2026 12:50:07 -0300 Subject: [PATCH 14/23] fix pt_BR locale typos --- _locales/pt_BR/messages.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/_locales/pt_BR/messages.json b/_locales/pt_BR/messages.json index 9d2d9a95..4fdf3b26 100644 --- a/_locales/pt_BR/messages.json +++ b/_locales/pt_BR/messages.json @@ -554,13 +554,13 @@ "message": "Quantidade mínima de retweets" }, "min_retweets_example": { - "message": "Example: 10 - somente tweets retweetados 10 vezes" + "message": "Exemplo: 10 - somente tweets retweetados 10 vezes" }, "min_favorites": { "message": "Quantidade mínima de favoritos" }, "min_favorites_example": { - "message": "Example: 10 - somente tweets com 10 curtidas" + "message": "Exemplo: 10 - somente tweets com 10 curtidas" }, "dates": { "message": "Datas" @@ -635,7 +635,7 @@ "message": "Ao apertar o botão sincronizar a cor escolhida irá ser enviada para nossa base de dados e será mostrada para outros usuários do OldTwitter." }, "color_years_ago": { - "message": "Se você já configurou alguma cor no Twitter (anos atrás, quando isso ainda existia), essa opção substituíra a cor antiga." + "message": "Se você já configurou alguma cor no Twitter (anos atrás, quando isso ainda existia), essa opção substituirá a cor antiga." }, "sync": { "message": "Sincronizar" @@ -2050,4 +2050,4 @@ "message": "$NAME$ compartilhou um tweet", "placeholders": { "name": { "content": "Display Name" } } } -} \ No newline at end of file +} From 6656ed977b82d6635766b959ca6beae806645d5d Mon Sep 17 00:00:00 2001 From: dimden Date: Fri, 24 Apr 2026 21:44:37 +0200 Subject: [PATCH 15/23] fix challenge solver --- sandbox.html | 63 +++++++++++++++++++++++++++++----------------------- 1 file changed, 35 insertions(+), 28 deletions(-) diff --git a/sandbox.html b/sandbox.html index 128fef27..54848d14 100644 --- a/sandbox.html +++ b/sandbox.html @@ -38,25 +38,34 @@ } let verif = document.querySelector('meta[name="twitter-site-verification"]'); verif.content = data.verificationCode; - let headerRegex = /(\d+):(.+)=>.+default:\(\)=>(\w)}\);/; - let headerMatch = challengeData.match(headerRegex); - if (!headerMatch) { - console.error('Uh oh, header not found!! Report to https://github.com/dimdenGD/OldTwitter/issues'); - event.source.postMessage({ action: 'initError', error: `Header not found at ${data.challengeCode} (${String(challengeData).slice(0, 500)}...)` }, event.origin); + const idMatch = challengeData.match(/\.push\(\[\[\d+\],\{(\d+):/); + if (!idMatch) { + console.error('Module ID not found'); + event.source.postMessage({ action: 'initError', error: 'Module ID not found' }, event.origin); initError = true; return; } + const id = idMatch[1]; + const defaultMatch = challengeData.match(/default:\(\)=>(\w+)\}\)/); + if (!defaultMatch) { + console.error('Default export not found'); + event.source.postMessage({ action: 'initError', error: 'Default export not found' }, event.origin); + initError = true; + return; + } + const defaultVar = defaultMatch[1]; // TO EXTENSION REVIEWERS (mostly Mozilla): // This script is part of Twitter's security challenge, before mindlessly rejecting extension actually review what code does please! It's in sandbox for a reason. // It only ever executes code from trusted Twitter domain, abs.twimg.com (specifically their script that generates security headers) // It's impossible to have it contained in extension itself, since it's generated dynamically // you can see where script is loaded in scripts/twchallenge.js // it also can't use any extension APIs, since it's contained in object url iframe - const patchedChallengeData = challengeData - .replace(headerRegex, '$1:$2=>{window._CHALLENGE=()=>$3;'); + const patchedChallengeData = challengeData.replace( + `default:()=>${defaultVar}`, + `default:(window._CHALLENGE=()=>${defaultVar})` + ); eval(patchedChallengeData); - let id = headerMatch[1]; // 1) Collect all module factories that have already been pushed const chunks = self.webpackChunk_twitter_responsive_web || []; const registry = {}; @@ -76,31 +85,29 @@ const module = { id, loaded: false, exports: {} }; cache[id] = module; - // Minimal helpers used by many bundles - wreq.d = (exports, definition) => { - for (const key in definition) { - Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); - } - }; - wreq.r = (exports) => { - if (typeof Symbol !== "undefined" && Symbol.toStringTag) { - Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" }); - } - Object.defineProperty(exports, "__esModule", { value: true }); - }; - wreq.n = (mod) => { - const getter = mod && mod.__esModule ? () => mod.default : () => mod; - wreq.d(getter, { a: getter }); - return getter; - }; - wreq.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop); - - // 3) Execute the module factory: (module, exports, __webpack_require__) factory(module, module.exports, wreq); module.loaded = true; return module.exports; } + + wreq.d = (exports, definition) => { + for (const key in definition) { + Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); + } + }; + wreq.r = (exports) => { + if (typeof Symbol !== "undefined" && Symbol.toStringTag) { + Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" }); + } + Object.defineProperty(exports, "__esModule", { value: true }); + }; + wreq.n = (mod) => { + const getter = mod && mod.__esModule ? () => mod.default : () => mod; + wreq.d(getter, { a: getter }); + return getter; + }; + wreq.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop); webpackChunk_twitter_responsive_web[1][1][id](chunks, cache, wreq); solver = window._CHALLENGE()(); event.source.postMessage({ action: 'ready' }, event.origin); From 5a56f99893077eb5a56edfc8e61d4ab3a6accb43 Mon Sep 17 00:00:00 2001 From: dimden Date: Fri, 24 Apr 2026 21:46:20 +0200 Subject: [PATCH 16/23] send user to new user on header error --- scripts/twchallenge.js | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/twchallenge.js b/scripts/twchallenge.js index a180fb2d..49943108 100644 --- a/scripts/twchallenge.js +++ b/scripts/twchallenge.js @@ -109,6 +109,7 @@ window.addEventListener("message", (e) => { ); console.error("Error initializing solver:"); console.error(data.error); + location.href = `${location.pathname}?newtwitter=true`; } else if (data.action === "ready") { solverReady = true; for (let task of solveQueue) { From b05992f98a700a001e37815ded98ac3b81e47708 Mon Sep 17 00:00:00 2001 From: dimden Date: Fri, 24 Apr 2026 21:47:33 +0200 Subject: [PATCH 17/23] bump ver --- manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manifest.json b/manifest.json index dac0bb3a..f512c4f3 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "name": "Old Twitter Layout (2026)", "description": "__MSG_ext_description__", - "version": "1.9.6.3", + "version": "1.9.6.4", "manifest_version": 3, "homepage_url": "https://github.com/dimdenGD/OldTwitter", "background": { From fc3f66130b4951cf23dc6df6d8a47b2016e8b405 Mon Sep 17 00:00:00 2001 From: Aman Karn Date: Sat, 25 Apr 2026 13:43:14 +0530 Subject: [PATCH 18/23] profile preview fixed --- layouts/header/script.js | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/layouts/header/script.js b/layouts/header/script.js index 870c7f2a..14d711bc 100644 --- a/layouts/header/script.js +++ b/layouts/header/script.js @@ -2576,12 +2576,27 @@ let userDataFunction = async user => { }); shadow.appendChild(div); - if(isSticky(el)) { + if(isSticky(el) && !el.closest('#search-results')) { el.after(userPreview); } else { let rects = el.getBoundingClientRect(); - userPreview.style.top = `${rects.top + window.scrollY+ 20}px`; - userPreview.style.left = `${rects.left + window.scrollX}px`; + let topValue; + + if (el.closest('#search-results')) { + let searchInput = document.getElementById('search-input'); + let searchRect = searchInput.getBoundingClientRect(); + + topValue = searchRect.top + window.scrollY + 40; + + userPreview.style.left = `${rects.left + window.scrollX - 320}px`; + userPreview.style.zIndex = "10000"; + } else { + topValue = rects.top + window.screenY + 60; + userPreview.style.left = `${rects.left + window.scrollX}px`; + } + + userPreview.style.top = `${topValue}px`; + let closestTweet = el.closest('.tweet'); if(closestTweet) { let linkColor = closestTweet.style.getPropertyValue('--link-color'); From 49b875bcd9326355f504990688f953b1a39c41d2 Mon Sep 17 00:00:00 2001 From: celestial04 Date: Sat, 25 Apr 2026 20:34:27 +0200 Subject: [PATCH 19/23] updated translation credits for FR --- README.md | 2 +- scripts/injection.js | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7d4b35e0..b5a1c217 100644 --- a/README.md +++ b/README.md @@ -164,7 +164,7 @@ These will work when reply/quote/new tweet modal is focused. English - [dimden](https://dimden.dev/) Russian - [dimden](https://dimden.dev/) Ukrainian - [dimden](https://dimden.dev/) -French - [Aurore C.](https://asuure.com/), [zdimension](https://twitter.com/zdimension_), [Pikatchoum](https://twitter.com/applitom45), [adriend](https://twitter.com/_adriend_), [celestial04_](https://twitter.com/celestial04_) +French - [Aurore C.](https://asuure.com/), [zdimension](https://twitter.com/zdimension_), [Pikatchoum](https://twitter.com/applitom45), [adriend](https://twitter.com/_adriend_), [celestial04_](https://twitter.com/clst04_), [_maxokie](https://x.com/_maxokie) Portuguese (Brazil) - [kigidere](https://twitter.com/kigidere), [guko](https://twitter.com/gukodev), [prophamoon](https://twitter.com/prophamoony) Spanish - [rogerpb98](https://twitter.com/anbulansia), [gaelcoral](https://twitter.com/gaelcoral), [hue](https://twitter.com/huey1116), Beelzenef, [elderreka](https://twitter.com/elderreka) Greek - [VasilisTheChu](https://pikachu.systems/) diff --git a/scripts/injection.js b/scripts/injection.js index fae6a3ca..9b4428b1 100644 --- a/scripts/injection.js +++ b/scripts/injection.js @@ -181,7 +181,9 @@ const TRANSLATORS = { ["zdimension", "/zdimension_"], ["Pikatchoum", "/applitom45"], ["adriend", "/_adriend_"], - ["celestial04_", "/celestial04_"], + ["clst04_", "/clst04_"], + ["_maxokie", "/_maxokie"] + ], pt_BR: [ ["kigi", "/kigidere"], From 239c56b0cdab1bfb512b84a7c08e3f27f849727e Mon Sep 17 00:00:00 2001 From: celestial04 Date: Sat, 25 Apr 2026 20:35:22 +0200 Subject: [PATCH 20/23] updated --- scripts/injection.js | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/injection.js b/scripts/injection.js index 9b4428b1..a7188d44 100644 --- a/scripts/injection.js +++ b/scripts/injection.js @@ -183,7 +183,6 @@ const TRANSLATORS = { ["adriend", "/_adriend_"], ["clst04_", "/clst04_"], ["_maxokie", "/_maxokie"] - ], pt_BR: [ ["kigi", "/kigidere"], From 220a41816b81109be45afe5d41edf6be40e191f6 Mon Sep 17 00:00:00 2001 From: dimden Date: Mon, 27 Apr 2026 19:38:01 +0200 Subject: [PATCH 21/23] fix oldtwitter --- manifest.json | 2 +- sandbox.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/manifest.json b/manifest.json index f512c4f3..865f0dd5 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "name": "Old Twitter Layout (2026)", "description": "__MSG_ext_description__", - "version": "1.9.6.4", + "version": "1.9.6.5", "manifest_version": 3, "homepage_url": "https://github.com/dimdenGD/OldTwitter", "background": { diff --git a/sandbox.html b/sandbox.html index 54848d14..e8e21585 100644 --- a/sandbox.html +++ b/sandbox.html @@ -38,7 +38,7 @@ } let verif = document.querySelector('meta[name="twitter-site-verification"]'); verif.content = data.verificationCode; - const idMatch = challengeData.match(/\.push\(\[\[\d+\],\{(\d+):/); + const idMatch = challengeData.match(/\.push\(\[\[\d+\],\{(\d+)[:(]/); if (!idMatch) { console.error('Module ID not found'); event.source.postMessage({ action: 'initError', error: 'Module ID not found' }, event.origin); From 81427bd151d48d18a5b66defb7b340d659f291a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=E2=98=B0Wi?= <40286070+DaGamerFiles@users.noreply.github.com> Date: Mon, 4 May 2026 09:19:07 +0700 Subject: [PATCH 22/23] Indonesian locale update added "preserve timeline position" and fixed word consistency --- _locales/id/messages.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/_locales/id/messages.json b/_locales/id/messages.json index f372a8d0..fd74cba6 100644 --- a/_locales/id/messages.json +++ b/_locales/id/messages.json @@ -395,6 +395,7 @@ "copy_tweet_links_as": { "message": "Salin tautan tweet sebagai", "example": "->Copy links as<- vxtwitter.com" }, "use_new_icon": { "message": "Gunakan logo baru sebagai ikon tab" }, "update_timeline_automatically": { "message": "Perbarui linimasa secara otomatis saat tweet baru muncul." }, + "keep_timeline_position": { "message": "Pertahankan posisi linimasa setelah diperbarui." }, "chrono_no_retweets": { "message": "Kronologi terbalik (tanpa retweet)" }, "chrono_retweets": { "message": "Kronologi terbalik (hanya retweet)" }, "hide_trends": { "message": "Sembunyikan tren" }, @@ -654,6 +655,6 @@ "based_in_vpn": { "message": "(VPN)" }, "new_gallery": { "message": "Gunakan galeri baru untuk halaman media profil" }, "popular_from_follows": { "message": "Populer dari yang diikuti" }, - "popular_from_follows_help": { "message": "Ini akan menampilkan tweet populer terkini hanya dari pengguna yang kamu ikuti." }, + "popular_from_follows_help": { "message": "Ini akan menampilkan tweet populer terkini hanya dari pengguna yang Anda ikuti." }, "use_x_chat": { "message": "Gunakan Obrolan X, bukan DM OldTwitter." } } From b273d19d15ac66a302c01db93e5eb82baca42378 Mon Sep 17 00:00:00 2001 From: sayan <54yan@pm.me> Date: Sun, 15 Mar 2026 22:35:18 -0400 Subject: [PATCH 23/23] change x chat iframe URL --- layouts/header/script.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/layouts/header/script.js b/layouts/header/script.js index 14d711bc..7d8a505b 100644 --- a/layouts/header/script.js +++ b/layouts/header/script.js @@ -1398,7 +1398,7 @@ let userDataFunction = async user => { modal = createModal(html`
- +
`, "inbox-modal", () => {